PrintMeta (Write metadata to text files)

This add-in creates the Script Command PrintMeta. It writes metadata of the selected files and folders to text files using Opus as well as ExifTool and Mediainfo.

The text filenames are based on the original filenames and receive an appendix. If files exist, the script will append a counter as needed. The script will never overwrite files. These different versions can easily be used with diff tools, if you want to analyze metadata manipulation, e.g. find out, how using ExifTool on files is reflected in Opus metadata.

By default, the files will be placed right next to the files for which they are created. In case this is not advisable (e.g. system folders) or possible (read-only media), the files will be written to /profile\OpusMeta.

The parameter TO lets you take control over the output directory.

PrintMeta TO=dest sends the files to the destination.

PrintMeta TO=D:\Test sends the files to D:\test.

PrintMeta TO=ask will prompt for a directory.

PrintMeta TO=source will keep the files in the source directory. Useful in Flatview, if you want to keep the files at the top level and not let them disappear in subfolders.

By default, text files will be generated by all three tools. The switches OPUS, EXIFTOOL, and MEDIAINFO let you specify, which output you want. E.g. PrintMeta EXIFTOOL OPUS will generate the files with ExifTool and Opus.

Opus can generate metadata info for files on FTP servers, but it's probably rather slow and the available info is reduced. It's better to copy the files to a local directory. ExifTool and MediaInfo cannot handle FTP.

The files generated by Opus list the metadata that is available from Opus' object model. The property names you'll find are similar to the keywords you can use in columns and with the SetAttr META command, but they are not the same! Have I missed any metadata? Let me know!

ExifTool will generate two files with all the metadata it finds, one written as tags, the other one as descriptions.

MediaInfo will generate its standard output and the extended version.

