summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/login.js6
-rw-r--r--lib/videos.js93
-rw-r--r--mongo-edu.js13
-rw-r--r--package.json6
4 files changed, 96 insertions, 22 deletions
diff --git a/lib/login.js b/lib/login.js
index 87066f5..d1b2d8c 100644
--- a/lib/login.js
+++ b/lib/login.js
@@ -100,17 +100,17 @@ module.exports = {
});
},
- getList: function getList(opt, callback) {
+ getList: function getList(opt, argv, callback) {
request({ url: opt.url, jar: jar }, function get(err, res, body) {
if (err !== null) { return callback(err, null); }
if (res.statusCode === 200) {
- var list = [], getCourses = [], $ = cheerio.load(body), tag = opt.url.replace('course_', '');
+ var list = [], getCourses = [], $ = cheerio.load(body), tag = opt.url.replace('course_', ''), options = (!argv.h)? 'Video' : 'Handout';
$('div.wiki-article p').children().filter('a').map(function map(i, item) {
var current = $(item);
- if (current.text().indexOf('Video') !== -1) { list.push(current.attr('href')); }
+ if (current.text().indexOf(options) !== -1) { list.push(current.attr('href')); }
});
getCourses = _.filter(list, function map(item) { return item.match(/(wiki\/M101|wiki\/M102|wiki\/C100|wiki\/M202)/); });
diff --git a/lib/videos.js b/lib/videos.js
index eec817c..2ddeb7b 100644
--- a/lib/videos.js
+++ b/lib/videos.js
@@ -6,36 +6,90 @@
* https://github.com/przemyslawpluta/mongo-edu/blob/master/LICENSE
*/
-var youtubedl = require('youtube-dl'),
+var path = require('path'),
+ fs = require('fs'),
+ youtubedl = require('youtube-dl'),
+ filesize = require('filesize'),
ProgressBar = require('progress'),
+ request = require('request'),
+ progress = require('request-progress'),
colors = require('colors'),
_ = require('lodash');
-var downloadPath = '', ncc = false;
+var downloadPath = '', ncc = false, handout = false;
var handleList = function handleList(list) {
var currentList = list,
opt = (!ncc) ? ['--max-quality=18'] : ['--max-quality=18', '--no-check-certificate'],
+ getHandouts = function getHandouts(item) {
+
+ var name = path.basename(item), bar, dounloadFile, dlh, left,
+
+ downloadItem = function downloadItem() {
+
+ dlh = progress(request(item), { throttle: 0 });
+
+ console.log('[' + 'i'.magenta + '] Downloading: ' + name.cyan);
+
+ dlh.on('progress', function(state) {
+ if (!bar) {
+ bar = new ProgressBar('[' + '>'.green + '] ' + filesize(state.total) + ' [:bar] :percent :etas', { complete: '=', incomplete: ' ', width: 20, total: 100.0 });
+ }
+ if (!bar.complete) { bar.tick(parseInt(state.percent, 10)); }
+ });
+
+ dlh.on('error', function error(err) {
+ return console.log(err.stack);
+ });
+
+ dounloadFile = dlh.pipe(fs.createWriteStream(downloadPath + name));
+
+ dounloadFile.on('close', function close() {
+ console.log('[' + 'i'.green + '] Done.' + left);
+ handleList(currentList);
+ });
+
+ dounloadFile.on('error', function error(err) {
+ return console.log(err.stack);
+ });
+ };
+
+ fs.exists(downloadPath + name, function (exists) {
+ left = (currentList.length)? ' ' + currentList.length + ' left ...' : '';
+
+ if (exists) {
+ console.log('[' + '>'.magenta + '] ' + name + ' has already been downloaded.' + left);
+ return handleList(currentList);
+ }
+
+ downloadItem();
+
+ });
+
+ },
+
getVideos = function getVideos(item) {
+ if (handout) { return getHandouts(item); }
+
var dl = youtubedl.download(item, downloadPath, opt), bar;
- dl.on('download', function(data) {
+ dl.on('download', function download(data) {
console.log('[' + 'i'.magenta + '] Downloading: ' + data.filename.cyan + ' > ' + item);
bar = new ProgressBar('[' + '>'.green + '] ' + data.size + ' [:bar] :percent :etas', { complete: '=', incomplete: ' ', width: 20, total: 100.0 });
});
- dl.on('progress', function(data) {
+ dl.on('progress', function progress(data) {
if (!bar.complete) { bar.tick(parseInt(data.percent, 10)); }
});
- dl.on('error', function(err) {
+ dl.on('error', function error(err) {
return console.log(err.stack);
});
- dl.on('end', function(data) {
+ dl.on('end', function end(data) {
var left = (currentList.length)? ' ' + currentList.length + ' left ...' : '';
if (data.filename) {
if (data.filename.indexOf('has already been downloaded') !== -1) {
@@ -62,14 +116,32 @@ module.exports = {
downloadPath = argv.d;
if (argv.ncc) { ncc = true; }
+ if (argv.h) { handout = true; }
var bar = new ProgressBar('[' + '>'.magenta + '] Collecting [:bar] :percent', { complete: '=', incomplete: ' ', width: 20, total: opt.length }),
options = (!ncc) ? [] : ['--no-check-certificate'];
- var getDetails = function getDetails(item, i) {
+ var isFinished = function isFinished(count, items) {
+ if (count === 0) {
+
+ var sortedList = _.map(_.sortBy(items, 'id'));
+
+ sortedList.unshift({name: 'All', value: 'all', checked: true}, {name: 'Cancel', value: 'cancel'});
+ callback(null, sortedList);
+ }
+ },
+
+ getDetails = function getDetails(item, i) {
function getInfo() {
+ if (handout) {
+ items.push({name: path.basename(item), value: item, id: i});
+ count = count - 1;
+ bar.tick();
+ return isFinished(count, items);
+ }
+
youtubedl.getInfo(item, options, function(err, info) {
items.push((!err)?{name: info.title + ' - ' + info.resolution, value: item, id: i}:{name: 'No info: ' + item, value: item, id: i});
@@ -78,13 +150,8 @@ module.exports = {
bar.tick();
- if (count === 0) {
-
- var sortedList = _.map(_.sortBy(items, 'id'));
+ isFinished(count, items);
- sortedList.unshift({name: 'All', value: 'all', checked: true}, {name: 'Cancel', value: 'cancel'});
- callback(null, sortedList);
- }
});
}
diff --git a/mongo-edu.js b/mongo-edu.js
index 6a5d1e1..ad9059c 100644
--- a/mongo-edu.js
+++ b/mongo-edu.js
@@ -14,11 +14,14 @@ var mdbvideos = require('./lib/login'),
argv = require('optimist')
.usage('Usage: $0 -u [user name] -d [download path] --ncc [no check certificate]')
.describe('d', 'download path').describe('u', 'email address')
+ .describe('h', 'switch from videos (default) to handouts').boolean('h')
.describe('ncc', 'no check certificate with py3.x').boolean('ncc')
.demand('d').argv;
exports.create = function start() {
+ var lookFor = ((!argv.h)? 'Videos' : 'Handouts');
+
validate.init(argv, function (err, profile) {
if (err !== null) { throw err; }
run(profile);
@@ -52,7 +55,7 @@ exports.create = function start() {
function currentList() {
inquirer.prompt(classes, function prompt(answers) {
- mdbvideos.getList(answers, function get(err, data) {
+ mdbvideos.getList(answers, argv, function get(err, data) {
if (err !== null) { throw err; }
if (data.length) {
@@ -64,7 +67,8 @@ exports.create = function start() {
}
- return console.log('[' + 'i'.red + '] Unable to locate any lists in the wiki. Is course available?');
+ return console.log('[' + 'i'.red + '] Unable to locate any ' + lookFor.toLowerCase() + ' lists in the wiki. Is course available / ' +
+ lookFor.toLowerCase() + ' list present in the wiki?');
});
});
@@ -84,8 +88,9 @@ exports.create = function start() {
function showDetails(err, data) {
if (err !== null) { throw err; }
+
if (data.length) {
- check[0].message = 'Select From ' + (data.length - 2) + ' Videos. Download:';
+ check[0].message = 'Select From ' + (data.length - 2) + ' ' + lookFor + '. Download:';
check[0].choices = data;
return inquirer.prompt(check, function prompt(answers) {
@@ -94,7 +99,7 @@ exports.create = function start() {
}
- console.log('[' + 'i'.red + '] Could not locate any videos.'); process.exit(0);
+ console.log('[' + 'i'.red + '] Could not locate any ' + lookFor.toLowerCase() + '.'); process.exit(0);
}
});
diff --git a/package.json b/package.json
index 848be6e..39f2967 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "mongo-edu",
"preferGlobal": true,
- "version": "0.1.5",
+ "version": "0.1.6",
"author": "Przemyslaw Pluta <przemyslawplutadev@gmail.com> (http://przemyslawpluta.com)",
"description": "Select and download video courses from education.mongodb.com",
"main": "./mongo-edu",
@@ -34,7 +34,9 @@
"inquirer": "~0.4.0",
"progress": "~1.1.3",
"mkdirp": "~0.3.5",
- "optimist": "~0.6.1"
+ "optimist": "~0.6.1",
+ "request-progress": "^0.3.1",
+ "filesize": "^2.0.3"
},
"engines": {
"node": ">= 0.8.x"