2024-02-22 21:02:31 +08:00

1657 lines
71 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import flet
import ujson as json
import os
import ast
# from ChatGPT
def update_nested_json(json_obj, updates):
for key, value in updates.items():
if key in json_obj:
if isinstance(value, dict) and isinstance(json_obj[key], dict):
update_nested_json(json_obj[key], value)
elif isinstance(value, list) and isinstance(json_obj[key], list):
if len(value) == len(json_obj[key]):
for i in range(len(value)):
if isinstance(value[i], dict) and isinstance(
json_obj[key][i], dict
):
update_nested_json(json_obj[key][i], value[i])
else:
json_obj[key][i] = value[i]
else:
json_obj[key] = value
else:
json_obj[key] = value
else:
json_obj[key] = value
return json_obj
def toint(page: flet.Page, arg):
# def closeFailedDialog(e):
# failedDialog.open = False
# page.update()
# failedDialog = flet.AlertDialog(
# modal=True,
# title=flet.Text('Update failed', color='FF0000'),
# content=flet.Text('Please Check You Input\n\n'+str(arg)),
# actions=[flet.TextButton("OK", on_click=closeFailedDialog)],
# actions_alignment=flet.MainAxisAlignment.END,
# )
# def openFailedDialog():
# page.dialog = failedDialog
# failedDialog.open = True
# page.update()
try:
return int(arg)
except:
# openFailedDialog()
return None
def _Save(page: flet.Page, args):
def closeSuccessDialog(e):
successDialog.open = False
page.update()
successDialog = flet.AlertDialog(
modal=True,
title=flet.Text("Update success"),
content=flet.Text(
"Update Content: "
+ str(args)
+ "\n\nYour original config.json file have been rename configN.bak"
),
actions=[flet.TextButton("OK", on_click=closeSuccessDialog)],
actions_alignment=flet.MainAxisAlignment.END,
)
def openSuccessDialog():
page.dialog = successDialog
successDialog.open = True
page.update()
def closeFailedDialog(e):
failedDialog.open = False
page.update()
failedDialog = flet.AlertDialog(
modal=True,
title=flet.Text("Update failed", color="FF0000"),
content=flet.Text("Please Check You Input\n\n" + str(args)),
actions=[flet.TextButton("OK", on_click=closeFailedDialog)],
actions_alignment=flet.MainAxisAlignment.END,
)
def openFailedDialog():
page.dialog = failedDialog
failedDialog.open = True
page.update()
# print(args)
try:
with open("./data/config.json", "r+", encoding="utf-8") as f:
config = json.loads(f.read())
config = update_nested_json(config, args)
i = 1
while 1:
try:
os.rename("./data/config.json", f"config{i}.bak")
break
except:
i += 1
with open("./data/config.json", "w+", encoding="utf-8") as f:
f.write(
json.dumps(
config, indent=4, ensure_ascii=False, escape_forward_slashes=False
)
)
openSuccessDialog()
except:
openFailedDialog()
def _404(page: flet.Page):
return [
flet.Container(
content=flet.Text(value="404", size=50), alignment=flet.alignment.center
),
flet.Container(
content=flet.ElevatedButton("返回主页", on_click=lambda _: page.go("/")),
alignment=flet.alignment.center,
),
]
# def _Save_Cookiepool(page: flet.Page, p, v):
# return []
def CommonPage(page: flet.Page):
common = config["common"]
common_host_label = flet.TextField(
label="服务器启动时所使用的HOST地址", value=common["host"]
)
common_ports_label = flet.TextField(
label="服务器启动时所使用的端口,使用list格式", value=common["ports"]
)
common_ssl_info_label = flet.ElevatedButton(
"服务器https配置", on_click=lambda _: page.go("/common/ssl_info")
)
common_reverse_proxy_label = flet.ElevatedButton(
"针对类似于nginx一类的反代的配置",
on_click=lambda _: page.go("/common/reverse_proxy"),
)
common_debug_mode_label = flet.Checkbox(
label="是否开启调试模式", value=common["debug_mode"]
)
common_log_length_limit_label = flet.TextField(
label="单条日志长度限制", value=common["log_length_limit"]
)
common_fakeip_label = flet.TextField(
label="服务器在海外时的IP伪装值", value=common["fakeip"]
)
common_proxy_label = flet.ElevatedButton(
"代理配置HTTP与HTTPS协议需分开配置",
on_click=lambda _: page.go("/common/proxy"),
)
common_log_file_label = flet.Checkbox(
label="是否开启日志文件", value=bool(common["log_file"])
)
common_cookiepool_label = flet.Checkbox(
label="是否开启cookie池", value=bool(config["common"]["cookiepool"])
)
common_download_config_label = flet.ElevatedButton(
"下载脚本配置", on_click=lambda _: page.go("/common/download_config")
)
return [
common_host_label,
common_ports_label,
common_ssl_info_label,
common_reverse_proxy_label,
common_debug_mode_label,
common_log_length_limit_label,
common_fakeip_label,
common_proxy_label,
common_log_file_label,
common_cookiepool_label,
flet.Text("这将允许用户配置多个cookie并在请求时随机使用一个"),
flet.Text(
"启用后请在module.cookiepool中配置cookie在user处配置的cookie会被忽略"
),
flet.Text("cookiepool中格式统一为列表嵌套user处的cookie的字典"),
common_download_config_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"common": {
"host": str(common_host_label.value),
"ports": json.loads(
str(common_ports_label.value).replace("'", '"')
),
"debug_mode": bool(common_debug_mode_label.value),
"log_length_limit": toint(
page, common_log_length_limit_label.value
),
"fakeip": str(common_fakeip_label.value),
"log_file": bool(common_log_file_label.value),
"cookiepool": bool(common_cookiepool_label.value),
}
},
),
),
]
def CommonPageExpand(page: flet.Page):
if page.route.split("/")[2] == "ssl_info":
ssl_info = config["common"]["ssl_info"]
common_is_https_label = flet.Checkbox(
label="是否开启HTTPS", value=bool(ssl_info["is_https"])
)
common_enable_label = flet.Checkbox(
label="启用", value=bool(ssl_info["enable"])
)
common_ssl_ports_label = flet.TextField(
label="SSL端口,使用list格式", value=ssl_info["ssl_ports"]
)
common_path_cert_label = flet.TextField(
label="ssl证书的cert文件地址", value=ssl_info["path"]["cert"]
)
common_path_privkey_label = flet.TextField(
label="ssl证书的private key文件地址", value=ssl_info["path"]["privkey"]
)
return [
flet.Container(
content=flet.Text(value="SSL Info", size=30),
alignment=flet.alignment.center,
),
flet.Text(
'服务器https配置"是否开启HTTPS"是这个服务器是否是https服务器如果你使用了反向代理来转发这个服务器如果它使用了https也请将它设置为true'
),
common_is_https_label,
common_enable_label,
common_ssl_ports_label,
common_path_cert_label,
common_path_privkey_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/common")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"common": {
"ssl_info": {
"is_https": bool(common_is_https_label.value),
"enable": bool(common_enable_label.value),
"ssl_ports": json.loads(
str(common_ssl_ports_label.value).replace("'", '"')
),
"path": {
"cert": str(common_path_cert_label.value),
"privkey": str(common_path_privkey_label.value),
},
}
}
},
),
),
]
elif page.route.split("/")[2] == "reverse_proxy":
reverse_proxy = config["common"]["reverse_proxy"]
common_allow_proxy_label = flet.Checkbox(
label="是否允许反代", value=bool(reverse_proxy["allow_proxy"])
)
common_proxy_whitelist_remote_label = flet.TextField(
label="反代时允许的ip来源列表通常为127.0.0.1",
value=reverse_proxy["proxy_whitelist_remote"],
)
common_real_ip_header_label = flet.TextField(
label="反代来源ip的来源头不懂请保持默认",
value=reverse_proxy["real_ip_header"],
)
return [
flet.Container(
content=flet.Text(value="Reverse Proxy", size=30),
alignment=flet.alignment.center,
),
common_allow_proxy_label,
common_proxy_whitelist_remote_label,
common_real_ip_header_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/common")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"common": {
"reverse_proxy": {
"allow_proxy": bool(common_allow_proxy_label.value),
"proxy_whitelist_remote": json.loads(
str(
common_proxy_whitelist_remote_label.value
).replace("'", '"')
),
"real_ip_header": str(
common_real_ip_header_label.value
),
}
}
},
),
),
]
elif page.route.split("/")[2] == "proxy":
proxy = config["common"]["proxy"]
common_proxy_enable_label = flet.Checkbox(
label="是否开启代理", value=bool(proxy["enable"])
)
common_http_value_label = flet.TextField(
label="HTTP协议配置", value=proxy["http_value"]
)
common_https_value_label = flet.TextField(
label="HTTPS协议配置", value=proxy["https_value"]
)
return [
flet.Container(
content=flet.Text(value="Proxy", size=30),
alignment=flet.alignment.center,
),
# flet.AppBar(title=flet.Text('proxy'), bgcolor=flet.colors.SURFACE_VARIANT),
common_proxy_enable_label,
common_http_value_label,
common_https_value_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/common")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"common": {
"proxy": {
"enable": bool(common_proxy_enable_label.value),
"http_value": str(common_http_value_label.value),
"https_value": str(common_https_value_label.value),
}
}
},
),
),
]
elif page.route.split("/")[2] == "download_config":
download_config = config["common"]["download_config"]
common_allow_download_script_label = flet.Checkbox(
label="是否允许直接从服务端下载脚本,开启后可以直接访问 /script?key=你的请求key 下载脚本",
value=bool(config["common"]["allow_download_script"]),
)
common_name_label = flet.TextField(
label="修改为你的源脚本名称", value=download_config["name"]
)
common_intro_label = flet.TextField(
label="修改为你的源脚本描述", value=download_config["intro"]
)
common_author_label = flet.TextField(
label="修改为你的源脚本作者", value=download_config["author"]
)
common_version_label = flet.TextField(
label="修改为你的源版本", value=download_config["version"]
)
common_filename_label = flet.TextField(
label="客户端保存脚本时的文件名(可能因浏览器不同出现不一样的情况)",
value=download_config["filename"],
)
common_dev_label = flet.Checkbox(
label="是否启用开发模式", value=bool(download_config["dev"])
)
# common_quality_label = flet.Tabs(
# selected_index=0,
# animation_duration=300,
# tabs=[
# flet.Tab(
# text='kw',
# content=flet.Row(
# [
# flet.Checkbox(label="128k", value=True),
# flet.Checkbox(label="320k", value=False),
# flet.Checkbox(label="flac", value=False),
# flet.Checkbox(label="flac24bit", value=False),
# ]
# ),
# ),
# flet.Tab(
# text='kg',
# content=flet.Row(
# [
# flet.Checkbox(label="128k", value=True),
# flet.Checkbox(label="320k", value=False),
# flet.Checkbox(label="flac", value=False),
# flet.Checkbox(label="flac24bit", value=False),
# ]
# ),
# ),
# flet.Tab(
# text='tx',
# content=flet.Row(
# [
# flet.Checkbox(label="128k", value=True),
# flet.Checkbox(label="320k", value=False),
# flet.Checkbox(label="flac", value=False),
# flet.Checkbox(label="flac24bit", value=False),
# ]
# ),
# ),
# flet.Tab(
# text='wy',
# content=flet.Row(
# [
# flet.Checkbox(label="128k", value=True),
# flet.Checkbox(label="320k", value=False),
# flet.Checkbox(label="flac", value=False),
# flet.Checkbox(label="flac24bit", value=False),
# ]
# ),
# ),
# flet.Tab(
# text='mg',
# content=flet.Row(
# [
# flet.Checkbox(label="128k", value=True),
# flet.Checkbox(label="320k", value=False),
# flet.Checkbox(label="flac", value=False),
# flet.Checkbox(label="flac24bit", value=False),
# ]
# ),
# ),
# ],
# expand=1,
# )
common_quality_label = flet.TextField(
label="支持的音质", value=download_config["quality"]
)
return [
flet.Container(
content=flet.Text(value="源脚本的相关配置", size=30),
alignment=flet.alignment.center,
),
# flet.AppBar(title=flet.Text('源脚本的相关配置'), bgcolor=flet.colors.SURFACE_VARIANT),
common_allow_download_script_label,
common_name_label,
common_intro_label,
common_author_label,
common_version_label,
common_filename_label,
common_dev_label,
# flet.Text(value='支持的音质'),
common_quality_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/common")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"common": {
"allow_download_script": bool(
common_allow_download_script_label.value
),
"download_config": json.loads(
str(common_quality_label.value).replace("'", '"')
),
}
},
),
),
]
else:
return _404(page)
def SecurityPage(page: flet.Page):
security = config["security"]
security_rate_limit_label = flet.ElevatedButton(
"请求速率限制", on_click=lambda _: page.go("/security/rate_limit")
)
security_key_label = flet.ElevatedButton(
"请求key", on_click=lambda _: page.go("/security/key")
)
security_whitelist_host_label = flet.TextField(
label="强制白名单HOST", value=security["whitelist_host"]
)
security_check_lxm_label = flet.Checkbox(
label='是否检查lxm请求头正常的LX Music以"测试接口"的方式请求时都会携带这个请求头)',
value=bool(security["check_lxm"]),
)
security_lxm_ban_label = flet.Checkbox(
label="lxm请求头不存在或不匹配时是否将用户IP加入黑名单",
value=bool(security["lxm_ban"]),
)
security_allowed_host_label = flet.ElevatedButton(
"HOST允许列表", on_click=lambda _: page.go("/security/allowed_host")
)
security_banlist_label = flet.ElevatedButton(
"黑名单", on_click=lambda _: page.go("/security/banlist")
)
return [
security_rate_limit_label,
security_key_label,
security_whitelist_host_label,
security_lxm_ban_label,
security_check_lxm_label,
security_allowed_host_label,
security_banlist_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"security": {
"whitelist_host": json.loads(
str(security_whitelist_host_label.value).replace("'", '"')
),
"check_lxm": bool(security_check_lxm_label.value),
"lxm_ban": bool(security_lxm_ban_label.value),
}
},
),
),
]
def SecurityPageExpand(page: flet.Page):
if page.route.split("/")[2] == "rate_limit":
rate_limit = config["security"]["rate_limit"]
security_global_label = flet.TextField(
label="全局请求速率限制", value=rate_limit["global"]
)
security_ip_label = flet.TextField(
label="单个ip请求速率限制", value=rate_limit["ip"]
)
return [
flet.Container(
content=flet.Text(value="Rate Limit", size=30),
alignment=flet.alignment.center,
),
# flet.AppBar(title=flet.Text('ssl_info'), bgcolor=flet.colors.SURFACE_VARIANT),
flet.Text(
"请求速率限制填入的值为至少间隔多久才能进行一次请求单位不限制请填为0"
),
security_global_label,
security_ip_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/security")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"security": {
"rate_limit": {
"global": toint(page, security_global_label.value),
"ip": toint(page, security_ip_label.value),
}
}
},
),
),
]
elif page.route.split("/")[2] == "key":
key = config["security"]["key"]
security_key_enable_label = flet.Checkbox(
label="是否开启请求key开启后只有请求头中包含key且值一样时可以访问API",
value=bool(key["enable"]),
)
security_ban_label = flet.Checkbox(label="ban", value=bool(key["ban"]))
security_values_label = flet.TextField(
label="key(使用列表格式)", value=key["values"]
)
return [
flet.Container(
content=flet.Text(value="Key", size=30), alignment=flet.alignment.center
),
# flet.AppBar(title=flet.Text('ssl_info'), bgcolor=flet.colors.SURFACE_VARIANT),
security_key_enable_label,
security_ban_label,
security_values_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/security")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"security": {
"key": {
"enable": bool(security_key_enable_label.value),
"ban": bool(security_ban_label.value),
"value": json.loads(
str(security_values_label.value).replace("'", '"')
),
}
}
},
),
),
]
elif page.route.split("/")[2] == "allowed_host":
allowed_host = config["security"]["allowed_host"]
security_allowed_host_enable_label = flet.Checkbox(
label="启用", value=bool(allowed_host["enable"])
)
security_list_label = flet.TextField(label="列表", value=allowed_host["list"])
security_blacklist_enable_label = flet.Checkbox(
label="启用", value=bool(allowed_host["blacklist"]["enable"])
)
security_blacklist_length_label = flet.TextField(
label="长度", value=allowed_host["blacklist"]["length"]
)
return [
flet.Container(
content=flet.Text(value="Allowd Host", size=30),
alignment=flet.alignment.center,
),
# flet.AppBar(title=flet.Text('ssl_info'), bgcolor=flet.colors.SURFACE_VARIANT),
flet.Text(
"HOST允许列表启用后只允许列表内的HOST访问服务器不需要加端口号"
),
security_allowed_host_enable_label,
security_list_label,
flet.Text(
"当用户访问的HOST并不在允许列表中时是否将请求IP加入黑名单长度单位"
),
security_blacklist_enable_label,
security_blacklist_length_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/security")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"security": {
"allowed_host": {
"enable": bool(
security_allowed_host_enable_label.value
),
"blacklist": {
"enable": bool(
security_blacklist_enable_label.value
),
"length": toint(
page, security_blacklist_length_label.value
),
},
"list": json.loads(
str(security_list_label.value).replace("'", '"')
),
}
}
},
),
),
]
elif page.route.split("/")[2] == "banlist":
banlist = config["security"]["banlist"]
security_banlist_enable_label = flet.Checkbox(
label="启用", value=bool(banlist["enable"])
)
security_expire_enable_label = flet.Checkbox(
label="启用", value=bool(banlist["expire"]["enable"])
)
security_expire_length_label = flet.TextField(
label="长度", value=banlist["expire"]["length"]
)
return [
flet.Container(
content=flet.Text(value="Ban List", size=30),
alignment=flet.alignment.center,
),
# flet.AppBar(title=flet.Text('ssl_info'), bgcolor=flet.colors.SURFACE_VARIANT),
flet.Text(
"是否启用黑名单(全局设置,关闭后已存储的值并不受影响,但不会再检查"
),
security_banlist_enable_label,
flet.Text("是否启用黑名单IP过期关闭后其他地方的配置会失效"),
security_expire_enable_label,
security_expire_length_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/security")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"security": {
"banlist": {
"enable": bool(security_banlist_enable_label.value),
"expire": {
"enable": bool(security_expire_enable_label),
"length": toint(
page, security_expire_length_label.value
),
},
}
}
},
),
),
]
return [flet.ElevatedButton("返回", on_click=lambda _: page.go("/security"))]
def ModulePage(page: flet.Page):
kg_label = flet.ElevatedButton("kg", on_click=lambda _: page.go("/module/kg"))
tx_label = flet.ElevatedButton("tx", on_click=lambda _: page.go("/module/tx"))
wy_label = flet.ElevatedButton("wy", on_click=lambda _: page.go("/module/wy"))
mg_label = flet.ElevatedButton("mg", on_click=lambda _: page.go("/module/mg"))
kw_label = flet.ElevatedButton("kw", on_click=lambda _: page.go("/module/kw"))
cookiepool_label = flet.ElevatedButton(
"cookiepool", on_click=lambda _: page.go("/module/cookiepool")
)
return [
kg_label,
tx_label,
wy_label,
mg_label,
kw_label,
cookiepool_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/")),
]
def ModulePageExpand(page: flet.Page):
if page.route.split("/")[2] == "kg":
if page.route.split("/")[-1] == "kg":
return [
flet.Container(
content=flet.Text(value="酷狗音乐相关配置", size=30),
alignment=flet.alignment.center,
),
flet.ElevatedButton(
"client", on_click=lambda _: page.go("/module/kg/client")
),
flet.ElevatedButton(
"tracker", on_click=lambda _: page.go("/module/kg/tracker")
),
flet.ElevatedButton(
"user", on_click=lambda _: page.go("/module/kg/user")
),
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
]
else:
if page.route.split("/")[3] == "client":
kg_client = config["module"]["kg"]["client"]
module_kg_client_appid_label = flet.TextField(
label="酷狗音乐的appid官方安卓为1005官方PC为1001",
value=kg_client["appid"],
)
module_kg_client_signatureKey_label = flet.TextField(
label="客户端signature采用的key值需要与appid对应",
value=kg_client["signatureKey"],
)
module_kg_client_clientver_label = flet.TextField(
label="客户端versioncodepidversionsecret可能随此值而变化",
value=kg_client["clientver"],
)
module_kg_client_pidversionsecret_label = flet.TextField(
label="获取URL时所用的key值计算验证值",
value=kg_client["pidversionsecret"],
)
module_kg_client_pid_label = flet.TextField(
label="pid", value=kg_client["pid"]
)
return [
flet.Container(
content=flet.Text(
value="客户端请求配置,不懂请保持默认", size=30
),
alignment=flet.alignment.center,
),
module_kg_client_appid_label,
module_kg_client_signatureKey_label,
module_kg_client_clientver_label,
module_kg_client_pidversionsecret_label,
module_kg_client_pid_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/kg")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"kg": {
"client": {
"appid": str(
module_kg_client_appid_label.value
),
"signatureKey": str(
module_kg_client_signatureKey_label.value
),
"clientver": str(
module_kg_client_clientver_label.value
),
"pidversionsecret": str(
module_kg_client_pidversionsecret_label.value
),
"pid": str(
module_kg_client_pid_label.value
),
}
}
}
},
),
),
]
elif page.route.split("/")[3] == "tracker":
kg_tracker = config["module"]["kg"]["tracker"]
module_kg_tracker_host_label = flet.TextField(
label="host", value=kg_tracker["host"]
)
module_kg_tracker_path_label = flet.TextField(
label="path", value=kg_tracker["path"]
)
module_kg_tracker_version_label = flet.TextField(
label="客户端versioncodepidversionsecret可能随此值而变化",
value=kg_tracker["version"],
)
module_kg_tracker_xrouter_enable_label = flet.Checkbox(
label="启用", value=bool(kg_tracker["x-router"]["enable"])
)
module_kg_tracker_xrouter_value_label = flet.TextField(
label="x-router", value=kg_tracker["x-router"]["value"]
)
module_kg_tracker_extra_params_label = flet.TextField(
label="自定义添加的param优先级大于默认填写类型为普通的JSON数据会自动转换为请求param",
value=kg_tracker["extra_params"],
)
return [
flet.Container(
content=flet.Text(
value="trackerapi请求配置不懂请保持默认", size=30
),
alignment=flet.alignment.center,
),
module_kg_tracker_host_label,
module_kg_tracker_path_label,
module_kg_tracker_version_label,
flet.Text(
"当host为gateway.kugou.com时需要追加此头为tracker类地址时则不需要"
),
module_kg_tracker_xrouter_enable_label,
module_kg_tracker_xrouter_value_label,
module_kg_tracker_extra_params_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/kg")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"kg": {
"tracker": {
"host": str(
module_kg_tracker_host_label.value
),
"path": str(
module_kg_tracker_path_label.value
),
"version": str(
module_kg_tracker_version_label.value
),
"x-router": {
"enable": bool(
module_kg_tracker_xrouter_enable_label.value
),
"value": str(
module_kg_tracker_xrouter_value_label.value
),
},
"extra_params": json.loads(
str(
module_kg_tracker_extra_params_label.value
).replace("'", '"')
),
}
}
}
},
),
),
]
elif page.route.split("/")[3] == "user":
kg_user = config["module"]["kg"]["user"]
module_kg_user_token_label = flet.TextField(
label="token", value=kg_user["token"]
)
module_kg_user_userid_label = flet.TextField(
label="userid", value=kg_user["userid"]
)
module_kg_user_mid_label = flet.TextField(
label="mid", value=kg_user["mid"]
)
module_kg_user_lite_sign_in_enable_label = flet.Checkbox(
label="启用", value=bool(kg_user["lite_sign_in"]["enable"])
)
module_kg_user_lite_sign_in_interval_label = flet.TextField(
label="interval", value=kg_user["lite_sign_in"]["interval"]
)
module_kg_user_lite_sign_in_mixsongmid_label = flet.TextField(
label="mix_songmid的获取方式, 默认auto, 可以改成一个数字手动",
value=kg_user["lite_sign_in"]["mixsongmid"]["value"],
)
return [
flet.Container(
content=flet.Text(
value="此处内容请统一抓包获取需要vip账号来获取会员歌曲如果没有请留为空值mid必填可以瞎填一段数字",
size=30,
),
alignment=flet.alignment.center,
),
module_kg_user_token_label,
module_kg_user_userid_label,
module_kg_user_mid_label,
flet.Text("是否启用概念版自动签到仅在appid=3116时运行"),
module_kg_user_lite_sign_in_enable_label,
module_kg_user_lite_sign_in_interval_label,
module_kg_user_lite_sign_in_mixsongmid_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/kg")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"kg": {
"user": {
"token": str(
module_kg_user_token_label.value
),
"userid": str(
module_kg_user_userid_label.value
),
"mid": str(module_kg_user_mid_label.value),
"lite_sign_in": {
"enable": bool(
module_kg_user_lite_sign_in_enable_label.value
),
"interval": toint(
page,
module_kg_user_lite_sign_in_interval_label.value,
),
"mixsongmid": {
"value": str(
module_kg_user_lite_sign_in_mixsongmid_label.value
)
},
},
}
}
}
},
),
),
]
else:
return _404(page)
elif page.route.split("/")[2] == "tx":
if page.route.split("/")[-1] == "tx":
module_tx_cdnaddr_label = flet.TextField(
label="CDN地址", value=config["module"]["tx"]["cdnaddr"]
)
return [
flet.Container(
content=flet.Text(value="QQ音乐相关配置", size=30),
alignment=flet.alignment.center,
),
flet.ElevatedButton(
"vkeyserver", on_click=lambda _: page.go("/module/tx/vkeyserver")
),
flet.ElevatedButton(
"user", on_click=lambda _: page.go("/module/tx/user")
),
module_tx_cdnaddr_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"tx": {"cdnaddr": str(module_tx_cdnaddr_label.value)}
}
},
),
),
]
else:
if page.route.split("/")[3] == "vkeyserver":
tx_vkeyserver = config["module"]["tx"]["vkeyserver"]
module_tx_vkeyserver_guid_label = flet.TextField(
label="guid", value=tx_vkeyserver["guid"]
)
module_tx_vkeyserver_uin_label = flet.TextField(
label="uin", value=tx_vkeyserver["uin"]
)
return [
flet.Container(
content=flet.Text(
value="请求官方api时使用的guiduin等信息不需要与cookie中信息一致",
size=30,
),
alignment=flet.alignment.center,
),
module_tx_vkeyserver_guid_label,
module_tx_vkeyserver_uin_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/tx")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"tx": {
"vkeyserver": {
"guid": str(
module_tx_vkeyserver_guid_label.value
),
"uin": str(
module_tx_vkeyserver_uin_label.value
),
}
}
}
},
),
),
]
elif page.route.split("/")[3] == "user":
tx_user = config["module"]["tx"]["user"]
module_tx_user_qqmusic_key_label = flet.TextField(
label="qqmusic_key 可以从Cookie中/客户端的请求体中comm.authst获取",
value=tx_user["qqmusic_key"],
)
module_tx_user_uin_label = flet.TextField(
label="key对应的QQ号", value=tx_user["uin"]
)
module_tx_user_refresh_login_enable_label = flet.Checkbox(
label="启用", value=bool(tx_user["refresh_login"]["enable"])
)
module_tx_user_refresh_login_interval_label = flet.TextField(
label="interval刷新间隔", value=tx_user["refresh_login"]["interval"]
)
return [
flet.Container(
content=flet.Text(
value="用户数据可以通过浏览器获取需要vip账号来获取会员歌曲如果没有请留为空值",
size=30,
),
alignment=flet.alignment.center,
),
module_tx_user_qqmusic_key_label,
module_tx_user_uin_label,
flet.Text("刷新登录相关配置"),
module_tx_user_refresh_login_enable_label,
module_tx_user_refresh_login_interval_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/tx")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"tx": {
"user": {
"qqmusic_key": str(
module_tx_user_qqmusic_key_label.value
),
"uin": str(module_tx_user_uin_label.value),
"refresh_login": {
"enable": bool(
module_tx_user_refresh_login_enable_label.value
),
"interval": toint(
page,
module_tx_user_refresh_login_interval_label.value,
),
},
}
}
}
},
),
),
]
elif page.route.split("/")[2] == "wy":
module_wy_cookie_label = flet.TextField(
label="cookie", value=config["module"]["wy"]["user"]["cookie"]
)
return [
flet.Container(
content=flet.Text(value="网易云音乐相关配置", size=30),
alignment=flet.alignment.center,
),
flet.Text(
"账号cookie数据可以通过浏览器获取需要vip账号来获取会员歌曲如果没有请留为空值"
),
module_wy_cookie_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"wy": {
"user": {"cookie": str(module_wy_cookie_label.value)}
}
}
},
),
),
]
elif page.route.split("/")[2] == "mg":
mg_user = config["module"]["mg"]["user"]
module_mg_aversionid_label = flet.TextField(
label="aversionid", value=mg_user["aversionid"]
)
module_mg_token_label = flet.TextField(label="token", value=mg_user["token"])
module_mg_osversion_label = flet.TextField(
label="osversion", value=mg_user["osversion"]
)
module_mg_useragent_label = flet.TextField(
label="useragent", value=mg_user["useragent"]
)
return [
flet.Container(
content=flet.Text(value="咪咕音乐相关配置", size=30),
alignment=flet.alignment.center,
),
module_mg_aversionid_label,
module_mg_token_label,
module_mg_osversion_label,
module_mg_useragent_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"mg": {
"user": {
"aversionid": str(module_mg_aversionid_label.value),
"token": str(module_mg_token_label.value),
"osversion": str(module_mg_osversion_label.value),
"useragent": str(module_mg_useragent_label.value),
}
}
}
},
),
),
]
elif page.route.split("/")[2] == "kw":
if page.route.split("/")[-1] == "kw":
module_kw_proto_label = flet.Dropdown(
# width=100,
options=[
flet.dropdown.Option("bd-api"),
flet.dropdown.Option("kuwodes"),
],
value=config["module"]["kw"]["proto"],
)
return [
flet.Container(
content=flet.Text(value="酷我音乐相关配置", size=30),
alignment=flet.alignment.center,
),
flet.Text("在下方选择proto值"),
module_kw_proto_label,
flet.ElevatedButton(
"user", on_click=lambda _: page.go("/module/kw/user")
),
flet.ElevatedButton(
"des", on_click=lambda _: page.go("/module/kw/des")
),
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{"module": {"kw": {"proto": str(module_kw_proto_label.value)}}},
),
),
]
else:
if page.route.split("/")[3] == "user":
kw_user = config["module"]["kw"]["user"]
module_kw_user_uid_label = flet.TextField(
label="uid", value=kw_user["uid"]
)
module_kw_user_token_label = flet.TextField(
label="token", value=kw_user["token"]
)
module_kw_user_device_id_label = flet.TextField(
label="device_id", value=kw_user["device_id"]
)
return [
flet.Container(
content=flet.Text(value="User", size=30),
alignment=flet.alignment.center,
),
module_kw_user_uid_label,
module_kw_user_token_label,
module_kw_user_device_id_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/kw")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"kw": {
"user": {
"uid": str(module_kw_user_uid_label.value),
"token": str(
module_kw_user_token_label.value
),
"device_id": str(
module_kw_user_device_id_label.value
),
}
}
}
},
),
),
]
elif page.route.split("/")[3] == "des":
kw_des = config["module"]["kw"]["des"]
module_kw_des_f_label = flet.TextField(label="f", value=kw_des["f"])
module_kw_des_need_encrypt_label = flet.Checkbox(
label="need_encrypt", value=bool(kw_des["need_encrypt"])
)
module_kw_des_params_label = flet.TextField(
label="params", value=kw_des["params"]
)
module_kw_des_host_label = flet.TextField(
label="host", value=kw_des["host"]
)
module_kw_des_path_label = flet.TextField(
label="path", value=kw_des["path"]
)
module_kw_des_response_type_label = flet.Dropdown(
# width=100,
options=[
flet.dropdown.Option("json"),
flet.dropdown.Option("text"),
],
value=kw_des["response_type"],
)
module_kw_des_url_json_path_label = flet.TextField(
label="url_json_path", value=kw_des["url_json_path"]
)
module_kw_des_bitrate_json_path_label = flet.TextField(
label="bitrate_json_path", value=kw_des["bitrate_json_path"]
)
module_kw_des_headers_label = flet.TextField(
label="headers", value=kw_des["headers"]
)
return [
flet.Container(
content=flet.Text(
value="kuwodes接口mobi, nmobi一类的加密相关配置",
size=30,
),
alignment=flet.alignment.center,
),
module_kw_des_f_label,
module_kw_des_need_encrypt_label,
flet.Text(
"param填写注释: {songId}为歌曲id, {map_quality}为map后的歌曲音质酷我规范, {raw_quality}为请求时的歌曲音质LX规范, {ext}为歌曲文件扩展名"
),
module_kw_des_params_label,
module_kw_des_host_label,
module_kw_des_path_label,
flet.Text(
"当设置为json时会使用到下面的两个值来获取url/bitrate如果为text则为传统的逐行解析方式"
),
module_kw_des_response_type_label,
module_kw_des_url_json_path_label,
module_kw_des_bitrate_json_path_label,
module_kw_des_headers_label,
flet.ElevatedButton(
"返回", on_click=lambda _: page.go("/module/kw")
),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"kw": {
"des": {
"f": str(module_kw_des_f_label.value),
"need_encrypt": bool(
module_kw_des_need_encrypt_label.value
),
"params": str(
module_kw_des_params_label.value
),
"host": str(module_kw_des_host_label.value),
"path": str(module_kw_des_path_label.value),
"response_type": str(
module_kw_des_response_type_label.value
),
"url_json_path": str(
module_kw_des_url_json_path_label.value
),
"bitrate_json_path": str(
module_kw_des_bitrate_json_path_label.value
),
"headers": json.loads(
str(
module_kw_des_headers_label.value
).replace("'", '"')
),
}
}
}
},
),
),
]
elif page.route.split("/")[2] == "cookiepool":
if page.route.split("/")[-1] == "cookiepool":
cookiepool = config["module"]["cookiepool"]
# module_cookiepool_kg_label = flet.ElevatedButton(
# "kg", on_click=lambda _: page.go("/module/cookiepool/kg")
# )
# module_cookiepool_tx_label = flet.ElevatedButton(
# "tx", on_click=lambda _: page.go("/module/cookiepool/tx")
# )
# module_cookiepool_wy_label = flet.ElevatedButton(
# "wy", on_click=lambda _: page.go("/module/cookiepool/wy")
# )
# module_cookiepool_mg_label = flet.ElevatedButton(
# "mg", on_click=lambda _: page.go("/module/cookiepool/mg")
# )
# module_cookiepool_kw_label = flet.ElevatedButton(
# "kw", on_click=lambda _: page.go("/module/cookiepool/kw")
# )
module_cookiepool_kg_label = flet.TextField(
label="kg", value=str(cookiepool["kg"])
)
module_cookiepool_tx_label = flet.TextField(
label="tx", value=str(cookiepool["tx"])
)
module_cookiepool_wy_label = flet.TextField(
label="wy", value=str(cookiepool["wy"])
)
module_cookiepool_mg_label = flet.TextField(
label="mg", value=str(cookiepool["mg"])
)
module_cookiepool_kw_label = flet.TextField(
label="kw", value=str(cookiepool["kw"])
)
# print(str(module_cookiepool_kg_label.value).replace("'", '"'))
return [
flet.Container(
content=flet.Text(value="Cookie Pool", size=30),
alignment=flet.alignment.center,
),
module_cookiepool_kg_label,
module_cookiepool_tx_label,
module_cookiepool_wy_label,
module_cookiepool_mg_label,
module_cookiepool_kw_label,
flet.ElevatedButton("返回", on_click=lambda _: page.go("/module")),
flet.ElevatedButton(
"保存",
on_click=lambda _: _Save(
page,
{
"module": {
"cookiepool": {
# 这里应该用json.loads, 但是一直报错, 索性直接用ast.literal_eval了
"kg": ast.literal_eval(
str(module_cookiepool_kg_label.value).replace(
"'", '"'
)
),
"tx": ast.literal_eval(
str(module_cookiepool_tx_label.value).replace(
"'", '"'
)
),
"wy": ast.literal_eval(
str(module_cookiepool_wy_label.value).replace(
"'", '"'
)
),
"mg": ast.literal_eval(
str(module_cookiepool_mg_label.value).replace(
"'", '"'
)
),
"kw": ast.literal_eval(
str(module_cookiepool_kw_label.value).replace(
"'", '"'
)
),
}
}
},
),
),
]
# else:
# # todo 还没写完
# # 想用列表一一对应的方式, 感觉也不太好, 以后重构(也许)再说吧
# if page.route.split("/")[3] == "kg":
# cookiepool_kg = config["module"]["cookiepool"]["kg"]
# cookiepool_kg_userid = []
# for i in cookiepool_kg:
# cookiepool_kg_userid.append(i["userid"])
# cookiepool_kg_token = []
# for i in cookiepool_kg:
# cookiepool_kg_token.append(i["token"])
# cookiepool_kg_mid = []
# for i in cookiepool_kg:
# cookiepool_kg_mid.append(i["mid"])
# cookiepool_kg_lite_sign_in_enable = []
# for i in cookiepool_kg:
# cookiepool_kg_lite_sign_in_enable.append(
# i["lite_sign_in"]["enable"]
# )
# cookiepool_kg_lite_sign_in_interval = []
# for i in cookiepool_kg:
# cookiepool_kg_lite_sign_in_interval.append(
# i["lite_sign_in"]["interval"]
# )
# cookiepool_kg_lite_sign_in_mixsongmid = []
# for i in cookiepool_kg:
# cookiepool_kg_lite_sign_in_mixsongmid.append(
# i["lite_sign_in"]["mixsongmid"]["value"]
# )
# module_cookiepool_kg_userid_label = flet.TextField(
# label="userid", value=cookiepool_kg_userid
# )
# module_cookiepool_kg_token_label = flet.TextField(
# label="token", value=cookiepool_kg_token
# )
# module_cookiepool_kg_mid_label = flet.TextField(
# label="mid", value=cookiepool_kg_mid
# )
# module_cookiepool_kg_lite_sign_in_enable_label = flet.TextField(
# label="启用", value=cookiepool_kg_lite_sign_in_enable
# )
# module_cookiepool_kg_lite_sign_in_interval_label = flet.TextField(
# label="interval", value=cookiepool_kg_lite_sign_in_interval
# )
# module_cookiepool_kg_lite_sign_in_mixsongmid_label = flet.TextField(
# label="mix_songmid的获取方式, 默认auto, 可以改成一个数字手动",
# value=cookiepool_kg_lite_sign_in_mixsongmid,
# )
# return [
# flet.Container(
# content=flet.Text(value="Cookie Pool KG", size=30),
# alignment=flet.alignment.center,
# ),
# flet.Text("使用列表格式,请一一对应"),
# module_cookiepool_kg_userid_label,
# module_cookiepool_kg_token_label,
# module_cookiepool_kg_mid_label,
# module_cookiepool_kg_lite_sign_in_enable_label,
# module_cookiepool_kg_lite_sign_in_interval_label,
# module_cookiepool_kg_lite_sign_in_mixsongmid_label,
# flet.ElevatedButton(
# "返回", on_click=lambda _: page.go("/module/cookiepool")
# ),
# flet.ElevatedButton(
# "保存",
# on_click=lambda _: _Save_Cookiepool(
# page,
# "kg",
# {
# "module": {
# "cookiepool": {
# "kg": {
# "userid": json.loads(
# str(
# module_cookiepool_kg_userid_label.value
# ).replace("'", '"')
# ),
# "token": json.loads(
# str(
# module_cookiepool_kg_token_label.value
# ).replace("'", '"')
# ),
# "mid": json.loads(
# str(
# module_cookiepool_kg_mid_label.value
# ).replace("'", '"')
# ),
# "lite_sign_in_enable": json.loads(
# str(
# module_cookiepool_kg_lite_sign_in_enable_label.value
# ).replace("'", '"')
# ),
# "lite_sign_in_interval": json.loads(
# str(
# module_cookiepool_kg_lite_sign_in_interval_label.value
# ).replace("'", '"')
# ),
# "lite_sign_in_mixsongmid": json.loads(
# str(
# module_cookiepool_kg_lite_sign_in_mixsongmid_label.value
# ).replace("'", '"')
# ),
# }
# }
# }
# },
# ),
# ),
# ]
# else:
# return _404(page)
return _404(page)
def main(page: flet.Page):
mainKeys = list(config.keys())
page.title = "LX Music API Server WebUI"
def route_change(route):
page.views.clear()
page.scroll = "AUTO"
page.views.append(
flet.View(
"/",
[
flet.Container(
content=flet.Text(
"在下方配置你的config", size=30
),
alignment=flet.alignment.center,
),
flet.Container(
content=flet.Row(
[
flet.ElevatedButton(
mainKeys[0],
on_click=lambda _: page.go(f"/{mainKeys[0]}"),
),
flet.ElevatedButton(
mainKeys[1],
on_click=lambda _: page.go(f"/{mainKeys[1]}"),
),
flet.ElevatedButton(
mainKeys[2],
on_click=lambda _: page.go(f"/{mainKeys[2]}"),
),
],
alignment=flet.MainAxisAlignment.CENTER,
),
alignment=flet.alignment.center,
),
],
)
)
if page.route.split("/")[1] in mainKeys:
if page.route[1:] == "common":
page.views.append(flet.View(f"/{page.route[1:]}", CommonPage(page)))
elif page.route[1:] == "security":
page.views.append(flet.View(f"/{page.route[1:]}", SecurityPage(page)))
elif page.route[1:] == "module":
page.views.append(flet.View(f"/{page.route[1:]}", ModulePage(page)))
elif page.route.split("/")[1] == mainKeys[0]:
page.views.append(
flet.View(
f"/{mainKeys[0]}/{page.route.split('/')[2]}",
CommonPageExpand(page),
)
)
elif page.route.split("/")[1] == mainKeys[1]:
page.views.append(
flet.View(
f"/{mainKeys[1]}/{page.route.split('/')[2]}",
SecurityPageExpand(page),
)
)
elif page.route.split("/")[1] == mainKeys[2]:
page.views.append(
flet.View(
f"/{mainKeys[2]}/{page.route.split('/')[2]}",
ModulePageExpand(page),
)
)
elif page.route != "/":
# print(page.route)
page.views.append(
flet.View(
f"/404",
_404(page),
)
)
page.update()
page.on_route_change = route_change
page.go(page.route)
if __name__ == "__main__":
try:
with open("./data/config.json", "r+", encoding="utf-8") as f:
config = json.loads(f.read())
except:
print("无法找到config.json,请先运行main.py生成config.json")
flet.app(target=main)
# flet.app(target=main, view=flet.AppView.WEB_BROWSER)