diff --git a/common/Httpx.py b/common/Httpx.py index bed301f..a02d0b0 100644 --- a/common/Httpx.py +++ b/common/Httpx.py @@ -108,7 +108,7 @@ def request(url: str, options = {}) -> requests.Response: # 获取请求方法,没有则默认为GET请求 try: - method = options['method'] + method = options['method'].upper() options.pop('method') except Exception as e: method = 'GET' @@ -277,14 +277,14 @@ async def AsyncRequest(url, options = {}) -> ClientResponse: logger.debug(f'HTTP Request: {url}\noptions: {options}') # 转换body/form参数为原生的data参数,并为form请求追加Content-Type头 if (method == 'POST') or (method == 'PUT'): - if options.get('body'): + if (options.get('body') is not None): options['data'] = options['body'] options.pop('body') - if options.get('form'): + if (options.get('form') is not None): options['data'] = convert_dict_to_form_string(options['form']) options.pop('form') options['headers']['Content-Type'] = 'application/x-www-form-urlencoded' - if (isinstance(options['data'], dict)): + if (isinstance(options.get('data'), dict)): options['data'] = json.dumps(options['data']) # 进行请求 try: diff --git a/common/config.py b/common/config.py index 11f84b4..2aa04ff 100644 --- a/common/config.py +++ b/common/config.py @@ -234,11 +234,15 @@ default = { "mg": { "desc": "咪咕音乐相关配置", "user": { - "desc": "研究不深,后两项自行抓包获取,在header里", - "aversionid": "", - "token": "", - "osversion": "10", + "desc": "研究不深,后两项自行抓包获取,网页端cookie", + "by": "", + "session": "", "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36", + "refresh_login": { + "enable": False, + "interval": 86400, + "desc": "进行cookie保活" + } }, }, "kw": { @@ -301,10 +305,13 @@ default = { ], 'mg': [ { - 'aversionid': '', - 'token': '', - 'osversion': '10', + 'by': '', + 'session': '', 'useragent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36', + "refresh_login": { + "enable": False, + "interval": 86400 + } } ], 'kw': [ diff --git a/modules/mg/__init__.py b/modules/mg/__init__.py index a28fbca..ae90f6a 100644 --- a/modules/mg/__init__.py +++ b/modules/mg/__init__.py @@ -12,48 +12,52 @@ from common import Httpx from common import config from common import variable from common.exceptions import FailedException +from . import refresh_login tools = { - 'url': 'https://app.c.nf.migu.cn/MIGUM2.0/strategy/listen-url/v2.4?toneFlag=__quality__&songId=__songId__&resourceType=2', 'qualityMap': { - '128k': 'PQ', - '320k': 'HQ', - 'flac': 'SQ', - 'flac24bit': 'ZQ', + '128k': '1', + '320k': '2', + 'flac': '3', + 'flac24bit': '4', + "master": "5" }, 'qualityMapReverse': { - 'PQ': '128k', - 'HQ': '320k', - 'SQ': 'flac', - 'ZQ': 'flac24bit', + '000009': '128k', + '020010': '320k', + '011002': 'flac', + '011005': 'flac24bit', }, } -async def url(songId, quality): +async def url(songmid, quality): + info_url = f"http://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/resourceinfo.do?resourceType=2©rightId=" + songmid + info_request = await Httpx.AsyncRequest(info_url, {"method": "POST", "cache": 259200}) + infobody = info_request.json() + if infobody["code"] != "000000": + raise FailedException("failed to fetch song info") user_info = config.read_config('module.mg.user') if (not variable.use_cookie_pool) else random.choice(config.read_config('module.cookiepool.mg')) - req = await Httpx.AsyncRequest(tools['url'].replace('__quality__', tools['qualityMap'][quality]).replace('__songId__', songId), { + req = await Httpx.AsyncRequest(f'https://m.music.migu.cn/migumusic/h5/play/auth/getSongPlayInfo?type={tools["qualityMap"][quality]}©rightId={infobody["resource"][0]["copyrightId"]}', { 'method': 'GET', 'headers': { 'User-Agent': user_info['useragent'], - 'aversionid': user_info['aversionid'], - 'token': user_info['token'], - 'channel': '0146832', - 'language': 'Chinese', - 'ua': 'Android_migu', - 'mode': 'android', - 'os': 'Android ' + user_info['osversion'], + "by": user_info["by"], + "Cookie": "SESSION=" + user_info["session"], + "Referer": "https://m.music.migu.cn/v4/", + "Origin": "https://m.music.migu.cn", }, }) try: body = req.json() - data = body['data'] - if ((not int(body['code']) == 0) or ( not data['url'])): - raise FailedException('failed') + if (int(body['code']) != 200 or (not body.get("data")) or (not body["data"]["playUrl"])): + raise FailedException(body.get("msg") if body.get("msg") else "failed") + + data = body["data"] return { - 'url': data['url'].split('?')[0], - 'quality': tools['qualityMapReverse'][data['audioFormatType']], + 'url': body["data"]["playUrl"].split("?")[0] if body["data"]["playUrl"].split("?")[0].startswith("http") else "http:" + body["data"]["playUrl"].split("?")[0], + 'quality': tools['qualityMapReverse'].get(data['formatId']) if (tools['qualityMapReverse'].get(data['formatId'])) else "unknown", } except: raise FailedException('failed') \ No newline at end of file diff --git a/modules/mg/refresh_login.py b/modules/mg/refresh_login.py new file mode 100644 index 0000000..9adc07d --- /dev/null +++ b/modules/mg/refresh_login.py @@ -0,0 +1,51 @@ +# ---------------------------------------- +# - mode: python - +# - author: helloplhm-qwq - +# - name: refresh_login.py - +# - project: lx-music-api-server - +# - license: MIT - +# ---------------------------------------- +# This file is part of the "lx-music-api-server" project. + +from common import Httpx +from common import config +from common.exceptions import FailedException +from common import scheduler +from common import variable +from common import log + +logger = log.log("migu_refresh_login") + +async def do_account_refresh(user_info): + req = await Httpx.AsyncRequest("https://m.music.migu.cn/migumusic/h5/user/auth/userActiveNotice", { + "method": "POST", + "body": "", + "headers": { + "User-Agent": user_info["useragent"], + "by": user_info["by"], + "Cookie": "SESSION=" + user_info["session"], + "Referer": "https://m.music.migu.cn/v4/my", + "Origin": "https://m.music.migu.cn", + }, + }) + + body = req.json() + + if (int(body["code"]) != 200): + raise FailedException("咪咕session保活失败: " + str(body["msg"])) + return logger.info("咪咕session保活成功") + +if (variable.use_cookie_pool): + users = config.read_config("module.cookiepool.mg") + for u in users: + ref = u.get("refresh_login") if u.get("refresh_login") else { + "enable": False, + "interval": 86400 + } + if (ref["enable"]): + scheduler.append("migu_refresh_login_pooled_" + users["by"], do_account_refresh, ref["interval"], {"user_info": u}) +else: + u = config.read_config("module.mg.user") + ref = config.read_config("module.mg.user.refresh_login") + if (ref["enable"]): + scheduler.append("migu_refresh_login", do_account_refresh, ref["interval"], {"user_info": u}) \ No newline at end of file