SyncLabels (Sync labels between files)

SyncLabels combines the labels of selected items (files and folders) from the source with those in the destination with the same name. By default, only explicitly assigned labels are processed. To include labels set via wildcard and label filters, add the switch INCLUDEIMPLICIT. The labels will be applied to both items in a pair.

Please note that the script works within collections but does not function in Flatview or Expanded Folders.

How to set up and use

:one: Save CommandSyncLabels.js.txt to   ↓

%appdata%\GPSoftware\Directory Opus\Script AddIns

:two: Add the new command to a button, hotkey, context menu, etc. like any built-in command, or run it from the FAYT Command field.

Example: Button
@keydown:none
SyncLabels

@keydown:ctrl
SyncLabels INCLUDEIMPLICIT
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>SyncLabels</label>
	<tip>Sync labels between files (Ctrl to include implicit labels)</tip>
	<icon1>#properties</icon1>
	<function type="normal">
		<instruction>@keydown:none</instruction>
		<instruction>SyncLabels</instruction>
		<instruction />
		<instruction>@keydown:ctrl</instruction>
		<instruction>SyncLabels INCLUDEIMPLICIT</instruction>
	</function>
</button>

Things you might enjoy reading

Labels and Status Icons

How to use buttons and scripts from this forum

The script's inner workings

JScript
function OnInit(initData) {
    initData.name = 'SyncLabels';
    initData.version = '2024-04-29';
    initData.url = 'https://resource.dopus.com/t/sync-labels-between-files/42543';
    initData.desc = 'Sync labels between files in source and destination';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

function OnAddCommands(addCmdData) {
    var cmd = addCmdData.AddCommand();
    cmd.name = 'SyncLabels';
    cmd.method = 'OnSyncLabels';
    cmd.desc = 'Sync labels between files in source and destination';
    cmd.label = '';
    cmd.template = 'includeimplicit/s';
    cmd.hide = false;
    cmd.icon = 'script';
}

function OnSyncLabels(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();

    cmd.deselect = false;

    if (tab.selected.count == 0) return;
    if (!dtab) return;

    var flags = args.includeimplicit ? '' : 'explicit';
    var vec = DOpus.Create().Vector();

    cmd.RunCommand('Set UTILITY=scriptlog');
    DOpus.ClearOutput();

    DOpus.Output('Enumerating...');
    DOpus.Output('');

    for (var e = new Enumerator(tab.selected); !e.atEnd(); e.moveNext()) {
        var srcItem = e.item();

        var dstItem = fsu.GetItem(fsu.Resolve(dtab.path + '\\' + srcItem.name));
        if (!fsu.Exists(dstItem)) continue;

        vec.assign(srcItem.Labels('', flags));
        vec.append(dstItem.Labels('', flags));
        vec.sort();
        vec.unique();

        if (vec.count == 0) continue;

        var labelString = '';
        for (var ee = new Enumerator(vec); !ee.atEnd(); ee.moveNext()) {
            if (labelString) labelString += ',';
            labelString += ee.item();
        }

        var cmdLine = 'Properties SETLABEL="' + labelString + '"';

        cmd.ClearFiles();
        cmd.AddFile(srcItem);
        cmd.AddFile(dstItem);

        DOpus.Output(srcItem);
        DOpus.Output(dstItem);
        DOpus.Output(cmdLine);
        DOpus.Output('');

        cmd.RunCommand(cmdLine);
    }

    DOpus.Output('... done.');
}
7 Likes

It's been a while since I've had to edit code so I'd like to doublecheck here that this would be theoretically possible.

Could this also handle subfolders if we added a recursive version of the function to it? As long as it checked to make sure that the folder existed in both the source and destination, I don't think it would cause any issues.

1 Like

Yes, this script can be adapted in many directions. Let it loop through subfolders, use other criteria than "same name" to pick sync pairs, sync the labels from more than two files, change the labels before writing them back... whatever you need.

1 Like

Update 2024-04-29

  • Converted to script command for easier handling
  • Added switch INCLUDEIMPLICIT
2 Likes