| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- const fs = require('fs');
- const path = require('path');
- const paths = require('../data/paths.json'); // get our paths
- const settings = require('../data/settings.json'); // get the settings
- const { log, toTitleCase } = require('./utils');
- const db = require('./db');
- const handbrake = require('./handbrake');
- const tvdb = require('./tvdb');
- const dirs = Object.keys(paths); // get a list of the paths from the keys
- const defaults = settings.defaults || {}; // load the defaults
- const exists = async file => fs.existsSync(file);
- const stat = async file => fs.statSync(file);
- const mkdir = async file => fs.mkdirSync(file, { recursive: true });
- const remove = async file => fs.unlinkSync(file);
- const fileSize = async file => {
- let stats = (await exists(file)) ? await stat(file) : false;
- let bytes = stats ? stats['size'] : 0;
- return bytes && bytes > 0 ? bytes / 1024 : 0;
- };
- const cleanFileName = async (output='', clean = {}) => {
- // clean the output name
- let cleanKeys = Object.keys(clean);
- for (let c in cleanKeys) {
- let key = cleanKeys[c];
- let val = clean[key];
- let re = new RegExp(key, 'gi');
- output = output.replace(re, val);
- }
- // baseline the output name
- output = output.trim(); // trim the whitespace
- output = output.replace(/(\d{4})$/, `($1)`); // if there is a date at the end wrap it
- return output;
- };
- const process = async file => {
- let database,
- options,
- type = 'movie',
- preset = 'Fast 1080p30',
- clean = {
- '.': ' ',
- },
- ext = 'm4v',
- filename = path.parse(file).name,
- input = file,
- output = filename,
- titlecase = false,
- folder = false,
- genre = false,
- destination = '';
- // determine the presets and clean object
- for (let i = 0, l = dirs.length; i < l; i++) {
- let dir = dirs[i]; // pointer to the dir
- if (file && dir && file.indexOf(dir) > -1) {
- // is this in this path?
- options = Object.assign({}, defaults, paths[dir]); // baseline the options
- database = db.connect(dir, options); // init the db connection
- let found = db.find(database, file); // does it already exist?
- if (found && found.status && found.status === 'success') {
- // was it already processed?
- return false; // break this loop
- } else if (!found) {
- // was it found? .. nope
- log(` -> "${path.basename(file)}" [processing]`);
- db.set(database, {
- input: file,
- output: '',
- status: '',
- date: new Date(),
- }); // push onto the list an entry
- } else {
- log(` -> "${path.basename(file)}" [re-processing]`);
- db.set(database, file, {
- status: '',
- date: new Date(),
- }); // set the status to blank
- }
- type = options.type; // apply the specifics ...
- preset = options.preset; // apply the specifics ...
- clean = options.clean; // ...
- ext = options.ext; // ...
- titlecase = !!options.titlecase; // ...
- folder = !!options.folder; // ...
- genre = !!options.genre; // ...
- destination = options.destination; // ...
- break; // break the loop
- }
- }
- // clean the output name
- output = await cleanFileName(output,clean);
- // do we have a sub folder option?
- if (folder) {
- let match = output.match(/^(.*?)?\./gm); // get the name for the file before the first .
- folder = match && match.length > 0 ? match[0].slice(0, -1) : false; // get just the stuff before the dot ... or false
- }
- // do we want to use the genre for a parent folder?
- if (genre) {
- folder = await tvdb.genre(output, type); // lookup the genre name
- }
- // do we have title case enabled?
- if (options.titlecase) output = toTitleCase(output); // titlecase that string
- // baseline the target
- let target = destination + (folder ? '/' + folder : ''); // setup the target location
- output = target + '/' + output + '.' + ext; // update the new name
- // do we already have an existing output that matches?
- if (exists(output)) {
- let outputSize = await fileSize(output); //get output filesize
- if (outputSize > 100) {
- //make sure its bigger than 100k
- log(` -> "${path.basename(file)}" [skipping] (already processed)\n`);
- db.set(database, file, {
- output: output,
- status: 'success',
- date: new Date(),
- }); // update database with status
- return false;
- }
- }
- //process.stdout.write('\n'); // send a new line
- // update database with output name
- db.set(database, file, {
- output: output,
- });
- // create parent if required
- if (!exists(target)) {
- log(` -> "${path.basename(file)}" [creating parent directory] ("${target}")`);
- await mkdir(target);
- }
- // spawn handbrake
- if (!test) {
- try {
- await handbrake.process(input, output, preset);
- db.set(database, file, {
- status: 'success',
- date: new Date(),
- }); // update database with status
- } catch (err) {
- if (exists(output)) remove(output); // remove file on failure
- db.set(database, file, {
- status: 'failure',
- date: new Date(),
- }); // update database with status
- }
- }
- return true; // when complete return true
- };
- /*
- * cleanup removes from the db
- *
- * @async
- * @param Array dirs list of dirs.
- * @param String file file name to find/match.
- *
- * @return Boolean did we clean it up
- */
- const cleanup = async (dirs, file) => {
- let database, result;
- // loop the dirs for matches
- for (let i = 0, l = dirs.length; i < l; i++) {
- let dir = dirs[i]; // pointer to the dir
- // is this in this path?
- if (file && dir && file.indexOf(dir) > -1) {
- database = await db.connect(dir); // init the database connection
- result = await db.remove(database, file); // remove file form database
- break;
- }
- }
- return result;
- };
- module.exports = {
- cleanup,
- exists,
- fileSize,
- mkdir,
- process,
- stat
- };
|