Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unblock-netease-music

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unblock-netease-music - npm Package Compare versions

Comparing version 2.5.5 to 3.0.0

dist/modules/pair/index.js

131

dist/app.js

@@ -7,10 +7,2 @@ 'use strict';

var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
require('colors');

@@ -26,5 +18,5 @@

var _koaRoute = require('koa-route');
var _koaRouter = require('koa-router');
var _koaRoute2 = _interopRequireDefault(_koaRoute);
var _koaRouter2 = _interopRequireDefault(_koaRouter);

@@ -39,2 +31,6 @@ var _config = require('./modules/config');

var _netease = require('./modules/utils/netease');
var _netease2 = _interopRequireDefault(_netease);
var _modify = require('./modules/modify');

@@ -44,6 +40,2 @@

var _netease = require('./modules/utils/netease');
var _netease2 = _interopRequireDefault(_netease);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

@@ -53,76 +45,53 @@

var app = new _koa2.default();
// import * as pair from './modules/pair';
const errorHandler = async (ctx, next) => {
const data = ctx.body;
let json = '';
try {
json = JSON.parse(ctx.body.toString());
} catch (error) {
console.log('Pares failed. Maybe encrypted.');
ctx.body = data;
return;
}
if (Array.isArray(json.data)) {
json.data = json.data.map(e => _netease2.default.fixJsonData(e));
} else {
json.data = _netease2.default.fixJsonData(json.data);
}
try {
ctx.body = json;
await next();
} catch (err) {
if (_config2.default.verbose) {
console.log(err);
}
ctx.body = json;
console.log('Modify failed.'.red);
}
};
const app = new _koa2.default();
app.use((0, _koaLogger2.default)());
app.use(_proxy2.default);
app.use(function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(ctx, next) {
var data, json;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
data = ctx.body;
json = '';
_context.prev = 2;
json = JSON.parse(ctx.body.toString());
_context.next = 11;
break;
const router = (0, _koaRouter2.default)();
case 6:
_context.prev = 6;
_context.t0 = _context['catch'](2);
// Route for native netease client
router.post('/eapi/song/enhance/player/url', _proxy2.default, errorHandler, modify.player);
router.post('/api/plugin/player', _proxy2.default, errorHandler, modify.player);
router.post('/eapi/song/enhance/download/url', _proxy2.default, errorHandler, modify.download);
router.post('/api/plugin/download', _proxy2.default, errorHandler, modify.download);
router.post('/api/linux/forward', _proxy2.default, errorHandler, modify.forward);
console.log('Pares failed. Maybe encrypted.');
ctx.body = data;
return _context.abrupt('return');
// Route for Unblock Netease Music Server itself
// router
// .use('/api/pair/*', pair.permission)
// .get('/api/pair/recent', pair.recent)
// .get('/api/pair', pair.list)
// .put('/api/pair', pair.save)
// .post('/api/pair/:songId', pair.update);
case 11:
if (Array.isArray(json.data)) {
json.data = json.data.map(function (e) {
return _netease2.default.fixJsonData(e);
});
} else {
json.data = _netease2.default.fixJsonData(json.data);
}
_context.prev = 12;
app.use(router.routes()).use(router.allowedMethods());
ctx.body = json;
_context.next = 16;
return next();
case 16:
_context.next = 23;
break;
case 18:
_context.prev = 18;
_context.t1 = _context['catch'](12);
if (_config2.default.verbose) {
console.log(_context.t1);
}
ctx.body = json;
console.log('Modify failed.'.red);
case 23:
case 'end':
return _context.stop();
}
}
}, _callee, undefined, [[2, 6], [12, 18]]);
}));
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
}());
app.use(_koaRoute2.default.post('/eapi/song/enhance/player/url', modify.player));
app.use(_koaRoute2.default.post('/eapi/song/enhance/download/url', modify.download));
app.use(_koaRoute2.default.post('/api/linux/forward', modify.forward));
app.use(_koaRoute2.default.post('/api/plugin', modify.player));
app.use(_koaRoute2.default.post('/api/plugin/player', modify.player));
app.use(_koaRoute2.default.post('/api/plugin/download', modify.download));
exports.default = app;

@@ -28,3 +28,3 @@ #!/usr/bin/env node

var port = _config2.default.port || '8123';
const port = _config2.default.port || '8123';

