This script scans the selection for tags and labels. It lists the tags and labels it has found in the log panel and creates two dated text files with them in the source. Folders get scanned recursively. Reading metadata is time-consuming, you will need a bit of patience when scanning many files, especially media files.
// https://resource.dopus.com/t/list-tags-and-labels/41360
// 2022-05-31
function OnClick(clickData) {
var cmd = clickData.func.command;
var tab = clickData.func.sourcetab;
var fsu = DOpus.FSUtil();
var fso = new ActiveXObject('Scripting.FileSystemObject');
var tagSet = DOpus.Create().StringSet();
var labelSet = DOpus.Create().StringSet();
var currDate = DOpus.Create().Date().Format('D#yyyyMMdd-T#HHmmss');
cmd.deselect = false;
function GetTagsFromItem(item) {
var itemTags = item.metadata.tags;
if (typeof itemTags == 'undefined') return;
if (itemTags.count == 0) return;
for (var e = new Enumerator(itemTags); !e.atEnd(); e.moveNext()) {
tagSet.insert(e.item());
}
}
function GetLabelsFromItem(item) {
var itemLabels = item.Labels();
if (typeof itemLabels == 'undefined') return;
if (itemLabels.count == 0) return;
for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {
labelSet.insert(e.item());
}
}
if (tab.selected.count == 0) return;
cmd.RunCommand('Set UTILITY=otherlog');
DOpus.ClearOutput();
DOpus.Output('Enumerating...');
for (var e = new Enumerator(tab.selected); !e.atEnd(); e.moveNext()) {
var item = e.item();
if (item.is_dir) {
var folderEnum = fsu.ReadDir(item, 'r')
while (!folderEnum.complete) {
var folderItem = folderEnum.Next();
if (folderItem.is_dir) continue;
GetTagsFromItem(folderItem);
GetLabelsFromItem(folderItem);
}
} else {
GetTagsFromItem(item);
GetLabelsFromItem(item);
}
}
DOpus.Output('\n... done!');
var tagsFile = fso.CreateTextFile(tab.path + '\\Tags-' + currDate + '.txt');
DOpus.Output('\n\n*** Tags:\n');
if (tagSet.empty) {
DOpus.Output('<<<none>>>');
tagsFile.WriteLine('<<<none>>>');
} else {
for (var e = new Enumerator(tagSet); !e.atEnd(); e.moveNext()) {
DOpus.Output(e.item());
tagsFile.WriteLine(e.item());
}
}
tagsFile.Close();
var labelsFile = fso.CreateTextFile(tab.path + '\\Labels-' + currDate + '.txt');
DOpus.Output('\n\n*** Labels:\n');
if (labelSet.empty) {
DOpus.Output('<<<none>>>');
labelsFile.WriteLine('<<<none>>>');
} else {
for (var e = new Enumerator(labelSet); !e.atEnd(); e.moveNext()) {
DOpus.Output(e.item());
labelsFile.WriteLine(e.item());
}
}
labelsFile.Close();
}
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
<label>List Tags and Labels</label>
<tip>Scan selection for tags and labels</tip>
<icon1>#newcommand</icon1>
<function type="script">
<instruction>@script JScript</instruction>
<instruction>// https://resource.dopus.com/t/list-tags-and-labels/41360</instruction>
<instruction />
<instruction>// 2022-05-31</instruction>
<instruction />
<instruction>function OnClick(clickData) {</instruction>
<instruction> var cmd = clickData.func.command;</instruction>
<instruction> var tab = clickData.func.sourcetab;</instruction>
<instruction> var fsu = DOpus.FSUtil();</instruction>
<instruction> var fso = new ActiveXObject('Scripting.FileSystemObject');</instruction>
<instruction> var tagSet = DOpus.Create().StringSet();</instruction>
<instruction> var labelSet = DOpus.Create().StringSet();</instruction>
<instruction> var currDate = DOpus.Create().Date().Format('D#yyyyMMdd-T#HHmmss');</instruction>
<instruction> cmd.deselect = false;</instruction>
<instruction />
<instruction> function GetTagsFromItem(item) {</instruction>
<instruction> var itemTags = item.metadata.tags;</instruction>
<instruction> if (typeof itemTags == 'undefined') return;</instruction>
<instruction> if (itemTags.count == 0) return;</instruction>
<instruction> for (var e = new Enumerator(itemTags); !e.atEnd(); e.moveNext()) {</instruction>
<instruction> tagSet.insert(e.item());</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction />
<instruction> function GetLabelsFromItem(item) {</instruction>
<instruction> var itemLabels = item.Labels();</instruction>
<instruction> if (typeof itemLabels == 'undefined') return;</instruction>
<instruction> if (itemLabels.count == 0) return;</instruction>
<instruction> for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {</instruction>
<instruction> labelSet.insert(e.item());</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction />
<instruction> if (tab.selected.count == 0) return;</instruction>
<instruction />
<instruction> cmd.RunCommand('Set UTILITY=otherlog');</instruction>
<instruction> DOpus.ClearOutput();</instruction>
<instruction> DOpus.Output('Enumerating...');</instruction>
<instruction />
<instruction> for (var e = new Enumerator(tab.selected); !e.atEnd(); e.moveNext()) {</instruction>
<instruction> var item = e.item();</instruction>
<instruction> if (item.is_dir) {</instruction>
<instruction> var folderEnum = fsu.ReadDir(item, 'r')</instruction>
<instruction> while (!folderEnum.complete) {</instruction>
<instruction> var folderItem = folderEnum.Next();</instruction>
<instruction> if (folderItem.is_dir) continue;</instruction>
<instruction> GetTagsFromItem(folderItem);</instruction>
<instruction> GetLabelsFromItem(folderItem);</instruction>
<instruction> }</instruction>
<instruction> } else {</instruction>
<instruction> GetTagsFromItem(item);</instruction>
<instruction> GetLabelsFromItem(item);</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction />
<instruction> DOpus.Output('\n... done!');</instruction>
<instruction />
<instruction> var tagsFile = fso.CreateTextFile(tab.path + '\\Tags-' + currDate + '.txt');</instruction>
<instruction />
<instruction> DOpus.Output('\n\n*** Tags:\n');</instruction>
<instruction> if (tagSet.empty) {</instruction>
<instruction> DOpus.Output('<<<none>>>');</instruction>
<instruction> tagsFile.WriteLine('<<<none>>>');</instruction>
<instruction> } else {</instruction>
<instruction> for (var e = new Enumerator(tagSet); !e.atEnd(); e.moveNext()) {</instruction>
<instruction> DOpus.Output(e.item());</instruction>
<instruction> tagsFile.WriteLine(e.item());</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction> tagsFile.Close();</instruction>
<instruction />
<instruction> var labelsFile = fso.CreateTextFile(tab.path + '\\Labels-' + currDate + '.txt');</instruction>
<instruction />
<instruction> DOpus.Output('\n\n*** Labels:\n');</instruction>
<instruction> if (labelSet.empty) {</instruction>
<instruction> DOpus.Output('<<<none>>>');</instruction>
<instruction> labelsFile.WriteLine('<<<none>>>');</instruction>
<instruction> } else {</instruction>
<instruction> for (var e = new Enumerator(labelSet); !e.atEnd(); e.moveNext()) {</instruction>
<instruction> DOpus.Output(e.item());</instruction>
<instruction> labelsFile.WriteLine(e.item());</instruction>
<instruction> }</instruction>
<instruction> }</instruction>
<instruction> labelsFile.Close();</instruction>
<instruction>}</instruction>
</function>
</button>
Thanks for this! Can you point me to a method for having it match the filenames to the labels/tags output? I ran it through a large directory and while it enumerates the tags, I don't know which belongs to which file.
If you want an offline list of files and their tags, you can find all files with * (use wildcards) as a tag, then turn on the column which shows them, and use Tools > Print / Export Folder Listing to save it to a text file.
(The CSV or TSV formats are best, as then you don't have to worry about column widths, and you can import them into Excel or Google Sheets. Make sure the Export dialog is set up to include the columns you need as well. Full Path is probably one you would want.)
I've made some changes to the original @lxp script, but there are still two things I haven't been able to do, can someone help me?
Make the script work for all files/folders and not just selected files/folders.
That the TXT document also include the full path of the files, and not just the labels?
Thank
function OnClick(clickData) {
var cmd = clickData.func.command;
var tab = clickData.func.sourcetab;
var fsu = DOpus.FSUtil();
var fso = new ActiveXObject('Scripting.FileSystemObject');
var labelSet = DOpus.Create().StringSet();
var currDate = DOpus.Create().Date().Format('D#dd-MM-yy');
cmd.deselect = false;
function GetLabelsFromItem(item) {
var itemLabels = item.Labels();
if (typeof itemLabels == 'undefined') return;
if (itemLabels.count == 0) return;
for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {
labelSet.insert(e.item());
}
}
if (tab.selected.count == 0) return;
cmd.RunCommand('Set UTILITY=otherlog');
DOpus.ClearOutput();
for (var e = new Enumerator(tab.selected); !e.atEnd(); e.moveNext()) {
var item = e.item();
if (item.is_dir) {
var folderEnum = fsu.ReadDir(item, 'r')
while (!folderEnum.complete) {
var folderItem = folderEnum.Next();
if (folderItem.is_dir) continue;
GetLabelsFromItem(folderItem);
}
} else {
GetLabelsFromItem(item);
}
}
var labelsFile = fso.CreateTextFile(tab.path + '\\Etiquetas (' + currDate + ').txt');
DOpus.Output('ETIQUETAS ENCONTRADAS\n');
labelsFile.WriteLine('ETIQUETAS ENCONTRADAS\n');
if (labelSet.empty)
DOpus.Output('< ninguna >');
labelsFile.WriteLine('< ninguna >');
} else {
for (var e = new Enumerator(labelSet); !e.atEnd(); e.moveNext()) {
DOpus.Output(e.item());
labelsFile.WriteLine(e.item());
}
}
labelsFile.Close();
}
Thank you very much again @Chuck , I got it, inserting the line labelsFile.WriteLine(item.realpath);
I will show the complete code in case someone might be interested. This is executed from a button on the toolbar, in JScript mode, and its objective is to make a report, both in a TXT document and in the Utilities Panel, of all the files/folders that contain labels in the current folder (of recursive way).
function OnClick(clickData) {
var cmd = clickData.func.command;
var tab = clickData.func.sourcetab;
var fsu = DOpus.FSUtil();
var fso = new ActiveXObject('Scripting.FileSystemObject');
var labelSet = DOpus.Create().StringSet();
var currDate = DOpus.Create().Date().Format('D#dd-MM-yy');
cmd.deselect = false;
function GetLabelsFromItem(item) {
var itemLabels = item.Labels();
if (typeof itemLabels == 'undefined') return;
if (itemLabels.count == 0) return;
for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {
labelSet.insert(e.item());
}
}
cmd.RunCommand('Set UTILITY=otherlog');
DOpus.ClearOutput();
for (var e = new Enumerator(tab.all); !e.atEnd(); e.moveNext()) {
var item = e.item();
if (item.is_dir) {
var folderEnum = fsu.ReadDir(item, 'r')
while (!folderEnum.complete) {
var folderItem = folderEnum.Next();
if (folderItem.is_dir) continue;
GetLabelsFromItem(folderItem);
}
} else {
GetLabelsFromItem(item);
}
}
var labelsFile = fso.CreateTextFile(tab.path + '\\Labels (' + currDate + ').txt');
DOpus.Output('LABELS\n');
labelsFile.WriteLine('LABELS\n');
if (labelSet.empty) {
DOpus.Output('< none >');
labelsFile.WriteLine('< none >');
} else {
for (var e = new Enumerator(labelSet); !e.atEnd(); e.moveNext()) {
DOpus.Output(item.realpath);
DOpus.Output(e.item());
DOpus.Output("");
labelsFile.WriteLine(item.realpath);
labelsFile.WriteLine(e.item());
labelsFile.WriteLine("");
}
}
labelsFile.Close();
}
Hello @Chuck and @bytespiller, could you help me, please? Since yesterday I've been trying to solve this problem and I can't, and it hasn't been due to a lack of dedication because I've studied and tried a lot, a lot.
The problem I'm having is that all the labels found are always given the name of the last file in the folder, whether it has this label or not?
function OnClick(clickData) {
var cmd = clickData.func.command;
var tab = clickData.func.sourcetab;
var fsu = DOpus.FSUtil();
var fso = new ActiveXObject('Scripting.FileSystemObject');
var labelSet = DOpus.Create().StringSet();
cmd.deselect = false;
function GetLabelsFromItem(item) {
var itemLabels = item.Labels();
if (typeof itemLabels == 'undefined') return;
if (itemLabels.count == 0) return;
for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {
labelSet.insert(e.item());
}
}
cmd.RunCommand('Set UTILITY=otherlog');
DOpus.ClearOutput();
for (var e = new Enumerator(tab.all); !e.atEnd(); e.moveNext()) {
var item = e.item();
if (item.is_dir) {
var folderEnum = fsu.ReadDir(item, 'r')
while (!folderEnum.complete) {
var folderItem = folderEnum.Next();
if (folderItem.is_dir) continue;
GetLabelsFromItem(folderItem);
}
} else {
GetLabelsFromItem(item);
}
}
DOpus.Output('LABELS\n');
if (labelSet.empty) {
DOpus.Output('< none >');
} else {
for (var e = new Enumerator(labelSet); !e.atEnd(); e.moveNext()) {
DOpus.Output(item.realpath);
DOpus.Output(e.item());
DOpus.Output("");
}
}
}
The reason it's printing only the final file is because the item variable you're using always contains only the final file (the variable gets overwritten each loop and ends up with whatever was the last file in the loop).
Here's the modification where I've added a new filesWithLabels variable which is a Map type. It remembers all files with all their labels so it's easy to print the results:
function OnClick(clickData) {
var cmd = clickData.func.command;
var tab = clickData.func.sourcetab;
var fsu = DOpus.FSUtil();
var fso = new ActiveXObject('Scripting.FileSystemObject');
var labelSet = DOpus.Create().StringSet();
var filesWithLabels = DOpus.Create.Map();
cmd.deselect = false;
function GetLabelsFromItem(item) {
var itemLabels = item.Labels();
if (typeof itemLabels == 'undefined') return;
if (itemLabels.count == 0) return;
for (var e = new Enumerator(itemLabels); !e.atEnd(); e.moveNext()) {
labelSet.insert(e.item());
}
filesWithLabels(item.realpath) = itemLabels;
}
cmd.RunCommand('Set UTILITY=otherlog');
DOpus.ClearOutput();
for (var e = new Enumerator(tab.all); !e.atEnd(); e.moveNext()) {
var item = e.item();
if (item.is_dir) {
var folderEnum = fsu.ReadDir(item, 'r')
while (!folderEnum.complete) {
var folderItem = folderEnum.Next();
if (folderItem.is_dir) continue;
GetLabelsFromItem(folderItem);
}
} else {
GetLabelsFromItem(item);
}
}
DOpus.Output('LABELS\n');
if (labelSet.empty) {
DOpus.Output('< none >');
} else {
for (var e = new Enumerator(filesWithLabels); !e.atEnd(); e.moveNext()) {
var filepath = e.item(); // key
var labels = filesWithLabels(filepath); // values
DOpus.Output(filepath);
var strLabels = "";
for (var i = 0; i < labels.count; i++) {
strLabels += labels(i) + ", ";
}
strLabels = strLabels.slice(0, -2); // Gets rid of final comma & space ", "
DOpus.Output(strLabels);
DOpus.Output("");
}
}
}
This code will now display all the file paths with labels (multiple labels are comma-separated, see strLabels var).
@bytespiller No wonder I was not getting it, nothing I did is similar to what you did, who knows, knows. I have no words to thank you so much, THANK YOU SO MUCH!!!
Hi @bytespiller, me again, sorry, but I wanted to ask you something. I have the following labels...
The first ones (Colores) are applied automatically according to the type of file (images, audio, etc.), and the second (Estado) are applied by me. I would like the script to only consider the labels that I apply, that is, "Favorito", "Ok" and "Posición Actual".
I tried to create the following condition but it didn't work...
PS: I think you should ask these questions in the appropriate Help section in a new post, as asking about modifications or uploading modified versions of the original script may dilute its original purpose. Your questions and doubts are always welcome, but this section is for posting finished scripts only.
Thank you so much @errante for the code, that worked PERFECT, as for the recommendation to ask in the appropriate section (Help section), I had not perceived that I was asking in the finished scripts section, sorry everyone, mushas thanks once again!!!