Add a log objet to do some fancy output on the command line (not fully enabled under windows as it need some tests)

This commit is contained in:
Godzil 2017-01-28 13:38:14 +00:00
parent ce63ae9a16
commit 8dfd1b447c
8 changed files with 92 additions and 17 deletions

View File

@ -1,6 +1,6 @@
{ {
"author": "Godzil", "author": "Godzil",
"description": "Crunchy.js is a fork of Crunchyroll.js, capable of downloading anime episodes from the popular CrunchyRoll streaming service.", "description": "Crunchy is a fork of Crunchyroll.js, capable of downloading anime episodes from the popular CrunchyRoll streaming service.",
"license": "MIT", "license": "MIT",
"keywords": [ "keywords": [
"anime", "anime",

View File

@ -7,6 +7,7 @@ import path = require('path');
import subtitle from './subtitle/index'; import subtitle from './subtitle/index';
import video from './video/index'; import video from './video/index';
import xml2js = require('xml2js'); import xml2js = require('xml2js');
import log = require('./log');
/** /**
* Streams the episode to disk. * Streams the episode to disk.
@ -24,12 +25,12 @@ export default function(config: IConfig, address: string, done: (err: Error, ign
/** /**
* Completes a download and writes the message with an elapsed time. * Completes a download and writes the message with an elapsed time.
*/ */
function complete(message: string, begin: number, done: (err: Error, ign: boolean) => void) { function complete(epName: string, message: string, begin: number, done: (err: Error, ign: boolean) => void) {
var timeInMs = Date.now() - begin; var timeInMs = Date.now() - begin;
var seconds = prefix(Math.floor(timeInMs / 1000) % 60, 2); var seconds = prefix(Math.floor(timeInMs / 1000) % 60, 2);
var minutes = prefix(Math.floor(timeInMs / 1000 / 60) % 60, 2); var minutes = prefix(Math.floor(timeInMs / 1000 / 60) % 60, 2);
var hours = prefix(Math.floor(timeInMs / 1000 / 60 / 60), 2); var hours = prefix(Math.floor(timeInMs / 1000 / 60 / 60), 2);
console.log(message + ' (' + hours + ':' + minutes + ':' + seconds + ')'); log.dispEpisode(epName, message + ' (' + hours + ':' + minutes + ':' + seconds + ')', true);
done(null, false); done(null, false);
} }
@ -57,14 +58,14 @@ function download(config: IConfig, page: IEpisodePage, player: IEpisodePlayer, d
if (fileExist(filePath + ".mkv")) if (fileExist(filePath + ".mkv"))
{ {
var count = 0; var count = 0;
console.info("File '"+fileName+"' already exist..."); log.warn("File '"+fileName+"' already exist...");
do do
{ {
count = count + 1; count = count + 1;
fileName = name(config, page, series, "-" + count).replace("/","_").replace("'","_").replace(":","_"); fileName = name(config, page, series, "-" + count).replace("/","_").replace("'","_").replace(":","_");
filePath = path.join(config.output || process.cwd(), series, fileName); filePath = path.join(config.output || process.cwd(), series, fileName);
} while(fileExist(filePath + ".mkv")) } while(fileExist(filePath + ".mkv"))
console.info("Renaming to '"+fileName+"'..."); log.warn("Renaming to '"+fileName+"'...");
} }
mkdirp(path.dirname(filePath), (err: Error) => { mkdirp(path.dirname(filePath), (err: Error) => {
@ -74,20 +75,20 @@ function download(config: IConfig, page: IEpisodePage, player: IEpisodePlayer, d
var now = Date.now(); var now = Date.now();
if (player.video.file != undefined) if (player.video.file != undefined)
{ {
console.log('Fetching ' + fileName); log.dispEpisode(fileName, 'Fetching...', false);
downloadVideo(config, page, player, filePath, err => { downloadVideo(config, page, player, filePath, err => {
if (err) return done(err, false); if (err) return done(err, false);
if (config.merge) return complete('Finished ' + fileName, now, done); if (config.merge) return complete(fileName, 'Finished!', now, done);
var isSubtited = Boolean(player.subtitle); var isSubtited = Boolean(player.subtitle);
video.merge(config, isSubtited, player.video.file, filePath, player.video.mode, err => { video.merge(config, isSubtited, player.video.file, filePath, player.video.mode, err => {
if (err) return done(err, false); if (err) return done(err, false);
complete('Finished ' + fileName, now, done); complete(fileName, 'Finished!', now, done);
}); });
}); });
} }
else else
{ {
console.log('Ignoring ' + fileName + ': not released yet'); log.dispEpisode(fileName, 'Ignoring: not released yet', true);
done(null, true); done(null, true);
} }
}); });
@ -166,8 +167,8 @@ function scrapePage(config: IConfig, address: string, done: (err: Error, page?:
if (!swf || !data) if (!swf || !data)
{ {
console.info('Something wrong in the page at '+address+' (data are: '+look+')'); log.warn('Something wrong in the page at '+address+' (data are: '+look+')');
console.info('Setting Season to 0 and episode to \0\...'); log.warn('Setting Season to 0 and episode to \0\...');
done(null, { done(null, {
id: id, id: id,
episode: "0", episode: "0",

71
src/log.ts Normal file
View File

@ -0,0 +1,71 @@
'use strict';
import os = require('os');
export function error(str: string)
{
if (os.platform() === 'win32')
{
console.log(' * ERROR: ' + str);
}
else
{
/* Do more fancy output */
console.error(' \x1B[1;31m* ERROR\x1B[0m: ' + str);
}
}
export function info(str: string)
{
if (os.platform() === 'win32')
{
console.log(' * INFO : ' + str);
}
else
{
/* Do more fancy output */
console.log(' \x1B[1;32m* INFO \x1B[0m: ' + str);
}
}
export function debug(str: string)
{
if (os.platform() === 'win32')
{
console.log(' * DEBUG: ' + str);
}
else
{
/* Do more fancy output */
console.log(' \x1B[1;35m* DEBUG\x1B[0m: ' + str);
}
}
export function warn(str: string)
{
if (os.platform() === 'win32')
{
console.log(' * WARN : ' + str);
}
else
{
/* Do more fancy output */
console.log(' \x1B[1;33m* WARN \x1B[0m: ' + str);
}
}
export function dispEpisode(name: string, status: string, addNL: boolean)
{
if (os.platform() === 'win32')
{
process.stdout.write(' > ' + name + ' : ' + status + '\x1B[0G');
}
else
{
/* Do more fancy output */
process.stdout.write(' \x1B[1;33m> \x1B[37m' + name + '\x1B[0m : \x1B[33m' + status + '\x1B[0m\x1B[0G');
}
if (addNL)
{
console.log('');
}
}

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
import request = require('request'); import request = require('request');
import cheerio = require('cheerio'); import cheerio = require('cheerio');
import log = require('./log');
var isAuthenticated = false; var isAuthenticated = false;
var isPremium = false; var isPremium = false;
@ -80,8 +81,8 @@ function authenticate(config: IConfig, done: (err: Error) => void) {
var error = $('ul.message, li.error').text(); var error = $('ul.message, li.error').text();
return done(new Error('Authentication failed: ' + error)); return done(new Error('Authentication failed: ' + error));
} }
if (isPremium === false) { console.log('Do not use this app without a premium account.'); } if (isPremium === false) { log.warn('Do not use this app without a premium account.'); }
else { console.log('You have a premium account! Good!'); } else { log.info('You have a premium account! Good!'); }
done(null); done(null);
}); });
}); });

View File

@ -5,6 +5,7 @@ import fs = require('fs');
import request = require('./request'); import request = require('./request');
import path = require('path'); import path = require('path');
import url = require('url'); import url = require('url');
import log = require('./log');
var persistent = '.crpersistent'; var persistent = '.crpersistent';
/** /**
@ -84,6 +85,7 @@ function page(config: IConfig, address: string, done: (err: Error, result?: ISer
var $ = cheerio.load(result); var $ = cheerio.load(result);
var title = $('span[itemprop=name]').text(); var title = $('span[itemprop=name]').text();
if (!title) return done(new Error('Invalid page.(' + address + ')')); if (!title) return done(new Error('Invalid page.(' + address + ')'));
log.info("Checking availability for " + title);
var episodes: ISeriesEpisode[] = []; var episodes: ISeriesEpisode[] = [];
$('.episode').each((i, el) => { $('.episode').each((i, el) => {
if ($(el).children('img[src*=coming_soon]').length) return; if ($(el).children('img[src*=coming_soon]').length) return;

View File

@ -2,6 +2,7 @@
import childProcess = require('child_process'); import childProcess = require('child_process');
import path = require('path'); import path = require('path');
import os = require('os'); import os = require('os');
import log = require('../log');
/** /**
* Streams the video to disk. * Streams the video to disk.
@ -19,7 +20,7 @@ import os = require('os');
} }
else if (mode == "HLS") else if (mode == "HLS")
{ {
console.info("Experimental FFMPEG, MAY FAIL!!!"); log.debug("Experimental FFMPEG, MAY FAIL!!!");
var cmd=command("ffmpeg") + ' ' + var cmd=command("ffmpeg") + ' ' +
'-i "' + rtmpInputPath + '" ' + '-i "' + rtmpInputPath + '" ' +
'-c copy -bsf:a aac_adtstoasc ' + '-c copy -bsf:a aac_adtstoasc ' +
@ -30,7 +31,7 @@ import os = require('os');
} }
else else
{ {
console.error("No such mode: " + mode); log.error("No such mode: " + mode);
} }
} }

View File

@ -18,6 +18,7 @@
"src/cli.ts", "src/cli.ts",
"src/episode.ts", "src/episode.ts",
"src/index.ts", "src/index.ts",
"src/log.ts",
"src/interface/IConfig.d.ts", "src/interface/IConfig.d.ts",
"src/interface/IConfigLine.d.ts", "src/interface/IConfigLine.d.ts",
"src/interface/IConfigTask.d.ts", "src/interface/IConfigTask.d.ts",

View File

@ -47,8 +47,6 @@
"no-var-requires": true, "no-var-requires": true,
"one-line": [true, "one-line": [true,
"check-catch", "check-catch",
"check-else",
"check-open-brace",
"check-whitespace" "check-whitespace"
], ],
"quotemark": [true, "single"], "quotemark": [true, "single"],