batch.ts 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use strict';
  2. export = main;
  3. import commander = require('commander');
  4. import fs = require('fs');
  5. import path = require('path');
  6. import series = require('./series');
  7. import typings = require('./typings');
  8. /**
  9. * Streams the batch of series to disk.
  10. */
  11. function main(args: string[], done: (err?: Error) => void) {
  12. var config = parse(args);
  13. var batchPath = path.join(config.output || process.cwd(), 'CrunchyRoll.txt');
  14. tasks(config, batchPath, (err, tasks) => {
  15. if (err) return done(err);
  16. var i = 0;
  17. (function next() {
  18. if (i >= tasks.length) return done();
  19. series(tasks[i].config, tasks[i].address, err => {
  20. if (err) return done(err);
  21. i += 1;
  22. next();
  23. });
  24. })();
  25. });
  26. }
  27. /**
  28. * Splits the value into arguments.
  29. */
  30. function split(value: string): string[] {
  31. var inQuote = false;
  32. var i: number;
  33. var pieces: string[] = [];
  34. var previous = 0;
  35. for (i = 0; i < value.length; i += 1) {
  36. if (value.charAt(i) === '"') inQuote = !inQuote;
  37. if (!inQuote && value.charAt(i) === ' ') {
  38. pieces.push(value.substring(previous, i).match(/^"?(.+?)"?$/)[1]);
  39. previous = i + 1;
  40. }
  41. }
  42. pieces.push(value.substring(previous, i).match(/^"?(.+?)"?$/)[1]);
  43. return pieces;
  44. }
  45. /**
  46. * Parses the configuration or reads the batch-mode file for tasks.
  47. */
  48. function tasks(config: typings.IConfigLine, batchPath: string, done: (err: Error, tasks?: typings.IConfigTask[]) => void) {
  49. if (config.args.length) {
  50. return done(null, config.args.map(address => {
  51. return {address: address, config: config};
  52. }));
  53. }
  54. fs.exists(batchPath, exists => {
  55. if (!exists) return done(null, []);
  56. fs.readFile(batchPath, 'utf8', (err, data) => {
  57. if (err) return done(err);
  58. var map: typings.IConfigTask[] = [];
  59. data.split(/\r?\n/).forEach(line => {
  60. if (/^(\/\/|#)/.test(line)) return;
  61. var lineConfig = parse(process.argv.concat(split(line)));
  62. lineConfig.args.forEach(address => {
  63. if (!address) return;
  64. map.push({address: address, config: lineConfig});
  65. });
  66. });
  67. done(null, map);
  68. });
  69. });
  70. }
  71. /**
  72. * Parses the arguments and returns a configuration.
  73. */
  74. function parse(args: string[]): typings.IConfigLine {
  75. return new commander.Command().version(require('../package').version)
  76. // Authentication
  77. .option('-p, --pass <s>', 'The password.')
  78. .option('-u, --user <s>', 'The e-mail address or username.')
  79. // Disables
  80. .option('-c, --cache', 'Disables the cache.')
  81. .option('-m, --merge', 'Disables merging subtitles and videos.')
  82. // Filters
  83. .option('-e, --episode <i>', 'The episode filter.')
  84. .option('-v, --volume <i>', 'The volume filter.')
  85. // Settings
  86. .option('-f, --format <s>', 'The subtitle format. (Default: ass)')
  87. .option('-o, --output <s>', 'The output path.')
  88. .option('-s, --series <s>', 'The series override.')
  89. .option('-t, --tag <s>', 'The subgroup. (Default: CrunchyRoll)')
  90. .parse(args);
  91. }