Skip to content

Commit c87b48a

Browse files
committed
feat: sign-server
1 parent d4065de commit c87b48a

39 files changed

+877
-775
lines changed

api/gcsp_handler.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import zlib
22
import time
3-
import ujson
3+
from utils import orjson
44
import modules
55
import binascii
66

@@ -44,10 +44,10 @@ async def getKuwoOldInfo(request: Request, songId: int):
4444
@router.api_route("/client/cgi-bin/{method}", methods=["GET", "POST"])
4545
async def GcspApi(request: Request, method: str) -> Response:
4646
try:
47-
PACKAGE = config.read("module.gcsp.package_md5")
48-
SALT_1 = config.read("module.gcsp.salt_1")
49-
SALT_2 = config.read("module.gcsp.salt_2")
50-
NEED_VERIFY = config.read("module.gcsp.enable_verify")
47+
PACKAGE = config.read("modules.gcsp.package_md5")
48+
SALT_1 = config.read("modules.gcsp.salt_1")
49+
SALT_2 = config.read("modules.gcsp.salt_2")
50+
NEED_VERIFY = config.read("modules.gcsp.enable_verify")
5151

5252
qm = {
5353
"mp3": "128k",
@@ -66,7 +66,7 @@ async def GcspApi(request: Request, method: str) -> Response:
6666
}
6767

6868
def decode(indata: bytes) -> dict:
69-
return ujson.loads(binascii.unhexlify(zlib.decompress(indata)))
69+
return orjson.loads(binascii.unhexlify(zlib.decompress(indata)))
7070

