function OnInit(initData) { initData.name = 'SyncTags'; initData.version = '2025-05-17'; initData.url = 'https://resource.dopus.com/t/sync-tags-between-files/41616'; initData.desc = 'Sync tags between pairs of files in source and destination'; initData.default_enable = true; initData.min_version = '12.0'; } function OnAddCommands(addCmdData) { var cmd = addCmdData.AddCommand(); cmd.name = 'SyncTags'; cmd.method = 'OnSyncTags'; cmd.desc = 'Sync tags between pairs of files in source and destination'; cmd.label = ''; cmd.template = '' + 'from/k,' + 'to/k,' + 'pattern/o,' + 'recurse/s,' + 'dryrun/s'; cmd.hide = false; cmd.icon = 'script'; } function OnSyncTags(scriptCmdData) { var cmd = scriptCmdData.func.command; var tab = scriptCmdData.func.sourcetab; var dtab = scriptCmdData.func.desttab; var args = scriptCmdData.func.args; var fsu = DOpus.FSUtil(); var wld = fsu.NewWild(); cmd.deselect = false; var srcPath = fsu.Resolve(args.from ? args.from : tab.path); if (!fsu.Exists(srcPath)) { DOpus.Output('Source path not valid: ' + srcPath); return; } var dstPath = args.to || (dtab && dtab.path); if (dstPath) dstPath = fsu.Resolve(dstPath); if (!dstPath || !fsu.Exists(dstPath)) { DOpus.Output('Destination path not valid: ' + (dstPath || '(not set)')); return; } var itemsToEnum; if (args.from || args.recurse) { itemsToEnum = DOpus.Create().Vector(); var hasPattern = args.got_arg.pattern; if (hasPattern) { wld.Parse(args.pattern); } DOpus.Output('Enumerating...'); var folderEnum = fsu.ReadDir(srcPath, args.recurse ? 'r' : ''); while (!folderEnum.complete) { var folderItem = folderEnum.Next(); if (folderItem.is_dir) continue; if (hasPattern && !wld.Match(folderItem.name)) continue; itemsToEnum.push_back(folderItem); } folderEnum.Close(); DOpus.Output('... done.'); DOpus.Output(''); if (itemsToEnum.count == 0) { DOpus.Output('No matching items found in source path'); return; } } else { itemsToEnum = tab.selected_files; if (itemsToEnum.count == 0) { DOpus.Output('No items selected in source'); return; } } var vec = DOpus.Create().Vector(); DOpus.Output('Processing ' + itemsToEnum.count + ' files...' + (args.dryrun ? ' (dry run)' : '')); DOpus.Output(''); for (var e = new Enumerator(itemsToEnum); !e.atEnd(); e.moveNext()) { var srcItem = e.item(); if (srcItem.metadata == 'none') { DOpus.Output('skipped (no metadata): ' + srcItem); continue; } var destItem = fsu.GetItem(String(srcItem.realpath).replace(srcPath, dstPath)); if (!fsu.Exists(destItem)) { DOpus.Output('skipped (does not exist): ' + destItem); continue; } if (destItem.metadata == 'none') { DOpus.Output('skipped (no metadata): ' + destItem); continue; } vec.assign(srcItem.metadata.tags); vec.append(destItem.metadata.tags); vec.sort(); vec.unique(); // remove duplicates if (vec.empty) { DOpus.Output('skipped (no tags): ' + srcItem); continue; } var tagString = JoinObject(vec, ';'); var cmdLine = 'SetAttr META "tags:' + tagString + '"'; cmd.ClearFiles(); cmd.AddFile(srcItem); cmd.AddFile(destItem); DOpus.Output(''); DOpus.Output(srcItem); DOpus.Output(destItem); DOpus.Output(cmdLine); DOpus.Output(''); if (!args.dryrun) cmd.RunCommand(cmdLine); } DOpus.Output(''); DOpus.Output('... done.'); } function JoinObject(obj, str) { var tmp = ''; for (var e = new Enumerator(obj); !e.atEnd(); e.moveNext()) { if (tmp) tmp += str; tmp += e.item(); } return tmp; }