Commands for Tag Management

Bellow are some commands to make it easier to manage tags on media files.

I am sharing just the callback functions, as I put them in a script with many other commands that are not relevant here.

  1. List Tags
  • Lists all unique tags for items in the current source directory.
function OnListTags(scriptCmdData) {
	var tags = {};
	
	for (var eSel = new Enumerator(scriptCmdData.func.sourcetab.all); !eSel.atEnd(); eSel.moveNext())
	{
		if (eSel.item().metadata.tags && eSel.item().metadata.tags.count != 0)
		{
			for (var iSel = new Enumerator(eSel.item().metadata.tags); !iSel.atEnd(); iSel.moveNext())
			{
				current_tag = iSel.item();
				tags[current_tag] = current_tag;
			}
		}
	}
	
	var tag_list = "";
	
	for (tag in tags) {
		tag_list += tag + "; ";
	}
	
	DOpus.Output("----------- List Tags -----------")
	DOpus.Output("Target: " + scriptCmdData.func.sourcetab.path);
	DOpus.Output("Tags: " + tag_list);
	DOpus.Output("---------------------------------");
}
  1. Enforce Standard Tag Names
  • Find and replace with a dictionary;
  • Dictionary hard-coded on the script;
  • Selected files only;
  • One-to-one and one-to-many;
function OnEnforceStandardTagNames(scriptCmdData) {
	var dict = {
		"1": "One",
		"A B": {"A": "", "B": ""}
		//"": "",
	}
	
	var Progress = scriptCmdData.Func.Command.Progress;
	Progress.pause = true; // Allow pause button.
	Progress.abort = true; // Allow abort button.
	Progress.Init(scriptCmdData.func.sourcetab, "Enforce Standard Tag Names");
	Progress.SetStatus("Enforcing standard tag names...");
	Progress.SetFiles(scriptCmdData.func.sourcetab.selected.count);
	DOpus.Delay(200);
	Progress.Show();
	
	var factory = DOpus.Create();
	var tagCmd = factory.Command();
	
	var eSel = new Enumerator(scriptCmdData.func.sourcetab.selected);
	while (!eSel.atEnd()) {
		// Handle progress flow control.
		var abortState = Progress.GetAbortState();
		if (abortState == "a")
			break; // Aborted.
		if (abortState == "p")
		{
			DOpus.Delay(500);
			continue; // Paused; restart the loop to see if we are still paused.
		}
		
		var current_item = eSel.item();
		
		// Handle progress display.
		Progress.SetName(current_item.name);
		Progress.SetType("file");
		
		if (eSel.item().metadata.tags && eSel.item().metadata.tags.count != 0)
		{
			//DOpus.Output("[Tag Replacement] Target: " + current_item.RealPath + ";");
			tagCmd.Clear();
			tagCmd.ClearFiles();
			tagCmd.AddFile(current_item);
			var replaceOptions = "";
			for (var iSel = new Enumerator(eSel.item().metadata.tags); !iSel.atEnd(); iSel.moveNext())
			{
				current_tag = iSel.item();
				for (key in dict) {
					if (current_tag == key) {
						replaceOptions += "-" + key + ";";
						logNote = "[Tag Replacement] Removed: " + key
						if (dict[key] != "") {
							if (typeof dict[key] == "string") {
								replaceOptions += "+" + dict[key] + ";";
								logNote += "; Added: " + dict[key];
							} else if (typeof dict[key] == "object") {
								for (nested_tag in dict[key]) {
									replaceOptions += "+" + nested_tag + ";";
									logNote += "; Added: " + nested_tag;
								}
							}
						}
						//DOpus.Output(logNote);
					}
				}
			}
			if (replaceOptions != "") {
				var replaceCmd = "SetAttr META=\"tags:" + replaceOptions + "\"";
				tagCmd.AddLine(replaceCmd);
				tagCmd.Run();
			} else {
				//DOpus.Output("[Tag Replacement] Nothing to do for this target.");
			}
		}
		
		// Update state data.
		Progress.StepFiles(1);
		DOpus.Delay(100);
		eSel.moveNext();
	}
}

The common use case is: list the unique tags in your items, create the dictionary with your preferred tags, then enforce their use.

To do (would be nice to have some day):

  • Conditional or Implications: if tag X and tag Y are present, add or remove tag Z.
  • Aliases: intercept search and add other relevant tags.
4 Likes