@@ -35,3 +35,3 @@ /**

var server = _http2.default.createServer(_app2.default.callback());
const server = _http2.default.createServer(_app2.default.callback());

@@ -47,3 +47,3 @@ /**

var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`;

@@ -53,7 +53,7 @@ // handle specific listen errors with friendly messages

case 'EACCES':
console.error(bind + ' requires elevated privileges');
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
console.error(`${bind} is already in use`);
process.exit(1);

@@ -71,4 +71,4 @@ break;

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
const addr = server.address();
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
console.log('Listening on '.yellow + bind.yellow);

@@ -75,0 +75,0 @@ }

@@ -8,14 +8,2 @@ 'use strict';

var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
require('colors');

@@ -33,224 +21,82 @@

var utils = new _utils2.default();
const utils = new _utils2.default();
var player = exports.player = function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(ctx, next) {
var data, playbackReturnCode, songId, urlInfo;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
data = ctx.body;
playbackReturnCode = data.data[0].code;
songId = data.data[0].id;
const player = exports.player = async (ctx, next) => {
const data = ctx.body;
if (!(playbackReturnCode === 200)) {
_context.next = 6;
break;
}
const playbackReturnCode = data.data[0].code;
const songId = data.data[0].id;
console.log('The song URL is '.green + data.data[0].url);
return _context.abrupt('return', next());
if (playbackReturnCode === 200) {
console.log('The song URL is '.green + data.data[0].url);
return next();
}
case 6:
urlInfo = void 0;
_context.prev = 7;
_context.next = 10;
return utils.getUrlInfo(songId);
let urlInfo;
try {
urlInfo = await utils.getUrlInfo(songId);
} catch (err) {
console.log(err);
throw new Error(err);
}
if (urlInfo) {
try {
data.data[0] = await _netease2.default.modifyPlayerApiCustom(urlInfo, data.data[0]);
} catch (error) {
console.log('No resource.'.red);
throw new Error(error);
}
} else {
console.log('No resource.'.red);
}
ctx.body = JSON.stringify(data);
return next();
};
case 10:
urlInfo = _context.sent;
_context.next = 17;
break;
const download = exports.download = async (ctx, next) => {
const data = ctx.body;
case 13:
_context.prev = 13;
_context.t0 = _context['catch'](7);
if (_netease2.default.getDownloadReturnCode(data) === 200) {
return console.log('The song URL is '.green + data.data.url);
}
const songId = _netease2.default.getDownloadSongId(data);
let urlInfo;
try {
urlInfo = await utils.getUrlInfo(songId);
} catch (err) {
console.log(err);
throw new Error(err);
}
if (urlInfo) {
try {
data.data = await _netease2.default.modifyDownloadApiCustom(urlInfo, data.data);
} catch (error) {
console.log('No resource.'.red);
throw new Error(error);
}
} else {
console.log('No resource.'.red);
}
return next();
};
console.log(_context.t0);
throw new Error(_context.t0);
case 17:
if (!urlInfo) {
_context.next = 30;
break;
}
_context.prev = 18;
_context.next = 21;
return _netease2.default.modifyPlayerApiCustom(urlInfo, data.data[0]);
case 21:
data.data[0] = _context.sent;
_context.next = 28;
break;
case 24:
_context.prev = 24;
_context.t1 = _context['catch'](18);
console.log('No resource.'.red);
throw new Error(_context.t1);
case 28:
_context.next = 31;
break;
case 30:
console.log('No resource.'.red);
case 31:
ctx.body = (0, _stringify2.default)(data);
return _context.abrupt('return', next());
case 33:
case 'end':
return _context.stop();
}
}
}, _callee, undefined, [[7, 13], [18, 24]]);
}));
return function player(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
var download = exports.download = function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(ctx, next) {
var data, songId, urlInfo;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
data = ctx.body;
if (!(_netease2.default.getDownloadReturnCode(data) === 200)) {
_context2.next = 3;
break;
}
return _context2.abrupt('return', console.log('The song URL is '.green + data.data.url));
case 3:
songId = _netease2.default.getDownloadSongId(data);
urlInfo = void 0;
_context2.prev = 5;
_context2.next = 8;
return utils.getUrlInfo(songId);
case 8:
urlInfo = _context2.sent;
_context2.next = 15;
break;
case 11:
_context2.prev = 11;
_context2.t0 = _context2['catch'](5);
console.log(_context2.t0);
throw new Error(_context2.t0);
case 15:
if (!urlInfo) {
_context2.next = 28;
break;
}
_context2.prev = 16;
_context2.next = 19;
return _netease2.default.modifyDownloadApiCustom(urlInfo, data.data);
case 19:
data.data = _context2.sent;
_context2.next = 26;
break;
case 22:
_context2.prev = 22;
_context2.t1 = _context2['catch'](16);
console.log('No resource.'.red);
throw new Error(_context2.t1);
case 26:
_context2.next = 29;
break;
case 28:
console.log('No resource.'.red);
case 29:
return _context2.abrupt('return', next());
case 30:
case 'end':
return _context2.stop();
}
}
}, _callee2, undefined, [[5, 11], [16, 22]]);
}));
return function download(_x3, _x4) {
return _ref2.apply(this, arguments);
};
}();
var forward = exports.forward = function () {
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(ctx, next) {
var req, url, body, json;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
req = ctx.request;
if (Object.prototype.hasOwnProperty.call(req, 'body')) {
_context3.next = 3;
break;
}
return _context3.abrupt('return', next());
case 3:
url = void 0;
_context3.prev = 4;
body = _netease2.default.decryptLinuxForwardApi(req.body.split('=')[1]);
json = JSON.parse(body);
url = json.url;
_context3.next = 14;
break;
case 10:
_context3.prev = 10;
_context3.t0 = _context3['catch'](4);
console.log('Parse body failed.');
throw new Error(_context3.t0);
case 14:
console.log('API:'.green, url);
if (!(url !== 'http://music.163.com/api/song/enhance/player/url')) {
_context3.next = 17;
break;
}
return _context3.abrupt('return', next());
case 17:
return _context3.abrupt('return', player(ctx, next));
case 18:
case 'end':
return _context3.stop();
}
}
}, _callee3, undefined, [[4, 10]]);
}));
return function forward(_x5, _x6) {
return _ref3.apply(this, arguments);
};
}();
const forward = exports.forward = async (ctx, next) => {
const req = ctx.request;
if (!Object.prototype.hasOwnProperty.call(req, 'body')) {
return next();
}
let url;
try {
const body = _netease2.default.decryptLinuxForwardApi(req.body.split('=')[1]);
const json = JSON.parse(body);
url = json.url;
} catch (err) {
console.log('Parse body failed.');
throw new Error(err);
}
console.log('API:'.green, url);
if (url !== 'http://music.163.com/api/song/enhance/player/url') {
return next();
}
return player(ctx, next);
};

@@ -7,18 +7,8 @@ 'use strict';

var _regenerator = require('babel-runtime/regenerator');
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _regenerator2 = _interopRequireDefault(_regenerator);
var _rawBody = require('raw-body');
var _assign = require('babel-runtime/core-js/object/assign');
var _rawBody2 = _interopRequireDefault(_rawBody);
var _assign2 = _interopRequireDefault(_assign);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _rawBody2 = require('raw-body');
var _rawBody3 = _interopRequireDefault(_rawBody2);
var _config = require('../config');

@@ -36,121 +26,65 @@

var middleware = function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(ctx, next) {
var req, rawBody, ip, url, newHeader, _rawBody, options, result, headers, body;
const middleware = async function (ctx, next) {
const req = ctx.request;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
req = ctx.request;
if (req.url.indexOf('/api/plugin') !== -1) {
let rawBody;
try {
rawBody = await (0, _rawBody2.default)(ctx.req, {
length: ctx.length,
encoding: ctx.charset
});
} catch (error) {
console.log('Cannot get post body.'.red);
throw new Error(error);
}
ctx.body = rawBody;
await next();
} else if (req.method === 'POST') {
const ip = _config2.default.forceIp ? _config2.default.forceIp : '223.252.199.7';
const url = `http://${ip}${req.url}`;
if (!(req.url.indexOf('/api/plugin') !== -1)) {
_context.next = 18;
break;
}
const newHeader = _extends({}, req.headers, {
host: 'music.163.com',
'x-real-ip': `202.114.79.${Math.floor(Math.random() * 255) + 1}`
});
rawBody = void 0;
_context.prev = 3;
_context.next = 6;
return (0, _rawBody3.default)(ctx.req, {
length: ctx.length,
encoding: ctx.charset
});
const rawBody = await (0, _rawBody2.default)(ctx.req, {
length: ctx.length,
encoding: ctx.charset
});
case 6:
rawBody = _context.sent;
_context.next = 13;
break;
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](3);
console.log('Cannot get post body.'.red);
throw new Error(_context.t0);
case 13:
ctx.body = rawBody;
_context.next = 16;
return next();
case 16:
_context.next = 45;
break;
case 18:
if (!(req.method === 'POST')) {
_context.next = 45;
break;
}
ip = _config2.default.forceIp ? _config2.default.forceIp : '223.252.199.7';
url = 'http://' + ip + req.url;
newHeader = (0, _assign2.default)({}, req.headers, {
host: 'music.163.com'
});
_context.next = 24;
return (0, _rawBody3.default)(ctx.req, {
length: ctx.length,
encoding: ctx.charset
});
case 24:
_rawBody = _context.sent;
options = {
url: url,
headers: newHeader,
method: 'post',
encoding: null,
gzip: true
};
if (_rawBody) {
options.body = _rawBody;
try {
req.body = _rawBody.toString();
} catch (err) {
console.log('Body is not string.');
}
}
result = void 0;
_context.prev = 28;
_context.next = 31;
return common.sendRequest(options);
case 31:
result = _context.sent;
_context.next = 38;
break;
case 34:
_context.prev = 34;
_context.t1 = _context['catch'](28);
console.log('Cannot get orignal response.'.red);
throw new Error(_context.t1);
case 38:
headers = result.headers;
body = result.body;
delete headers['content-encoding'];
ctx.set(headers);
ctx.body = body.toString();
_context.next = 45;
return next();
case 45:
case 'end':
return _context.stop();
}
const options = {
url,
headers: newHeader,
method: 'post',
encoding: null,
gzip: true
};
if (rawBody) {
options.body = rawBody;
try {
req.body = rawBody.toString();
} catch (err) {
console.log('Body is not string.');
}
}, _callee, this, [[3, 9], [28, 34]]);
}));
}
let result;
try {
result = await common.sendRequest(options);
} catch (err) {
console.log('Cannot get orignal response.'.red);
throw new Error(err);
}
return function middleware(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
const headers = result.headers;
const body = result.body;
delete headers['content-encoding'];
ctx.set(headers);
ctx.body = body.toString();
await next();
// console.log(ctx.body);
}
};
exports.default = middleware;

@@ -8,14 +8,4 @@ 'use strict';

var _regenerator = require('babel-runtime/regenerator');
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _regenerator2 = _interopRequireDefault(_regenerator);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _requestPromise = require('request-promise');

@@ -27,48 +17,19 @@

var sendRequest = exports.sendRequest = function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(options) {
var defaults, result;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
defaults = {
method: 'get',
followRedirect: true,
timeout: 10000,
resolveWithFullResponse: true
};
options = (0, _assign2.default)({}, defaults, options);
result = void 0;
_context.prev = 3;
_context.next = 6;
return (0, _requestPromise2.default)(options);
case 6:
result = _context.sent;
_context.next = 12;
break;
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](3);
throw new Error(_context.t0);
case 12:
return _context.abrupt('return', result);
case 13:
case 'end':
return _context.stop();
}
}
}, _callee, undefined, [[3, 9]]);
}));
return function sendRequest(_x) {
return _ref.apply(this, arguments);
const sendRequest = exports.sendRequest = async options => {
const defaults = {
method: 'get',
followRedirect: true,
timeout: 10000,
resolveWithFullResponse: true
};
}();
options = _extends({}, defaults, options);
let result;
try {
result = await (0, _requestPromise2.default)(options);
} catch (err) {
throw new Error(err);
}
return result;
};
exports.default = sendRequest;

@@ -7,22 +7,2 @@ 'use strict';

var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
require('colors');

@@ -52,7 +32,5 @@

var Utils = function () {
function Utils() {
(0, _classCallCheck3.default)(this, Utils);
var ip = _config2.default.forceIp ? _config2.default.forceIp : '223.252.199.7';
class Utils {
constructor() {
const ip = _config2.default.forceIp ? _config2.default.forceIp : '223.252.199.7';
this.netease = new _netease2.default(ip);

@@ -63,227 +41,113 @@ this.plugins = [];

(0, _createClass3.default)(Utils, [{
key: 'initPlugins',
value: function initPlugins() {
var _this = this;
initPlugins() {
_fs2.default.readdirSync(_path2.default.resolve(__dirname, 'plugins')).forEach(file => {
const Plugin = require(_path2.default.resolve(__dirname, 'plugins', file));
this.plugins.push(new Plugin());
});
this.plugins.sort((a, b) => a.order - b.order);
// console.log(this.plugins);
}
_fs2.default.readdirSync(_path2.default.resolve(__dirname, 'plugins')).forEach(function (file) {
var Plugin = require(_path2.default.resolve(__dirname, 'plugins', file));
_this.plugins.push(new Plugin());
});
this.plugins.sort(function (a, b) {
return a.order - b.order;
});
// console.log(this.plugins);
async batchSeachMusic(songName, artist, album) {
const result = [];
for (const plugin of this.plugins) {
console.log(`Search from ${plugin.name}`.green);
const keyword = `${artist} ${songName} ${album}`;
let searchResult;
try {
searchResult = await plugin.search(keyword);
} catch (error) {
console.log(`Cannot search from ${plugin.name}`.red);
console.log(error);
continue;
}
if (searchResult.length > 0) {
// console.log(searchResult);
const searchName = searchResult[0].name.replace(/ /g, '').toLowerCase();
const trueName = songName.replace(/ /g, '').toLowerCase();
if (searchName.indexOf(trueName) !== -1) {
result.push({
plugin,
searchResult: searchResult[0]
});
} else {
console.log(`No resource found from ${plugin.name}`.yellow);
}
} else {
console.log(`No resource found from ${plugin.name}`.yellow);
}
}
}, {
key: 'batchSeachMusic',
value: function batchSeachMusic(songName, artist, album) {
var _this2 = this;
return result;
}
return new _promise2.default(function (resolve, reject) {
_async2.default.map(_this2.plugins, function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(plugin, callback) {
var keyword, searchResult, searchName, trueName;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
console.log(('Search from ' + plugin.name).green);
keyword = artist + ' ' + songName + ' ' + album;
searchResult = void 0;
_context.prev = 3;
_context.next = 6;
return plugin.search(keyword);
case 6:
searchResult = _context.sent;
_context.next = 14;
break;
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](3);
console.log(('Cannot search from ' + plugin.name).red);
console.log(_context.t0);
return _context.abrupt('return', callback(null));
case 14:
if (!(searchResult.length > 0)) {
_context.next = 19;
break;
}
// console.log(searchResult);
searchName = searchResult[0].name.replace(/ /g, '').toLowerCase();
trueName = songName.replace(/ /g, '').toLowerCase();
if (!(searchName.indexOf(trueName) !== -1)) {
_context.next = 19;
break;
}
return _context.abrupt('return', callback(null, {
plugin: plugin,
searchResult: searchResult[0]
}));
case 19:
console.log(('No resource found from ' + plugin.name).yellow);
return _context.abrupt('return', callback(null));
case 21:
case 'end':
return _context.stop();
}
}
}, _callee, _this2, [[3, 9]]);
}));
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
}(), function (err, result) {
if (err) return reject(err);
return resolve(result);
});
});
/*
Get song url.
*/
async getUrlInfo(songId) {
let detail;
try {
detail = await this.netease.getSongDetail(songId);
} catch (err) {
console.log('Cannot get song info from netease.'.red);
throw new Error(err);
}
/*
Get song url.
*/
}, {
key: 'getUrlInfo',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(songId) {
var detail, songName, artist, album, result, plugin, data, songInfo, url;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
detail = void 0;
_context2.prev = 1;
_context2.next = 4;
return this.netease.getSongDetail(songId);
case 4:
detail = _context2.sent;
_context2.next = 11;
break;
case 7:
_context2.prev = 7;
_context2.t0 = _context2['catch'](1);
console.log('Cannot get song info from netease.'.red);
throw new Error(_context2.t0);
case 11:
songName = _netease2.default.getSongName(detail);
artist = _netease2.default.getArtistName(detail);
album = _netease2.default.getAlbumName(detail);
console.log('Song name: '.green + songName);
console.log('Artist: '.green + artist);
console.log('Album: '.green + album);
result = void 0;
_context2.prev = 18;
_context2.next = 21;
return this.batchSeachMusic(songName, artist, album);
case 21:
result = _context2.sent;
_context2.next = 28;
break;
case 24:
_context2.prev = 24;
_context2.t1 = _context2['catch'](18);
console.log('Batch search failed.'.red);
throw new Error(_context2.t1);
case 28:
result = result.sort(function (a, b) {
if (!a) {
return 1;
}
if (!b) {
return -1;
}
if (parseInt(a.searchResult.bitrate, 10) > parseInt(b.searchResult.bitrate, 10)) {
return -1;
}
if (parseInt(a.searchResult.bitrate, 10) < parseInt(b.searchResult.bitrate, 10)) {
return 1;
}
if (a.searchResult.bitrate === b.searchResult.bitrate) {
return a.searchResult.order - b.searchResult.order;
}
return 0;
});
if (!result[0]) {
_context2.next = 48;
break;
}
plugin = result[0].plugin;
data = result[0].searchResult;
songInfo = {
bitrate: data.bitrate,
filesize: data.filesize,
hash: data.hash,
type: data.type
};
url = void 0;
_context2.prev = 34;
_context2.next = 37;
return plugin.getUrl(data);
case 37:
url = _context2.sent;
_context2.next = 44;
break;
case 40:
_context2.prev = 40;
_context2.t2 = _context2['catch'](34);
console.log('Cannot get song url'.red);
throw new Error(_context2.t2);
case 44:
songInfo.origUrl = null;
// 魔改 URL 应对某司防火墙
if (_config2.default.rewriteUrl) {
songInfo.origUrl = url;
url = url.replace(plugin.baseUrl, 'm8.music.126.net/' + plugin.name.replace(/ /g, '').toLowerCase());
}
songInfo.url = url;
return _context2.abrupt('return', songInfo);
case 48:
return _context2.abrupt('return', null);
case 49:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[1, 7], [18, 24], [34, 40]]);
}));
function getUrlInfo(_x3) {
return _ref2.apply(this, arguments);
const songName = _netease2.default.getSongName(detail);
const artist = _netease2.default.getArtistName(detail);
const album = _netease2.default.getAlbumName(detail);
console.log('Song name: '.green + songName);
console.log('Artist: '.green + artist);
console.log('Album: '.green + album);
let result;
try {
result = await this.batchSeachMusic(songName, artist, album);
} catch (err) {
console.log('Batch search failed.'.red);
throw new Error(err);
}
result = result.sort((a, b) => {
if (!a) {
return 1;
}
return getUrlInfo;
}()
}]);
return Utils;
}();
if (!b) {
return -1;
}
if (parseInt(a.searchResult.bitrate, 10) > parseInt(b.searchResult.bitrate, 10)) {
return -1;
}
if (parseInt(a.searchResult.bitrate, 10) < parseInt(b.searchResult.bitrate, 10)) {
return 1;
}
if (a.searchResult.bitrate === b.searchResult.bitrate) {
return a.searchResult.order - b.searchResult.order;
}
return 0;
});
if (result[0]) {
const plugin = result[0].plugin;
const data = result[0].searchResult;
const songInfo = {
bitrate: data.bitrate,
filesize: data.filesize,
hash: data.hash,
type: data.type
};
let url;
try {
url = await plugin.getUrl(data);
} catch (err) {
console.log('Cannot get song url'.red);
throw new Error(err);
}
songInfo.origUrl = null;
// 魔改 URL 应对某司防火墙
if (_config2.default.rewriteUrl) {
songInfo.origUrl = url;
url = url.replace(plugin.baseUrl, `m8.music.126.net/${plugin.name.replace(/ /g, '').toLowerCase()}`);
}
songInfo.url = url;
return songInfo;
}
return null;
}
}
exports.default = Utils;

