chore: 优化代码

This commit is contained in:
“Folltoshe”
2023-12-10 22:03:58 +08:00
parent f6eafff8a9
commit 92236c549a
16 changed files with 72 additions and 85 deletions

View File

@ -12,23 +12,23 @@ from Crypto.Cipher import AES, DES
import binascii import binascii
import base64 import base64
def AESEncrypt(plainText, key, iv): def createAesEncrypt(plainText, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
if isinstance(plainText, str): if isinstance(plainText, str):
plainText = plainText.encode('utf-8') plainText = plainText.encode('utf-8')
return cipher.encrypt(pad(plainText)) return cipher.encrypt(pad(plainText))
def AESDecrypt(cipherText, key, iv): def createAesDecrypt(cipherText, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(cipherText)) return unpad(cipher.decrypt(cipherText))
def hexAESDecrypt(cipherText, key, iv): def createAesEncryptByHex(cipherText, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
if isinstance(cipherText, str): if isinstance(cipherText, str):
cipherText = cipherText.encode('utf-8') cipherText = cipherText.encode('utf-8')
return unpad(cipher.decrypt(binascii.unhexlify(cipherText))) return unpad(cipher.decrypt(binascii.unhexlify(cipherText)))
def base64AESDecrypt(cipherText, key, iv): def createAesEncryptByBase64(cipherText, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
if isinstance(cipherText, str): if isinstance(cipherText, str):
cipherText = cipherText.encode('utf-8') cipherText = cipherText.encode('utf-8')

View File

@ -95,12 +95,12 @@ def request(url, options = {}):
for i in options.get('cache-ignore'): for i in options.get('cache-ignore'):
cache_key = cache_key.replace(str(i), '') cache_key = cache_key.replace(str(i), '')
options.pop('cache-ignore') options.pop('cache-ignore')
cache_key = utils.md5(cache_key) cache_key = utils.createMD5(cache_key)
if options.get("cache") and options["cache"] != "no-cache": if options.get("cache") and options["cache"] != "no-cache":
cache = config.getCache("httpx", cache_key) cache = config.getCache("httpx", cache_key)
if cache: if cache:
logger.debug(f"请求 {url} 有可用缓存") logger.debug(f"请求 {url} 有可用缓存")
return pickle.loads(utils.from_base64(cache["data"])) return pickle.loads(utils.createBase64Decode(cache["data"]))
if "cache" in list(options.keys()): if "cache" in list(options.keys()):
cache_info = options.get("cache") cache_info = options.get("cache")
options.pop("cache") options.pop("cache")
@ -170,7 +170,7 @@ def request(url, options = {}):
if (cache_info and cache_info != "no-cache"): if (cache_info and cache_info != "no-cache"):
cache_data = pickle.dumps(req) cache_data = pickle.dumps(req)
expire_time = (cache_info if isinstance(cache_info, int) else 3600) + int(time.time()) expire_time = (cache_info if isinstance(cache_info, int) else 3600) + int(time.time())
config.updateCache("httpx", cache_key, {"expire": True, "time": expire_time, "data": utils.to_base64(cache_data)}) config.updateCache("httpx", cache_key, {"expire": True, "time": expire_time, "data": utils.createBase64Encode(cache_data)})
logger.debug("缓存已更新: " + url) logger.debug("缓存已更新: " + url)
# 返回请求 # 返回请求
return req return req
@ -179,7 +179,7 @@ def request(url, options = {}):
def checkcn(): def checkcn():
try: try:
req = request("https://mips.kugou.com/check/iscn?&format=json") req = request("https://mips.kugou.com/check/iscn?&format=json")
body = utils.jsobject(req.json()) body = utils.CreateObject(req.json())
variable.iscn = bool(body.flag) variable.iscn = bool(body.flag)
if (not variable.iscn): if (not variable.iscn):
variable.fakeip = config.read_config('common.fakeip') variable.fakeip = config.read_config('common.fakeip')
@ -211,12 +211,12 @@ async def asyncrequest(url, options = {}):
for i in options.get('cache-ignore'): for i in options.get('cache-ignore'):
cache_key = cache_key.replace(str(i), '') cache_key = cache_key.replace(str(i), '')
options.pop('cache-ignore') options.pop('cache-ignore')
cache_key = utils.md5(cache_key) cache_key = utils.createMD5(cache_key)
if options.get("cache") and options["cache"] != "no-cache": if options.get("cache") and options["cache"] != "no-cache":
cache = config.getCache("httpx", cache_key) cache = config.getCache("httpx", cache_key)
if cache: if cache:
logger.debug(f"请求 {url} 有可用缓存") logger.debug(f"请求 {url} 有可用缓存")
return pickle.loads(utils.from_base64(cache["data"])) return pickle.loads(utils.createBase64Decode(cache["data"]))
if "cache" in list(options.keys()): if "cache" in list(options.keys()):
cache_info = options.get("cache") cache_info = options.get("cache")
options.pop("cache") options.pop("cache")

View File

@ -14,7 +14,7 @@ import os
from pygments import highlight from pygments import highlight
from pygments.lexers import PythonLexer from pygments.lexers import PythonLexer
from pygments.formatters import TerminalFormatter from pygments.formatters import TerminalFormatter
from .utils import sanitize_filename, add_to_global_namespace from .utils import filterFileName, addToGlobalNamespace
from .variable import debug_mode, log_length_limit from .variable import debug_mode, log_length_limit
if not os.path.exists("logs"): if not os.path.exists("logs"):
@ -66,7 +66,7 @@ class log:
datefmt='%Y-%m-%d %H:%M:%S' datefmt='%Y-%m-%d %H:%M:%S'
) )
if filename: if filename:
filename = sanitize_filename(filename) filename = filterFileName(filename)
else: else:
filename = './logs/' + module_name + '.log' filename = './logs/' + module_name + '.log'
file_handler = logging.FileHandler(filename, encoding = "utf-8") file_handler = logging.FileHandler(filename, encoding = "utf-8")
@ -159,4 +159,4 @@ printlogger = log('print')
def logprint(*args, sep = ' ', end = '', file = None, flush = None): def logprint(*args, sep = ' ', end = '', file = None, flush = None):
printlogger.info(sep.join(str(arg) for arg in args), allow_hidden = False) printlogger.info(sep.join(str(arg) for arg in args), allow_hidden = False)
add_to_global_namespace('print', logprint) addToGlobalNamespace('print', logprint)

View File

@ -21,9 +21,8 @@ def checklxmheader(lxm, url):
cop, version = tuple(lxm.split('&')) cop, version = tuple(lxm.split('&'))
version = (3 - len(version) % 3) * '0' + version version = (3 - len(version) % 3) * '0' + version
cop = utils.inflate_raw_sync(binascii.unhexlify(cop.encode('utf-8'))).decode('utf-8') cop = utils.handleInflateRawSync(binascii.unhexlify(cop.encode('utf-8'))).decode('utf-8')
cop = utils.from_base64(cop).decode('utf-8') cop = utils.createBase64Decode(cop).decode('utf-8')
# print(retvalue + version)
arr, outsideversion = tuple([cop.split(']')[0] + ']', cop.split(']')[1]]) arr, outsideversion = tuple([cop.split(']')[0] + ']', cop.split(']')[1]])
arr = json.loads(arr) arr = json.loads(arr)
version = re.findall("\\d+", version)[0] version = re.findall("\\d+", version)[0]

View File

@ -17,27 +17,27 @@ import re
import ujson as json import ujson as json
import xmltodict import xmltodict
from urllib.parse import quote from urllib.parse import quote
from hashlib import md5 as _md5 from hashlib import md5 as handleCreateMD5
from aiohttp.web import Response from aiohttp.web import Response
# from flask import Response # from flask import Response
def to_base64(data_bytes): def createBase64Encode(data_bytes):
encoded_data = base64.b64encode(data_bytes) encoded_data = base64.b64encode(data_bytes)
return encoded_data.decode('utf-8') return encoded_data.decode('utf-8')
def to_hex(data_bytes): def createHexEncode(data_bytes):
hex_encoded = binascii.hexlify(data_bytes) hex_encoded = binascii.hexlify(data_bytes)
return hex_encoded.decode('utf-8') return hex_encoded.decode('utf-8')
def from_base64(data): def createBase64Decode(data):
decoded_data = base64.b64decode(data) decoded_data = base64.b64decode(data)
return decoded_data return decoded_data
def from_hex(data): def createHexDecode(data):
decoded_data = binascii.unhexlify(data.decode('utf-8')) decoded_data = binascii.unhexlify(data.decode('utf-8'))
return decoded_data return decoded_data
def inflate_raw_sync(data): def handleInflateRawSync(data):
decompress_obj = zlib.decompressobj(-zlib.MAX_WBITS) decompress_obj = zlib.decompressobj(-zlib.MAX_WBITS)
decompressed_data = decompress_obj.decompress(data) + decompress_obj.flush() decompressed_data = decompress_obj.decompress(data) + decompress_obj.flush()
return decompressed_data return decompressed_data
@ -54,10 +54,10 @@ def require(module):
index += 1 index += 1
return _module return _module
def add_to_global_namespace(key, data): def addToGlobalNamespace(key, data):
setattr(builtins, key, data) setattr(builtins, key, data)
def sanitize_filename(filename): def filterFileName(filename):
if platform.system() == 'Windows' or platform.system() == 'Cygwin': if platform.system() == 'Windows' or platform.system() == 'Cygwin':
# Windows不合法文件名字符 # Windows不合法文件名字符
illegal_chars = r'[<>:"/\\|?*\x00-\x1f]' illegal_chars = r'[<>:"/\\|?*\x00-\x1f]'
@ -67,21 +67,19 @@ def sanitize_filename(filename):
# 将不合法字符替换为下划线 # 将不合法字符替换为下划线
return re.sub(illegal_chars, '_', filename) return re.sub(illegal_chars, '_', filename)
def md5(s: str): def createMD5(s: str):
# 计算md5 return handleCreateMD5(s.encode("utf-8")).hexdigest()
# print(s)
return _md5(s.encode("utf-8")).hexdigest()
def readfile(path, mode = "text"): def readFile(path, mode = "text"):
try: try:
fileObj = open(path, "rb") fileObj = open(path, "rb")
except FileNotFoundError: except FileNotFoundError:
return "file not found" return "file not found"
content = fileObj.read() content = fileObj.read()
if mode == "base64": if mode == "base64":
return to_base64(content) return createBase64Encode(content)
elif mode == "hex": elif mode == "hex":
return to_hex(content) return createHexEncode(content)
elif mode == "text": elif mode == "text":
return content.decode("utf-8") return content.decode("utf-8")
else: else:
@ -92,29 +90,29 @@ def unique_list(list_in):
[unique_list.append(x) for x in list_in if x not in unique_list] [unique_list.append(x) for x in list_in if x not in unique_list]
return unique_list return unique_list
def handle_response(dic, status = 200): def handleResult(dic, status = 200):
return Response(body = json.dumps(dic, indent=2, ensure_ascii=False), content_type='application/json', status = status) return Response(body = json.dumps(dic, indent=2, ensure_ascii=False), content_type='application/json', status = status)
def encodeURIComponent(component): def encodeURIComponent(component):
return quote(component) return quote(component)
def sort_dict(dictionary): def sortDict(dictionary):
sorted_items = sorted(dictionary.items()) sorted_items = sorted(dictionary.items())
sorted_dict = {k: v for k, v in sorted_items} sorted_dict = {k: v for k, v in sorted_items}
return sorted_dict return sorted_dict
def merge_dict(dict1, dict2): def mergeDict(dict1, dict2):
merged_dict = dict2.copy() merged_dict = dict2.copy()
merged_dict.update(dict1) merged_dict.update(dict1)
return merged_dict return merged_dict
class jsobject(dict): class CreateObject(dict):
def __init__(self, d): def __init__(self, d):
super().__init__(d) super().__init__(d)
self._raw = d self._raw = d
for key, value in d.items(): for key, value in d.items():
if isinstance(value, dict): if isinstance(value, dict):
setattr(self, key, jsobject(value)) setattr(self, key, CreateObject(value))
else: else:
setattr(self, key, value) setattr(self, key, value)
@ -126,7 +124,7 @@ class jsobject(dict):
def to_dict(self): def to_dict(self):
result = {} result = {}
for key, value in self.items(): for key, value in self.items():
if isinstance(value, jsobject): if isinstance(value, CreateObject):
result[key] = value.to_dict() result[key] = value.to_dict()
else: else:
result[key] = value result[key] = value
@ -141,5 +139,5 @@ def dump_xml(data):
def load_xml(data): def load_xml(data):
return xmltodict.parse(data) return xmltodict.parse(data)
add_to_global_namespace('require', require) addToGlobalNamespace('require', require)

View File

@ -28,7 +28,7 @@ logger = log.log("main")
from common import utils from common import utils
from common import lxsecurity from common import lxsecurity
from common import Httpx from common import Httpx
from apis import SongURL from modules import SongURL
import traceback import traceback
import time import time
Httpx.checkcn() Httpx.checkcn()

26
main.py
View File

@ -15,7 +15,7 @@ from common import lxsecurity
from common import utils from common import utils
from common import log from common import log
from common import Httpx from common import Httpx
from apis import handle_api_request from modules import handleApiRequest
import traceback import traceback
import time import time
@ -32,20 +32,20 @@ async def handle_before_request(app, handler):
request.remote = request.headers.get("X-Real-IP") request.remote = request.headers.get("X-Real-IP")
# check ip # check ip
if (config.check_ip_banned(request.remote)): if (config.check_ip_banned(request.remote)):
return utils.handle_response({"code": 1, "msg": "您的IP已被封禁", "data": None}, 403) return utils.handleResult({"code": 1, "msg": "您的IP已被封禁", "data": None}, 403)
# check global rate limit # check global rate limit
if ( if (
(time.time() - config.getRequestTime('global')) (time.time() - config.getRequestTime('global'))
< <
(config.read_config("security.rate_limit.global")) (config.read_config("security.rate_limit.global"))
): ):
return utils.handle_response({"code": 5, "msg": "全局限速", "data": None}, 429) return utils.handleResult({"code": 5, "msg": "全局限速", "data": None}, 429)
if ( if (
(time.time() - config.getRequestTime(request.remote)) (time.time() - config.getRequestTime(request.remote))
< <
(config.read_config("security.rate_limit.ip")) (config.read_config("security.rate_limit.ip"))
): ):
return utils.handle_response({"code": 5, "msg": "IP限速", "data": None}, 429) return utils.handleResult({"code": 5, "msg": "IP限速", "data": None}, 429)
# update request time # update request time
config.updateRequestTime('global') config.updateRequestTime('global')
config.updateRequestTime(request.remote) config.updateRequestTime(request.remote)
@ -54,21 +54,21 @@ async def handle_before_request(app, handler):
if request.remote_host.split(":")[0] not in config.read_config("security.allowed_host.list"): if request.remote_host.split(":")[0] not in config.read_config("security.allowed_host.list"):
if config.read_config("security.allowed_host.blacklist.enable"): if config.read_config("security.allowed_host.blacklist.enable"):
config.ban_ip(request.remote, int(config.read_config("security.allowed_host.blacklist.length"))) config.ban_ip(request.remote, int(config.read_config("security.allowed_host.blacklist.length")))
return utils.handle_response({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404) return utils.handleResult({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404)
try: try:
resp = await handler(request) resp = await handler(request)
aiologger.info(f'{request.remote} - {request.method} "{request.path}", {resp.status}') aiologger.info(f'{request.remote} - {request.method} "{request.path}", {resp.status}')
return resp return resp
except web.HTTPException as ex: except web.HTTPException as ex:
if ex.status == 500: # 捕获500错误 if ex.status == 500: # 捕获500错误
return utils.handle_response({"code": 4, "msg": "内部服务器错误", "data": None}, 500) return utils.handleResult({"code": 4, "msg": "内部服务器错误", "data": None}, 500)
else: else:
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
return utils.handle_response({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404) return utils.handleResult({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404)
return handle_request return handle_request
async def main(request): async def main(request):
return utils.handle_response({"code": 0, "msg": "success", "data": None}) return utils.handleResult({"code": 0, "msg": "success", "data": None})
async def handle(request): async def handle(request):
@ -80,22 +80,22 @@ async def handle(request):
if (request.headers.get("X-Request-Key")) != config.read_config("security.key.value"): if (request.headers.get("X-Request-Key")) != config.read_config("security.key.value"):
if (config.read_config("security.key.ban")): if (config.read_config("security.key.ban")):
config.ban_ip(request.remote) config.ban_ip(request.remote)
return utils.handle_response({"code": 1, "msg": "key验证失败", "data": None}, 403) return utils.handleResult({"code": 1, "msg": "key验证失败", "data": None}, 403)
if (config.read_config('security.check_lxm.enable') and request.host.split(':')[0] not in config.read_config('security.whitelist_host')): if (config.read_config('security.check_lxm.enable') and request.host.split(':')[0] not in config.read_config('security.whitelist_host')):
lxm = request.headers.get('lxm') lxm = request.headers.get('lxm')
if (not lxsecurity.checklxmheader(lxm, request.url)): if (not lxsecurity.checklxmheader(lxm, request.url)):
if (config.read_config('security.lxm_ban.enable')): if (config.read_config('security.lxm_ban.enable')):
config.ban_ip(request.remote) config.ban_ip(request.remote)
return utils.handle_response({"code": 1, "msg": "lxm请求头验证失败", "data": None}, 403) return utils.handleResult({"code": 1, "msg": "lxm请求头验证失败", "data": None}, 403)
try: try:
return utils.handle_response(await handle_api_request(method, source, songId, quality)) return utils.handleResult(await handleApiRequest(method, source, songId, quality))
except Exception as e: except Exception as e:
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
return utils.handle_response({'code': 4, 'msg': '内部服务器错误', 'data': None}, 500) return utils.handleResult({'code': 4, 'msg': '内部服务器错误', 'data': None}, 500)
async def handle_404(request): async def handle_404(request):
return utils.handle_response({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404) return utils.handleResult({'code': 6, 'msg': '未找到您所请求的资源', 'data': None}, 404)
app = web.Application(middlewares=[handle_before_request]) app = web.Application(middlewares=[handle_before_request])
# mainpage # mainpage

View File

@ -48,7 +48,7 @@ sourceExpirationTime = {
} }
async def handle_api_request(command, source, songId, quality): async def handleApiRequest(command, source, songId, quality):
if (source == "kg"): if (source == "kg"):
songId = songId.lower() songId = songId.lower()
try: try:
@ -63,7 +63,7 @@ async def handle_api_request(command, source, songId, quality):
except: except:
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
try: try:
func = require('apis.' + source + '.' + command) func = require('modules.' + source + '.' + command)
except: except:
return { return {
'code': 1, 'code': 1,

View File

@ -14,17 +14,17 @@ from common import Httpx
import ujson as json import ujson as json
import time import time
jsobject = utils.jsobject createObject = utils.CreateObject
def buildsignparams(dictionary, body = ""): def buildSignatureParams(dictionary, body = ""):
joined_str = ''.join([f'{k}={v}' for k, v in dictionary.items()]) joined_str = ''.join([f'{k}={v}' for k, v in dictionary.items()])
return joined_str + body return joined_str + body
def buildrequestparams(dictionary): def buildRequestParams(dictionary):
joined_str = '&'.join([f'{k}={v}' for k, v in dictionary.items()]) joined_str = '&'.join([f'{k}={v}' for k, v in dictionary.items()])
return joined_str return joined_str
tools = jsobject({ tools = createObject({
"signkey": config.read_config("module.kg.client.signatureKey"), "signkey": config.read_config("module.kg.client.signatureKey"),
"pidversec": config.read_config("module.kg.client.pidversionsecret"), "pidversec": config.read_config("module.kg.client.pidversionsecret"),
"clientver": config.read_config("module.kg.client.clientver"), "clientver": config.read_config("module.kg.client.clientver"),
@ -53,18 +53,18 @@ tools = jsobject({
}) })
def sign(params, body = ""): def sign(params, body = ""):
params = utils.sort_dict(params) params = utils.sortDict(params)
params = buildsignparams(params, body) params = buildSignatureParams(params, body)
return utils.md5(tools["signkey"] + params + tools["signkey"]) return utils.createMD5(tools["signkey"] + params + tools["signkey"])
def signRequest(url, params, options): def signRequest(url, params, options):
params = utils.merge_dict(tools["extra_params"], params) params = utils.mergeDict(tools["extra_params"], params)
url = url + "?" + buildrequestparams(params) + "&signature=" + sign(params, options.get("body") if options.get("body") else (options.get("data") if options.get("data") else "")) url = url + "?" + buildRequestParams(params) + "&signature=" + sign(params, options.get("body") if options.get("body") else (options.get("data") if options.get("data") else ""))
return Httpx.request(url, options) return Httpx.request(url, options)
def getKey(hash_): def getKey(hash_):
# print(hash_ + tools.pidversec + tools.appid + tools.mid + tools.userid) # print(hash_ + tools.pidversec + tools.appid + tools.mid + tools.userid)
return utils.md5(hash_.lower() + tools.pidversec + tools.appid + tools.mid + tools.userid) return utils.createMD5(hash_.lower() + tools.pidversec + tools.appid + tools.mid + tools.userid)
async def getMusicInfo(hash_): async def getMusicInfo(hash_):
tn = int(time.time()) tn = int(time.time())
@ -145,7 +145,7 @@ async def url(songId, quality):
# print(params.quality) # print(params.quality)
if (tools.version == "v4"): if (tools.version == "v4"):
params['version'] = tools.clientver params['version'] = tools.clientver
headers = jsobject({ headers = createObject({
'User-Agent': 'Android712-AndroidPhone-8983-18-0-NetMusic-wifi', 'User-Agent': 'Android712-AndroidPhone-8983-18-0-NetMusic-wifi',
'KG-THash': '3e5ec6b', 'KG-THash': '3e5ec6b',
'KG-Rec': '1', 'KG-Rec': '1',
@ -154,7 +154,7 @@ async def url(songId, quality):
if (tools['x-router']['enable']): if (tools['x-router']['enable']):
headers['x-router'] = tools['x-router']['value'] headers['x-router'] = tools['x-router']['value']
req = signRequest(tools.url, params, {'headers': headers}) req = signRequest(tools.url, params, {'headers': headers})
body = jsobject(req.json()) body = createObject(req.json())
if body.status == 3: if body.status == 3:
raise FailedException('该歌曲在酷狗没有版权,请换源播放') raise FailedException('该歌曲在酷狗没有版权,请换源播放')

View File

@ -7,7 +7,7 @@
# ---------------------------------------- # ----------------------------------------
# This file is part of the "lx-music-api-server" project. # This file is part of the "lx-music-api-server" project.
from common.utils import md5 as _md5 from common.utils import createMD5
import re as _re import re as _re
def v(b): def v(b):
@ -92,7 +92,7 @@ def t(b):
return res return res
def sign(params): def sign(params):
md5Str = _md5(params).upper() md5Str = createMD5(params).upper()
h = v(md5Str) h = v(md5Str)
e = c(md5Str) e = c(md5Str)
ls = t(md5Str) ls = t(md5Str)

View File

@ -14,9 +14,9 @@ from common import config
from .QMWSign import sign from .QMWSign import sign
import ujson as json import ujson as json
jsobject = utils.jsobject createObject = utils.CreateObject
tools = jsobject({ tools = createObject({
"fileInfo": { "fileInfo": {
"128k": { "128k": {
'e': '.mp3', 'e': '.mp3',
@ -80,7 +80,7 @@ async def url(songId, quality):
}, },
} }
infoRequest = signRequest(infoReqBody, True) infoRequest = signRequest(infoReqBody, True)
infoBody = jsobject(infoRequest.json()) infoBody = createObject(infoRequest.json())
if (infoBody.code != 0 or infoBody.req.code != 0): if (infoBody.code != 0 or infoBody.req.code != 0):
raise FailedException("获取音乐信息失败") raise FailedException("获取音乐信息失败")
strMediaMid = infoBody.req.data.track_info.file.media_mid strMediaMid = infoBody.req.data.track_info.file.media_mid
@ -107,7 +107,7 @@ async def url(songId, quality):
}, },
} }
req = signRequest(requestBody) req = signRequest(requestBody)
body = jsobject(req.json()) body = CreateObject(req.json())
# js const { purl } = data.req_0.data.midurlinfo[0] # js const { purl } = data.req_0.data.midurlinfo[0]
if (not body.req_0.data.midurlinfo[0]['purl']): if (not body.req_0.data.midurlinfo[0]['purl']):
raise FailedException('failed') raise FailedException('failed')

View File

@ -13,8 +13,9 @@ from base64 import b64encode
from binascii import hexlify from binascii import hexlify
from hashlib import md5 from hashlib import md5
from Crypto.Cipher import AES from Crypto.Cipher import AES
from common import utils
__all__ = ["weEncrypt", "linuxEncrypt", "eEncrypt", "MD5"] __all__ = ["weEncrypt", "linuxEncrypt", "eEncrypt"]
MODULUS = ( MODULUS = (
"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7" "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7"
@ -28,13 +29,6 @@ NONCE = b"0CoJUm6Qyw8W8jud"
LINUXKEY = b"rFgB&h#%2?^eDg:Q" LINUXKEY = b"rFgB&h#%2?^eDg:Q"
EAPIKEY = b'e82ckenh8dichen8' EAPIKEY = b'e82ckenh8dichen8'
def MD5(value):
m = md5()
m.update(value.encode())
return m.hexdigest()
def weEncrypt(text): def weEncrypt(text):
""" """
引用自 https://github.com/darknessomi/musicbox/blob/master/NEMbox/encrypt.py#L40 引用自 https://github.com/darknessomi/musicbox/blob/master/NEMbox/encrypt.py#L40
@ -46,7 +40,6 @@ def weEncrypt(text):
encseckey = rsa(secret, PUBKEY, MODULUS) encseckey = rsa(secret, PUBKEY, MODULUS)
return {"params": params, "encSecKey": encseckey} return {"params": params, "encSecKey": encseckey}
def linuxEncrypt(text): def linuxEncrypt(text):
""" """
参考自 https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/util/crypto.js#L28 参考自 https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/util/crypto.js#L28
@ -55,14 +48,12 @@ def linuxEncrypt(text):
data = aes(text, LINUXKEY) data = aes(text, LINUXKEY)
return {"eparams": data.decode()} return {"eparams": data.decode()}
def eapiEncrypt(url, text): def eapiEncrypt(url, text):
text = str(text) text = str(text)
digest = MD5("nobody{}use{}md5forencrypt".format(url, text)) digest = utils.createMD5("nobody{}use{}md5forencrypt".format(url, text))
data = "{}-36cd479b6b5-{}-36cd479b6b5-{}".format(url, text, digest) data = "{}-36cd479b6b5-{}-36cd479b6b5-{}".format(url, text, digest)
return {"params": aes(data.encode(), EAPIKEY).decode("utf-8")} return {"params": aes(data.encode(), EAPIKEY).decode("utf-8")}
def aes(text, key, method={}): def aes(text, key, method={}):
pad = 16 - len(text) % 16 pad = 16 - len(text) % 16
text = text + bytearray([pad] * pad) text = text + bytearray([pad] * pad)
@ -75,7 +66,6 @@ def aes(text, key, method={}):
return b64encode(ciphertext) return b64encode(ciphertext)
return hexlify(ciphertext).upper() return hexlify(ciphertext).upper()
def rsa(text, pubkey, modulus): def rsa(text, pubkey, modulus):
text = text[::-1] text = text[::-1]
rs = pow(int(hexlify(text), 16), rs = pow(int(hexlify(text), 16),