exec(cmd,{ cwd : certDir },function(err,stdout,stderr){ if(err){ callback && callback(new Error("error when generating certificate"),null); }else{ var tipText = "certificate created for __HOST".replace(/__HOST/,hostname); logUtil.printLog(color.yellow(color.bold("[internal https]")) + color.yellow(tipText)) ; callback(null); } });
],function(err,result){ if(!err){ var tipText = "proxy server for __NAME established".replace("__NAME",serverName); logUtil.printLog(color.yellow(color.bold("[internal https]")) + color.yellow(tipText)); SNICallback(null,ctx); }else{ logUtil.printLog("err occurred when prepare certs for SNI - " + err, logUtil.T_ERR); logUtil.printLog("you may upgrade your Node.js to the lastest version", logUtil.T_ERR); } });
exports.artistlistHelp = function() { var text = c.green('§ Arist\n') + this.blanks() + c.yellow('[o] ') + c.grey('Show albums ') + c.yellow('[l] ') + c.grey('Playlist ') + c.yellow('[q] ') + c.grey('Back '); return text }
setInterval(function(){ var timeNow = new Date().getTime(); for(var serverName in self.serverList){ var item = self.serverList[serverName]; if( (timeNow - item.lastestUse) > DEFAULT_RELEASE_TIME){ item.server.close(); delete self.serverList[serverName]; console.log(color.yellow(color.bold("[internal https]")) + color.yellow("https server released : " + serverName)); } } },DEFAULT_RELEASE_TIME);
certMgr.getCertificate(hostname,function(err,keyContent,crtContent){ var server = createHttpsServer(port,keyContent,crtContent,userRequesthandler); self.serverList[hostname] = { port : port, server : server, lastestUse : new Date().getTime() }; var tipText = "https server @port __portNum for __HOST established".replace(/__portNum/,port).replace(/__HOST/,hostname); console.log(color.yellow(color.bold("[internal https]")) + color.yellow(tipText)); callback && callback(null,port); });
exports.albumlistHelp = function() { var text = c.green('§ Albums\n') + this.blanks() + c.yellow('[o] ') + c.grey('Show tracks ') + c.yellow('[i] ') + c.grey('Add this album to playlist ') + c.yellow('[l] ') + c.grey('Playlist ') + c.yellow('[s] ') + c.grey('Play/Stop ') + c.yellow('[q] ') + c.grey('Back '); return text; }
exports.playlistHelp = function() { var text = c.green('§ Playlist\n') + this.blanks() + c.yellow('[l] ') + c.grey('Search list ') + c.yellow('[n] ') + c.grey('Next ') + c.yellow('[s] ') + c.grey('Play/Stop ') + c.yellow('[o] ') + c.grey('Play this ') + c.yellow('[q] ') + c.grey('Main menu '); return text; }
/** * [song] * @param {[type]} s [description] * @param {[type]} selectText [description] * @param {[type]} silence [description] * @return {[type]} [description] */ function song(s, selectText, silence) { var label = '♫ '; var song = s.title ? s : {}; if (!song.title) { song.text = label + '未知曲目...'; if (!silence) this.notify(song); return color.grey(song.text); } song.text = label + song.title + ' - ' + song.artist; song.open = utils.album(song.album); if (!silence) this.notify(song); return printf( '%s %s %s %s %s %s %s %s', song.like == 1 ? color.red('♥') : color.grey('♥'), color.green(song.title), color.grey(song.kbps + 'kbps'), color.grey('... ♪ ♫ ♫ ♪ ♫ ♫ ♪ ♪ ...'), selectText || color.yellow(song.albumtitle), selectText ? '' : color.grey('•'), selectText ? '' : song.artist, selectText ? '' : color.grey(song.public_time) ) }
Fm.prototype.stop = function() { if (!this.player) return false; var menu = this.menu; menu.clear(1); menu.label(1, color.yellow('||')); return this.player.stop(); }
self.player.on('playing', function(song) { self.status = 'playing'; if (song.title && song.sid) self.log(song); menu.update(0, color.yellow('>>')); if (self.isShowLrc) lrc.fetch(self, song); menu.update( channel.index, template.song(song) ); if (song._id < self.player.list.length - 1) return false; self.status = 'switching'; return sdk.fetch({ channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs) { if (err) return false; // 没有对尝试获取列表失败进行处理,如果失败2次,则不会再播放任何歌曲 if (!songs) return false; return songs.forEach(function(s, index) { s._id = self.player.list.length; self.player.add(s); }); }); });
exports.logo = function(account) { return printf( '%s %s %s', color.yellow('Douban FM'), color.grey('v' + pkg.version), account ? color.grey('/ ' + account.user_name) : '' ); }
(err, resp, msg) => { if(err){ rej(err); console.log(color.red('Error: ' + err.message)); } else{ res(msg); resp.statusCode === 200 ? console.log(color.cyan('=> ' + poster.name), paths.serverFilepath): console.log(color.yellow('Warn: ' + msg), color.gray('[post|post.js|97]')); } }
function printLog(content, type) { if (!ifPrint) { return; } const timeString = util.formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss'); switch (type) { case LogLevelMap.tip: { if (logLevel > 0) { return; } console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content)); break; } case LogLevelMap.system_error: { if (logLevel > 1) { return; } console.error(color.red(`[AnyProxy ERROR][${timeString}]: ` + content)); break; } case LogLevelMap.rule_error: { if (logLevel > 2) { return; } console.error(color.red(`[AnyProxy RULE_ERROR][${timeString}]: ` + content)); break; } case LogLevelMap.warn: { if (logLevel > 3) { return; } console.error(color.yellow(`[AnyProxy WARN][${timeString}]: ` + content)); break; } case LogLevelMap.debug: { console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content)); return; } default : { console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content)); break; } } }
self.player.on('playing', function(song) { self.status = 'playing'; menu.label(1, color.yellow('>>')); lrc.playLrc(self, song); menu.update( channel.index, printf( '%s %s %s %s %s %s %s %s', song.like == 1 ? color.red('♥') : color.grey('♥'), color.green(song.title), color.grey(song.kbps + 'kbps'), color.grey('... ♪ ♫ ♫ ♪ ♫ ♫ ♪ ♪ ...'), color.yellow(song.albumtitle), color.grey('•'), song.artist, color.grey(song.public_time) ) ); if (song._id < self.player.list.length - 1) return false; self.status = 'switching'; return sdk.fetch({ channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs) { if (err) return false; // 没有对尝试获取列表失败进行处理,如果失败2次,则不会再播放任何歌曲 if (!songs) return false; return songs.forEach(function(s, index) { s._id = self.player.list.length; self.player.add(s); }); }); });
function generateRootCA(){ if(isRootCAFileExists()){ logUtil.printLog(color.yellow("rootCA exists at " + certDir)); var rl = readline.createInterface({ input : process.stdin, output: process.stdout }); rl.question("do you really want to generate a new one ?)(yes/NO)", function(answer) { if(/yes/i.test(answer)){ startGenerating(); }else{ logUtil.printLog("will not generate a new one"); process.exit(0); } rl.close(); }); }else{ startGenerating(); } function startGenerating(){ //clear old certs clearCerts(function(){ logUtil.printLog(color.green("temp certs cleared")); var spawnSteam = spawn(cmd_genRoot,['.'],{cwd:certDir,stdio: 'inherit'}); spawnSteam.on('close', function (code) { if(code == 0){ logUtil.printLog(color.green("rootCA generated")); logUtil.printLog(color.green(color.bold("please trust the rootCA.crt in " + certDir))); logUtil.printLog(color.green(color.bold("or you may get it via anyproxy webinterface"))); }else{ logUtil.printLog(color.red("fail to generate root CA"),logUtil.T_ERR); } //process.exit(0); }); }); } }
/** * 执行上传操作 * @example this.get(['lib']).post() */ post() { var array; var config = this.config.get(); var poster = config.poster[config.posterSelectedIndex || 0]; // 当前CONFIG不存在paths配置时 if(!config.poster[config.posterSelectedIndex || 0].paths){ return console.log(color.yellow('Warn: Please collocate paths first')) } array = this.files.map((file) => { var paths = this.getPaths(file, poster); return new Promise((res, rej) => { form( poster.url, { file: file, field: 'files', filepath: paths.serverFilepath }, (err, resp, msg) => { if(err){ rej(err); console.log(color.red('Error: ' + err.message)); } else{ res(msg); resp.statusCode === 200 ? console.log(color.cyan('=> ' + poster.name), paths.serverFilepath): console.log(color.yellow('Warn: ' + msg), color.gray('[post|post.js|97]')); } } ) }) }) Promise .all(array) .catch(function(err) { throw err; }) }
self.configs(function(err, user) { self.menu = new termList(); self.menu.adds( ['', printf( '%s %s %s', color.yellow('Douban FM'), color.grey('v' + sys.version), user && user.account && user.account.user_name ? color.grey('/ ' + user.account.user_name) : '' )].concat(list) ) self.menu.on('keypress', function(key, index){ if (!shorthands[key.name]) return false; if (index < 2 && key.name != 'q') return utils.go(sys.repository.url); // self.currentMenu = index; return self[shorthands[key.name]](self.menu.items[index], user); }); self.menu.start(1); });
exports.playHelp = function() { var text = c.green('§ Songs\n') + this.blanks() + c.yellow('[o] ') + c.grey('Play this ') + c.yellow('[a] ') + c.grey('Add ') + c.yellow('[s] ') + c.grey('Play/Stop ') + c.yellow('[i] ') + c.grey('Add all ') + c.yellow('[l] ') + c.grey('Playlist ') + c.yellow('[n] ') + c.grey('Next ') + c.yellow('[q] ') + c.grey('Back '); return text; }
sdk.love(query, function(err, result) { var tips = !(song.like) ? color.red('♥') : color.grey('♥'); if (err) tips = color.red('x'); if (!err) self.player.playing.like = !song.like; // TODO: 这里有冗余代码 menu.clear(-1); return menu.update( self.channel, printf( '%s %s %s %s %s %s %s %s', tips, color.green(song.title), color.grey(song.kbps + 'kbps'), color.grey('... ♪ ♫ ♫ ♪ ♫ ♫ ♪ ♪ ...'), color.yellow(song.albumtitle), color.grey('•'), song.artist, color.grey(song.public_time) ) ); });
/** * 获取文件路径信息 * @param {String} file 本地文件路径 * @param {Object} poster 当前POST配置项 * @return {Object} 本地文件的相关路径信息 */ getPaths(file, poster) { var paths, local, cwd; // 获取服务器路径配置 paths = poster.paths.find((url) => { // 标准化路径 cwd = this.pathend(this.cwd); local = this.pathend(url.local); return local === cwd || cwd.indexOf(local) === 0; }) // 如果为空则退出进程 if(!paths){ console.log(color.yellow('Warn: This folder is not workplace')) process.exit(1) } return { local: paths.local, server: paths.server, relative: path.relative(paths.local, file), localFilepath: path.join(this.cwd, file), serverFilepath: path.join(paths.server, path.relative(paths.local, file)) } }
/** * [pause] * @return {[type]} [description] */ function pause() { this.title('Douban FM'); return color.yellow('||'); }
exports.pause = function() { this.title('Douban FM'); return color.yellow('||'); }
exports.log = function(text) { console.log(this.blanks() + c.yellow(text)); }
function connectReqHandler(req, socket, head){ var host = req.url.split(":")[0], targetPort= req.url.split(":")[1], resourceInfo, resourceInfoId; var shouldIntercept = userRule.shouldInterceptHttpsReq(req); //bypass webSocket on webinterface if(targetPort == 8003){ shouldIntercept = false; // TODO : a more general solution? } //Cojad: surpress too much message here. logUtil.printLog(color.yellow("[https connect] " + host)); /*logUtil.printLog(color.green("\nreceived https CONNECT request " + host)); if(shouldIntercept){ logUtil.printLog("==>will forward to local https server"); }else{ logUtil.printLog("==>will bypass the man-in-the-middle proxy"); }*/ //record resourceInfo = { host : host, method : req.method, path : "", url : "https://" + host, req : req, startTime : new Date().getTime() }; resourceInfoId = GLOBAL.recorder.appendRecord(resourceInfo); var proxyPort, proxyHost, internalHttpsPort, httpsServerMgrInstance; async.series([ //check if internal https server exists function(callback){ if(!shouldIntercept){ callback(); return; }else{ if(internalHttpsPort){ callback(); }else{ getPort(function(port){ internalHttpsPort = port; httpsServerMgrInstance = new httpsServerMgr({ port :port, handler :userRequestHandler }); callback(); }); } } }, //determine the target server function(callback){ if(shouldIntercept){ proxyPort = internalHttpsPort; proxyHost = "127.0.0.1"; callback(); }else{ proxyPort = (targetPort == 80)? 443 : targetPort; proxyHost = host; callback(); } //connect },function(callback){ try{ var conn = net.connect(proxyPort, proxyHost, function(){ socket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', function(){ //throttle for direct-foward https if(GLOBAL._throttle && !shouldIntercept ){ var readable = conn.pipe(GLOBAL._throttle.throttle()); readable.pipe(socket); socket.pipe(conn); }else{ conn.pipe(socket); socket.pipe(conn); } callback(); }); }); conn.on("error",function(e){ logUtil.printLog("err when connect to + " + host + " , " + e, logUtil.T_ERR); }); }catch(e){ logUtil.printLog("err when connect to remote https server (__host)".replace(/__host/,host), logUtil.T_ERR); } //update record },function(callback){ resourceInfo.endTime = new Date().getTime(); resourceInfo.statusCode = "200"; resourceInfo.resHeader = {}; resourceInfo.resBody = ""; resourceInfo.length = 0; GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo); callback(); } ],function(err,result){ if(err){ logUtil.printLog("err " + err, logUtil.T_ERR); throw err; } }); }
exports.logo = function() { return c.yellow('Netease Player ') + c.cyan(sysInfo.version) }
Fm.prototype.play = function(channel, user) { var self = this, menu = self.menu, account = user && user.account ? user.account : {}, privateMhz = (channel.channel_id == 0 || channel.channel_id == -3) && !account.token; // 检查是否是私人兆赫,如果没有设置账户直接返回 if (privateMhz) return menu.update(channel.index, color.yellow(errors.account_missing)); if (self.status === 'fetching' || self.status === 'downloading') return false; if (self.status === 'playing') { if (typeof(self.channel) != undefined) menu.clear(self.channel); self.player.stop(); self.player.status = 'stoped'; self.player = null; } // 清除标志状态,加载标志 menu.clear(0); self.channel = channel.index; self.status = 'fetching'; menu.update(channel.index, template.listing()); // 获取相应频道的曲目 sdk.fetch({ local: (channel.channel_id == -99) ? self.home : false, history: self.rc.history, channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs, result) { if (err) return menu.update(channel.index, color.red(err.toString())); // 标记 PRO 账户 if (result && !result.warning) menu.update(0, color.inverse(' PRO ')); self.status = 'ready'; self.player = new Player(songs, { src: 'url', cache: true, downloads: self.home }); self.player.play(); self.player.on('downloading', function(url) { self.status = 'downloading'; menu.update(channel.index, template.loading()); }); // 更新歌单 self.player.on('playing', function(song) { self.status = 'playing'; if (song.title && song.sid) self.log(song); menu.update(0, color.yellow('>>')); if (self.isShowLrc) lrc.fetch(self, song); menu.update( channel.index, template.song(song) ); if (song._id < self.player.list.length - 1) return false; self.status = 'switching'; return sdk.fetch({ channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs) { if (err) return false; // 没有对尝试获取列表失败进行处理,如果失败2次,则不会再播放任何歌曲 if (!songs) return false; return songs.forEach(function(s, index) { s._id = self.player.list.length; self.player.add(s); }); }); }); }); }
http.createServer(app).listen(app.get('port'), function(){ console.log(color.yellow('[' + pkg.name + ']' + ' is running on ......' + ' ==> http://localhost:' + app.get('port'))); });
export function logo(account) { return `${ color.yellow('Douban FM') } ${color.grey('v' + pkg.version)} ${account ? color.grey('/ ' + account.user_name) : ''}` }
Fm.prototype.play = function(channel, user) { var self = this, menu = self.menu, account = user && user.account ? user.account : {}, privateHz = (channel.channel_id == 0 || channel.channel_id == -3) && !account.token; // 检查是否是私人兆赫,如果没有设置账户直接返回 if (privateHz) return menu.update(channel.index, color.yellow(errors.account_missing)); if (self.status === 'fetching' || self.status === 'downloading') return false; if (self.status === 'playing') { if (typeof(self.channel) != undefined) menu.clear(self.channel); self.player.stop(); self.player.status = 'stoped'; self.player = null; } // 清除标志状态,加载标志 menu.clear(1); self.channel = channel.index; self.status = 'fetching'; menu.update(channel.index, color.grey('加载列表中,请稍等...')); // 获取相应频道的曲目 sdk.fetch({ channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs, result) { if (err) return menu.update(channel.index, color.red(err.toString())); // 标记 PRO 账户 if (result && !result.warning) menu.label(1, color.inverse(' PRO ')); self.status = 'ready'; self.player = new Player(songs, { srckey: 'url', downloads: self.home }); self.player.play(); // 同步下载不太好,但是在解决 stream 的无法获取抛错之前没有好办法 self.player.on('downloading', function(url) { self.status = 'downloading'; menu.update(channel.index, color.grey('下载歌曲中,请稍等...')); }); // 更新歌单 self.player.on('playing', function(song) { self.status = 'playing'; menu.label(1, color.yellow('>>')); lrc.playLrc(self, song); menu.update( channel.index, printf( '%s %s %s %s %s %s %s %s', song.like == 1 ? color.red('♥') : color.grey('♥'), color.green(song.title), color.grey(song.kbps + 'kbps'), color.grey('... ♪ ♫ ♫ ♪ ♫ ♫ ♪ ♪ ...'), color.yellow(song.albumtitle), color.grey('•'), song.artist, color.grey(song.public_time) ) ); if (song._id < self.player.list.length - 1) return false; self.status = 'switching'; return sdk.fetch({ channel: channel.channel_id, user_id: account.user_id, expire: account.expire, token: account.token, kbps: 192 }, function(err, songs) { if (err) return false; // 没有对尝试获取列表失败进行处理,如果失败2次,则不会再播放任何歌曲 if (!songs) return false; return songs.forEach(function(s, index) { s._id = self.player.list.length; self.player.add(s); }); }); }); }); }
// 如果默认项被删除则默认选中1 if(config.posterSelectedIndex == index){ config.posterSelectedIndex = 0; } this.config.save(); console.log('') console.log(' ' + name, 'has been deleted') console.log('') } } Post.msg = { none() { console.log('') console.error(' ' + color.yellow('Warn: Can\'t find this config, Please input the correct config name')) console.log('') }, removeIndex(arr, index){ arr.splice(index, 1); return arr; } } post = new Post; post.Post = Post; module.exports = post;