@@ -7,30 +7,4 @@ 'use strict';

var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
require('colors');

@@ -56,314 +30,165 @@

var Netease = function () {
function Netease(ip) {
(0, _classCallCheck3.default)(this, Netease);
class Netease {
constructor(ip) {
this.baseUrl = `http://${ip}`;
}
this.baseUrl = 'http://' + ip;
static getDownloadReturnCode(body) {
return body.data.code;
}
(0, _createClass3.default)(Netease, [{
key: 'getSongDetail',
value: function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(songId) {
var header, options, result;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
header = {
host: 'music.163.com',
'content-type': 'application/x-www-form-urlencoded'
};
options = {
url: this.baseUrl + '/api/song/detail/?ids=[' + songId + ']&id=' + songId,
headers: header,
method: 'get',
gzip: true
};
result = void 0;
_context.prev = 3;
_context.next = 6;
return (0, _requestPromise2.default)(options);
static getDownloadUrl(body) {
return body.data.url;
}
case 6:
result = _context.sent;
_context.next = 12;
break;
static getSongName(body) {
body = JSON.parse(body);
return body.songs[0].name;
}
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](3);
throw new Error(_context.t0);
static getArtistName(body) {
body = JSON.parse(body);
return body.songs[0].artists[0].name;
}
case 12:
return _context.abrupt('return', result);
static getAlbumName(body) {
body = JSON.parse(body);
return body.songs[0].album.name;
}
case 13:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[3, 9]]);
}));
static getDownloadSongId(body) {
return body.data.id;
}
function getSongDetail(_x) {
return _ref.apply(this, arguments);
}
static getFilesize(url) {
console.log('Getting filesize.'.yellow);
return new Promise((resolve, reject) => {
(0, _remoteFileSize2.default)(url, (err, size) => {
if (err) return reject(err);
console.log('Filesize:'.green, size);
return resolve(size);
});
});
}
return getSongDetail;
}()
}], [{
key: 'getDownloadReturnCode',
value: function getDownloadReturnCode(body) {
return body.data.code;
}
}, {
key: 'getDownloadUrl',
value: function getDownloadUrl(body) {
return body.data.url;
}
}, {
key: 'getSongName',
value: function getSongName(body) {
body = JSON.parse(body);
return body.songs[0].name;
}
}, {
key: 'getArtistName',
value: function getArtistName(body) {
body = JSON.parse(body);
return body.songs[0].artists[0].name;
}
}, {
key: 'getAlbumName',
value: function getAlbumName(body) {
body = JSON.parse(body);
return body.songs[0].album.name;
}
}, {
key: 'getDownloadSongId',
value: function getDownloadSongId(body) {
return body.data.id;
}
}, {
key: 'getFilesize',
value: function getFilesize(url) {
console.log('Getting filesize.'.yellow);
return new _promise2.default(function (resolve, reject) {
(0, _remoteFileSize2.default)(url, function (err, size) {
if (err) return reject(err);
console.log('Filesize:'.green, size);
return resolve(size);
static getFileInfo(url) {
console.log('Getting file info.'.yellow);
return new Promise((resolve, reject) => {
const hash = _crypto2.default.createHash('md5');
hash.setEncoding('hex');
let filesize = 0;
let md5 = '';
_request2.default.get(url).on('error', err => reject(err)).on('response', res => {
filesize = parseInt(res.headers['content-length'], 10);
console.log('Filesize:'.green, filesize);
}).pipe(hash).on('finish', () => {
hash.end();
md5 = hash.read();
console.log('MD5:'.green, md5);
return resolve({
filesize,
md5
});
});
});
}
static fixJsonData(body) {
if (body.code === 200) {
return body;
}
}, {
key: 'getFileInfo',
value: function getFileInfo(url) {
console.log('Getting file info.'.yellow);
return new _promise2.default(function (resolve, reject) {
var hash = _crypto2.default.createHash('md5');
hash.setEncoding('hex');
var filesize = 0;
var md5 = '';
_request2.default.get(url).on('error', function (err) {
return reject(err);
}).on('response', function (res) {
filesize = parseInt(res.headers['content-length'], 10);
console.log('Filesize:'.green, filesize);
}).pipe(hash).on('finish', function () {
hash.end();
md5 = hash.read();
console.log('MD5:'.green, md5);
return resolve({
filesize: filesize,
md5: md5
});
});
});
}
}, {
key: 'fixJsonData',
value: function fixJsonData(body) {
return (0, _assign2.default)({}, body, {
url: null,
type: null,
md5: null,
uf: null
});
}
}, {
key: 'modifyPlayerApiCustom',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(urlInfo, body) {
var filesize;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
console.log('Player API Injected'.green);
console.log('New URL is '.green + urlInfo.url);
body.url = urlInfo.url;
body.br = urlInfo.bitrate;
body.code = 200;
body.type = urlInfo.type;
body.md5 = urlInfo.hash;
return _extends({}, body, {
url: null,
type: null,
md5: null,
uf: null
});
}
if (urlInfo.filesize) {
_context2.next = 21;
break;
}
_context2.prev = 8;
_context2.next = 11;
return Netease.getFilesize(urlInfo.origUrl || urlInfo.url);
case 11:
filesize = _context2.sent;
body.size = filesize;
_context2.next = 19;
break;
case 15:
_context2.prev = 15;
_context2.t0 = _context2['catch'](8);
console.log('Cannot get file size.'.red);
throw new Error(_context2.t0);
case 19:
_context2.next = 22;
break;
case 21:
body.size = urlInfo.filesize;
case 22:
return _context2.abrupt('return', body);
case 23:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[8, 15]]);
}));
function modifyPlayerApiCustom(_x2, _x3) {
return _ref2.apply(this, arguments);
static async modifyPlayerApiCustom(urlInfo, body) {
console.log('Player API Injected'.green);
console.log('New URL is '.green + urlInfo.url);
body.url = urlInfo.url;
body.br = urlInfo.bitrate;
body.code = 200;
body.type = urlInfo.type;
body.md5 = urlInfo.hash;
if (!urlInfo.filesize) {
try {
const filesize = await Netease.getFilesize(urlInfo.origUrl || urlInfo.url);
body.size = filesize;
} catch (error) {
console.log('Cannot get file size.'.red);
throw new Error(error);
}
} else {
body.size = urlInfo.filesize;
}
return body;
}
return modifyPlayerApiCustom;
}()
}, {
key: 'modifyDownloadApiCustom',
value: function () {
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(urlInfo, body) {
var _ref4, filesize, md5;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
console.log('Download API Injected'.green);
console.log('New URL is '.green + urlInfo.url);
body.url = urlInfo.url;
body.br = urlInfo.bitrate;
body.code = 200;
body.type = urlInfo.type;
body.md5 = urlInfo.hash;
body.expi = 1200;
if (!(!urlInfo.filesize || !urlInfo.md5)) {
_context3.next = 24;
break;
}
_context3.prev = 9;
_context3.next = 12;
return Netease.getFileInfo(urlInfo.origUrl || urlInfo.url);
case 12:
_ref4 = _context3.sent;
filesize = _ref4.filesize;
md5 = _ref4.md5;
body.size = filesize;
body.md5 = md5;
_context3.next = 22;
break;
case 19:
_context3.prev = 19;
_context3.t0 = _context3['catch'](9);
throw new Error(_context3.t0);
case 22:
_context3.next = 26;
break;
case 24:
body.size = urlInfo.filesize;
body.md5 = urlInfo.md5;
case 26:
return _context3.abrupt('return', body);
case 27:
case 'end':
return _context3.stop();
}
}
}, _callee3, this, [[9, 19]]);
}));
function modifyDownloadApiCustom(_x4, _x5) {
return _ref3.apply(this, arguments);
static async modifyDownloadApiCustom(urlInfo, body) {
console.log('Download API Injected'.green);
console.log('New URL is '.green + urlInfo.url);
body.url = urlInfo.url;
body.br = urlInfo.bitrate;
body.code = 200;
body.type = urlInfo.type;
body.md5 = urlInfo.hash;
body.expi = 1200;
if (!urlInfo.filesize || !urlInfo.md5) {
try {
const {
filesize,
md5
} = await Netease.getFileInfo(urlInfo.origUrl || urlInfo.url);
body.size = filesize;
body.md5 = md5;
} catch (error) {
throw new Error(error);
}
} else {
body.size = urlInfo.filesize;
body.md5 = urlInfo.md5;
}
return body;
}
return modifyDownloadApiCustom;
}()
}, {
key: 'decryptLinuxForwardApi',
value: function decryptLinuxForwardApi(eparams) {
var key = new Buffer('7246674226682325323F5E6544673A51', 'hex');
var decipher = _crypto2.default.createDecipheriv('aes-128-ecb', key, '');
decipher.setAutoPadding(true);
var cipherChunks = [];
cipherChunks.push(decipher.update(eparams, 'hex'));
cipherChunks.push(decipher.final());
async getSongDetail(songId) {
const header = {
host: 'music.163.com',
'content-type': 'application/x-www-form-urlencoded'
};
var totalLength = 0;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
const options = {
url: `${this.baseUrl}/api/song/detail/?ids=[${songId}]&id=${songId}`,
headers: header,
method: 'get',
gzip: true
};
let result;
try {
result = await (0, _requestPromise2.default)(options);
} catch (err) {
throw new Error(err);
}
return result;
}
try {
for (var _iterator = (0, _getIterator3.default)(cipherChunks), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var e = _step.value;
static decryptLinuxForwardApi(eparams) {
const key = new Buffer('7246674226682325323F5E6544673A51', 'hex');
const decipher = _crypto2.default.createDecipheriv('aes-128-ecb', key, '');
decipher.setAutoPadding(true);
const cipherChunks = [];
cipherChunks.push(decipher.update(eparams, 'hex'));
cipherChunks.push(decipher.final());
totalLength += e.length;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return Buffer.concat(cipherChunks, totalLength);
let totalLength = 0;
for (const e of cipherChunks) {
totalLength += e.length;
}
}]);
return Netease;
}();
return Buffer.concat(cipherChunks, totalLength);
}
}
exports.default = Netease;
'use strict';
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _md = require('md5');