JScript
function OnInit(initData) {
    initData.name = 'PrintMeta';
    initData.version = '2022-11-13';
    initData.copyright = '';
    initData.url = 'https://resource.dopus.com/t/printmeta-write-metadata-to-text-files/42786';
    initData.desc = 'Write metadata of selected items to text files.';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

function OnAddCommands(addCmdData) {
    var cmd = addCmdData.AddCommand();
    cmd.name = 'PrintMeta';
    cmd.method = 'OnPrintMeta';
    cmd.desc = 'Write metadata of selected items to text files.';
    cmd.label = 'PrintMeta';
    cmd.template = 'opus/s,exiftool/s,mediainfo/s,to/k[source,dest,ask]';
    cmd.hide = false;
    cmd.icon = 'script';
}

function OnPrintMeta(scriptCmdData) {
    var cmd = scriptCmdData.func.command;
    var tab = scriptCmdData.func.sourcetab;
    var dtab = scriptCmdData.func.desttab;
    var args = scriptCmdData.func.args;
    var dlg = scriptCmdData.func.Dlg();
    var fsu = DOpus.FSUtil();
    var fso = new ActiveXObject('Scripting.FileSystemObject');

    // alternative destination for files sitting in forbidden folders
    var altDest = fsu.Resolve('/profile\\OpusMeta');
    // var altDest = fsu.Resolve('/desktop\\OpusMeta');

    // -- 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 system. Copy the path to MediaInfo.exe with 'Edit - Copy Other - Copy Full Pathnames (Double Backslashes)'
    var exeMediaInfo = fsu.Resolve('/bin\\MediaInfo.CLI\\MediaInfo.exe');

    function IsForbiddenDest(item) {
        var tmp = String(item);

        // Libraries are ok. We check early to not confuse fso later
        if (tmp.substring(0, 6) == 'lib://') return false;

        // Not allowed: 'This PC' & collections
        if (tmp.substring(0, 2) == '::') return true;
        if (tmp.substring(0, 7) == 'coll://') return true;
        if (tmp.substring(0, 6) == 'ftp://') return true;

        // Not allowed: specific folders (subfolders are ok)
        if (tmp == 'C:\\') return true;
        if (tmp == 'C:\\Users') return true;
        if (tmp == String(fsu.Resolve('/users'))) return true;
        if (tmp == String(fsu.Resolve('/dopusdata\\Script AddIns'))) return true;

        // Not allowed: specific folders and all their subfolders
        if (tmp.indexOf('C:\\Perl64') == 0) return true;
        if (tmp.indexOf(String(fsu.Resolve('/commonappdata'))) == 0) return true;
        if (tmp.indexOf(String(fsu.Resolve('/programfiles'))) == 0) return true;
        if (tmp.indexOf(String(fsu.Resolve('/programfilesx86'))) == 0) return true;
        if (tmp.indexOf(String(fsu.Resolve('/windows'))) == 0) return true;

        // Not allowed: specific drives and drive types
        var itemDrive = fsu.NewPath(item);
        itemDrive.Root();
        if (String(itemDrive) == 'Z:\\') return true;

        var itemDriveType = fso.GetDrive(itemDrive).DriveType;
        if (itemDriveType == 0) return true; // 0 = unknown
        if (itemDriveType == 4) return true; // 4 = CD-ROM

        return false;
    }

    function WriteOpus(item) {
        cmd.RunCommand('FileType NEW=.txt NEWNAME="norename:' + item.name + '.txt');
        var outFilePath = dstPath + '\\' + cmd.vars.Get('newfile');
        cmd.AddFile(outFilePath);
        DOpus.Output('---> ' + outFilePath + '\n');

        var outFile = fsu.OpenFile(outFilePath, 'wa');

        outFile.Write('Item:       ' + item.name + '\r\n');
        outFile.Write('Type:       ' + (item.is_dir ? 'folder' : 'file') + '\r\n');
        outFile.Write('Metadata:   ' + item.metadata + ' (primary type)' + '\r\n');

        outFile.Write('\r\n*** item ***\r\n');
        outFile.Write('    def_value:               ' + item.def_value + '\r\n');
        outFile.Write('    access:                  ' + item.access + '\r\n');
        outFile.Write('    access_utc:              ' + item.access_utc + '\r\n');
        outFile.Write('    accessed:                ' + item.accessed + '\r\n');
        outFile.Write('    accesseddate:            ' + item.accesseddate + '\r\n');
        outFile.Write('    accessedtime:            ' + item.accessedtime + '\r\n');
        outFile.Write('    attr:                    ' + item.attr + '\r\n');
        outFile.Write('    attr_text:               ' + item.attr_text + '\r\n');
        outFile.Write('    cdaterel:                ' + item.cdaterel + '\r\n');
        outFile.Write('    checked:                 ' + item.checked + '\r\n');
        outFile.Write('    create:                  ' + item.create + '\r\n');
        outFile.Write('    create_utc:              ' + item.create_utc + '\r\n');
        outFile.Write('    created:                 ' + item.created + '\r\n');
        outFile.Write('    createddate:             ' + item.createddate + '\r\n');
        outFile.Write('    createdtime:             ' + item.createdtime + '\r\n');
        outFile.Write('    current:                 ' + item.current + '\r\n');
        outFile.Write('    daterel:                 ' + item.daterel + '\r\n');
        outFile.Write('    disksize:                ' + item.disksize + '\r\n');
        outFile.Write('    disksizeauto:            ' + item.disksizeauto + '\r\n');
        outFile.Write('    disksizekb:              ' + item.disksizekb + '\r\n');
        outFile.Write('    disksizerel:             ' + item.disksizerel + '\r\n');
        outFile.Write('    display_name:            ' + item.display_name + '\r\n');
        outFile.Write('    ext:                     ' + item.ext + '\r\n');
        outFile.Write('    ext_m:                   ' + item.ext_m + '\r\n');
        outFile.Write('    extdir:                  ' + item.extdir + '\r\n');
        outFile.Write('    failed:                  ' + item.failed + '\r\n');
        outFile.Write('    fileattr:                ' + item.fileattr + '\r\n');
        outFile.Write('    filegroup:               ' + (fromLib ? 'undefined' : item.filegroup) + '\r\n');
        outFile.Write('    fullpath:                ' + item.fullpath + '\r\n');
        outFile.Write('    got_size:                ' + item.got_size + '\r\n');
        outFile.Write('    groups:                  ' + item.groups + '\r\n');
        outFile.Write('    id:                      ' + item.id + '\r\n');
        outFile.Write('    is_dir:                  ' + item.is_dir + '\r\n');
        outFile.Write('    metadata:                ' + item.metadata + '\r\n');
        outFile.Write('    modified:                ' + item.modified + '\r\n');
        outFile.Write('    modifieddate:            ' + item.modifieddate + '\r\n');
        outFile.Write('    modifiedtime:            ' + item.modifiedtime + '\r\n');
        outFile.Write('    modify:                  ' + item.modify + '\r\n');
        outFile.Write('    modify_utc:              ' + item.modify_utc + '\r\n');
        outFile.Write('    name:                    ' + item.name + '\r\n');
        outFile.Write('    name_stem:               ' + item.name_stem + '\r\n');
        outFile.Write('    name_stem_m:             ' + item.name_stem_m + '\r\n');
        outFile.Write('    parent:                  ' + item.parent + '\r\n');
        outFile.Write('    parentlocation:          ' + item.parentlocation + '\r\n');
        outFile.Write('    parentpath:              ' + item.parentpath + '\r\n');
        outFile.Write('    path:                    ' + item.path + '\r\n');
        outFile.Write('    pathlen:                 ' + item.pathlen + '\r\n');
        outFile.Write('    pathrel:                 ' + item.pathrel + '\r\n');
        outFile.Write('    realpath:                ' + item.realpath + '\r\n');
        outFile.Write('    selected:                ' + item.selected + '\r\n');
        outFile.Write('    shortname:               ' + item.shortname + '\r\n');
        outFile.Write('    shortpath:               ' + item.shortpath + '\r\n');
        outFile.Write('    size:                    ' + item.size + '\r\n');
        outFile.Write('    sizeauto:                ' + item.sizeauto + '\r\n');
        outFile.Write('    sizekb:                  ' + item.sizekb + '\r\n');
        outFile.Write('    sizerel:                 ' + item.sizerel + '\r\n');
        outFile.Write('    uncompressedsize:        ' + item.uncompressedsize + '\r\n');

        if (item.metadata != 'none') {
            outFile.Write('\r\n*** item.metadata.audio ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.audio.def_value + '\r\n');
            outFile.Write('    album:                   ' + item.metadata.audio.album + '\r\n');
            outFile.Write('    albumartist:             ' + item.metadata.audio.albumartist + '\r\n');
            outFile.Write('    artist:                  ' + item.metadata.audio.artist + '\r\n');
            outFile.Write('    audiocodec:              ' + item.metadata.audio.audiocodec + '\r\n');
            outFile.Write('    authorurl:               ' + item.metadata.audio.authorurl + '\r\n');
            outFile.Write('    bpm:                     ' + item.metadata.audio.bpm + '\r\n');
            outFile.Write('    compilation:             ' + item.metadata.audio.compilation + '\r\n');
            outFile.Write('    composers:               ' + item.metadata.audio.composers + '\r\n');
            outFile.Write('    conductor:               ' + item.metadata.audio.conductor + '\r\n');
            outFile.Write('    conductors:              ' + item.metadata.audio.conductors + '\r\n');
            outFile.Write('    contentgroup:            ' + item.metadata.audio.contentgroup + '\r\n');
            outFile.Write('    copyright:               ' + item.metadata.audio.copyright + '\r\n');
            outFile.Write('    discnumber:              ' + item.metadata.audio.discnumber + '\r\n');
            outFile.Write('    duration:                ' + item.metadata.audio.duration + '\r\n');
            outFile.Write('    encoder:                 ' + item.metadata.audio.encoder + '\r\n');
            outFile.Write('    encodingsoftware:        ' + item.metadata.audio.encodingsoftware + '\r\n');
            outFile.Write('    genre:                   ' + item.metadata.audio.genre + '\r\n');
            outFile.Write('    initialkey:              ' + item.metadata.audio.initialkey + '\r\n');
            outFile.Write('    mood:                    ' + item.metadata.audio.mood + '\r\n');
            outFile.Write('    mp3album:                ' + item.metadata.audio.mp3album + '\r\n');
            outFile.Write('    mp3albumartist:          ' + item.metadata.audio.mp3albumartist + '\r\n');
            outFile.Write('    mp3artist:               ' + item.metadata.audio.mp3artist + '\r\n');
            outFile.Write('    mp3bitrate:              ' + item.metadata.audio.mp3bitrate + '\r\n');
            outFile.Write('    mp3bpm:                  ' + item.metadata.audio.mp3bpm + '\r\n');
            outFile.Write('    mp3comment:              ' + item.metadata.audio.mp3comment + '\r\n');
            outFile.Write('    mp3disc:                 ' + item.metadata.audio.mp3disc + '\r\n');
            outFile.Write('    mp3disk:                 ' + item.metadata.audio.mp3disk + '\r\n');
            outFile.Write('    mp3drm:                  ' + item.metadata.audio.mp3drm + '\r\n');
            outFile.Write('    mp3encoder:              ' + item.metadata.audio.mp3encoder + '\r\n');
            outFile.Write('    mp3encodingsoftware:     ' + item.metadata.audio.mp3encodingsoftware + '\r\n');
            outFile.Write('    mp3genre:                ' + item.metadata.audio.mp3genre + '\r\n');
            outFile.Write('    mp3info:                 ' + item.metadata.audio.mp3info + '\r\n');
            outFile.Write('    mp3mode:                 ' + item.metadata.audio.mp3mode + '\r\n');
            outFile.Write('    mp3samplerate:           ' + item.metadata.audio.mp3samplerate + '\r\n');
            outFile.Write('    mp3songlength:           ' + item.metadata.audio.mp3songlength + '\r\n');
            outFile.Write('    mp3title:                ' + item.metadata.audio.mp3title + '\r\n');
            outFile.Write('    mp3track:                ' + item.metadata.audio.mp3track + '\r\n');
            outFile.Write('    mp3type:                 ' + item.metadata.audio.mp3type + '\r\n');
            outFile.Write('    mp3year:                 ' + item.metadata.audio.mp3year + '\r\n');
            outFile.Write('    origartist:              ' + item.metadata.audio.origartist + '\r\n');
            outFile.Write('    picdepth:                ' + item.metadata.audio.picdepth + '\r\n');
            outFile.Write('    publisher:               ' + item.metadata.audio.publisher + '\r\n');
            outFile.Write('    releasedate:             ' + item.metadata.audio.releasedate + '\r\n');
            outFile.Write('    subtitle:                ' + item.metadata.audio.subtitle + '\r\n');
            outFile.Write('    track:                   ' + item.metadata.audio.track + '\r\n');
            outFile.Write('    year:                    ' + item.metadata.audio.year + '\r\n');

            outFile.Write('\r\n*** item.metadata.audio.coverart ***\r\n');
            var itemCoverArt = item.metadata.audio.coverart;
            if (itemCoverArt > 0) {
                for (var ee = new Enumerator(itemCoverArt); !ee.atEnd(); ee.moveNext()) {
                    var covArt = ee.item();
                    var desc = covArt.desc;
                    outFile.Write('    intended use:            ' + covArt + '\r\n');
                    outFile.Write('    description:             ' + (desc == '' ? '<none>' : desc) + '\r\n');
                }
            } else {
                outFile.Write('    <no coverart>\r\n');
            }

            outFile.Write('\r\n*** item.metadata.doc ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.doc.def_value + '\r\n');
            outFile.Write('    author:                  ' + item.metadata.doc.author + '\r\n');
            outFile.Write('    category:                ' + item.metadata.doc.category + '\r\n');
            outFile.Write('    comments:                ' + item.metadata.doc.comments + '\r\n');
            outFile.Write('    company:                 ' + item.metadata.doc.company + '\r\n');
            outFile.Write('    companyname:             ' + item.metadata.doc.companyname + '\r\n');
            outFile.Write('    contentstatus:           ' + item.metadata.doc.contentstatus + '\r\n');
            outFile.Write('    contenttype:             ' + item.metadata.doc.contenttype + '\r\n');
            outFile.Write('    copyright:               ' + item.metadata.doc.copyright + '\r\n');
            outFile.Write('    creator:                 ' + item.metadata.doc.creator + '\r\n');
            outFile.Write('    doccreateddate:          ' + item.metadata.doc.doccreateddate + '\r\n');
            outFile.Write('    docedittime:             ' + item.metadata.doc.docedittime + '\r\n');
            outFile.Write('    doclastsavedby:          ' + item.metadata.doc.doclastsavedby + '\r\n');
            outFile.Write('    doclastsaveddate:        ' + item.metadata.doc.doclastsaveddate + '\r\n');
            outFile.Write('    language:                ' + item.metadata.doc.language + '\r\n');
            outFile.Write('    lastsavedby:             ' + item.metadata.doc.lastsavedby + '\r\n');
            outFile.Write('    manager:                 ' + item.metadata.doc.manager + '\r\n');
            outFile.Write('    pages:                   ' + item.metadata.doc.pages + '\r\n');
            outFile.Write('    producer:                ' + item.metadata.doc.producer + '\r\n');
            outFile.Write('    subject:                 ' + item.metadata.doc.subject + '\r\n');
            outFile.Write('    title:                   ' + item.metadata.doc.title + '\r\n');

            outFile.Write('\r\n*** item.metadata.exe ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.exe.def_value + '\r\n');
            outFile.Write('    companyname:             ' + item.metadata.exe.companyname + '\r\n');
            outFile.Write('    copyright:               ' + item.metadata.exe.copyright + '\r\n');
            outFile.Write('    moddesc:                 ' + item.metadata.exe.moddesc + '\r\n');
            outFile.Write('    modversion:              ' + item.metadata.exe.modversion + '\r\n');
            outFile.Write('    prodname:                ' + item.metadata.exe.prodname + '\r\n');
            outFile.Write('    prodversion:             ' + item.metadata.exe.prodversion + '\r\n');

            outFile.Write('\r\n*** item.metadata.image ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.image.def_value + '\r\n');
            outFile.Write('    35mmfocallength:         ' + item.metadata.image['35mmfocallength'] + '\r\n');
            outFile.Write('    altitude:                ' + item.metadata.image.altitude + '\r\n');
            outFile.Write('    aperture:                ' + item.metadata.image.aperture + '\r\n');
            outFile.Write('    apertureval:             ' + item.metadata.image.apertureval + '\r\n');
            outFile.Write('    aspectratio:             ' + item.metadata.image.aspectratio + '\r\n');
            outFile.Write('    cameramake:              ' + item.metadata.image.cameramake + '\r\n');
            outFile.Write('    cameramodel:             ' + item.metadata.image.cameramodel + '\r\n');
            outFile.Write('    colorspace:              ' + item.metadata.image.colorspace + '\r\n');
            outFile.Write('    contrast:                ' + item.metadata.image.contrast + '\r\n');
            outFile.Write('    coords:                  ' + item.metadata.image.coords + '\r\n');
            outFile.Write('    copyright:               ' + item.metadata.image.copyright + '\r\n');
            outFile.Write('    datedigitized:           ' + item.metadata.image.datedigitized + '\r\n');
            outFile.Write('    datetaken:               ' + item.metadata.image.datetaken + '\r\n');
            outFile.Write('    digitalzoom:             ' + item.metadata.image.digitalzoom + '\r\n');
            outFile.Write('    dimensions:              ' + item.metadata.image.dimensions + '\r\n');
            outFile.Write('    exposurebias:            ' + item.metadata.image.exposurebias + '\r\n');
            outFile.Write('    exposureprogram:         ' + item.metadata.image.exposureprogram + '\r\n');
            outFile.Write('    exposuretime:            ' + item.metadata.image.exposuretime + '\r\n');
            outFile.Write('    flash:                   ' + item.metadata.image.flash + '\r\n');
            outFile.Write('    fnumber:                 ' + item.metadata.image.fnumber + '\r\n');
            outFile.Write('    focallength:             ' + item.metadata.image.focallength + '\r\n');
            outFile.Write('    gpsaltitude:             ' + item.metadata.image.gpsaltitude + '\r\n');
            outFile.Write('    gpslatitude:             ' + item.metadata.image.gpslatitude + '\r\n');
            outFile.Write('    gpslongitude:            ' + item.metadata.image.gpslongitude + '\r\n');
            outFile.Write('    imagedesc:               ' + item.metadata.image.imagedesc + '\r\n');
            outFile.Write('    imagequality:            ' + item.metadata.image.imagequality + '\r\n');
            outFile.Write('    instructions:            ' + item.metadata.image.instructions + '\r\n');
            outFile.Write('    isorating:               ' + item.metadata.image.isorating + '\r\n');
            outFile.Write('    isospeed:                ' + item.metadata.image.isospeed + '\r\n');
            outFile.Write('    latitude:                ' + item.metadata.image.latitude + '\r\n');
            outFile.Write('    lensmake:                ' + item.metadata.image.lensmake + '\r\n');
            outFile.Write('    lensmodel:               ' + item.metadata.image.lensmodel + '\r\n');
            outFile.Write('    lenstype:                ' + item.metadata.image.lenstype + '\r\n');
            outFile.Write('    longitude:               ' + item.metadata.image.longitude + '\r\n');
            outFile.Write('    macromode:               ' + item.metadata.image.macromode + '\r\n');
            outFile.Write('    meteringmode:            ' + item.metadata.image.meteringmode + '\r\n');
            outFile.Write('    mp3artist:               ' + item.metadata.image.mp3artist + '\r\n');
            outFile.Write('    orientation:             ' + item.metadata.image.orientation + '\r\n');
            outFile.Write('    picdepth:                ' + item.metadata.image.picdepth + '\r\n');
            outFile.Write('    picheight:               ' + item.metadata.image.picheight + '\r\n');
            outFile.Write('    picphyssize:             ' + item.metadata.image.picphyssize + '\r\n');
            outFile.Write('    picphysx:                ' + item.metadata.image.picphysx + '\r\n');
            outFile.Write('    picphysy:                ' + item.metadata.image.picphysy + '\r\n');
            outFile.Write('    picresx:                 ' + item.metadata.image.picresx + '\r\n');
            outFile.Write('    picresy:                 ' + item.metadata.image.picresy + '\r\n');
            outFile.Write('    picsize:                 ' + item.metadata.image.picsize + '\r\n');
            outFile.Write('    picwidth:                ' + item.metadata.image.picwidth + '\r\n');
            outFile.Write('    rotation:                ' + item.metadata.image.rotation + '\r\n');
            outFile.Write('    saturation:              ' + item.metadata.image.saturation + '\r\n');
            outFile.Write('    scenecapturetype:        ' + item.metadata.image.scenecapturetype + '\r\n');
            outFile.Write('    scenemode:               ' + item.metadata.image.scenemode + '\r\n');
            outFile.Write('    sharpness:               ' + item.metadata.image.sharpness + '\r\n');
            outFile.Write('    shootingtime:            ' + item.metadata.image.shootingtime + '\r\n');
            outFile.Write('    shutterspeed:            ' + item.metadata.image.shutterspeed + '\r\n');
            outFile.Write('    software:                ' + item.metadata.image.software + '\r\n');
            outFile.Write('    subject:                 ' + item.metadata.image.subject + '\r\n');
            outFile.Write('    subjectdistance:         ' + item.metadata.image.subjectdistance + '\r\n');
            outFile.Write('    title:                   ' + item.metadata.image.title + '\r\n');
            outFile.Write('    whitebalance:            ' + item.metadata.image.whitebalance + '\r\n');

            outFile.Write('\r\n*** item.metadata.other ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.other.def_value + '\r\n');
            outFile.Write('    attr:                    ' + item.metadata.other.attr + '\r\n');
            outFile.Write('    autodesc:                ' + item.metadata.other.autodesc + '\r\n');
            outFile.Write('    availability:            ' + item.metadata.other.availability + '\r\n');
            outFile.Write('    desc:                    ' + item.metadata.other.desc + '\r\n');
            outFile.Write('    dircount:                ' + item.metadata.other.dircount + '\r\n');
            outFile.Write('    dircounttotal:           ' + item.metadata.other.dircounttotal + '\r\n');
            outFile.Write('    filecount:               ' + item.metadata.other.filecount + '\r\n');
            outFile.Write('    filecounttotal:          ' + item.metadata.other.filecounttotal + '\r\n');
            outFile.Write('    foldercontents:          ' + item.metadata.other.foldercontents + '\r\n');
            outFile.Write('    fontname:                ' + item.metadata.other.fontname + '\r\n');
            outFile.Write('    group:                   ' + item.metadata.other.group + '\r\n');
            outFile.Write('    index:                   ' + item.metadata.other.index + '\r\n');
            outFile.Write('    keywords:                ' + item.metadata.other.keywords + '\r\n');
            outFile.Write('    label:                   ' + item.metadata.other.label + '\r\n');
            outFile.Write('    md5sum:                  ' + item.metadata.other.md5sum + '\r\n');
            outFile.Write('    nsdesc:                  ' + item.metadata.other.nsdesc + '\r\n');
            outFile.Write('    owner:                   ' + item.metadata.other.owner + '\r\n');
            outFile.Write('    rating:                  ' + item.metadata.other.rating + '\r\n');
            outFile.Write('    shasum:                  ' + item.metadata.other.shasum + '\r\n');
            outFile.Write('    status:                  ' + item.metadata.other.status + '\r\n');
            outFile.Write('    target:                  ' + item.metadata.other.target + '\r\n');
            outFile.Write('    target_type:             ' + item.metadata.other.target_type + '\r\n');
            outFile.Write('    thumbnail:               ' + item.metadata.other.thumbnail + '\r\n');
            outFile.Write('    type:                    ' + item.metadata.other.type + '\r\n');
            outFile.Write('    usercomment:             ' + item.metadata.other.usercomment + '\r\n');
            outFile.Write('    userdesc:                ' + item.metadata.other.userdesc + '\r\n');

            outFile.Write('\r\n*** item.metadata.video ***\r\n');
            outFile.Write('    def_value:               ' + item.metadata.video.def_value + '\r\n');
            outFile.Write('    artist:                  ' + item.metadata.video.artist + '\r\n');
            outFile.Write('    aspectratio:             ' + item.metadata.video.aspectratio + '\r\n');
            outFile.Write('    authorurl:               ' + item.metadata.video.authorurl + '\r\n');
            outFile.Write('    bpm:                     ' + item.metadata.video.bpm + '\r\n');
            outFile.Write('    broadcastdate:           ' + item.metadata.video.broadcastdate + '\r\n');
            outFile.Write('    channel:                 ' + item.metadata.video.channel + '\r\n');
            outFile.Write('    composers:               ' + item.metadata.video.composers + '\r\n');
            outFile.Write('    conductor:               ' + item.metadata.video.conductor + '\r\n');
            outFile.Write('    contentgroup:            ' + item.metadata.video.contentgroup + '\r\n');
            outFile.Write('    credits:                 ' + item.metadata.video.credits + '\r\n');
            outFile.Write('    datarate:                ' + item.metadata.video.datarate + '\r\n');
            outFile.Write('    dimensions:              ' + item.metadata.video.dimensions + '\r\n');
            outFile.Write('    directors:               ' + item.metadata.video.directors + '\r\n');
            outFile.Write('    duration:                ' + item.metadata.video.duration + '\r\n');
            outFile.Write('    encoder:                 ' + item.metadata.video.encoder + '\r\n');
            outFile.Write('    encodingsoftware:        ' + item.metadata.video.encodingsoftware + '\r\n');
            outFile.Write('    episodename:             ' + item.metadata.video.episodename + '\r\n');
            outFile.Write('    fourcc:                  ' + item.metadata.video.fourcc + '\r\n');
            outFile.Write('    framerate:               ' + item.metadata.video.framerate + '\r\n');
            outFile.Write('    genre:                   ' + item.metadata.video.genre + '\r\n');
            outFile.Write('    ishd:                    ' + item.metadata.video.ishd + '\r\n');
            outFile.Write('    isrepeat:                ' + item.metadata.video.isrepeat + '\r\n');
            outFile.Write('    mood:                    ' + item.metadata.video.mood + '\r\n');
            outFile.Write('    mp3bitrate:              ' + item.metadata.video.mp3bitrate + '\r\n');
            outFile.Write('    mp3mode:                 ' + item.metadata.video.mp3mode + '\r\n');
            outFile.Write('    mp3samplerate:           ' + item.metadata.video.mp3samplerate + '\r\n');
            outFile.Write('    mp3songlength:           ' + item.metadata.video.mp3songlength + '\r\n');
            outFile.Write('    mp3type:                 ' + item.metadata.video.mp3type + '\r\n');
            outFile.Write('    picdepth:                ' + item.metadata.video.picdepth + '\r\n');
            outFile.Write('    picheight:               ' + item.metadata.video.picheight + '\r\n');
            outFile.Write('    picphyssize:             ' + item.metadata.video.picphyssize + '\r\n');
            outFile.Write('    picsize:                 ' + item.metadata.video.picsize + '\r\n');
            outFile.Write('    picwidth:                ' + item.metadata.video.picwidth + '\r\n');
            outFile.Write('    producers:               ' + item.metadata.video.producers + '\r\n');
            outFile.Write('    publisher:               ' + item.metadata.video.publisher + '\r\n');
            outFile.Write('    recordingtime:           ' + item.metadata.video.recordingtime + '\r\n');
            outFile.Write('    releasedate:             ' + item.metadata.video.releasedate + '\r\n');
            outFile.Write('    station:                 ' + item.metadata.video.station + '\r\n');
            outFile.Write('    subtitle:                ' + item.metadata.video.subtitle + '\r\n');
            outFile.Write('    videocodec:              ' + item.metadata.video.videocodec + '\r\n');
            outFile.Write('    writers:                 ' + item.metadata.video.writers + '\r\n');
            outFile.Write('    year:                    ' + item.metadata.video.year + '\r\n');

            outFile.Write('\r\n*** item.metadata.tags ***\r\n');
            var itemTags = item.metadata.tags;
            if (itemTags.count > 0) {
                for (var ee = new Enumerator(itemTags); !ee.atEnd(); ee.moveNext()) {
                    outFile.Write('    tag:                     ' + ee.item() + '\r\n');
                }
            } else {
                outFile.Write('    <no tags>\r\n');
            }

            outFile.Write('\r\n*** item.Labels() ***\r\n');
            // var itemLabels = item.Labels('', 'explicit');
            var itemLabels = item.Labels();
            if (itemLabels.count > 0) {
                for (var ee = new Enumerator(itemLabels); !ee.atEnd(); ee.moveNext()) {
                    outFile.Write('    label:                   ' + ee.item() + '\r\n');
                }
            } else {
                outFile.Write('    <no labels>\r\n');
            }

            outFile.Write('\r\n*** GetADSNames(item) ***\r\n');
            var itemADS = fsu.GetADSNames(item);
            if (itemADS.count > 0) {
                for (var ee = new Enumerator(itemADS); !ee.atEnd(); ee.moveNext()) {
                    outFile.Write('    ADS:                     ' + ee.item() + '\r\n');
                }
            } else {
                outFile.Write('    <no ADS>\r\n');
            }
        }
        outFile.Close();
    }

    function WriteExifTool(item) {
        if (item.def_value.substring(0, 6) == 'ftp://') {
            DOpus.Output('Sorry, ExifTool does not work on FTP.');
            return;
        }

        cmd.Clear();
        cmd.SetType('msdos');
        cmd.SetModifier('runmode', 'min');

        cmd.RunCommand('FileType NEW=.txt NEWNAME="norename:' + item.name + '-ExifTool.Tags.txt');
        var outFilePath = dstPath + '\\' + cmd.vars.Get('newfile');
        cmd.AddFile(outFilePath);
        cmd.AddLine('"' + exeExifTool + '" -short -duplicates -unknown -groupHeadings "' + item + '" > "' + outFilePath + '"');
        DOpus.Output('---> ' + outFilePath);

        cmd.RunCommand('FileType NEW=.txt NEWNAME="norename:' + item.name + '-ExifTool.Descriptions.txt');
        var outFilePath = dstPath + '\\' + cmd.vars.Get('newfile');
        cmd.AddFile(outFilePath);
        cmd.AddLine('"' + exeExifTool + '" "' + item + '" > "' + outFilePath + '"');
        DOpus.Output('---> ' + outFilePath);

        cmd.Run();
    }

    function WriteMediaInfo(item) {
        if (item.def_value.substring(0, 6) == 'ftp://') {
            DOpus.Output('Sorry, MediaInfo does not work on FTP.');
            return;
        }

        cmd.Clear();
        cmd.SetType('msdos');
        cmd.SetModifier('runmode', 'min');

        cmd.RunCommand('FileType NEW=.txt NEWNAME="norename:' + item.name + '-MediaInfo.txt');
        var outFilePath = dstPath + '\\' + cmd.vars.Get('newfile');
        cmd.AddFile(outFilePath);
        cmd.AddLine('"' + exeMediaInfo + '" "' + item + '" > "' + outFilePath + '"');
        DOpus.Output('---> ' + outFilePath);

        cmd.RunCommand('FileType NEW=.txt NEWNAME="norename:' + item.name + '-MediaInfo.Full.txt');
        var outFilePath = dstPath + '\\' + cmd.vars.Get('newfile');
        cmd.AddFile(outFilePath);
        cmd.AddLine('"' + exeMediaInfo + '" --full "' + item + '" > "' + outFilePath + '"');
        DOpus.Output('---> ' + outFilePath);

        cmd.Run();
    }

    cmd.deselect = false;

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

    var to = args.to;
    var toPath;
    var dstPath;
    var openDest = false;

    if (typeof to == 'string') {
        to = to.toLowerCase();

        if (to == 'source') {
            toPath = tab.path;
        } else if (to == 'dest') {
            toPath = dtab ? dtab.path : tab.path;
        } else if (to == 'ask') {
            toPath = dlg.Folder('Pick target folder for metadata text files', '/profile', true);
            if (!toPath.result) return; // user has cancelled
        } else {
            toPath = to;
        }

        toPath = fsu.Resolve(toPath);
        openDest = true;
    }

    var useAll = !args.opus && !args.exiftool && !args.mediainfo;

    var useOpus = useAll || args.opus;
    var useExifTool = useAll || args.exiftool;
    var useMediaInfo = useAll || args.mediainfo;

    if (useExifTool && !fsu.Exists(exeExifTool)) {
        useExifTool = false;
        DOpus.Output('*** exiftool.exe not found!\n');
        DOpus.Output('');
    }

    if (useMediaInfo && !fsu.Exists(exeMediaInfo)) {
        useMediaInfo = false;
        DOpus.Output('*** MediaInfo.exe not found!');
        DOpus.Output('');
    }

    cmd.ClearFiles();

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

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

        if (item.def_value.substring(0, 6) == 'lib://') {
            item = fsu.GetItem(fsu.Resolve(item));
            var fromLib = true;
        } else {
            var fromLib = false;
        }

        // We check every time in case the items are from a collection
        var dstPath = to ? toPath : item.path;

        if (IsForbiddenDest(dstPath)) {
            dstPath = altDest;
            openDest = true;
            cmd.RunCommand('CreateFolder NAME="' + altDest + '"');
        }

        cmd.SetSource(dstPath);

        DOpus.Output('');
        DOpus.Output('     ' + item);

        if (useOpus) WriteOpus(item);
        if (useExifTool) WriteExifTool(item);
        if (useMediaInfo) WriteMediaInfo(item);
    }

    DOpus.Output('');
    DOpus.Output('... done');

    if (openDest) {
        cmd.RunCommand('Go PATH="' + dstPath + '" OPENINDUAL NEWTAB=findexisting');
        cmd.SetSourceTab(tab.lister.desttab);
        cmd.RunCommand('Set FOCUS=dest');
    }

    cmd.RunCommand('Select NONE');
    cmd.RunCommand('Select FROMSCRIPT SETFOCUS');
    cmd.RunCommand('Select SHOWFOCUS');
}

How to install

Save CommandPrintMeta.js.txt to

%appdata%\GPSoftware\Directory Opus\Script AddIns

If you want to use ExifTool and/or MediaInfo, you need to install these tools and tell the script, where it can find them.

Get ExifTool from exiftool.org and MediaInfo from mediaarea.net. For this script, you need the CLI version of MediaInfo.exe.

Update the paths:

var exeExifTool = fsu.Resolve('/bin\\exiftool\\exiftool.exe');
var exeMediaInfo = fsu.Resolve('/bin\\MediaInfo.CLI\\MediaInfo.exe');

How to use

Use PrintMeta in a button or add it to a context menu. Here's a button to get you started:

Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>PrintMeta</label>
	<icon1>#print</icon1>
	<function type="normal">
		<instruction>PrintMeta</instruction>
		<instruction />
		<instruction>// PrintMeta EXIFTOOL MEDIAINFO OPUS </instruction>
		<instruction> </instruction>
		<instruction>// PrintMeta TO=dest</instruction>
		<instruction>// PrintMeta TO=source</instruction>
		<instruction>// PrintMeta TO=ask</instruction>
		<instruction>// PrintMeta TO=D:\Test</instruction>
	</function>
</button>

Here the script just ran on an image:


6 Likes

Wow, nice one. Thanks!