Read and cache EXIF data into <metadata.json>

pull/9/head
rprieto 10 years ago
parent 06b2714fde
commit 11575c65d4

@ -33,6 +33,7 @@
"glob": "~3.2.9",
"async": "~0.7.0",
"pad": "~0.0.4",
"regen": "~0.0.6"
"regen": "~0.0.6",
"exif-parser": "~0.1.6"
}
}

@ -4,6 +4,7 @@ var path = require('path');
var async = require('async');
var pad = require('pad');
var regen = require('regen');
var metadata = require('./metadata');
var website = require('./website');
var thumbs = require('./thumbs');
@ -21,16 +22,11 @@ exports.build = function(opts) {
thumbs.sizes.thumb = opts.thumbSize;
thumbs.sizes.large = opts.largeSize;
fs.mkdirp(opts.output);
fs.mkdirpSync(opts.output);
var media = path.join(opts.output, 'media');
async.series([
function staticWebsite(callback) {
website.build(opts, callback);
},
buildStep('Original media', {
cwd: opts.input,
src: '**/*.{jpg,jpeg,png,mp4,mov}',
@ -71,7 +67,31 @@ exports.build = function(opts) {
src: '**/*.{mp4,mov}',
dest: media + '/thumbs/$path/$name.jpg',
process: thumbs.videoSquare,
})
}),
// buildStep('Read EXIF data', {
// cwd: opts.input,
// src: '**/*.{jpg,jpeg}',
// dest: metaFile,
// process: function(src, dest, callback) {
// fs.readFile(src, function(err, buffer) {
// var result = exif.create(buffer).parse();
// var filePath = path.relative(opts.input, src);
// metadata.exif[filePath] = {
// date: result.tags.DateTimeOriginal
// };
// callback();
// });
// }
// }),
function updateMetadata(callback) {
metadata.update(opts, callback);
},
function staticWebsite(callback) {
website.build(opts, callback);
}
], finish);

@ -0,0 +1,80 @@
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var pad = require('pad');
var exif = require('exif-parser');
exports.update = function(opts, callback) {
var metadataPath = path.join(opts.output, 'metadata.json');
var existing = null;
try {
existing = require(metadataPath);
} catch (ex) {
existing = {};
}
function findFiles(callback) {
var globOptions = {
cwd: opts.input,
nonull: false,
nocase: true
};
glob('**/*.{jpg,jpeg,png,mp4,mov}', globOptions, callback);
}
function newer(filePath) {
var found = existing[filePath];
if (!found) return true;
var absolute = path.join(opts.input, filePath);
var stats = fs.statSync(absolute);
var latest = Math.max(stats.ctime.getTime(), stats.mtime.getTime());
return latest > (found.processed * 1000);
}
function metadata(filePath, callback) {
var absolute = path.join(opts.input, filePath);
return {
path: filePath,
type: mediaType(absolute),
date: mediaDate(absolute),
processed: Math.floor(new Date().getTime() / 1000)
};
}
function mediaType(filePath) {
return filePath.match(/\.(mp4|mov)$/) ? 'video' : 'photo';
}
function mediaDate(filePath) {
// timestamp in UNIX format
var timestamp = fs.statSync(filePath).ctime.getTime() / 1000;
if (filePath.match(/\.(jpg|jpeg)$/)) {
var contents = fs.readFileSync(filePath);
var result = exif.create(contents).parse();
var exifDate = result.tags.DateTimeOriginal;
return exifDate || timestamp;
} else {
return timestamp;
}
}
findFiles(function(err, files) {
var toProcess = files.filter(newer);
if (toProcess.length > 0) {
process.stdout.write(pad('Update metadata', 20));
var data = toProcess.filter(newer).map(metadata);
data.forEach(function(file) {
existing[file.path] = _.omit(file, 'path');
});
fs.writeFileSync(metadataPath, JSON.stringify(existing, null, ' '));
console.log('[===================] done');
callback();
} else {
callback();
}
});
};

@ -51,8 +51,8 @@ exports.build = function(opts, callback) {
customStyle
], function(err) {
process.stdout
callback(err);
console.log('[===================] done');
callback(err);
});
};

Loading…
Cancel
Save