@@ -35,6 +15,4 @@

var Kugou = function () {
function Kugou() {
(0, _classCallCheck3.default)(this, Kugou);
class Kugou {
constructor() {
this.name = 'Kugou';

@@ -45,222 +23,82 @@ this.order = 2;

(0, _createClass3.default)(Kugou, [{
key: 'getPluginInfo',
value: function getPluginInfo() {
return {
name: this.name,
order: this.order
};
getPluginInfo() {
return {
name: this.name,
order: this.order
};
}
async search(keyword) {
const options = {
url: `http://mobilecdn.kugou.com/api/v3/search/song?format=json&keyword=${encodeURIComponent(keyword)}&page=1&pagesize=1&showtype=1`
};
let data;
try {
const result = await common.sendRequest(options);
data = JSON.parse(result.body);
} catch (err) {
throw new Error(err);
}
}, {
key: 'search',
value: function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(keyword) {
var options, data, _result, result, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, e, filesize, hash, bitrate;
const result = [];
if (data.status === 1 && data.data.info.length > 0) {
for (const e of data.data.info) {
let filesize;
let hash;
let bitrate;
// if (Object.prototype.hasOwnProperty.call(e, 'sqhash')) {
// bitrate = '999000';
// filesize = e.sqfilesize;
// hash = e.sqhash;
// type = 'flac';
// } else if (Object.prototype.hasOwnProperty.call(e, '320hash')) {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
options = {
url: 'http://mobilecdn.kugou.com/api/v3/search/song?format=json&keyword=' + encodeURIComponent(keyword) + '&page=1&pagesize=1&showtype=1'
};
data = void 0;
_context.prev = 2;
_context.next = 5;
return common.sendRequest(options);
case 5:
_result = _context.sent;
data = JSON.parse(_result.body);
_context.next = 12;
break;
case 9:
_context.prev = 9;
_context.t0 = _context['catch'](2);
throw new Error(_context.t0);
case 12:
result = [];
if (!(data.status === 1 && data.data.info.length > 0)) {
_context.next = 55;
break;
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 17;
_iterator = (0, _getIterator3.default)(data.data.info);
case 19:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 41;
break;
}
e = _step.value;
filesize = void 0;
hash = void 0;
bitrate = void 0;
// if (Object.prototype.hasOwnProperty.call(e, 'sqhash')) {
// bitrate = '999000';
// filesize = e.sqfilesize;
// hash = e.sqhash;
// type = 'flac';
// } else if (Object.prototype.hasOwnProperty.call(e, '320hash')) {
if (!(Object.prototype.hasOwnProperty.call(e, '320hash') && e['320hash'].lenght > 0)) {
_context.next = 30;
break;
}
bitrate = '320000';
filesize = e['320filesize'];
hash = e['320hash'];
_context.next = 37;
break;
case 30:
if (!(Object.prototype.hasOwnProperty.call(e, 'hash') && e.hash.lenght > 0)) {
_context.next = 36;
break;
}
bitrate = '128000';
filesize = e.filesize;
hash = e.hash;
_context.next = 37;
break;
case 36:
return _context.abrupt('continue', 38);
case 37:
result.push({
name: e.filename,
artist: e.singername,
type: 'mp3',
filesize: filesize,
bitrate: bitrate,
hash: hash
});
case 38:
_iteratorNormalCompletion = true;
_context.next = 19;
break;
case 41:
_context.next = 47;
break;
case 43:
_context.prev = 43;
_context.t1 = _context['catch'](17);
_didIteratorError = true;
_iteratorError = _context.t1;
case 47:
_context.prev = 47;
_context.prev = 48;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 50:
_context.prev = 50;
if (!_didIteratorError) {
_context.next = 53;
break;
}
throw _iteratorError;
case 53:
return _context.finish(50);
case 54:
return _context.finish(47);
case 55:
return _context.abrupt('return', result);
case 56:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[2, 9], [17, 43, 47, 55], [48,, 50, 54]]);
}));
function search(_x) {
return _ref.apply(this, arguments);
if (Object.prototype.hasOwnProperty.call(e, '320hash') && e['320hash'].lenght > 0) {
bitrate = '320000';
filesize = e['320filesize'];
hash = e['320hash'];
} else if (Object.prototype.hasOwnProperty.call(e, 'hash') && e.hash.lenght > 0) {
bitrate = '128000';
filesize = e.filesize;
hash = e.hash;
} else {
continue;
}
result.push({
name: e.filename,
artist: e.singername,
type: 'mp3',
filesize,
bitrate,
hash
});
}
}
return result;
}
return search;
}()
}, {
key: 'getUrl',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(searchResult) {
var hash, key, options, data, result, url;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
hash = searchResult.hash;
key = (0, _md2.default)(hash + 'kgcloud');
options = {
url: 'http://trackercdn.kugou.com/i/?acceptMp3=1&cmd=4&pid=6&hash=' + hash + '&key=' + key
};
data = void 0;
_context2.prev = 4;
_context2.next = 7;
return common.sendRequest(options);
async getUrl(searchResult) {
const hash = searchResult.hash;
const key = (0, _md2.default)(`${hash}kgcloud`);
const options = {
url: `http://trackercdn.kugou.com/i/?acceptMp3=1&cmd=4&pid=6&hash=${hash}&key=${key}`
};
case 7:
result = _context2.sent;
let data;
try {
const result = await common.sendRequest(options);
data = JSON.parse(result.body);
} catch (err) {
throw new Error(err);
}
data = JSON.parse(result.body);
_context2.next = 14;
break;
let url;
if (data.error || data.status !== 1) {
url = null;
} else {
url = data.url;
}
return url;
}
}
case 11:
_context2.prev = 11;
_context2.t0 = _context2['catch'](4);
throw new Error(_context2.t0);
case 14:
url = void 0;
if (data.error || data.status !== 1) {
url = null;
} else {
url = data.url;
}
return _context2.abrupt('return', url);
case 17:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[4, 11]]);
}));
function getUrl(_x2) {
return _ref2.apply(this, arguments);
}
return getUrl;
}()
}]);
return Kugou;
}();
module.exports = Kugou;
'use strict';
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
require('colors');

