evdh
Version:
evdh : EisF Video Download Helper, auto download videos on web pages.
396 lines (290 loc) • 8.48 kB
JavaScript
/* aurl.js, aurl: analyse url part for evdh: EisF Video Download Helper, sceext <sceext@foxmail.com> 2009EisF2015, 2015.02
* version 0.1.2.0 test201502142022 (public version)
* author sceext <sceext@foxmail.com> 2015.02
* copyright 2015 sceext
*
* This is FREE SOFTWARE, released under GNU GPLv3+
* please see README.md and LICENSE for more information.
*
* evdh : EisF Video Download Helper, auto download videos with analyse service provided by flv.cn (api.flvxz.com)
* Copyright (C) 2015 sceext <sceext@foxmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* require import modules */
// nodejs modules
var path = require('path');
// evdh modules
var _b = require('./b.js');
var _log = require('./log.js');
var _dl = require('./dl.js');
// this module global config object
var etc = {};
etc.log_path = '.';
etc.result_file = 'result.xml';
etc.header_file = 'header.log';
etc.token = ''; // token used to analyse url
etc.analyse_request_website = '';
etc.user_agent = '';
// import time_log for global use
var time_log = function(output){
_log.time_log(output);
};
/* objects */
/* object o_analyse_xml_raw start, axr, get raw info from response xml of video analyse request */
function o_analyse_xml_raw() {
// methods
this.load = axr_load;
// private methods
this._init = axr_init;
this._loaded = axr_loaded;
this._info_video = axr_info_video;
this._info_file = axr_info_file;
this._get_text = axr_get_text;
// attributes
this.callback = null; // finish callback(error);
this.info = {}; // response analyse video info object
// private attributes
this._o_xf = null; // sub object, xml parser
this._doc = null; // xml dom document object
// init this
this._init();
}
function axr_init() {
// create sub object
this._o_xf = new _b.o_xml_loader();
}
function axr_load(xml_text) {
// use o_xml_loader to parse xml text
this._doc = this._o_xf.to_dom(xml_text);
// do not call loaded now
var b = this;
setTimeout(function(){
// loaded
b._loaded();
}, 0);
}
function axr_loaded() {
var doc = this._doc;
// get root element
var e_root = doc.documentElement;
// get videos
var videos = e_root.getElementsByTagName('video');
this.info.video = [];
// get each video info
for (var i = 0; i < videos.length; i++) {
var video_info = this._info_video(videos[i]);
this.info.video.push(video_info);
}
// done, callback
this.callback(null);
}
function axr_info_video(node) {
var info = {}; // video info object
// get keys
var key_list = [
'title',
'site',
'quality',
'hd',
];
for (var i = 0; i < key_list.length; i++) {
var key = key_list[i];
var text = this._get_text(node.getElementsByTagName(key)[0]);
// set key
info[key] = text;
}
// process key
if (typeof info.hd == 'string') {
info.hd = parseInt(info.hd, 10);
}
info.file = [];
// get files info
var files = node.getElementsByTagName('files')[0];
if (typeof files == 'object') {
files = files.getElementsByTagName('file');
// get each file info
for (var i = 0; i < files.length; i++) {
var file_info = this._info_file(files[i]);
// add file_info
info.file.push(file_info);
}
}
// done
return info;
}
function axr_info_file(node) {
var info = {};
// get keys
var key_list = {
'url' : 'furl',
'type' : 'ftype',
'size' : 'size',
'time_s' : 'seconds',
};
for (var i in key_list) {
var key = key_list[i];
var text = this._get_text(node.getElementsByTagName(key)[0]);
// set key
info[i] = text;
}
// process key
key_list = [
'size',
'time_s',
];
for (var i = 0; i < key_list.length; i++) {
var key = key_list[i];
if (typeof info[key] == 'string') {
info[key] = parseInt(info[key], 10);
}
}
// done
return info;
}
function axr_get_text(node) {
if (typeof node != 'object') {
return null;
}
if (typeof node.firstChild == 'object') {
text = node.firstChild.nodeValue;
text = text.toString();
// remove '<![CDATA[' or 'CDATA[' before string
var rm_b = [ // remove before
'<![CDATA[',
'[CDATA[',
];
var rm_ed = -1;
for (var i = 0; i < rm_b.length; i++) {
var rm = rm_b[i];
if (text.indexOf(rm) == 0) {
text = text.slice(rm.length, text.length);
rm_ed = i;
break;
}
}
// remove ']]>' or ']' after string
if (rm_ed != -1) {
var rm_a = [
']]>',
']]',
];
if (text.slice(text.length - rm_a[rm_ed].length, text.length) == rm_a[rm_ed]) { // remove it
text = text.slice(0, text.length - rm_a[rm_ed].length);
}
}
return text;
} else {
return null;
}
}
/* end o_analyse_xml_raw object */
/* functions */
// analyse url
function aurl(url, callback) { // finish callback(error, info);
var _host = {};
// static config
_host.result_file = path.join(etc.log_path, etc.result_file);
_host.header_file = path.join(etc.log_path, etc.header_file);
_host.callback = callback;
_host.url = url;
_host.info = null; // info object to callback return
_host.error = null; // error callback info
// start
var _next = aurl_next;
_next(1, _host);
}
function aurl_next(_step, _host) {
var _next = aurl_next;
switch (_step) {
case 1: // first step
// make url in base64, for debug
// _host.base64 = _b.encode_url(_host.url);
// create request object
_host.hr = new _dl.o_http_requester();
// set callback
_host.hr.callback = function(err){
if (err) {
time_log('ERROR: request failed ! ');
_host.error = err;
_next(-1, _host);
} else {
_next(_step + 1, _host);
}
};
time_log('INFO: use token of length ' + etc.token.length);
// make url
var request_url = _b.make_request_url(etc.token, _host.url);
var request_option = _b.make_request_option(etc.analyse_request_website, request_url, etc.user_agent);
// do request
_host.hr.request(request_option);
// print info
time_log('INFO: getting info from \"' + etc.analyse_request_website + '\" ... ');
break;
case 2: // got result
// write log file
var header = JSON.stringify(_host.hr.header);
var log_text = 'http ' + _host.hr.status_code + ' ; response headers: ' + header;
_b.write_file(_host.header_file, new Buffer(log_text, 'utf-8'), function(err){
if (err) {
time_log('ERROR: can not wirte http header log file \"' + _host.header_file + '\" ! ');
}
});
// save data to result file
_b.write_file(_host.result_file, _host.hr.data, function(err){
if (err) {
time_log('ERROR: can not write result file \"' + _host.result_file + '\" ! ');
}
});
// analyse xml_text
var xml_text = _host.hr.data.toString('utf-8');
// create analyse object
_host.ao = new o_analyse_xml_raw();
// set ao
_host.ao.callback = function(err){
if (err) {
time_log('ERROR: analyse received xml failed ! ');
_host.error = err;
_next(-1, _host);
} else {
_next(_step + 1, _host);
}
};
// do analyse
_host.ao.load(xml_text);
time_log('INFO: analysing recevied xml ... ');
break;
case 3: // finish analyse
_host.info = _host.ao.info;
_next(0, _host);
break;
case 0: // finish step
// ok callback
_host.callback(null, _host.info);
break;
case -1: // error step
// error callback
_host.callback(_host.error, null);
break;
default: // step error
time_log('ERROR: aurl.js aurl_next: step error ! ');
}
}
/* exports */
exports.etc = etc;
// objects
exports.o_analyse_xml_raw = o_analyse_xml_raw;
// functions
exports.aurl = aurl;
/* end aurl.js */