mirror of https://github.com/thumbsup/thumbsup
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.3 KiB
JavaScript
101 lines
3.3 KiB
JavaScript
const debug = require('debug')('thumbsup')
|
|
const downsize = require('thumbsup-downsize')
|
|
const os = require('os')
|
|
const fs = require('fs-extra')
|
|
const ListrWorkQueue = require('listr-work-queue')
|
|
const path = require('path')
|
|
|
|
exports.run = function (files, opts, parentTask) {
|
|
const jobs = exports.create(files, opts)
|
|
// wrap each job in a Listr task that returns a Promise
|
|
const tasks = jobs.map(job => listrTaskFromJob(job, opts.output))
|
|
const listr = new ListrWorkQueue(tasks, {
|
|
concurrent: os.cpus().length,
|
|
update: (done, total) => {
|
|
const progress = done === total ? '' : `(${done}/${total})`
|
|
parentTask.title = `Processing media ${progress}`
|
|
}
|
|
})
|
|
return listr
|
|
}
|
|
|
|
/*
|
|
Return a list of task to build all required outputs (new or updated)
|
|
*/
|
|
exports.create = function (files, opts) {
|
|
var tasks = {}
|
|
const actionMap = getActionMap(opts)
|
|
// accumulate all tasks into an object
|
|
// to remove duplicate destinations
|
|
files.forEach(f => {
|
|
debug(`Tasks for ${f.path}, ${JSON.stringify(f.output)}`)
|
|
Object.keys(f.output).forEach(out => {
|
|
var src = path.join(opts.input, f.path)
|
|
var dest = path.join(opts.output, f.output[out].path)
|
|
var destDate = modifiedDate(dest)
|
|
var action = actionMap[f.output[out].rel]
|
|
// ignore output files that don't have an action (e.g. existing links)
|
|
if (action && f.date > destDate) {
|
|
tasks[dest] = {
|
|
file: f,
|
|
dest: dest,
|
|
rel: f.output[out].rel,
|
|
action: (done) => {
|
|
fs.mkdirsSync(path.dirname(dest))
|
|
debug(`${f.output[out].rel} from ${src} to ${dest}`)
|
|
return action({src: src, dest: dest}, done)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
})
|
|
// back into an array
|
|
const list = Object.keys(tasks).map(dest => tasks[dest])
|
|
debug(`Created ${list.length} tasks`)
|
|
return list
|
|
}
|
|
|
|
function listrTaskFromJob (job, outputRoot) {
|
|
const relative = path.relative(outputRoot, job.dest)
|
|
return {
|
|
title: relative,
|
|
task: (ctx, task) => {
|
|
return new Promise((resolve, reject) => {
|
|
var progressEmitter = job.action(err => {
|
|
err ? reject(err) : resolve()
|
|
})
|
|
// render progress percentage for videos
|
|
if (progressEmitter) {
|
|
progressEmitter.on('progress', (percent) => {
|
|
task.title = `${relative} (${percent}%)`
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
function modifiedDate (filepath) {
|
|
try {
|
|
return fs.statSync(filepath).mtime.getTime()
|
|
} catch (ex) {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
function getActionMap (opts) {
|
|
const thumbSize = opts.thumbSize || 120
|
|
const largeSize = opts.largeSize || 1000
|
|
const thumbnail = { height: thumbSize, width: thumbSize }
|
|
const large = { width: largeSize }
|
|
return {
|
|
'fs:copy': (task, done) => fs.copy(task.src, task.dest, done),
|
|
'fs:symlink': (task, done) => fs.symlink(task.src, task.dest, done),
|
|
'photo:thumbnail': (task, done) => downsize.image(task.src, task.dest, thumbnail, done),
|
|
'photo:large': (task, done) => downsize.image(task.src, task.dest, large, done),
|
|
'video:thumbnail': (task, done) => downsize.still(task.src, task.dest, thumbnail, done),
|
|
'video:poster': (task, done) => downsize.still(task.src, task.dest, large, done),
|
|
'video:resized': (task, done) => downsize.video(task.src, task.dest, {}, done)
|
|
}
|
|
}
|