@@ -31,8 +11,4 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var QQ = function () {
function QQ() {
(0, _classCallCheck3.default)(this, QQ);
class QQ {
constructor() {
this.name = 'QQ Music';

@@ -46,279 +22,102 @@ this.order = 1;

(0, _createClass3.default)(QQ, [{
key: 'getVKey',
value: function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(!this.updateTime || this.updateTime + 3600 * 1000 < new Date().valueOf())) {
_context.next = 12;
break;
}
_context.prev = 1;
_context.next = 4;
return this.updateVKey();
case 4:
this.vkey = _context.sent;
this.updateTime = new Date().valueOf();
_context.next = 12;
break;
case 8:
_context.prev = 8;
_context.t0 = _context['catch'](1);
console.log('Cannot update vkey.'.red);
console.log(_context.t0);
case 12:
return _context.abrupt('return', this.vkey);
case 13:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[1, 8]]);
}));
function getVKey() {
return _ref.apply(this, arguments);
async getVKey() {
if (!this.updateTime || this.updateTime + 3600 * 1000 < new Date().valueOf()) {
try {
this.vkey = await this.updateVKey();
this.updateTime = new Date().valueOf();
} catch (err) {
console.log('Cannot update vkey.'.red);
console.log(err);
}
}
return this.vkey;
}
return getVKey;
}()
}, {
key: 'updateVKey',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
var options, result, data;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
this.guid = QQ.getGUid();
options = {
url: 'https://c.y.qq.com/base/fcgi-bin/fcg_musicexpress.fcg?json=3&guid=' + this.guid + '&g_tk=5381&jsonpCallback=jsonCallback&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf8&notice=0&platform=yqq&needNewCode=0'
};
_context2.prev = 2;
_context2.next = 5;
return common.sendRequest(options);
static getGUid() {
const currentMs = new Date().getUTCMilliseconds();
return Math.round(2147483647 * Math.random()) * currentMs % 1e10;
}
case 5:
result = _context2.sent;
data = JSON.parse(result.body);
return _context2.abrupt('return', data.key);
async updateVKey() {
this.guid = QQ.getGUid();
const options = {
url: `https://c.y.qq.com/base/fcgi-bin/fcg_musicexpress.fcg?json=3&guid=${this.guid}&g_tk=5381&jsonpCallback=jsonCallback&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf8&notice=0&platform=yqq&needNewCode=0`
};
case 10:
_context2.prev = 10;
_context2.t0 = _context2['catch'](2);
throw new Error(_context2.t0);
try {
const result = await common.sendRequest(options);
const data = JSON.parse(result.body);
return data.key;
} catch (err) {
throw new Error(err);
}
}
case 13:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[2, 10]]);
}));
async search(keyword) {
try {
await this.getVKey();
} catch (err) {
return console.log('QQ Music module initial failed.'.red);
}
function updateVKey() {
return _ref2.apply(this, arguments);
if (!this.vkey || this.vkey.length !== 112) {
return console.log('QQ Music module is not ready.'.red);
}
const options = {
url: `https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&t=0&aggr=1&cr=1&catZhida=1&lossless=1&flag_qc=0&p=1&n=1&w=${encodeURIComponent(keyword)}&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0`
};
let data;
try {
const result = await common.sendRequest(options);
data = JSON.parse(result.body);
} catch (err) {
throw new Error(err);
}
const result = [];
if (data.code === 0 && data.data.song.list.length > 0) {
for (const e of data.data.song.list) {
const list = e.file;
let prefix;
let bitrate;
let filesize;
let type;
if (list.size_128 && list.size_128 > 0) {
prefix = 'M500';
type = 'mp3';
bitrate = 128000;
filesize = list.size_128;
}
if (list.size_320 && list.size_320 > 0) {
prefix = 'M800';
type = 'mp3';
bitrate = 320000;
filesize = list.size_320;
}
// if (list.size_flac && list.size_flac > 0) {
// prefix = 'F000';
// type = 'flac';
// bitrate = 999000;
// filesize = list.size_flac;
// }
result.push({
name: e.name || 'V.A.',
artist: e.singer.name || 'V.A.',
filesize,
hash: '',
mid: list.media_mid,
bitrate: String(bitrate),
prefix,
type
});
}
}
return result;
}
return updateVKey;
}()
}, {
key: 'search',
value: function () {
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(keyword) {
var options, data, _result, result, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, e, list, prefix, bitrate, filesize, type;
async getUrl(data) {
const url = `http://dl.stream.qqmusic.qq.com/${data.prefix}${data.mid}.${data.type}?vkey=${this.vkey}&guid=${this.guid}&uin=0&fromtag=30`;
return url;
}
}
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.prev = 0;
_context3.next = 3;
return this.getVKey();
case 3:
_context3.next = 8;
break;
case 5:
_context3.prev = 5;
_context3.t0 = _context3['catch'](0);
return _context3.abrupt('return', console.log('QQ Music module initial failed.'.red));
case 8:
if (!(!this.vkey || this.vkey.length !== 112)) {
_context3.next = 10;
break;
}
return _context3.abrupt('return', console.log('QQ Music module is not ready.'.red));
case 10:
options = {
url: 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&t=0&aggr=1&cr=1&catZhida=1&lossless=1&flag_qc=0&p=1&n=1&w=' + encodeURIComponent(keyword) + '&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'
};
data = void 0;
_context3.prev = 12;
_context3.next = 15;
return common.sendRequest(options);
case 15:
_result = _context3.sent;
data = JSON.parse(_result.body);
_context3.next = 22;
break;
case 19:
_context3.prev = 19;
_context3.t1 = _context3['catch'](12);
throw new Error(_context3.t1);
case 22:
result = [];
if (!(data.code === 0 && data.data.song.list.length > 0)) {
_context3.next = 43;
break;
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context3.prev = 27;
for (_iterator = (0, _getIterator3.default)(data.data.song.list); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
e = _step.value;
list = e.file;
prefix = void 0;
bitrate = void 0;
filesize = void 0;
type = void 0;
if (list.size_128 && list.size_128 > 0) {
prefix = 'M500';
type = 'mp3';
bitrate = 128000;
filesize = list.size_128;
}
if (list.size_320 && list.size_320 > 0) {
prefix = 'M800';
type = 'mp3';
bitrate = 320000;
filesize = list.size_320;
}
// if (list.size_flac && list.size_flac > 0) {
// prefix = 'F000';
// type = 'flac';
// bitrate = 999000;
// filesize = list.size_flac;
// }
result.push({
name: e.name || 'V.A.',
artist: e.singer.name || 'V.A.',
filesize: filesize,
hash: '',
mid: list.media_mid,
bitrate: String(bitrate),
prefix: prefix,
type: type
});
}
_context3.next = 35;
break;
case 31:
_context3.prev = 31;
_context3.t2 = _context3['catch'](27);
_didIteratorError = true;
_iteratorError = _context3.t2;
case 35:
_context3.prev = 35;
_context3.prev = 36;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 38:
_context3.prev = 38;
if (!_didIteratorError) {
_context3.next = 41;
break;
}
throw _iteratorError;
case 41:
return _context3.finish(38);
case 42:
return _context3.finish(35);
case 43:
return _context3.abrupt('return', result);
case 44:
case 'end':
return _context3.stop();
}
}
}, _callee3, this, [[0, 5], [12, 19], [27, 31, 35, 43], [36,, 38, 42]]);
}));
function search(_x) {
return _ref3.apply(this, arguments);
}
return search;
}()
}, {
key: 'getUrl',
value: function () {
var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(data) {
var url;
return _regenerator2.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
url = 'http://dl.stream.qqmusic.qq.com/' + data.prefix + data.mid + '.' + data.type + '?vkey=' + this.vkey + '&guid=' + this.guid + '&uin=0&fromtag=30';
return _context4.abrupt('return', url);
case 2:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
function getUrl(_x2) {
return _ref4.apply(this, arguments);
}
return getUrl;
}()
}], [{
key: 'getGUid',
value: function getGUid() {
var currentMs = new Date().getUTCMilliseconds();
return Math.round(2147483647 * Math.random()) * currentMs % 1e10;
}
}]);
return QQ;
}();
module.exports = QQ;
{
"name": "unblock-netease-music",
"version": "2.5.5",
"version": "3.0.0",
"scripts": {

@@ -12,15 +12,15 @@ "start": "babel-node -- src/bin/unblockneteasemusic -p 8123 -v",

"dependencies": {
"async": "^2.1.5",
"async": "^2.5.0",
"babel-runtime": "^6.11.6",
"colors": "^1.1.2",
"commander": "^2.9.0",
"koa": "^2.0.0-alpha.7",
"koa-logger": "^2.0.0",
"koa-route": "^3.2.0",
"koa": "^2.3.0",
"koa-logger": "^3.0.1",
"koa-router": "^7.2.1",
"md5": "^2.1.0",
"pkginfo": "^0.4.0",
"raw-body": "^2.1.6",
"pkginfo": "^0.4.1",
"raw-body": "^2.3.2",
"remote-file-size": "^3.0.3",
"request": "^2.69.0",
"request-promise": "^4.1.1"
"request": "^2.81.0",
"request-promise": "^4.2.1"
},

@@ -39,6 +39,4 @@ "keywords": [

"babel-eslint": "^7.1.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-polyfill": "^6.13.0",
"babel-preset-env": "^1.4.0",
"babel-preset-node8": "^1.2.0",
"eslint": "^3.13.0",

@@ -45,0 +43,0 @@ "eslint-config-airbnb": "^14.0.0",

import 'colors';
import Koa from 'koa';
import logger from 'koa-logger';
import route from 'koa-route';
import Router from 'koa-router';
import config from './modules/config';
import proxy from './modules/proxy';
import Netease from './modules/utils/netease';
import * as modify from './modules/modify';
import Netease from './modules/utils/netease';
// import * as pair from './modules/pair';
const app = new Koa();
app.use(logger());
app.use(proxy);
app.use(async (ctx, next) => {
const errorHandler = async (ctx, next) => {
const data = ctx.body;

@@ -40,10 +37,53 @@ let json = '';

}
});
app.use(route.post('/eapi/song/enhance/player/url', modify.player));
app.use(route.post('/eapi/song/enhance/download/url', modify.download));
app.use(route.post('/api/linux/forward', modify.forward));
app.use(route.post('/api/plugin', modify.player));
app.use(route.post('/api/plugin/player', modify.player));
app.use(route.post('/api/plugin/download', modify.download));
};
const app = new Koa();
app.use(logger());
const router = Router();
// Route for native netease client
router.post(
'/eapi/song/enhance/player/url',
proxy,
errorHandler,
modify.player,
);
router.post(
'/api/plugin/player',
proxy,
errorHandler,
modify.player,
);
router.post(
'/eapi/song/enhance/download/url',
proxy,
errorHandler,
modify.download,
);
router.post(
'/api/plugin/download',
proxy,
errorHandler,
modify.download,
);
router.post(
'/api/linux/forward',
proxy,
errorHandler,
modify.forward,
);
// Route for Unblock Netease Music Server itself
// router
// .use('/api/pair/*', pair.permission)
// .get('/api/pair/recent', pair.recent)
// .get('/api/pair', pair.list)
// .put('/api/pair', pair.save)
// .post('/api/pair/:songId', pair.update);
app
.use(router.routes())
.use(router.allowedMethods());
export default app;

@@ -0,0 +0,0 @@ #!/usr/bin/env node

@@ -28,2 +28,3 @@ import getRawBody from 'raw-body';

host: 'music.163.com',
'x-real-ip': `202.114.79.${Math.floor(Math.random() * 255) + 1}`,
};

@@ -30,0 +31,0 @@

@@ -26,33 +26,32 @@ import 'colors';

batchSeachMusic(songName, artist, album) {
return new Promise((resolve, reject) => {
async.map(this.plugins, async (plugin, callback) => {
console.log(`Search from ${plugin.name}`.green);
const keyword = `${artist} ${songName} ${album}`;
let searchResult;
try {
searchResult = await plugin.search(keyword);
} catch (error) {
console.log(`Cannot search from ${plugin.name}`.red);
console.log(error);
return callback(null);
async batchSeachMusic(songName, artist, album) {
const result = [];
for (const plugin of this.plugins) {
console.log(`Search from ${plugin.name}`.green);
const keyword = `${artist} ${songName} ${album}`;
let searchResult;
try {
searchResult = await plugin.search(keyword);
} catch (error) {
console.log(`Cannot search from ${plugin.name}`.red);
console.log(error);
continue;
}
if (searchResult.length > 0) {
// console.log(searchResult);
const searchName = searchResult[0].name.replace(/ /g, '').toLowerCase();
const trueName = songName.replace(/ /g, '').toLowerCase();
if (searchName.indexOf(trueName) !== -1) {
result.push({
plugin,
searchResult: searchResult[0],
});
} else {
console.log(`No resource found from ${plugin.name}`.yellow);
}
if (searchResult.length > 0) {
// console.log(searchResult);
const searchName = searchResult[0].name.replace(/ /g, '').toLowerCase();
const trueName = songName.replace(/ /g, '').toLowerCase();
if (searchName.indexOf(trueName) !== -1) {
return callback(null, {
plugin,
searchResult: searchResult[0],
});
}
}
} else {
console.log(`No resource found from ${plugin.name}`.yellow);
return callback(null);
}, (err, result) => {
if (err) return reject(err);
return resolve(result);
});
});
}
}
return result;
}

@@ -59,0 +58,0 @@

@@ -77,2 +77,5 @@ import 'colors';

static fixJsonData(body) {
if (body.code === 200) {
return body;
}
return {

@@ -79,0 +82,0 @@ ...body,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc