UNPKG

fetch-fic

Version:

Package up delicious, delicious fanfic from various sources into epub ebooks ready for reading in your ereader of choice.

137 lines (127 loc) 3.87 kB
#!/usr/bin/env node 'use strict' const outputFormats = require('./output-formats.js') const yargs = require('yargs') process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' let command function setCommand (cmd) { return () => command = cmd } function networkOptions (yargs, cacheDefault) { return yargs.option('xf_user', { type: 'string', describe: 'the value to set the xf_user cookie to, for authenticating with xenforo sites' }) .option('cache', { type: 'boolean', default: cacheDefault, describe: 'fetch from the network even if we have it cached' }) .option('network', { describe: 'allow network access; when false, cache-misses are errors', type: 'boolean', default: true }) .option('concurrency', { type: 'number', default: 4, describe: 'maximum number of chapters/images/etc to fetch at a time' }) .option('requests-per-second', { alias: 'rps', type: 'number', default: 1, describe: 'maximum number of HTTP requests per second' }) } const argv = yargs // .demand(1, 'ff <cmd> --help — for help on a specific command') .command({ command: 'read <url>', aliases: ['get', 'meta'], desc: 'Get chapter list for a fic', builder: yargs => { yargs.option('scrape', { type: 'boolean', describe: 'scrape the index instead of using threadmarks' }) .option('and-scrape', { type: 'boolean', describe: 'pull chapters from BOTH the index AND the threadmarks' }) .demand(1, '<url> - The URL to fetch chapters for') networkOptions(yargs, false) }, handler: setCommand('./ff-read.js') }) .command({ command: 'update <fic...>', desc: 'Update fic with latest chapter list', builder: yargs => { yargs.option('add-all', { type: 'boolean', default: false, describe: 'if true, merge ALL missing chapters in instead of just NEW ones' }) .option('scrape', { type: 'boolean', describe: 'scrape the index instead of using threadmarks' }) .option('and-scrape', { type: 'boolean', describe: 'pull chapters from BOTH the index AND the threadmarks' }) .demand(1, '<fic> - A fic metadata file to fetch a fic for. Typically ends in .fic.toml') networkOptions(yargs, false) }, handler: setCommand('./ff-update.js') }) .command({ command: 'gen <fic...>', aliases: ['write', 'fetch', 'generate',], desc: 'Generate epub (or other) from fic', builder: yargs => { yargs.option('o', { alias: 'output', describe: 'Set output format', default: 'epub', choices: outputFormats }) networkOptions(yargs, true) yargs.demand(1, '<fic> - A fic metadata file to fetch a fic for. Typically ends in .fic.toml') }, handler: setCommand('./ff-write.js') }) .command({ command: 'cache-clear <url>', desc: 'Remove a URL from the cache', builder: yargs => { yargs.demand(1, '<url> - A URL to remove from the cache.') }, handler: setCommand('./ff-cache-clear.js') }) .option('debug', { type: 'boolean', default: process.env.BLUEBIRD_DEBUG && process.env.BLUEBIRD_DEBUG !== '0', global: true }) .demand(1, ['debug']) .strict() .help() .argv if (argv.debug) process.env.BLUEBIRD_DEBUG = '1' require(command)(argv).catch(errorHandler).then(exitCodeHandler) function errorHandler (err) { if (argv.debug) { console.log(err.stack) } else if (err.code === 'ENOENT') { console.log(err.message.replace(/^ENOENT: no such file or directory, open '(.*?)'$/, 'Could not find fic: $1')) } else { console.log('An error occured: ' + err.message) } process.exit(1) } function exitCodeHandler (exitCode) { if (typeof exitCode === 'number') process.exit(exitCode) }