diff --git a/README.md b/README.md index a665122..d77ffbb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ - [ ] 完整性API(歌单,搜索) - [ ] 网易云刷新登录 - [ ] 服务器向webdav - - [ ] WebUI - [x] 客户端播放服务器上的本地音乐 - [x] Cookie池 - [x] https监听,多端口监听 diff --git a/README_EN.md b/README_EN.md index 8d79f60..9f48462 100644 --- a/README_EN.md +++ b/README_EN.md @@ -23,7 +23,6 @@ You can find the corresponding available source scripts in the original reposito - [ ] All APIs (playlist, search) - [ ] Netease Cloud Refresh Login - [ ] Client plays music on webdav - - [ ] WebUI - [x] Client plays local music on the server - [x] Cookie pool - [x] HTTPS listening, multi port listening diff --git a/webui.py b/webui.py deleted file mode 100644 index f6e37f1..0000000 --- a/webui.py +++ /dev/null @@ -1,1656 +0,0 @@ -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("./config/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("./config/config.json", f"./config/config{i}.bak") - break - except: - i += 1 - - with open("./config/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="客户端versioncode,pidversionsecret可能随此值而变化", - 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="客户端versioncode,pidversionsecret可能随此值而变化", - 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时使用的guid,uin等信息,不需要与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("./config/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)