home.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # File : index.py
  4. # Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
  5. # Date : 2022/9/6
  6. import json
  7. import ujson
  8. import os
  9. import re
  10. from flask import Blueprint, abort, render_template, render_template_string, url_for, redirect, make_response, \
  11. send_from_directory, request
  12. from controllers.service import storage_service, rules_service, parse_service
  13. from controllers.classes import getClasses, getClassInfo
  14. from utils.files import getPics, custom_merge, getAlist, get_live_url, get_multi_rules, getCustonDict
  15. from js.rules import getRules, getPys
  16. from utils.encode import parseText, base64Encode, base64Decode
  17. from base.R import R
  18. from utils.system import getHost, is_linux
  19. from utils.cfg import cfg
  20. from utils import parser
  21. from utils.ua import time, get_interval
  22. from utils.log import logger
  23. from utils.update import getLocalVer, getHotSuggest
  24. from js.rules import getJxs
  25. import random
  26. from utils.web import getParmas, verfy_token
  27. from utils.common_api import js_render
  28. import functools
  29. home = Blueprint("home", __name__, static_folder='/static')
  30. @home.route('/')
  31. def forbidden(): # put application's code here
  32. abort(403)
  33. @home.route('/favicon.ico') # 设置icon
  34. def favicon():
  35. # return home.send_static_file('img/favicon.svg')
  36. return redirect('/static/img/favicon.svg')
  37. # 对于当前文件所在路径,比如这里是static下的favicon.ico
  38. # return send_from_directory(os.path.join(app.root_path, 'static'), 'img/favicon.svg', mimetype='image/vnd.microsoft.icon')
  39. @home.route('/index')
  40. def index():
  41. sup_port = cfg.get('SUP_PORT', 9001)
  42. lsg = storage_service()
  43. pid_url = lsg.getItem('PID_URL')
  44. manager0 = ':'.join(getHost(0).split(':')[0:2])
  45. manager1 = ':'.join(getHost(1).split(':')[0:2])
  46. manager2 = pid_url or ':'.join(getHost(2).split(':')[0:2]).replace('https', 'http')
  47. if sup_port:
  48. manager0 += f':{sup_port}'
  49. manager1 += f':{sup_port}'
  50. if not pid_url:
  51. manager2 += f':{sup_port}'
  52. # print(manager2)
  53. ver = getLocalVer()
  54. return render_template('index.html', ver=ver, getHost=getHost, manager0=manager0, manager1=manager1,
  55. manager2=manager2, is_linux=is_linux())
  56. @home.route('/rules/clear')
  57. def rules_to_clear():
  58. if not verfy_token():
  59. # return render_template('login.html')
  60. return R.error('请登录后再试')
  61. return render_template('rules_to_clear.html', rules=getRules(), classes=getClasses())
  62. @home.route('/rules/view')
  63. def rules_to_view():
  64. if not verfy_token():
  65. # return render_template('login.html')
  66. return R.error('请登录后再试')
  67. return render_template('rules_to_view.html', rules=getRules(), classes=getClasses())
  68. @home.route('/pics')
  69. def random_pics():
  70. id = getParmas('id')
  71. # print(f'id:{id}')
  72. base_path = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) # 上级目录
  73. path = 'images'
  74. img_path = os.path.join(base_path, f'{path}')
  75. pics = getPics(img_path)
  76. # print(pics)
  77. new_conf = cfg
  78. lsg = storage_service()
  79. store_conf_dict = lsg.getStoreConfDict()
  80. new_conf.update(store_conf_dict)
  81. if not new_conf.WALL_PAPER or (id and len(pics) > 0):
  82. if id and f'{img_path}/{id}.jpg' in pics:
  83. pic = f'{img_path}/{id}.jpg'
  84. else:
  85. pic = random.choice(pics)
  86. file = open(pic, "rb").read()
  87. response = make_response(file)
  88. response.headers['Content-Type'] = 'image/jpeg'
  89. return response
  90. else:
  91. return redirect(new_conf.WALL_PAPER)
  92. @home.route('/clear')
  93. def clear_rule():
  94. rule = getParmas('rule')
  95. if not rule:
  96. return R.failed('规则字段必填')
  97. cache_path = os.path.abspath(f'cache/{rule}.js')
  98. if not os.path.exists(cache_path):
  99. return R.failed('服务端没有此规则的缓存文件!' + cache_path)
  100. os.remove(cache_path)
  101. return R.success('成功删除文件:' + cache_path)
  102. @home.route("/plugin/<name>", methods=['GET'])
  103. def plugin(name):
  104. # name=道长影视模板.js
  105. if not name or not name.split('.')[-1] in ['js', 'txt', 'py', 'json']:
  106. return R.failed(f'非法猥亵,未指定文件名。必须包含js|txt|json|py')
  107. try:
  108. return parser.toJs(name)
  109. except Exception as e:
  110. return R.failed(f'非法猥亵\n{e}')
  111. @home.route('/files/<name>')
  112. def get_files(name):
  113. base_path = 'base/files'
  114. os.makedirs(base_path, exist_ok=True)
  115. file_path = os.path.join(base_path, f'{name}')
  116. if not os.path.exists(file_path):
  117. return R.failed(f'{file_path}文件不存在')
  118. with open(file_path, mode='rb') as f:
  119. file_byte = f.read()
  120. response = make_response(file_byte)
  121. filename = name
  122. response.headers['Content-Type'] = 'application/octet-stream'
  123. response.headers['Content-Disposition'] = f'attachment;filename="{filename}"'
  124. return response
  125. @home.route('/txt/<path:filename>')
  126. def custom_static_txt(filename):
  127. # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
  128. # print(filename)
  129. return send_from_directory('txt', filename)
  130. @home.route('/libs/<path:filename>')
  131. def custom_static_libs(filename):
  132. # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
  133. # print(filename)
  134. return send_from_directory('libs', filename)
  135. # @home.route('/js/<path:filename>')
  136. # def custom_static_js(filename):
  137. # # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
  138. # # print(filename)
  139. # return send_from_directory('js', filename)
  140. @home.route('/js/<path:name>', methods=['GET'])
  141. def custom_static_js(name):
  142. # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
  143. # print(name)
  144. return js_render(name)
  145. @home.route('/raw/js/<path:filename>')
  146. def custom_raw_js(filename):
  147. return send_from_directory('js', filename)
  148. # @home.route('/txt/<name>')
  149. # def get_txt_files(name):
  150. # base_path = 'txt'
  151. # os.makedirs(base_path,exist_ok=True)
  152. # file_path = os.path.join(base_path, f'{name}')
  153. # if not os.path.exists(file_path):
  154. # return R.failed(f'{file_path}文件不存在')
  155. #
  156. # with open(file_path, mode='r',encoding='utf-8') as f:
  157. # file_byte = f.read()
  158. # response = make_response(file_byte)
  159. # response.headers['Content-Type'] = 'text/plain; charset=utf-8'
  160. # return response
  161. @home.route('/lives')
  162. def get_lives():
  163. # ?path=base/live.txt
  164. path = getParmas('path')
  165. live_path = path or 'base/直播.txt'
  166. if not re.search('(txt|json|conf)$', live_path, re.M | re.S) or not re.search('^(txt|base)', live_path,
  167. re.M | re.S):
  168. abort(403)
  169. if not os.path.exists(live_path):
  170. # with open(live_path,mode='w+',encoding='utf-8') as f:
  171. # f.write('')
  172. return ''
  173. with open(live_path, encoding='utf-8') as f:
  174. live_text = f.read()
  175. if len(live_text) > 100 and live_text.find('http') < 0:
  176. try:
  177. live_text = base64Decode(live_text)
  178. logger.info(f'{path} base64解码完毕')
  179. except Exception as e:
  180. logger.info(f'{path} base64解码失败:{e}')
  181. response = make_response(live_text)
  182. response.headers['Content-Type'] = 'text/plain; charset=utf-8'
  183. return response
  184. @home.route('/liveslib')
  185. def get_liveslib():
  186. lsg = storage_service()
  187. SPIDER_JAR = lsg.getItem('SPIDER_JAR', 'custom_spider.jar')
  188. live_path = f'libs/jar/{SPIDER_JAR}'
  189. logger.info(f'SPIDER_JAR:{SPIDER_JAR}>>当前系统挂载的指定jar文件位置:{live_path}')
  190. if not os.path.exists(live_path):
  191. with open(live_path, mode='w+', encoding='utf-8') as f:
  192. f.write('')
  193. with open(live_path, mode='rb') as f:
  194. live_text = f.read()
  195. response = make_response(live_text)
  196. filename = 'custom_spider.jar'
  197. response.headers['Content-Type'] = 'application/octet-stream'
  198. response.headers['Content-Disposition'] = f'attachment;filename="{filename}"'
  199. return response
  200. @home.route('/hotsugg')
  201. def get_hot_search():
  202. s_from = getParmas('from')
  203. size = getParmas('size')
  204. data = getHotSuggest(s_from, size)
  205. return R.success('获取成功', data)
  206. def merged_hide(merged_config):
  207. t1 = time()
  208. store_rule = rules_service()
  209. hide_rules = store_rule.getHideRules()
  210. hide_rule_names = list(map(lambda x: x['name'], hide_rules))
  211. # print(hide_rule_names)
  212. all_cnt = len(merged_config['sites'])
  213. def filter_show(x):
  214. name = x['api'].split('rule=')[1].split('&')[0] if 'rule=' in x['api'] else x['key'].replace('dr_', '')
  215. # print(name)
  216. if not str(x['key']).startswith('dr_') and name == 'drpy':
  217. name = x['key']
  218. return name not in hide_rule_names
  219. merged_config['sites'] = list(filter(filter_show, merged_config['sites']))
  220. logger.info(
  221. f'数据库筛选隐藏规则耗时{get_interval(t1)}毫秒,共计{all_cnt}条规则,隐藏后可渲染{len(merged_config["sites"])}条规则')
  222. @home.route('/config/<int:mode>')
  223. def config_render(mode):
  224. # print(dict(app.config))
  225. tt = time()
  226. UA = request.headers['User-Agent']
  227. ver = getParmas('ver')
  228. m = getParmas('mode')
  229. sp = getParmas('sp') # 优选
  230. logger.info(f'ver:{ver},UA:{UA}')
  231. if ver not in ['1', '2']:
  232. ISTVB = 'okhttp/3' in UA
  233. elif ver == '1':
  234. ISTVB = False
  235. elif ver == '2':
  236. ISTVB = True
  237. # print(ISTVB)
  238. if mode == 1:
  239. jyw_ip = getHost(mode)
  240. logger.info(jyw_ip)
  241. new_conf = cfg
  242. lsg = storage_service()
  243. store_conf_dict = lsg.getStoreConfDict()
  244. new_conf.update(store_conf_dict)
  245. # print(new_conf)
  246. # print(type(new_conf),new_conf)
  247. host = getHost(mode)
  248. # ali_token = lsg.getItem('ALI_TOKEN')
  249. ali_token = new_conf.ALI_TOKEN
  250. xr_mode = new_conf.XR_MODE
  251. js_proxy = new_conf.JS_PROXY
  252. js0_password = new_conf.JS0_PASSWORD
  253. js_mode = int(new_conf.JS_MODE or 0)
  254. if m:
  255. try:
  256. js_mode = int(m)
  257. except:
  258. pass
  259. print(f'{type(js_mode)} jsmode:{js_mode}')
  260. # print(ali_token)
  261. customConfig = getCustonDict(host, ali_token, js0_password)
  262. # print(customConfig)
  263. jxs = getJxs(host=host)
  264. use_py = lsg.getItem('USE_PY')
  265. pys = getPys() if use_py else []
  266. # print(pys)
  267. alists = getAlist()
  268. alists_str = json.dumps(alists, ensure_ascii=False)
  269. live_url = get_live_url(new_conf, mode)
  270. rules = getRules('js', js_mode)
  271. rules = get_multi_rules(rules)
  272. # html = render_template('config.txt',rules=getRules('js'),host=host,mode=mode,jxs=jxs,base64Encode=base64Encode,config=new_conf)
  273. if new_conf.EXT_FUNC and new_conf.EXT_FUNC.strip():
  274. try:
  275. new_conf.EXT_FUNC = json.loads(new_conf.EXT_FUNC)
  276. logger.info(f'扩展规则加载成功,共计:{len(new_conf.EXT_FUNC)}')
  277. except Exception as e:
  278. logger.info(f'加载扩展规则发生错误:{e}')
  279. new_conf.EXT_FUNC = []
  280. else:
  281. new_conf.EXT_FUNC = []
  282. html = render_template('config.txt', js0_password=js0_password, UA=UA, xr_mode=xr_mode, ISTVB=ISTVB, pys=pys,
  283. rules=rules, host=host, mode=mode, js_mode=js_mode, jxs=jxs, alists=alists,
  284. alists_str=alists_str, live_url=live_url, config=new_conf)
  285. merged_config = custom_merge(parseText(html), customConfig)
  286. # print(merged_config['sites'])
  287. merged_hide(merged_config)
  288. # response = make_response(html)
  289. # print(len(merged_config['sites']))
  290. # print(merged_config['sites'])
  291. merged_config['sites'] = sort_sites_by_order(merged_config['sites'], js_mode)
  292. # print(merged_config['sites'])
  293. if sp: # 执行动态优选源
  294. special_rule(merged_config, lsg)
  295. # print(merged_config['parses'])
  296. parses = sort_parses_by_order(merged_config['parses'], host)
  297. # print(parses)
  298. merged_config['parses'] = parses
  299. config_text = json.dumps(merged_config, ensure_ascii=False, indent=1)
  300. # 依赖代理逻辑修改,改为admin/view去动态代理
  301. # if js_proxy:
  302. # # print('js_proxy:',js_proxy)
  303. # if '=>' in js_proxy:
  304. # oldsrc = js_proxy.split('=>')[0]
  305. # newsrc = js_proxy.split('=>')[1]
  306. # print(f'js1源代理已启用,全局替换{oldsrc}为{newsrc}')
  307. # config_text = config_text.replace(oldsrc,newsrc)
  308. response = make_response(config_text)
  309. # response = make_response(str(merged_config))
  310. response.headers['Content-Type'] = 'application/json; charset=utf-8'
  311. logger.info(f'自动生成动态配置共计耗时:{get_interval(tt)}毫秒')
  312. return response
  313. def special_rule(merged_config, lsg):
  314. # print(merged_config['sites'])
  315. special = lsg.getItem('SPECIAL').strip()
  316. # print('SPECIAL:',special)
  317. special_dict = {}
  318. for sp in special.split('&'):
  319. special_dict[sp.split(':')[0]] = sp.split(':')[1] if ':' in sp else ''
  320. special_keys = list(special_dict.keys())
  321. special_ft = list(filter(lambda x: x.get('key').replace('dr_', '') in special_keys, merged_config['sites']))
  322. for spf in special_ft:
  323. spf['name'] = special_dict[spf['key'].replace('dr_', '')] or spf['name']
  324. special_st = sorted(special_ft, key=lambda x: special_keys.index(x.get('key').replace('dr_', '')))
  325. merged_config['sites'] = special_st
  326. merged_config['dr_count'] = len(special_st)
  327. def comp(x, y):
  328. if x['order'] > y['order']:
  329. return 1
  330. elif x['order'] < y['order']:
  331. return - 1
  332. else:
  333. if x['write_date'] < y['write_date']:
  334. return 1
  335. elif x['write_date'] > y['write_date']:
  336. return -1
  337. else:
  338. return 0
  339. def sort_sites_by_order(sites, js_mode=0):
  340. rules = rules_service()
  341. rule_list = rules.query_all()
  342. # print(rule_list)
  343. rule_names = list(map(lambda x: x['name'], rule_list))
  344. # print(rule_names)
  345. # print(sites)
  346. for i in range(len(sites)):
  347. # sites[i]['id'] = i+1
  348. site_name = sites[i]['api'].split('rule=')[1].split('&')[0] if 'rule=' in sites[i]['api'] else sites[i]['key']
  349. if js_mode and str(site_name).startswith('dr'):
  350. site_name = site_name.replace('dr_', '')
  351. if not str(sites[i]['key']).startswith('dr_') and site_name == 'drpy':
  352. site_name = sites[i]['key']
  353. # print(sites[i])
  354. # print(site_name)
  355. if site_name in rule_names:
  356. site_rule = rule_list[rule_names.index(site_name)]
  357. sites[i]['state'] = 1 if site_rule['state'] is None else site_rule['state']
  358. sites[i]['order'] = 0 if site_rule['order'] is None else site_rule['order']
  359. sites[i]['write_date'] = 0 if site_rule['write_date'] is None else site_rule['write_date'].timestamp()
  360. else:
  361. sites[i]['state'] = 1
  362. sites[i]['order'] = 0
  363. sites[i]['write_date'] = 0
  364. # sites[i]['site_name'] = site_name
  365. # print(sites)
  366. # sites.sort(key=lambda x: x['order'], reverse=False)
  367. sites.sort(key=functools.cmp_to_key(comp), reverse=False)
  368. # print(sites)
  369. for site in sites:
  370. del site['state']
  371. del site['order']
  372. del site['write_date']
  373. return sites
  374. def sort_parses_by_order(parses, host):
  375. t1 = time()
  376. parse = parse_service()
  377. parse_list = parse.query_all()
  378. parse_url_list = list(map(lambda x: x['url'], parse_list))
  379. new_parses = []
  380. new_parses_url = []
  381. for i in range(len(parses)):
  382. # parses[i]['id'] = i + 1
  383. # 去重
  384. if parses[i]['url'] in new_parses_url:
  385. # print(f"重复的解析:{parses[i]['name']},{parses[i]['url']}")
  386. continue
  387. if str(parses[i]['url']).startswith(host):
  388. parses[i]['url'] = parses[i]['url'].replace(host, '')
  389. if parses[i]['url'] in parse_url_list:
  390. parse_rule = parse_list[parse_url_list.index(parses[i]['url'])]
  391. parses[i]['state'] = 1 if parse_rule['state'] is None else parse_rule['state']
  392. parses[i]['order'] = 0 if parse_rule['order'] is None else parse_rule['order']
  393. parses[i]['write_date'] = 0 if parse_rule['write_date'] is None else parse_rule['write_date'].timestamp()
  394. else:
  395. parses[i]['state'] = 1
  396. parses[i]['order'] = 0
  397. parses[i]['write_date'] = 0
  398. # 外层自动补header
  399. if not parses[i].get('header'):
  400. parses[i]['header'] = {'User-Agent': 'Mozilla/5.0'}
  401. if str(parses[i]['url']).startswith('/'):
  402. parses[i]['url'] = host + parses[i]['url']
  403. new_parses.append(parses[i])
  404. new_parses_url.append(parses[i]['url'])
  405. new_parses.sort(key=functools.cmp_to_key(comp), reverse=False)
  406. # print(sites)
  407. for par in new_parses:
  408. del par['state']
  409. del par['order']
  410. del par['write_date']
  411. # print(new_parses)
  412. logger.info(f'{len(new_parses)}/{len(parses)}条解析解析排序耗时:{get_interval(t1)}毫秒')
  413. return new_parses
  414. @home.route('/configs')
  415. def config_gen():
  416. if not verfy_token():
  417. return R.failed('请登录后再试')
  418. # 生成文件
  419. os.makedirs('txt', exist_ok=True)
  420. new_conf = cfg
  421. lsg = storage_service()
  422. store_conf_dict = lsg.getStoreConfDict()
  423. new_conf.update(store_conf_dict)
  424. if new_conf.EXT_FUNC and new_conf.EXT_FUNC.strip():
  425. try:
  426. new_conf.EXT_FUNC = json.loads(new_conf.EXT_FUNC)
  427. logger.info(f'扩展规则加载成功,共计:{len(new_conf.EXT_FUNC)}')
  428. except Exception as e:
  429. logger.info(f'加载扩展规则发生错误:{e}')
  430. new_conf.EXT_FUNC = []
  431. else:
  432. new_conf.EXT_FUNC = []
  433. try:
  434. use_py = lsg.getItem('USE_PY')
  435. js_mode = int(new_conf.JS_MODE or 0)
  436. js0_password = new_conf.JS0_PASSWORD
  437. pys = getPys() if use_py else False
  438. alists = getAlist()
  439. alists_str = json.dumps(alists, ensure_ascii=False)
  440. rules = getRules('js', js_mode)
  441. rules = get_multi_rules(rules)
  442. host0 = getHost(0)
  443. jxs = getJxs(host=host0)
  444. set_local = render_template('config.txt', js0_password=js0_password, pys=pys, rules=rules, alists=alists,
  445. alists_str=alists_str, live_url=get_live_url(new_conf, 0), mode=0, js_mode=js_mode,
  446. host=host0, jxs=jxs, config=new_conf)
  447. # print(set_local)
  448. host1 = getHost(1)
  449. jxs = getJxs(host=host1)
  450. set_area = render_template('config.txt', js0_password=js0_password, pys=pys, rules=rules, alists=alists,
  451. alists_str=alists_str, live_url=get_live_url(new_conf, 1), mode=1, js_mode=js_mode,
  452. host=host1, jxs=jxs, config=new_conf)
  453. host2 = getHost(2) or host1
  454. # print('远程地址:'+host2)
  455. jxs = getJxs(host=host2)
  456. set_online = render_template('config.txt', js0_password=js0_password, pys=pys, rules=rules, alists=alists,
  457. alists_str=alists_str, live_url=get_live_url(new_conf, 2), mode=1, js_mode=js_mode,
  458. host=host2, jxs=jxs, config=new_conf)
  459. ali_token = new_conf.ALI_TOKEN
  460. # parses = []
  461. with open('txt/pycms0.json', 'w+', encoding='utf-8') as f:
  462. customConfig = getCustonDict(host0, ali_token, js0_password)
  463. set_dict = custom_merge(parseText(set_local), customConfig)
  464. merged_hide(set_dict)
  465. set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
  466. # if not parses:
  467. # print('生成静态配置时初始化排序parses')
  468. # parses = sort_parses_by_order(set_dict['parses'])
  469. # set_dict['parses'] = parses
  470. set_dict['parses'] = sort_parses_by_order(set_dict['parses'], host0)
  471. # set_dict = json.loads(set_local)
  472. f.write(json.dumps(set_dict, ensure_ascii=False, indent=4))
  473. with open('txt/pycms1.json', 'w+', encoding='utf-8') as f:
  474. customConfig = getCustonDict(host1, ali_token, js0_password)
  475. set_dict = custom_merge(parseText(set_area), customConfig)
  476. merged_hide(set_dict)
  477. set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
  478. set_dict['parses'] = sort_parses_by_order(set_dict['parses'], host1)
  479. # set_dict = json.loads(set_area)
  480. f.write(json.dumps(set_dict, ensure_ascii=False, indent=4))
  481. with open('txt/pycms2.json', 'w+', encoding='utf-8') as f:
  482. customConfig = getCustonDict(host2, ali_token, js0_password)
  483. set_dict = custom_merge(parseText(set_online), customConfig)
  484. merged_hide(set_dict)
  485. set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
  486. set_dict['parses'] = sort_parses_by_order(set_dict['parses'], host2)
  487. # set_dict = json.loads(set_online)
  488. f.write(json.dumps(set_dict, ensure_ascii=False, indent=4))
  489. files = [os.path.abspath(rf'txt\pycms{i}.json') for i in range(3)]
  490. # print(files)
  491. return R.success('猫配置生成完毕,文件位置在:\n' + '\n'.join(files))
  492. except Exception as e:
  493. return R.failed(f'配置文件生成错误:\n{e}')
  494. @home.route("/info", methods=['get'])
  495. def info_all():
  496. if not verfy_token():
  497. # return render_template('login.html')
  498. return R.error('请登录后再试')
  499. data = storage_service.query_all()
  500. return R.ok(data=data)