Remove <regen> dependency (faster builds)

Since we read all the file metadata for EXIF dates, and we need it as well for the view model,
we should use it to generate the thumbnails and save many calls to glob() and fs.stat()
pull/9/head
rprieto 10 years ago
parent a13b94ea3e
commit 436d126050

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

@ -2,11 +2,10 @@ var _ = require('lodash');
var fs = require('fs-extra');
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');
var make = require('./make');
exports.build = function(opts) {
@ -24,72 +23,73 @@ exports.build = function(opts) {
fs.mkdirpSync(opts.output);
var media = path.join(opts.output, 'media');
var meta = null;
function buildStep(options) {
return function(callback) {
make.exec(opts.input, media, meta, options, callback);
}
}
async.series([
buildStep('Original media', {
cwd: opts.input,
src: '**/*.{jpg,jpeg,png,mp4,mov}',
dest: media + '/original/$path/$name.$ext',
process: fs.copy
}),
function updateMetadata(callback) {
metadata.update(opts, function(err, data) {
meta = data;
callback(err);
});
},
buildStep('Photos (large)', {
cwd: opts.input,
src: '**/*.{jpg,jpeg,png}',
dest: media + '/large/$path/$name.$ext',
process: thumbs.photoLarge,
buildStep({
message: 'Original media',
ext: 'jpg|jpeg|png|mp4|mov',
dest: '/original/$path/$name.$ext',
func: fs.copy
}),
buildStep('Photos (thumbs)', {
cwd: opts.input,
src: '**/*.{jpg,jpeg,png}',
dest: media + '/thumbs/$path/$name.$ext',
process: thumbs.photoSquare,
buildStep({
message: 'Photos (large)',
ext: 'jpg|jpeg|png',
dest: '/large/$path/$name.$ext',
func: thumbs.photoLarge
}),
buildStep('Videos (web)', {
cwd: opts.input,
src: '**/*.{mp4,mov}',
dest: media + '/large/$path/$name.mp4',
process: thumbs.videoWeb,
buildStep({
message: 'Photos (thumbs)',
ext: 'jpg|jpeg|png',
dest: '/thumbs/$path/$name.$ext',
func: thumbs.photoSquare
}),
buildStep('Videos (poster)', {
cwd: opts.input,
src: '**/*.{mp4,mov}',
dest: media + '/large/$path/$name.jpg',
process: thumbs.videoLarge,
buildStep({
message: 'Videos (web)',
ext: 'mp4|mov',
dest: '/large/$path/$name.mp4',
func: thumbs.videoWeb
}),
buildStep('Videos (thumbs)', {
cwd: opts.input,
src: '**/*.{mp4,mov}',
dest: media + '/thumbs/$path/$name.jpg',
process: thumbs.videoSquare,
buildStep({
message: 'Videos (poster)',
ext: 'mp4|mov',
dest: '/large/$path/$name.jpg',
func: thumbs.videoLarge
}),
function updateMetadata(callback) {
metadata.update(opts, callback);
},
buildStep({
message: 'Videos (thumbs)',
ext: 'mp4|mov',
dest: '/thumbs/$path/$name.jpg',
func: thumbs.videoSquare
}),
function staticWebsite(callback) {
website.build(opts, callback);
website.build(meta, opts, callback);
}
], finish);
};
function buildStep(message, opts) {
return function(callback) {
regen(_.extend(opts, {
report: pad(message, 20) + '$progress'
}), callback);
}
}
function finish(err) {
console.log();
console.log(err || 'Gallery generated successfully');

@ -0,0 +1,57 @@
var fs = require('fs-extra');
var path = require('path');
var pad = require('pad');
var async = require('async');
var ProgressBar = require('progress');
exports.exec = function(input, output, metadata, options, callback) {
var message = pad(options.message, 20)
var paths = Object.keys(metadata).filter(extension(options.ext));
var tasks = paths.map(function(p) {
return {
relative: p,
absolute: path.join(input, p),
dest: path.join(output, transform(p, options.dest))
};
});
var process = tasks.filter(function(task) {
try {
var destDate = fs.statSync(task.dest).ctime.getTime();
return metadata[task.relative].fileDate > destDate;
} catch (ex) {
return true;
}
});
if (process.length > 0) {
var format = pad(options.message, 20) + '[:bar] :current/:total files';
var bar = new ProgressBar(format, { total: process.length, width: 20 });
var ops = process.map(function(task) {
return function(next) {
fs.mkdirpSync(path.dirname(task.dest));
options.func(task.absolute, task.dest, function(err) {
bar.tick();
next(err);
});
};
});
async.series(ops, callback);
} else {
callback();
}
}
function extension(regex) {
return function(p) {
return p.match(new RegExp('\.(' + regex + ')$', 'i'));
}
}
function transform(file, pattern) {
var absolutePrefix = (pattern[0] === '/') ? '/' : '';
var parts = pattern.split('/');
var full = path.join.apply(this, parts);
return absolutePrefix +
full.replace('$path', path.dirname(file))
.replace('$name', path.basename(file, path.extname(file)))
.replace('$ext', path.extname(file).substr(1));
}

@ -1,10 +1,11 @@
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var async = require('async');
var pad = require('pad');
var exif = require('exif-parser');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var async = require('async');
var pad = require('pad');
var exif = require('exif-parser');
var ProgressBar = require('progress');
exports.update = function(opts, callback) {
@ -56,7 +57,7 @@ exports.update = function(opts, callback) {
}
function mediaDate(fileInfo) {
if (fileInfo.relative.match(/\.(jpg|jpeg)$/)) {
if (fileInfo.relative.match(/\.(jpg|jpeg)$/i)) {
var contents = fs.readFileSync(fileInfo.absolute);
var result = exif.create(contents).parse();
var exifDate = result.tags.DateTimeOriginal * 1000;
@ -67,7 +68,7 @@ exports.update = function(opts, callback) {
}
function mediaType(fileInfo) {
return fileInfo.relative.match(/\.(mp4|mov)$/) ? 'video' : 'photo';
return fileInfo.relative.match(/\.(mp4|mov)$/i) ? 'video' : 'photo';
}
findFiles(function(err, files) {
@ -75,13 +76,16 @@ exports.update = function(opts, callback) {
var toProcess = allFiles.filter(newer);
var count = toProcess.length;
if (count > 0) {
process.stdout.write(pad('Update metadata', 20));
var update = toProcess.map(metadata);
var format = pad('Update metadata', 20) + '[:bar] :current/:total files';
var bar = new ProgressBar(format, { total: count, width: 20 });
var update = toProcess.map(function(fileInfo) {
bar.tick();
return metadata(fileInfo);
});
update.forEach(function(fileInfo) {
existing[fileInfo.path] = _.omit(fileInfo, 'path');
});
fs.writeFileSync(metadataPath, JSON.stringify(existing, null, ' '));
console.log('[===================] ' + count + '/' + count + ' files');
}
callback(null, existing);
});

@ -53,6 +53,7 @@ exports.build = function(metadata, thumbSize) {
.sortBy('date')
.groupBy(byFolder)
.map(folderInfo)
.sortBy('name')
.value();
};

@ -7,11 +7,10 @@ var render = require('./render');
var files = require('./files');
exports.build = function(opts, callback) {
exports.build = function(metadata, opts, callback) {
function website(callback) {
var metadata = require(path.join(opts.output, 'metadata.json'));
var galleries = viewModel.build(metadata, opts.thumbSize);
var style = opts.css ? path.basename(opts.css) : null;

Loading…
Cancel
Save