var cmd = DOpus.Create().Command(); var stt = DOpus.Create().StringTools(); var fsu = DOpus.FSUtil(); var fso = new ActiveXObject('Scripting.FileSystemObject'); var wsh = new ActiveXObject('WScript.Shell'); var exifColumns = DOpus.Create().Vector(); var exifTags = DOpus.Create().Map(); var vecBlob = DOpus.Create().Vector(); // -- Adjust to your system. Copy the path to exiftool.exe with 'Edit - Copy Other - Copy Full Pathnames (Double Backslashes)' var exeExifTool = fsu.Resolve('/bin\\exiftool\\exiftool.exe'); // -- Adjust to your preferences. Use double backslashes. var cacheFolder = fsu.Resolve('/profile\\ExifToolCache'); // Add extensions the script should filter // var specialExt = DOpus.Create().StringSetI('.iso', '.mkv'); var specialExt = DOpus.Create().StringSetI('.jpg', '.epub', '.txt'); // Pick one of the three options (by out-commenting the other two) to decide which files the script should process // var filterExt = 1; // process only files with a specialExt var filterExt = 0; // process all files // var filterExt = -1; // do not process files with a specialExt // Set to false if you don't want any logging var log = true; // Column definitions go here. // group, tag: reference for ExifTool (mandatory) // name, label, header: adjust to your preferences (optional) // justify: like Opus standard for columns (optional) // type: datetime, date, time, number. String, if left empty (optional) // defaultValue: value, if no tag is found via ExifTool (optional) // group, tag, name, label, header, defaultValue, justify, type exifColumns.push_back(DefineColumn('Canon', 'CanonExposureMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Canon', 'FocusMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Canon', 'MeteringMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Canon', 'NumAFPoints', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Canon', 'OneShotAFRelease', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Canon', 'ValidAFPoints', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'Aperture', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Composite', 'AvgBitrate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'CircleOfConfusion', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'Duration', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'FOV', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'FocalLength35efl', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'HyperfocalDistance', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'ImageSize', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'LensID', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'LightValue', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'Megapixels', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'Rotation', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Composite', 'ShootingMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'ShutterSpeed', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Composite', 'SubSecCreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('Composite', 'SubSecDateTimeOriginal', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('Composite', 'SubSecModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('EXE', 'CompanyName', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXE', 'MachineType', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXE', 'SubsystemVersion', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXE', 'TimeStamp', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('EXIF', 'ApertureValue', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'CreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('EXIF', 'DateTimeOriginal', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('EXIF', 'ExposureCompensation', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'ExposureMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'ExposureProgram', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'ExposureTime', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'FNumber', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'Flash', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'FocalLength', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'LensInfo', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'LensModel', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'LensSerialNumber', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'Make', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'Model', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'ModifyDate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'Orientation', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'XResolution', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'YResolution', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('EXIF', 'XPComment', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('ExifIFD', 'DateTimeOriginal', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('File', 'EncodingProcess', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('File', 'FileAccessDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('File', 'FileCreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('File', 'FileModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('File', 'FileTypeExtension', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'ApertureSetting', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'DateTimeOriginal', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('H264', 'ExposureProgram', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'ExposureTime', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'FNumber', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('H264', 'Focus', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'Gain', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'ImageHeight', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'ImageStabilization', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'ImageWidth', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'Make', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'Model', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'TimeCode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('H264', 'WhiteBalance', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('ID3', 'Genre', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('ID3', 'ReleaseTime', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('ID3', 'Subtitle', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('ID3', 'Year', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('M2TS', 'AudioBitrate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('M2TS', 'AudioChannels', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('M2TS', 'AudioSampleRate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('M2TS', 'Duration', '', '', '', '', '', 'time')); exifColumns.push_back(DefineColumn('M2TS', 'SurroundMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('M2TS', 'VideoStreamType', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('MakerNotes', 'CameraOrientation', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('MakerNotes', 'CanonExposureMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('MakerNotes', 'CanonFirmwareVersion', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('MakerNotes', 'CanonModelID', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('MakerNotes', 'ShutterCount', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('MakerNotes', 'WhiteBalance', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Matroska', 'DateTimeOriginal', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Matroska', 'DisplayHeight', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Matroska', 'DisplayWidth', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Matroska', 'Duration', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Matroska', 'ImageHeight', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Matroska', 'ImageWidth', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('Matroska', 'TrackNumber', '', '', '', '', 'number', '')); exifColumns.push_back(DefineColumn('PDF', 'CreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('PDF', 'Creator', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('PDF', 'ModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('PDF', 'PageCount', '', '', '', '', '', 'number')); exifColumns.push_back(DefineColumn('PDF', 'Producer', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('PDF', 'Title', '', '', '', '', 'left', '')); // exifColumns.push_back(DefineColumn('PDF', 'Title', 'PDF Title äöü ÄÖÜ ß Name', 'PDF Title äöü ÄÖÜ ß Label', 'PDF Title äöü ÄÖÜ ß Header', 'PDF Title äöü ÄÖÜ ß Default', 'left', '')); exifColumns.push_back(DefineColumn('QuickTime', 'AudioAvgBitrate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'CompressorID', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'ContentCreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'CreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'CreationDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'DateAcquired', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'DateTimeOriginal', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'Duration', '', '', '', '', '', 'time')); exifColumns.push_back(DefineColumn('QuickTime', 'EncodingTime', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'LocationDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'MajorBrand', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'Make', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'MediaCreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'MediaDuration', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'MediaModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'MinorVersion', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'Model', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'ModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'Title', '', '', '', 'äöü ÄÖÜ ß 123', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'TrackCreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'TrackDuration', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'TrackModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoAvgBitrate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoAvgFrameRate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoCodec', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoFrameRate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoMaxBitrate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoMaxFrameRate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'VideoSize', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'XResolution', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('QuickTime', 'YResolution', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('RIFF', 'AvgBytesPerSec', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('RIFF', 'BitsPerSample', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('RIFF', 'Encoding', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('RIFF', 'NumChannels', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('RIFF', 'SampleRate', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('Sony', 'FocusMode', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'CreationDateValue', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XML', 'DeviceManufacturer', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'DeviceModelName', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'DeviceSerialNo', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'VideoFormatVideoFrameCaptureFps', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'VideoFormatVideoFrameFormatFps', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'VideoFormatVideoFrameVideoCodec', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'VideoFormatVideoLayoutNumOfVerticalLine', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XML', 'VideoFormatVideoLayoutPixel', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Contributor', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'CreateDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XMP', 'Creator', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'CreatorTool', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Date', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XMP', 'DateCreated', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XMP', 'Description', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Format', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Headline', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'MetadataDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XMP', 'ModifyDate', '', '', '', '', '', 'datetime')); exifColumns.push_back(DefineColumn('XMP', 'Producer', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Subject', '', '', '', '', '', '')); exifColumns.push_back(DefineColumn('XMP', 'Title', '', '', '', '', 'left', '')); exifColumns.push_back(DefineColumn('XMP', 'XMPToolkit', '', '', '', '', '', '')); function DefineColumn(group, tag, name, label, header, defaultValue, justify, type) { var map = DOpus.Create().Map(); var tmp = (group + '-' + tag); map('group') = group; map('tag') = tag; map('name') = name == '' ? tmp : stt.Decode(name, 'utf8'); map('label') = label == '' ? tmp : stt.Decode(label, 'utf8'); map('header') = header == '' ? tmp : stt.Decode(header, 'utf8'); map('defaultValue') = defaultValue == '' ? '' : stt.Decode(defaultValue, 'utf8'); map('justify') = justify; map('type') = type; return map; } function OnInit(initData) { initData.name = 'ExifTool'; initData.desc = 'Provide columns for tags read via exiftool.exe'; initData.version = '2022-06-27'; initData.url = 'https://resource.dopus.com/t/exiftool-custom-columns/38975'; initData.default_enable = true; cmd.RunCommand('CreateFolder NAME="' + cacheFolder + '"'); Log('exeExifTool: ' + exeExifTool + (fsu.Exists(exeExifTool) ? ' - OK. File exists' : ' - Error. File not found!')); Log('cacheFolder: ' + cacheFolder + (fsu.Exists(cacheFolder) ? ' - OK. Folder exists' : ' - Error. Folder not found!')); } function OnAddColumns(AddColData) { for (var e = new Enumerator(exifColumns); !e.atEnd(); e.moveNext()) { var columnItem = e.item(); var col = AddColData.AddColumn(); col.multicol = true; col.label = columnItem('label'); col.header = columnItem('header'); col.justify = columnItem('justify'); col.name = columnItem('name'); col.type = columnItem('type'); col.method = 'OnColumn'; } } function OnColumn(scriptColData) { var item = scriptColData.item; var tab = scriptColData.tab; if (item.is_dir) return; if (!ProcessFile(item.ext)) return; if (fsu.GetItem(item.path).InGroup('Archives')) return; // ExifTool can't read from archives (I think) var cacheFile = fsu.GetItem(cacheFolder + '\\' + String(item.realpath).replace(':', '') + '.txt'); if (log) var startTime = DOpus.Create().Date(); if (!fsu.Exists(cacheFile) || cacheFile.modify.Compare(item.modify) < 0) { Log('Enumerating ' + tab.files.count + ' files in "' + tab.path + '"...', startTime); var argFile = fsu.GetTempFile(); var filesForExifTool = 0; for (var e = new Enumerator(tab.files); !e.atEnd(); e.moveNext()) { var tabItem = e.item(); if (!ProcessFile(tabItem.ext)) continue; var cacheTabItem = fsu.GetItem(cacheFolder + '\\' + String(tabItem.realpath).replace(':', '') + '.txt'); if (fsu.Exists(cacheTabItem) && cacheTabItem.modify.Compare(tabItem.modify) > 0) continue; argFile.Write('-short\n-duplicates\n-unknown\n-groupNames\n-tab\n-charset\nFileName=UTF8\n-textOut!\n' + cacheTabItem.path + '\\%f.%e.txt\n' + String(tabItem.realpath).replace(/\\$/, '') + '\n-execute\n'); Log(tabItem, startTime); filesForExifTool++; } argFile.Close(); Log('... Handing over ' + filesForExifTool + ' files to ExifTool...', startTime); var cmdLine = '"' + exeExifTool + '" -@ "' + argFile + '"'; Log(cmdLine, startTime); wsh.Run(cmdLine, 0, true); Log('... done!', startTime); } if (!fsu.Exists(cacheFile)) { Log('*** Error: cache file could not be created! ***'); Log('item: ' + item); Log('cacheFile: ' + cacheFile); Log(''); Log('cmdLine:'); Log(cmdLine); Log(''); return; } exifTags.clear(); vecBlob.clear(); var cf = cacheFile.Open(); var cfBlob = cf.Read(); var strBlob = stt.Decode(cfBlob, 'utf8'); vecBlob.assign(strBlob.split('\r\n')); for (var e = new Enumerator(vecBlob); !e.atEnd(); e.moveNext()) { var line = e.item().split('\t'); var group = line[0]; var tag = line[1]; var value = line[2]; var key = group + '-' + tag; exifTags(key) = value; } cf.Close(); for (var e = new Enumerator(exifColumns); !e.atEnd(); e.moveNext()) { var column = e.item(); var key = column('group') + '-' + column('tag'); var value = exifTags.exists(key) ? exifTags(key) : column('defaultValue'); if (value != '') { if (column('type') == 'datetime' || column('type') == 'date' || column('type') == 'time') { value = DOpus.Create().Date(value.replace(/:/g, '')); } else if (column('type') == 'number') { value = Number(value.replace(/s/g, '')); } else { // value = } } scriptColData.columns(column('name')).value = value; } } function ProcessFile(ext) { if (filterExt > 0 && specialExt.exists(ext)) return true; if (filterExt == 0) return true; if (filterExt < 0 && !specialExt.exists(ext)) return true; return false; } function Log(str, time) { if (!log) return; if (time) { var currTime = DOpus.Create().Date(); var gap = (currTime + currTime.ms - time - time.ms); DOpus.Output(padTime(gap) + ' ' + str); } else { DOpus.Output(str); } } function padTime(milliseconds) { var str = ('000000' + String(milliseconds)).slice(-6); var tmp = str.substring(0, 3) + ':' + str.substring(3, 6); tmp = tmp.replace(/^00/, ' '); tmp = tmp.replace(/^0/, ' '); return tmp; }