7171
def verify(data: dict) -> str:
7272
if not NEED_VERIFY:
@@ -75,8 +75,8 @@ def verify(data: dict) -> str:
7575
sign_1 = createMD5(PACKAGE + data["time"] + SALT_2)
7676
sign_2 = createMD5(
7777
str(
78-
ujson.dumps(data["text_1"])
79-
+ ujson.dumps(data["text_2"])
78+
orjson.dumps(data["text_1"])
79+
+ orjson.dumps(data["text_2"])
8080
+ sign_1
8181
+ data["time"]
8282
+ SALT_1
@@ -101,38 +101,34 @@ async def handleGcspBody(body: bytes):
101101

102102
if result != "success":
103103
compressed_data = zlib.compress(
104-
ujson.dumps(
104+
orjson.dumps(
105105
{
106106
"code": "403",
107107
"error_msg": internal_trans[result],
108108
"data": None,
109109
},
110-
ensure_ascii=False,
111110
).encode("utf-8")
112111
)
113112
return Response(
114113
content=compressed_data,
115114
media_type="application/octet-stream",
116115
)
117116

118-
data["te"] = ujson.loads(data["text_1"])
117+
data["te"] = orjson.loads(data["text_1"])
119118

120119
body = await modules.getUrlForAPI(
121120
pm[data["te"]["platform"]], data["te"]["t1"], qm[data["te"]["t2"]]
122121
)
123122

124123
if body["code"] != 200:
125-
data = ujson.dumps(
126-
{"code": "403", "error_msg": body["message"]}, ensure_ascii=False
127-
)
124+
data = orjson.dumps({"code": "403", "error_msg": body["message"]})
128125
else:
129-
data = ujson.dumps(
126+
data = orjson.dumps(
130127
{
131128
"code": "200",
132129
"error_msg": "success",
133130
"data": body["url"] if body["code"] == 200 else None,
134131
},
135-
ensure_ascii=False,
136132
)
137133

138134
compressed_data = zlib.compress(data.encode("utf-8"))
@@ -152,14 +148,14 @@ async def handleGcspBody(body: bytes):
152148
body = {
153149
"code": "200",
154150
"data": {
155-
"version": config.read("module.gcsp.update.ver"),
156-
"update_title": config.read("module.gcsp.update.title"),
157-
"update_log": config.read("module.gcsp.update.logs"),
158-
"down_url": config.read("module.gcsp.update.down_url"),
159-
"share_url": config.read("module.gcsp.update.pan_url"),
151+
"version": config.read("modules.gcsp.update.ver"),
152+
"update_title": config.read("modules.gcsp.update.title"),
153+
"update_log": config.read("modules.gcsp.update.logs"),
154+
"down_url": config.read("modules.gcsp.update.down_url"),
155+
"share_url": config.read("modules.gcsp.update.pan_url"),
160156
"compulsory": (
161157
"yes"
162-
if config.read("module.gcsp.update.required")
158+
if config.read("modules.gcsp.update.required")
163159
else "no"
164160
),
165161
"file_md5": PACKAGE,

api/music_handler.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import modules
22
from fastapi import Request
33
from fastapi.routing import APIRouter
4-
from modules.url.tx import getEncryptedUrl
5-
from server.exceptions import getSongInfoFailed, getUrlFailed
6-
from server.config import cache
74
from utils.response import handleResponse
8-
from server.models import UrlResponse
95

106
router = APIRouter()
117

@@ -35,35 +31,3 @@ async def handleLyric(request: Request, source: str, songId: str | int):
3531

3632
result = await modules.getLyricForAPI(source, songId)
3733
return handleResponse(request, result)
38-
39-
40-
@router.get("/eurl")
41-
async def handleEncryptSongUrl(request: Request, songId: str | int, quality: str):
42-
try:
43-
cache_data = cache.get("eurl", f"{songId}_{quality}")
44-
result = UrlResponse(**cache_data)
45-
print(
46-
f"获取缓存的Encrypt_QM_{songId}_{quality}成功, URL: {result.url}, Ekey: {result.ekey:10}"
47-
)
48-
return handleResponse(
49-
request,
50-
{"code": 200, "message": "成功", "url": result.url, "ekey": result.ekey},
51-
)
52-
except:
53-
pass
54-
55-
try:
56-
result = await getEncryptedUrl(songId, quality)
57-
print(
58-
f"获取Encrypt_QM_{songId}_{quality}成功, URL: {result.url}, Ekey: {result.ekey:10}"
59-
)
60-
cache.set("eurl", f"{songId}_{quality}", result.__dict__, 600)
61-
print(f"缓存已更新: Encrypt_QM_{songId}_{quality}")
62-
return handleResponse(
63-
request,
64-
{"code": 200, "message": "成功", "url": result.url, "ekey": result.ekey},
65-
)
66-
except getUrlFailed as e:
67-
return handleResponse(request, {"code": 500, "message": f"获取链接失败:{e}"})
68-
except getSongInfoFailed as e:
69-
return handleResponse(request, {"code": 500, "message": f"获取详情失败:{e}"})

api/script_handler.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import re
2-
import ujson
2+
from utils import orjson
33
from fastapi import APIRouter, Request, Response
44
from server.config import config
55
from utils.response import handleResponse
@@ -11,7 +11,7 @@
1111
@router.get("/script")
1212
async def lx_script(request: Request, key: str | None = None):
1313
try:
14-
with open(f"./static/lx-source.js", "r", encoding="utf-8") as f:
14+
with open("./static/lx-source.js", "r", encoding="utf-8") as f:
1515
script = f.read()
1616
except:
1717
return handleResponse(request, {"code": 404, "message": "本地无源脚本"})
@@ -26,7 +26,7 @@ async def lx_script(request: Request, key: str | None = None):
2626
if line.startswith("const API_URL"):
2727
newScriptLines.append(f'''const API_URL = "{url}"''')
2828
elif line.startswith("const API_KEY"):
29-
newScriptLines.append(f'''const API_KEY = "{key if key else ''}"''')
29+
newScriptLines.append(f'''const API_KEY = "{key if key else ""}"''')
3030
elif line.startswith("* @name"):
3131
newScriptLines.append(" * @name " + config.read("script.name"))
3232
elif line.startswith("* @description"):
@@ -50,7 +50,7 @@ async def lx_script(request: Request, key: str | None = None):
5050

5151
r = re.sub(
5252
r"const MUSIC_QUALITY = {[^}]+}",
53-
f"const MUSIC_QUALITY = JSON.parse('{ujson.dumps(config.read('script.qualitys'))}')",
53+
f"const MUSIC_QUALITY = JSON.parse('{orjson.dumps(config.read('script.qualitys'))}')",
5454
r,
5555
)
5656

@@ -85,10 +85,12 @@ async def lx_script(request: Request, key: str | None = None):
8585
content=r,
8686
media_type="text/javascript",
8787
headers={
88-
"Content-Disposition": f"""attachment; filename={(
89-
config.read('script.file')
90-
if config.read('script.file').endswith('.js')
91-
else config.read('script.file') + '.js'
92-
)}"""
88+
"Content-Disposition": f"""attachment; filename={
89+
(
90+
config.read("script.file")
91+
if config.read("script.file").endswith(".js")
92+
else config.read("script.file") + ".js"
93+
)
94+
}"""
9395
},
9496
)

main.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
try:
2-
from fastapi import FastAPI
3-
from fastapi import Request
4-
from shared import Dossier, HOME
5-
except:
6-
raise ImportError("Please run 'uv sync' to install packages.")
7-
1+
from fastapi import FastAPI
2+
from fastapi import Request
83
import asyncio
94
from pathlib import Path
105
from api import home_handler, gcsp_handler, script_handler, music_handler
@@ -24,16 +19,12 @@ async def clean():
2419
if variable.http_client:
2520
await variable.http_client.connector.close()
2621
await variable.http_client.close()
27-
28-
path = Path(HOME, "my_dossier")
29-
dossier = Dossier(path)
30-
dossier.set("registered", {"ok": False})
31-
3222
logger.info("等待部分进程暂停...")
3323

3424

3525
@asynccontextmanager
3626
async def lifespan(app: FastAPI):
27+
log.intercept_print()
3728
await scheduler.run()
3829

3930
yield
@@ -67,13 +58,13 @@ async def lifespan(app: FastAPI):
6758
app.include_router(home_handler.router)
6859
app.include_router(script_handler.router)
6960
app.include_router(music_handler.router)
70-
if config.read("module.gcsp.enable"):
61+
if config.read("modules.gcsp.enable"):
7162
app.include_router(gcsp_handler.router)
7263

7364

7465
@app.exception_handler(Exception)
7566
async def globalErrorHandler(request: Request, exc: Exception):
76-
logger.error(f"未处理的异常")
67+
logger.error("未处理的异常")
7768
return {"code": 500, "message": f"未处理的异常: {exc}"}
7869

7970

middleware/request_logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async def dispatch(self, request: Request, call_next):
3131
ip_info = {"local": "Unknown"}
3232

3333
logger.info(
34-
f"请求: {request.method} - {request.state.remote_addr} - "
34+
f"收到请求: {request.method} - {request.state.remote_addr} - "
3535
f"{ip_info['local']} - {request.url.path} - "
3636
f"{request.headers.get('User-Agent', '')} - "
3737
)

modules/info/tx.py

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
11
from modules.plat.tx.utils import signRequest
2-
from modules.plat.tx import build_common_params
2+
from modules.plat.tx import build_comm
33
from server.models import SongInfo
44
from server.exceptions import getSongInfoFailed
5-
from modules.plat import formatPlayTime, formatSinger
6-
from modules.lyric.tx import getLyric
5+
from modules.plat import formatSinger
76

87

98
async def IdGetInfo(songid: int) -> SongInfo:
10-
commonParams = await build_common_params()
11-
infoReqBody = {
12-
"comm": commonParams,
9+
comm = await build_comm()
10+
reqBody = {
11+
"comm": comm,
1312
"req": {
1413
"module": "music.trackInfo.UniformRuleCtrl",
1514
"method": "CgiGetTrackInfo",
1615
"param": {"types": [1], "ids": [songid], "ctx": 0},
1716
},
1817
}
19-
infoRequest = await signRequest(infoReqBody)
20-
infoBody = infoRequest.json()
18+
resp = await signRequest(reqBody)
19+
respBody = resp.json()
2120

22-
if infoBody["code"] != 0 or infoBody["req"]["code"] != 0:
21+
if respBody["code"] != 0 or respBody["req"]["code"] != 0:
2322
raise getSongInfoFailed("获取音乐信息失败")
2423

25-
info = infoBody["req"]["data"]["tracks"][0]
26-
27-
try:
28-
lyric = await getLyric(info["id"])
29-
except:
30-
lyric = None
24+
info = respBody["req"]["data"]["tracks"][0]
3125

3226
return SongInfo(
3327
songId=info.get("id"),
@@ -40,38 +34,29 @@ async def IdGetInfo(songid: int) -> SongInfo:
4034
),
4135
albumId=info.get("album", {}).get("id"),
4236
albumMid=info.get("album", {}).get("mid"),
43-
duration=(
44-
formatPlayTime(info.get("interval"))
45-
if info.get("interval") is not None
46-
else None
47-
),
37+
duration=info.get("interval", 0),
4838
mediaMid=info.get("file", {}).get("media_mid"),
49-
lyric=lyric,
5039
)
5140

5241

5342
async def MidGetInfo(mid: str) -> SongInfo:
54-
commonParams = await build_common_params()
55-
infoReqBody = {
56-
"comm": commonParams,
43+
comm = await build_comm()
44+
reqBody = {
45+
"comm": comm,
5746
"req": {
5847
"method": "get_song_detail_yqq",
5948
"param": {"song_type": 0, "song_mid": mid},
6049
"module": "music.pf_song_detail_svr",
6150
},
6251
}
63-
infoRequest = await signRequest(infoReqBody)
64-
infoBody = infoRequest.json()
6552

66-
if infoBody["code"] != 0 or infoBody["req"]["code"] != 0:
67-
raise getSongInfoFailed("获取音乐信息失败")
53+
resp = await signRequest(reqBody)
54+
respBody = resp.json()
6855

69-
info = infoBody["req"]["data"]["track_info"]
56+
if respBody["code"] != 0 or respBody["req"]["code"] != 0:
57+
raise getSongInfoFailed("获取音乐信息失败")
7058

71-
try:
72-
lyric = await getLyric(info["id"])
73-
except:
74-
lyric = None
59+
info = respBody["req"]["data"]["track_info"]
7560

7661
return SongInfo(
7762
songId=info.get("id"),
@@ -84,13 +69,8 @@ async def MidGetInfo(mid: str) -> SongInfo:
8469
),
8570
albumId=info.get("album", {}).get("id"),
8671
albumMid=info.get("album", {}).get("mid"),
87-
duration=(
88-
formatPlayTime(info.get("interval"))
89-
if info.get("interval") is not None
90-
else None
91-
),
72+
duration=info.get("interval", 0),
9273
mediaMid=info.get("file", {}).get("media_mid"),
93-
lyric=lyric,
9474
)
9575

9676

modules/info/wy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ujson
1+
from utils import orjson
22
from modules.lyric.wy import getLyric
33
from modules.plat.wy import eEncrypt
44
from server.models import SongInfo
@@ -11,7 +11,7 @@ async def getMusicInfo(songId: str):
1111
path = "/api/v3/song/detail"
1212
url = "http://interface.music.163.com/eapi/v3/song/detail"
1313
params = {
14-
"c": [ujson.dumps({"id": songId})],
14+
"c": [orjson.dumps({"id": songId})],
1515
"ids": [songId],
1616
}
1717
infoRequest = await HttpRequest(

0 commit comments

Comments
 (0)