2017-05-14 02:59:20 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
/* jslint node: true */
|
|
|
|
/* eslint-disable no-console */
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// :TODO: Make this it's own sep tool/repo
|
|
|
|
|
|
|
|
const exiftool = require('exiftool');
|
2017-05-20 03:20:19 +00:00
|
|
|
const fs = require('graceful-fs');
|
2017-05-20 00:41:13 +00:00
|
|
|
const moment = require('moment');
|
|
|
|
|
|
|
|
const TOOL_VERSION = '1.0.0.0';
|
|
|
|
|
|
|
|
// map fileTypes -> handlers
|
|
|
|
const FILETYPE_HANDLERS = {};
|
|
|
|
[ 'AIFF', 'APE', 'FLAC', 'OGG', 'MP3' ].forEach(ext => FILETYPE_HANDLERS[ext] = audioFile);
|
|
|
|
[ 'PDF', 'DOC', 'DOCX', 'DOCM', 'ODB', 'ODC', 'ODF', 'ODG', 'ODI', 'ODP', 'ODS', 'ODT' ].forEach(ext => FILETYPE_HANDLERS[ext] = documentFile);
|
|
|
|
[ 'PNG', 'JPEG', 'GIF', 'WEBP', 'XCF' ].forEach(ext => FILETYPE_HANDLERS[ext] = imageFile);
|
2017-08-27 22:25:32 +00:00
|
|
|
[ 'MP4', 'MOV', 'AVI', 'MKV', 'MPG', 'MPEG', 'M4V', 'WMV' ].forEach(ext => FILETYPE_HANDLERS[ext] = videoFile);
|
2017-05-20 00:41:13 +00:00
|
|
|
|
|
|
|
function audioFile(metadata) {
|
2018-06-30 04:39:36 +00:00
|
|
|
// nothing if we don't know at least the author or title
|
|
|
|
if(!metadata.author && !metadata.title) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let desc = `${metadata.artist||'Unknown Artist'} - ${metadata.title||'Unknown'} (`;
|
|
|
|
if(metadata.year) {
|
|
|
|
desc += `${metadata.year}, `;
|
|
|
|
}
|
|
|
|
desc += `${metadata.audioBitrate})`;
|
|
|
|
return desc;
|
2017-05-20 00:41:13 +00:00
|
|
|
}
|
|
|
|
|
2017-08-27 22:25:32 +00:00
|
|
|
function videoFile(metadata) {
|
2018-06-30 04:39:36 +00:00
|
|
|
return `${metadata.fileType} video(${metadata.imageSize}px, ${metadata.duration}, ${metadata.audioBitsPerSample}/${metadata.audioSampleRate} audio)`;
|
2017-08-27 22:25:32 +00:00
|
|
|
}
|
|
|
|
|
2017-05-20 00:41:13 +00:00
|
|
|
function documentFile(metadata) {
|
2018-06-30 04:39:36 +00:00
|
|
|
// nothing if we don't know at least the author or title
|
|
|
|
if(!metadata.author && !metadata.title) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let result = metadata.author || '';
|
|
|
|
if(result) {
|
|
|
|
result += ' - ';
|
|
|
|
}
|
|
|
|
result += metadata.title || 'Unknown Title';
|
|
|
|
return result;
|
2017-05-20 00:41:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function imageFile(metadata) {
|
2018-06-30 04:39:36 +00:00
|
|
|
let desc = `${metadata.fileType} image (`;
|
|
|
|
if(metadata.animationIterations) {
|
|
|
|
desc += 'Animated, ';
|
|
|
|
}
|
|
|
|
desc += `${metadata.imageSize}px`;
|
|
|
|
const created = moment(metadata.createdate);
|
|
|
|
if(created.isValid()) {
|
|
|
|
desc += `, ${created.format('YYYY')})`;
|
|
|
|
} else {
|
|
|
|
desc += ')';
|
|
|
|
}
|
|
|
|
return desc;
|
2017-05-20 00:41:13 +00:00
|
|
|
}
|
2017-05-14 02:59:20 +00:00
|
|
|
|
|
|
|
function main() {
|
2018-06-30 04:39:36 +00:00
|
|
|
const argv = exports.argv = require('minimist')(process.argv.slice(2), {
|
|
|
|
alias : {
|
|
|
|
h : 'help',
|
|
|
|
v : 'version',
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(argv.version) {
|
|
|
|
console.info(TOOL_VERSION);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(0 === argv._.length || argv.help) {
|
|
|
|
console.info('usage: exiftool2desc.js [--version] [--help] PATH');
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const path = argv._[0];
|
|
|
|
|
|
|
|
fs.readFile(path, (err, data) => {
|
|
|
|
if(err) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
exiftool.metadata(data, (err, metadata) => {
|
|
|
|
if(err) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const handler = FILETYPE_HANDLERS[metadata.fileType];
|
|
|
|
if(!handler) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const info = handler(metadata);
|
|
|
|
if(!info) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.info(info);
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
});
|
2017-05-14 02:59:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return main();
|