From 089da0eaae2628eff00e4b11379c797c78e37d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=9A=E9=A3=8E=E6=8B=82=E6=9F=B3=E9=A2=9C?= <434857005@qq.com> Date: Fri, 9 Jun 2023 15:10:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/admin.py | 124 ++++++++++++++++++++++----------- doc/更新日志.md | 3 + js/version.txt | 2 +- templates/edit_rule.html | 144 +++++++++++++++++++++++++++------------ 4 files changed, 187 insertions(+), 86 deletions(-) diff --git a/controllers/admin.py b/controllers/admin.py index 8cc2dfe..9da33a0 100644 --- a/controllers/admin.py +++ b/controllers/admin.py @@ -6,17 +6,17 @@ import os import ujson -from flask import Blueprint,request,render_template,render_template_string,jsonify,make_response,redirect -from controllers.service import storage_service,rules_service,parse_service +from flask import Blueprint, request, render_template, render_template_string, jsonify, make_response, redirect +from controllers.service import storage_service, rules_service, parse_service from base.R import R from base.database import db from utils.log import logger import shutil -from utils.update import getLocalVer,getOnlineVer,download_new_version,download_lives,copy_to_update +from utils.update import getLocalVer, getOnlineVer, download_new_version, download_lives, copy_to_update from utils import parser -from utils.env import get_env,update_env -from utils.web import getParmas,verfy_token -from js.rules import getRules,getCacheCount +from utils.env import get_env, update_env +from utils.web import getParmas, verfy_token +from js.rules import getRules, getCacheCount from utils.parser import runJScode from werkzeug.utils import secure_filename from utils.web import md5 @@ -24,6 +24,7 @@ from utils.common_api import js_render admin = Blueprint("admin", __name__) + # @admin.route("/",methods=['get']) # def index(): # return R.ok(msg='欢迎进入首页',data=None) @@ -46,7 +47,9 @@ def admin_index(): # 管理员界面 # print(rules) cache_count = getCacheCount() # print(cache_count) - return render_template('admin.html',js0_password=js0_password, pystate=use_py,rules=rules,cache_count=cache_count, ver=getLocalVer(), live_url=live_url) + return render_template('admin.html', js0_password=js0_password, pystate=use_py, rules=rules, + cache_count=cache_count, ver=getLocalVer(), live_url=live_url) + @admin.route('/settings') def admin_settings(): # 管理员界面 @@ -56,9 +59,10 @@ def admin_settings(): # 管理员界面 # conf_list = 'LIVE_URL|USE_PY|PLAY_URL|PLAY_DISABLE|LAZYPARSE_MODE|WALL_PAPER_ENABLE|WALL_PAPER|UNAME|PWD|LIVE_MODE|LIVE_URL|CATE_EXCLUDE|TAB_EXCLUDE'.split('|') conf_lists = lsg.getStoreConf() # print(conf_lists) - return render_template('settings.html', conf_lists=conf_lists,ver=getLocalVer()) + return render_template('settings.html', conf_lists=conf_lists, ver=getLocalVer()) -@admin.route('/save_conf',methods=['POST']) + +@admin.route('/save_conf', methods=['POST']) def admin_save_conf(): # 管理员界面 if not verfy_token(): # return render_template('login.html') @@ -67,10 +71,11 @@ def admin_save_conf(): # 管理员界面 value = getParmas('value') print(f'key:{key},value:{value}') lsg = storage_service() - res_id = lsg.setItem(key,value) + res_id = lsg.setItem(key, value) return R.success(f'修改成功,记录ID为:{res_id}') -@admin.route('/update_env',methods=['POST']) + +@admin.route('/update_env', methods=['POST']) def admin_update_env(): # 更新环境变量中的某个值 if not verfy_token(): # return render_template('login.html') @@ -78,17 +83,39 @@ def admin_update_env(): # 更新环境变量中的某个值 key = getParmas('key') value = getParmas('value') print(f'key:{key},value:{value}') - ENV = update_env(key,value) - return R.success(f'修改成功,最新的完整ENV见data',data=ENV) + ENV = update_env(key, value) + return R.success(f'修改成功,最新的完整ENV见data', data=ENV) -@admin.route("/edit/",methods=['GET']) + +@admin.route("/edit/", methods=['GET']) def admin_edit_rule(name): # print(name) if not verfy_token(): return render_template('login.html') return render_template('edit_rule.html', name=name) -@admin.route("/view/",methods=['GET']) + +@admin.route("/save_edit/", methods=['POST']) +def admin_save_edit_rule(name): + # print(name) + if not verfy_token(): + return R.error('请登录后再试') + + code = getParmas('code') + file_path = os.path.abspath(f'js/{name}') + if 'var rule' not in code and name != '模板.js': + return R.error(f'文件{name}保存失败,未检测到关键词:var rule') + if not os.path.exists(file_path): + return R.error('服务端没有此文件!' + file_path) + + logger.info(f'待保存文件路径:{file_path}') + with open(file_path, mode='w+', encoding='utf-8') as f: + f.write(code) + + return R.success(f'保存成功') + + +@admin.route("/view/", methods=['GET']) def admin_view_rule(name): return js_render(name) # if not name or not name.split('.')[-1] in ['js','txt','py','json']: @@ -123,9 +150,10 @@ def admin_view_rule(name): # except Exception as e: # return R.error(f'非法猥亵\n{e}') + @admin.route('/clear/') def admin_clear_rule(name): - if not name or not name.split('.')[-1] in ['js','txt','py','json']: + if not name or not name.split('.')[-1] in ['js', 'txt', 'py', 'json']: return R.error(f'非法猥亵,未指定文件名。必须包含js|txt|json|py') if not verfy_token(): return render_template('login.html') @@ -133,9 +161,10 @@ def admin_clear_rule(name): file_path = os.path.abspath(f'js/{name}') print(file_path) if not os.path.exists(file_path): - return R.error('服务端没有此文件!'+file_path) + return R.error('服务端没有此文件!' + file_path) os.remove(file_path) - return R.ok('成功删除文件:'+file_path) + return R.ok('成功删除文件:' + file_path) + @admin.route('/get_ver') def admin_get_ver(): @@ -144,8 +173,9 @@ def admin_get_ver(): return R.error('请登录后再试') lsg = storage_service() update_proxy = lsg.getItem('UPDATE_PROXY') - online_ver,msg = getOnlineVer(update_proxy) - return jsonify({'local_ver':getLocalVer(),'online_ver':online_ver,'msg':msg}) + online_ver, msg = getOnlineVer(update_proxy) + return jsonify({'local_ver': getLocalVer(), 'online_ver': online_ver, 'msg': msg}) + @admin.route('/update_db') def admin_update_db(): @@ -159,12 +189,13 @@ def admin_update_db(): db.session.execute('drop table if exists alembic_version') cmd = 'flask db migrate && flask db upgrade' if not os.path.exists('migrations'): - cmd = 'flask db init && '+cmd + cmd = 'flask db init && ' + cmd logger.info(f'开始执行cmd:{cmd}') result = os.system(cmd) logger.info(f'cmd执行结果:{result}') return R.success('数据库升级完毕') + @admin.route('/update_ver') def admin_update_ver(): if not verfy_token(): @@ -174,7 +205,8 @@ def admin_update_ver(): msg = download_new_version(update_proxy) return R.success(msg) -@admin.route('/rule_state/',methods=['POST']) + +@admin.route('/rule_state/', methods=['POST']) def admin_rule_state(state=0): # 管理员修改规则状态 if not verfy_token(): return R.error('请登录后再试') @@ -189,14 +221,15 @@ def admin_rule_state(state=0): # 管理员修改规则状态 success_list = [] for rule in rule_list: try: - res_id = rules.setState(rule,state) + res_id = rules.setState(rule, state) success_list.append(f'{rule}:{res_id}') except: success_list.append(rule) return R.success(f'修改成功,服务器反馈信息为:{success_list}') -@admin.route('/rule_order/',methods=['POST']) + +@admin.route('/rule_order/', methods=['POST']) def admin_rule_order(order=0): # 管理员修改规则顺序 if not verfy_token(): return R.error('请登录后再试') @@ -209,17 +242,18 @@ def admin_rule_order(order=0): # 管理员修改规则顺序 # print(rules.getState(rule_list[0])) # print(rule_list) success_list = [] - rule_list.reverse() # 倒序解决时间多重排序问题 + rule_list.reverse() # 倒序解决时间多重排序问题 for rule in rule_list: try: - res_id = rules.setOrder(rule,order) + res_id = rules.setOrder(rule, order) success_list.append(f'{rule}:{res_id}') except: success_list.append(rule) return R.success(f'修改成功,服务器反馈信息为:{success_list}') -@admin.route('/parse/save_data',methods=['POST']) + +@admin.route('/parse/save_data', methods=['POST']) def admin_parse_save_data(): # 管理员保存拖拽排序后的解析数据 if not verfy_token(): return R.error('请登录后再试') @@ -244,13 +278,13 @@ def admin_parse_save_data(): # 管理员保存拖拽排序后的解析数据 # if not d.get('url') and d.get('name') != '🌐Ⓤ': # continue obj = { - 'name':d.get('name', ''), - 'url':d.get('url', ''), - 'state':d.get('state',1), - 'type': d.get('state',0), - 'order':i+1, - 'ext':d.get('ext',''), - 'header':d.get('header',''), + 'name': d.get('name', ''), + 'url': d.get('url', ''), + 'state': d.get('state', 1), + 'type': d.get('state', 0), + 'order': i + 1, + 'ext': d.get('ext', ''), + 'header': d.get('header', ''), } # print(obj) try: @@ -264,6 +298,7 @@ def admin_parse_save_data(): # 管理员保存拖拽排序后的解析数据 # print(len(success_list)) return R.success(f'修改成功,服务器反馈信息为:{success_list}') + @admin.route('/force_update') def admin_force_update(): if not verfy_token(): @@ -276,6 +311,7 @@ def admin_force_update(): msg = '升级失败。具体原因只能去看实时日志(通过9001端口)' return R.failed(msg) + @admin.route('/update_lives') def admin_update_lives(): url = getParmas('url') @@ -290,6 +326,7 @@ def admin_update_lives(): else: return R.failed(f'直播源{live_url}同步失败') + @admin.route('/write_live_url') def admin_write_live_url(): url = getParmas('url') @@ -298,10 +335,11 @@ def admin_write_live_url(): if not verfy_token(): return R.failed('请登录后再试') lsg = storage_service() - id = lsg.setItem('LIVE_URL',url) + id = lsg.setItem('LIVE_URL', url) msg = f'已修改的配置记录id为:{id}' return R.success(msg) + @admin.route('/change_use_py') def admin_change_use_py(): if not verfy_token(): @@ -314,6 +352,7 @@ def admin_change_use_py(): msg = f'已修改的配置记录id为:{id},结果为{state}' return R.success(msg) + # @admin.route('/get_use_py') # def admin_get_use_py(): # if not verfy_token(): @@ -351,7 +390,7 @@ def upload_file(): except: return R.failed('文件上传失败,检测到上传的文件不是drpy框架支持的源代码') # print(savePath) - file.seek(0) # 读取后变成空文件,重新赋能 + file.seek(0) # 读取后变成空文件,重新赋能 file.save(savePath) return R.success('文件上传成功') except Exception as e: @@ -360,12 +399,13 @@ def upload_file(): # return render_template('upload.html') return R.failed('文件上传失败') -@admin.route('/login',methods=['GET','POST']) + +@admin.route('/login', methods=['GET', 'POST']) def login_api(): username = getParmas('username') password = getParmas('password') autologin = getParmas('autologin') - if not all([username,password]): + if not all([username, password]): return R.failed('账号密码字段必填') token = md5(f'{username};{password}') check = verfy_token(token=token) @@ -377,12 +417,14 @@ def login_api(): else: return R.failed('登录失败,用户名或密码错误') + @admin.route('/logtail') def admin_logtail(): if not verfy_token(): return R.failed('请登录后再试') return render_template('logtail.html') + @admin.route('/lives') def admin_lives(): if not verfy_token(): @@ -393,6 +435,7 @@ def admin_lives(): # 不带http的前缀 host # 当前路径 path host_url = request.host_url + def get_lives(): base_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在目录 # print(base_path) @@ -401,11 +444,12 @@ def admin_lives(): files = os.listdir(live_path) # print(files) # files = list(filter(lambda x: str(x).endswith('.txt') and str(x).find('模板') < 0, files)) - files = list(filter(lambda x: str(x).split('.')[-1] in ['txt','json','m3u'] and str(x).find('模板') < 0, files)) + files = list( + filter(lambda x: str(x).split('.')[-1] in ['txt', 'json', 'm3u'] and str(x).find('模板') < 0, files)) files = [f'{host_url}lives?path=txt/lives/{file}' for file in files] return files files = '\n'.join(get_lives()) response = make_response(files) response.headers['Content-Type'] = 'text/plain; charset=utf-8' - return response \ No newline at end of file + return response diff --git a/doc/更新日志.md b/doc/更新日志.md index 6d31642..72eadee 100644 --- a/doc/更新日志.md +++ b/doc/更新日志.md @@ -1,3 +1,6 @@ +###### 2023/06/09 +- [X] 发布新版本,增加上传源覆盖提示,增加在线编辑源功能(手机使用可能在此界面会卡死,推荐电脑) + ###### 2023/06/08 - [X] 后台管理增加优选源功能。参考config.py进行配置优选源参数 配置好优选源后在动态的在线配置链接ver=2后面添加参数 &sp=1 可以开启优选结果 diff --git a/js/version.txt b/js/version.txt index 92f41d7..e36868a 100644 --- a/js/version.txt +++ b/js/version.txt @@ -1 +1 @@ -3.9.43beta3 \ No newline at end of file +3.9.43beta4 \ No newline at end of file diff --git a/templates/edit_rule.html b/templates/edit_rule.html index 7790eab..bf1a2b5 100644 --- a/templates/edit_rule.html +++ b/templates/edit_rule.html @@ -14,29 +14,85 @@ + + + + + + + -
+
+ +
- + + + + +
@@ -46,41 +102,52 @@
+
+
- - +
+
-
+ +
- + \ No newline at end of file