unblock-netease-music
Advanced tools
Comparing version 2.5.5 to 3.0.0
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¬ice=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¬ice=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¬ice=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¬ice=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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11
33
369841
1616
+ Addedkoa-router@^7.2.1
+ Addedansi-styles@3.2.1(transitive)
+ Addedany-promise@1.3.0(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addeddebug@3.2.7(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedkoa-compose@3.2.1(transitive)
+ Addedkoa-logger@3.2.1(transitive)
+ Addedkoa-router@7.4.0(transitive)
+ Addedsupports-color@5.5.0(transitive)
+ Addedurijs@1.19.11(transitive)
- Removedkoa-route@^3.2.0
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedbytes@1.0.0(transitive)
- Removedchalk@1.1.3(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedkoa-logger@2.0.1(transitive)
- Removedkoa-route@3.2.0(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedsupports-color@2.0.0(transitive)
Updatedasync@^2.5.0
Updatedkoa@^2.3.0
Updatedkoa-logger@^3.0.1
Updatedpkginfo@^0.4.1
Updatedraw-body@^2.3.2
Updatedrequest@^2.81.0
Updatedrequest-promise@^4.2.1