UNPKG

nct-downloader

Version:
347 lines (293 loc) 10.6 kB
(function() { 'use strict'; var Download, Playlist, Search, Singer, Url, asset, c, celeri, chery, events, exec, fs, http, multimeter, path, readline, sys, unirest, util, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; http = require('http'); readline = require('readline'); chery = require('cheerio'); unirest = require('unirest'); sys = require('sys'); exec = require('child_process').exec(); fs = require('fs'); celeri = require('celeri'); c = console; path = require('path'); asset = path.resolve.bind(null, __dirname, '..'); events = require('events'); util = require('util'); multimeter = require('pm2-multimeter'); Url = (function(_super) { __extends(Url, _super); function Url(data) { var url; this.data = data; this.setMaxListeners(1000); url = this.data.url; if ('www' === url.substring(0, 3)) { url = "http://" + url; } if ('http' === url.substring(0, 4)) { this.url = url; } else { this.url = "http://www.nhaccuatui.com/" + url; } } Url.prototype.container = '.list'; Url.prototype.item = '.button_download'; Url.prototype.crawler = function(cb) { var fake_progress, t; t = this; this.emit('start', this.url); fake_progress = 1; http.get(this.url, function(res) { var html; res.setEncoding('utf8'); html = ''; return res.on('data', function(chunk) { var fake_progess; fake_progress++; if (fake_progess === 100) { fake_progess = 84; } html += chunk; t.emit('data', fake_progress); }).on('end', function(data) { t.emit('data', 100); return t.find_song_item(html); }); }).on('error', function(e) { return console.log(e.message()); }); return this; }; Url.prototype.find_song_item = function(html) { var $, song_list, song_total; $ = chery.load(html); song_total = $("" + this.container + " " + this.item).length; console.log("Found " + song_total + " songs"); song_list = []; $(this.container).find(this.item).each(function(index, elem) { var key, singer, title; key = $(elem).attr('key'); if (!(key != null)) { return false; } title = $(elem).attr('title'); title = title.split('-'); singer = title[1] != null ? title[1].trim() : ''; return song_list.push({ title: title[0].substring(16), singer: singer, key: key, songurl: "http://www.nhaccuatui.com/download/song/" + key }); }); this.emit('finish', song_list); }; return Url; })(events.EventEmitter); Playlist = (function(_super) { __extends(Playlist, _super); function Playlist() { return Playlist.__super__.constructor.apply(this, arguments); } Playlist.prototype.container = '.list_song_in_album'; Playlist.prototype.item = '.button_download'; return Playlist; })(Url); Search = (function(_super) { __extends(Search, _super); function Search(data) { var q; this.data = data; q = this.data.q; if ('http' === q.substring(0, 4)) { this.url = q; } else { this.url = "http://www.nhaccuatui.com/tim-kiem?q=" + q; } } Search.prototype.container = '.search_returns_list'; return Search; })(Url); Singer = (function(_super) { __extends(Singer, _super); function Singer() { return Singer.__super__.constructor.apply(this, arguments); } Singer.prototype.container = '.list_music'; return Singer; })(Url); Download = (function() { function Download() { this.multi = {}; this.bars = []; } Download.prototype.start = function() {}; Download.prototype.done = function(result) { if (result == null) { result = true; } if (result) { process.stdout.write("\nDone. Enjoy music.\n"); } else { process.stdout.write("\nAn error occured. Check syntax and URL.\n"); } return process.exit(); }; Download.prototype.process = function(cmd, data) { var bar, url; this.multi = multimeter(process); this.multi.on('^C', process.exit); this.multi.charm.reset(); switch (cmd) { case "singer": url = new Singer(data); break; case "search": url = new Search(data); break; case "playlist": url = new Playlist(data); break; case "page": url = new Search(data); break; default: console.log("Invalid command"); process.exit(false); } bar = {}; this.start(); return url.on('finish', this.download.bind(this)).on('start', (function(url) { this.multi.write("Start to find songs.\n"); this.multi.write("Progress: \n"); bar = this.multi(13, 2, { width: 20, solid: { text: '|', foreground: 'yellow', background: 'red' }, empty: { text: ' ' } }); }).bind(this)).on('data', function(data) { return bar.percent(data); }).crawler(); }; Download.prototype.download = function(song_list) { var download_file, number_of_downloaded, s, song_index, that, title, _fn, _i, _len; that = this; this.multi.charm.reset(); if (song_list.length === 0) { this.done(); } number_of_downloaded = 0; download_file = function(song_index, song_url, to) { var count_downloaded_size, file, request; file = fs.createWriteStream(to); file.on('finish', function() { number_of_downloaded++; if (number_of_downloaded === song_list.length) { that.done(); } return that.bars[song_index].percent(100); }); count_downloaded_size = 0; return request = http.get(song_url, function(response) { var total_length; total_length = parseInt(response.headers['content-length'], 10); response.on('data', function(chunk) { count_downloaded_size += chunk.length; return that.bars[song_index].percent(parseFloat(count_downloaded_size * 100 / total_length)); }); return response.pipe(file); }); }; _fn = function(song_index) { return unirest.get(s.songurl).end(function(res) { var p, real_song_url, song; song = JSON.stringify(res.body); song = JSON.parse(song); if (!(song.data.stream_url != null) || song.error_code === 8) { unirest.post('http://www.nhaccuatui.com/ajax/stream').send('type=playlist').send("key=" + song_list[song_index].key).send("v=" + (new Date().getTime())).end(function(res) { var p, real_song_url; song = JSON.parse(res.body); if (song.error_code === 0) { real_song_url = song.data.stream; } if (real_song_url != null) { p = real_song_url.split('/'); download_file(song_index, real_song_url, "" + (process.cwd()) + "/" + p[p.length - 1]); } else { number_of_downloaded++; } }); return false; } real_song_url = song.data.stream_url; p = real_song_url.split('/'); return download_file(song_index, real_song_url, "" + (process.cwd()) + "/" + p[p.length - 1]); }); }; for (song_index = _i = 0, _len = song_list.length; _i < _len; song_index = ++_i) { s = song_list[song_index]; title = "" + (song_index + 1) + ". " + s.title + ": \n"; this.multi.write("" + title); this.bars[song_index] = this.multi(title.length, song_index + 1, { width: 20, solid: { text: '|', foreground: 'yellow', background: 'red' }, empty: { text: ' ' } }); _fn(song_index); } return true; }; return Download; })(); exports.run = function() { var d, pjson; pjson = require(asset('package.json')); console.log("\n NCT-Downloader " + pjson.version + " \n \n .oo o .oPYo. \n .P 8 8 8 8 \n .P 8 `o o' .oPYo. .oPYo. o8P .oPYo. 8 .oPYo. ooYoYo. \n oPooo8 `bd' 8 ' 8 8 8 8 8 8 8 8 8' 8 8 \n .P 8 d'`b 8 . 8 8 8 8 8 8 8 8 8 8 8 8 \n.P 8 o' `o `YooP' `YooP' 8 `YooP' 88 `YooP' `YooP' 8 8 8 \n..:::::....:::..:.....::.....:::..::.....:..::.....::.....:..:..:..\n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\n"); celeri.usage('ndown [command] keyword_in_quote or url or album..'); if (process.argv.length === 2 || ['help', 'casi', 'singer', 'timkiem', 'search', 'playlist', 'page', 'trang'].indexOf(process.argv[2]) === -1) { console.log("Hey, type: ndown help.\n"); process.exit(); } d = new Download; celeri.option({ command: 'casi :url OR singer :url', description: ' Download nhạc của 1 ca sĩ' }, function(data) { return d.process("singer", data); }); celeri.option({ command: 'timkiem :q OR search :q', description: ' Download nhạc dựa theo từ khoá. Ví du: ' }, function(data) { return d.process("search", data); }); celeri.option({ command: 'playlist :url', description: ' Download nhạc của 1 playlist' }, function(data) { return d.process("playlist", data); }); celeri.option({ command: 'trang :url OR page :url', description: ' Download nhạc trên 1 trang cụ thể' }, function(data) { return d.process("page", data); }); return celeri.parse(process.argv); }; }).call(this);