batch.ts 2.9 KB

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