BackupMeta creates recovery files that let you restore Opus-specific metadata. Currently supported metadata are labels and user comments. This metadata is stored in the NTFS filesystem and might get deleted by other software or when files are moved to drives that don't support this type of metadata. Examples are non-NTFS drives, cloud storage, and archives except WinRAR.
The recovery file contains the Opus commands Properties and SetAttr that will restore the metadata. It should be self-explanatory and can easily be mass-edited to reflect e.g. changes in the drive/folder structure.
User comments may contain line breaks. Opus can read these multi-line comments, but cannot write them. For these files, the recovery file contains ExifTool commands.
How to set up and use
Save CommandBackupMeta.js.txt to
%appdata%\GPSoftware\Directory Opus\Script AddIns
Add the new command to a button, hotkey, context menu, etc. like any built-in command.
Optional: Get ExifTool and install it on your system. It's not needed to create the backup file.
Select the files and folders for which you want to create a recovery file, and run BackupMeta on them. Folders will be read recursively. The dated recovery file will show up in /profile\OpusBackup
. Make the necessary changes with a text editor. Depending on your system, you might need to adjust the path to exiftool.exe
.
To restore metadata, copy the commands from the recovery file to an Opus button and run them from there.
Things you might enjoy reading
How to use buttons and scripts from this forum
What are aliases?
The script's inner workings
JScript
function OnInit(initData) {
initData.name = 'BackupMeta';
initData.version = '2023-08-18';
initData.url = 'https://resource.dopus.com/t/backupmeta-backup-and-restore-opus-metadata/45497';
initData.desc = 'Write recovery commands for some metadata to a text file.';
initData.default_enable = true;
initData.min_version = '12.0';
}
function OnAddCommands(addCmdData) {
var cmd = addCmdData.AddCommand();
cmd.name = 'BackupMeta';
cmd.method = 'OnBackupMeta';
cmd.desc = 'Write recovery commands for some metadata to a text file.';
cmd.label = 'BackupMeta';
cmd.template = '';
cmd.hide = false;
cmd.icon = 'script';
}
function OnBackupMeta(scriptCmdData) {
var cmd = scriptCmdData.func.command;
var tab = scriptCmdData.func.sourcetab;
var fsu = DOpus.FSUtil();
cmd.deselect = false;
if (tab.selected.count == 0) return;
var progDlg = DOpus.Create().Command().progress;
progDlg.abort = true;
progDlg.delay = false;
progDlg.Init(tab.lister);
progDlg.SetTitle('BackupMeta');
progDlg.SetStatus('Enumerating selection...');
progDlg.SetFiles(tab.selected.count);
progDlg.Show();
var vec = DOpus.Create().Vector(tab.selected_files);
for (var e = new Enumerator(tab.selected_dirs); !e.atEnd(); e.moveNext()) {
var item = e.item();
vec.push_back(item);
progDlg.StepFiles(1);
progDlg.SetName(item);
var folderEnum = fsu.ReadDir(item, 'r');
while (!folderEnum.complete) {
if (progDlg.GetAbortState() == 'a') return;
var folderItem = folderEnum.Next();
vec.push_back(folderItem);
if (!folderItem.is_dir) continue;
progDlg.SetName(folderItem);
}
folderEnum.Close();
}
if (vec.empty) return;
progDlg.Restart();
progDlg.SetStatus('Generating commands for ' + vec.count + ' files...');
progDlg.SetFiles(vec.count);
var bakFileItem = fsu.GetItem(fsu.Resolve('/profile\\OpusBackup\\Recovery-' + DOpus.Create().Date().Format('D#yyyyMMdd-T#HHmmss') + '.txt'));
cmd.RunCommand('CreateFolder NAME="' + bakFileItem.path + '"');
var bakFile = bakFileItem.Open('wa'); // create a new file, always. If the file already exists it will be overwritten.
for (var e = new Enumerator(vec); !e.atEnd(); e.moveNext()) {
if (progDlg.GetAbortState() == 'a') break;
var item = e.item();
progDlg.StepFiles(1);
progDlg.SetName(item);
if (item.metadata == 'none') continue;
var itemLabels = item.Labels();
if (itemLabels.count > 0) {
var strLabels = '';
for (var ee = new Enumerator(itemLabels); !ee.atEnd(); ee.moveNext()) {
strLabels += ee.item() + ',';
}
var cmdLine = 'Properties' +
' FILE="' + item + '"' +
' SETLABEL="' + strLabels.slice(0, -1) + '"';
bakFile.Write(cmdLine + '\r\n');
}
var userComment = item.metadata.other.usercomment;
if (typeof userComment != 'undefined') {
if (userComment.indexOf('\r') < 0 && userComment.indexOf('\n') < 0) {
userComment = userComment.replace(/"/g, '""');
var cmdLine = 'SetAttr' +
' FILE="' + item + '"' +
' META' +
' "usercomment:' + userComment + '"';
} else {
userComment = userComment.replace(/\r/g, '\\r');
userComment = userComment.replace(/\n/g, '\\n');
userComment = userComment.replace(/"/g, '\\"');
var cmdLine = 'exiftool.exe' +
' -escapeC' +
' -UserComment="' + userComment + '"' +
' "' + item + '"';
}
bakFile.Write(cmdLine + '\r\n');
}
}
bakFile.Close();
cmd.RunCommand('Go' +
' PATH="' + bakFileItem + '"' +
' NEWTAB=findexisting' +
' OPENINDUAL');
}