home.py 16.4 KB
Newer Older
H
hjdhnx 已提交
1 2 3 4 5 6
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File  : index.py
# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
# Date  : 2022/9/6
import json
H
hjdhnx 已提交
7
import ujson
H
hjdhnx 已提交
8
import os
H
hjdhnx 已提交
9
import re
H
hjdhnx 已提交
10

H
hjdhnx 已提交
11
from flask import Blueprint,abort,render_template,render_template_string,url_for,redirect,make_response,send_from_directory,request
H
hjdhnx 已提交
12
from controllers.service import storage_service,rules_service,parse_service
H
hjdhnx 已提交
13
from controllers.classes import getClasses,getClassInfo
H
hjdhnx 已提交
14 15

from utils.files import getPics,custom_merge,getAlist,get_live_url,get_multi_rules,getCustonDict
H
hjdhnx 已提交
16
from js.rules import getRules,getPys
H
hjdhnx 已提交
17
from utils.encode import parseText,base64Encode,baseDecode
H
hjdhnx 已提交
18
from base.R import R
H
hjdhnx 已提交
19 20
from utils.system import getHost,is_linux
from utils.cfg import cfg
H
hjdhnx 已提交
21
from utils import parser
H
hjdhnx 已提交
22
from utils.ua import time,get_interval
H
hjdhnx 已提交
23
from utils.log import logger
H
hjdhnx 已提交
24
from utils.update import getLocalVer,getHotSuggest
H
hjdhnx 已提交
25 26
from js.rules import getJxs
import random
H
hjdhnx 已提交
27
from utils.web import getParmas
H
hjdhnx 已提交
28
import functools
H
hjdhnx 已提交
29

H
hjdhnx 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

home = Blueprint("home", __name__,static_folder='/static')

@home.route('/')
def forbidden():  # put application's code here
    abort(403)

@home.route('/favicon.ico')  # 设置icon
def favicon():
    # return home.send_static_file('img/favicon.svg')
    return redirect('/static/img/favicon.svg')
    # 对于当前文件所在路径,比如这里是static下的favicon.ico
    # return send_from_directory(os.path.join(app.root_path, 'static'),  'img/favicon.svg', mimetype='image/vnd.microsoft.icon')

@home.route('/index')
def index():
H
hjdhnx 已提交
46
    sup_port = cfg.get('SUP_PORT', 9001)
H
hjdhnx 已提交
47 48
    lsg = storage_service()
    pid_url = lsg.getItem('PID_URL')
H
hjdhnx 已提交
49 50
    manager0 = ':'.join(getHost(0).split(':')[0:2])
    manager1 = ':'.join(getHost(1).split(':')[0:2])
H
hjdhnx 已提交
51
    manager2 = pid_url or ':'.join(getHost(2).split(':')[0:2]).replace('https','http')
H
hjdhnx 已提交
52 53 54
    if sup_port:
        manager0 += f':{sup_port}'
        manager1 += f':{sup_port}'
H
hjdhnx 已提交
55 56 57
        if not pid_url:
            manager2 += f':{sup_port}'
    # print(manager2)
H
hjdhnx 已提交
58 59
    ver = getLocalVer()
    return render_template('index.html',ver=ver,getHost=getHost,manager0=manager0,manager1=manager1,manager2=manager2,is_linux=is_linux())
H
hjdhnx 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73

@home.route('/rules/clear')
def rules_to_clear():
    return render_template('rules_to_clear.html',rules=getRules(),classes=getClasses())

@home.route('/rules/view')
def rules_to_view():
    return render_template('rules_to_view.html',rules=getRules(),classes=getClasses())

@home.route('/pics')
def random_pics():
    id = getParmas('id')
    # print(f'id:{id}')
    pics = getPics()
H
hjdhnx 已提交
74
    # print(pics)
H
hjdhnx 已提交
75 76 77 78 79
    new_conf = cfg
    lsg = storage_service()
    store_conf_dict = lsg.getStoreConfDict()
    new_conf.update(store_conf_dict)
    if not new_conf.WALL_PAPER and len(pics) > 0:
H
hjdhnx 已提交
80 81 82 83 84 85 86 87 88
        if id and f'images/{id}.jpg' in pics:
            pic = f'images/{id}.jpg'
        else:
            pic = random.choice(pics)
        file = open(pic, "rb").read()
        response = make_response(file)
        response.headers['Content-Type'] = 'image/jpeg'
        return response
    else:
H
hjdhnx 已提交
89
        return redirect(new_conf.WALL_PAPER)
H
hjdhnx 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

@home.route('/clear')
def clear_rule():
    rule = getParmas('rule')
    if not rule:
        return R.failed('规则字段必填')
    cache_path = os.path.abspath(f'cache/{rule}.js')
    if not os.path.exists(cache_path):
        return R.failed('服务端没有此规则的缓存文件!'+cache_path)
    os.remove(cache_path)
    return R.success('成功删除文件:'+cache_path)

@home.route("/plugin/<name>",methods=['GET'])
def plugin(name):
    # name=道长影视模板.js
    if not name or not name.split('.')[-1] in ['js','txt','py','json']:
        return R.failed(f'非法猥亵,未指定文件名。必须包含js|txt|json|py')
    try:
        return parser.toJs(name)
    except Exception as e:
        return R.failed(f'非法猥亵\n{e}')

H
hjdhnx 已提交
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
@home.route('/files/<name>')
def get_files(name):
    base_path = 'base/files'
    os.makedirs(base_path,exist_ok=True)
    file_path = os.path.join(base_path, f'{name}')
    if not os.path.exists(file_path):
        return R.failed(f'{file_path}文件不存在')

    with open(file_path, mode='rb') as f:
        file_byte = f.read()
    response = make_response(file_byte)
    filename = name
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers['Content-Disposition'] = f'attachment;filename="{filename}"'
    return response

H
hjdhnx 已提交
128
@home.route('/txt/<path:filename>')
H
hjdhnx 已提交
129
def custom_static_txt(filename):
H
hjdhnx 已提交
130 131 132 133
    # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
    # print(filename)
    return send_from_directory('txt', filename)

H
hjdhnx 已提交
134 135 136 137 138 139
@home.route('/libs/<path:filename>')
def custom_static_libs(filename):
    # 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
    # print(filename)
    return send_from_directory('libs', filename)

H
hjdhnx 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152
# @home.route('/txt/<name>')
# def get_txt_files(name):
#     base_path = 'txt'
#     os.makedirs(base_path,exist_ok=True)
#     file_path = os.path.join(base_path, f'{name}')
#     if not os.path.exists(file_path):
#         return R.failed(f'{file_path}文件不存在')
#
#     with open(file_path, mode='r',encoding='utf-8') as f:
#         file_byte = f.read()
#     response = make_response(file_byte)
#     response.headers['Content-Type'] = 'text/plain; charset=utf-8'
#     return response
H
hjdhnx 已提交
153

H
hjdhnx 已提交
154

H
hjdhnx 已提交
155 156
@home.route('/lives')
def get_lives():
H
hjdhnx 已提交
157 158 159
    # ?path=base/live.txt
    path = getParmas('path')
    live_path = path or 'base/直播.txt'
H
hjdhnx 已提交
160 161
    if not re.search('(txt|json|conf)$',live_path,re.M|re.S) or not re.search('^(txt|base)',live_path,re.M|re.S):
        abort(403)
H
hjdhnx 已提交
162
    if not os.path.exists(live_path):
H
hjdhnx 已提交
163 164 165
        # with open(live_path,mode='w+',encoding='utf-8') as f:
        #     f.write('')
        return ''
H
hjdhnx 已提交
166 167 168

    with open(live_path,encoding='utf-8') as f:
        live_text = f.read()
H
hjdhnx 已提交
169 170 171 172 173 174
    if len(live_text) > 100 and live_text.find('http') < 0:
        try:
            live_text = baseDecode(live_text)
            logger.info(f'{path} base64解码完毕')
        except:
            pass
H
hjdhnx 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
    response = make_response(live_text)
    response.headers['Content-Type'] = 'text/plain; charset=utf-8'
    return response

@home.route('/liveslib')
def get_liveslib():
    live_path = 'js/custom_spider.jar'
    if not os.path.exists(live_path):
        with open(live_path,mode='w+',encoding='utf-8') as f:
            f.write('')

    with open(live_path,mode='rb') as f:
        live_text = f.read()
    response = make_response(live_text)
    filename = 'custom_spider.jar'
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers['Content-Disposition'] = f'attachment;filename="{filename}"'
    return response

H
hjdhnx 已提交
194 195 196 197 198
@home.route('/hotsugg')
def get_hot_search():
    data = getHotSuggest()
    return R.success('获取成功',data)

H
hjdhnx 已提交
199 200 201 202 203 204 205 206 207
def merged_hide(merged_config):
    t1 = time()
    store_rule = rules_service()
    hide_rules = store_rule.getHideRules()
    hide_rule_names = list(map(lambda x: x['name'], hide_rules))
    # print(hide_rule_names)
    all_cnt = len(merged_config['sites'])

    def filter_show(x):
H
hjdhnx 已提交
208
        name = x['api'].split('rule=')[1].split('&')[0] if 'rule=' in x['api'] else x['key'].replace('dr_','')
H
hjdhnx 已提交
209 210 211 212 213 214
        # print(name)
        return name not in hide_rule_names

    merged_config['sites'] = list(filter(filter_show, merged_config['sites']))
    logger.info(f'数据库筛选隐藏规则耗时{get_interval(t1)}毫秒,共计{all_cnt}条规则,隐藏后可渲染{len(merged_config["sites"])}条规则')

H
hjdhnx 已提交
215 216 217
@home.route('/config/<int:mode>')
def config_render(mode):
    # print(dict(app.config))
H
hjdhnx 已提交
218
    tt = time()
H
hjdhnx 已提交
219 220 221
    UA = request.headers['User-Agent']
    ISTVB = 'okhttp/3' in UA
    logger.info(UA)
H
hjdhnx 已提交
222 223 224 225
    if mode == 1:
        jyw_ip = getHost(mode)
        logger.info(jyw_ip)
    new_conf = cfg
H
hjdhnx 已提交
226 227 228
    lsg = storage_service()
    store_conf_dict = lsg.getStoreConfDict()
    new_conf.update(store_conf_dict)
H
hjdhnx 已提交
229
    # print(new_conf)
H
hjdhnx 已提交
230
    # print(type(new_conf),new_conf)
H
hjdhnx 已提交
231
    host = getHost(mode)
232 233
    # ali_token = lsg.getItem('ALI_TOKEN')
    ali_token = new_conf.ALI_TOKEN
H
hjdhnx 已提交
234
    xr_mode = new_conf.XR_MODE
H
hjdhnx 已提交
235
    js0_password = new_conf.JS0_PASSWORD
H
hjdhnx 已提交
236 237
    js_mode = int(new_conf.JS_MODE or 0)
    print(f'{type(js_mode)} jsmode:{js_mode}')
238
    # print(ali_token)
H
hjdhnx 已提交
239
    customConfig = getCustonDict(host,ali_token,js0_password)
H
hjdhnx 已提交
240
    # print(customConfig)
H
hjdhnx 已提交
241
    jxs = getJxs(host=host)
H
hjdhnx 已提交
242 243 244
    use_py = lsg.getItem('USE_PY')
    pys = getPys() if use_py else []
    # print(pys)
H
hjdhnx 已提交
245 246 247
    alists = getAlist()
    alists_str = json.dumps(alists, ensure_ascii=False)
    live_url = get_live_url(new_conf,mode)
H
hjdhnx 已提交
248
    rules = getRules('js',js_mode)
H
hjdhnx 已提交
249
    rules = get_multi_rules(rules)
H
hjdhnx 已提交
250
    # html = render_template('config.txt',rules=getRules('js'),host=host,mode=mode,jxs=jxs,base64Encode=base64Encode,config=new_conf)
H
hjdhnx 已提交
251
    html = render_template('config.txt',js0_password=js0_password,UA=UA,xr_mode=xr_mode,ISTVB=ISTVB,pys=pys,rules=rules,host=host,mode=mode,js_mode=js_mode,jxs=jxs,alists=alists,alists_str=alists_str,live_url=live_url,config=new_conf)
H
hjdhnx 已提交
252
    merged_config = custom_merge(parseText(html),customConfig)
H
hjdhnx 已提交
253 254
    # print(merged_config['sites'])
    merged_hide(merged_config)
H
hjdhnx 已提交
255
    # response = make_response(html)
H
hjdhnx 已提交
256
    # print(len(merged_config['sites']))
H
hjdhnx 已提交
257 258
    # print(merged_config['sites'])
    merged_config['sites'] = sort_sites_by_order(merged_config['sites'],js_mode)
H
hjdhnx 已提交
259 260 261 262
    # print(merged_config['parses'])
    parses = sort_parses_by_order(merged_config['parses'],host)
    # print(parses)
    merged_config['parses'] = parses
H
hjdhnx 已提交
263 264
    response = make_response(json.dumps(merged_config,ensure_ascii=False,indent=1))
    # response = make_response(str(merged_config))
H
hjdhnx 已提交
265
    response.headers['Content-Type'] = 'application/json; charset=utf-8'
H
hjdhnx 已提交
266
    logger.info(f'自动生成动态配置共计耗时:{get_interval(tt)}毫秒')
H
hjdhnx 已提交
267 268
    return response

H
hjdhnx 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281
def comp(x, y):
    if x['order'] > y['order']:
        return 1
    elif x['order'] < y['order']:
        return - 1
    else:
        if x['write_date'] < y['write_date']:
            return 1
        elif x['write_date'] > y['write_date']:
            return -1
        else:
            return 0

H
hjdhnx 已提交
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
def sort_sites_by_order(sites,js_mode=0):
    rules = rules_service()
    rule_list = rules.query_all()
    # print(rule_list)
    rule_names = list(map(lambda x: x['name'], rule_list))
    # print(rule_names)
    # print(sites)
    for i in range(len(sites)):
        # sites[i]['id'] = i+1
        site_name = sites[i]['api'].split('rule=')[1].split('&')[0] if 'rule=' in sites[i]['api'] else sites[i]['key']
        if js_mode and str(site_name).startswith('dr'):
            site_name = site_name.replace('dr_','')
        # print(site_name)
        if site_name in rule_names:
            site_rule = rule_list[rule_names.index(site_name)]
            sites[i]['state'] = 1 if site_rule['state'] is None else site_rule['state']
            sites[i]['order'] = 0 if site_rule['order'] is None else site_rule['order']
H
hjdhnx 已提交
299
            sites[i]['write_date'] = 0 if site_rule['write_date'] is None else site_rule['write_date'].timestamp()
H
hjdhnx 已提交
300 301 302
        else:
            sites[i]['state'] = 1
            sites[i]['order'] = 0
H
hjdhnx 已提交
303
            sites[i]['write_date'] = 0
H
hjdhnx 已提交
304 305
        # sites[i]['site_name'] = site_name
    # print(sites)
H
hjdhnx 已提交
306 307
    # sites.sort(key=lambda x: x['order'], reverse=False)
    sites.sort(key=functools.cmp_to_key(comp), reverse=False)
H
hjdhnx 已提交
308 309 310 311
    # print(sites)
    for site in sites:
        del site['state']
        del site['order']
H
hjdhnx 已提交
312
        del site['write_date']
H
hjdhnx 已提交
313 314
    return sites

H
hjdhnx 已提交
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
def sort_parses_by_order(parses,host):
    t1 = time()
    parse = parse_service()
    parse_list = parse.query_all()
    parse_url_list = list(map(lambda x: x['url'], parse_list))
    new_parses = []
    for i in range(len(parses)):
        # parses[i]['id'] = i + 1
        # 去重
        if parses[i]['url'] in new_parses:
            continue
        if str(parses[i]['url']).startswith(host):
            parses[i]['url'] = parses[i]['url'].replace(host,'')
        if parses[i]['url'] in parse_url_list:
            parse_rule = parse_list[parse_url_list.index(parses[i]['url'])]
            parses[i]['state'] = 1 if parse_rule['state'] is None else parse_rule['state']
            parses[i]['order'] = 0 if parse_rule['order'] is None else parse_rule['order']
            parses[i]['write_date'] = 0 if parse_rule['write_date'] is None else parse_rule['write_date'].timestamp()
        else:
            parses[i]['state'] = 1
            parses[i]['order'] = 0
            parses[i]['write_date'] = 0

        if not parses[i].get('header'):
            parses[i]['header'] = {'User-Agent': 'Mozilla/5.0'}
        if str(parses[i]['url']).startswith('/'):
            parses[i]['url'] = host + parses[i]['url']
        new_parses.append(parses[i])
    new_parses.sort(key=functools.cmp_to_key(comp), reverse=False)
    # print(sites)
    for par in new_parses:
        del par['state']
        del par['order']
        del par['write_date']
    # print(new_parses)
    logger.info(f'{len(parses)}条解析解析排序耗时:{get_interval(t1)}毫秒')
    return new_parses

H
hjdhnx 已提交
353 354 355 356 357
@home.route('/configs')
def config_gen():
    # 生成文件
    os.makedirs('txt',exist_ok=True)
    new_conf = cfg
H
hjdhnx 已提交
358 359 360
    lsg = storage_service()
    store_conf_dict = lsg.getStoreConfDict()
    new_conf.update(store_conf_dict)
H
hjdhnx 已提交
361 362
    try:
        use_py = lsg.getItem('USE_PY')
H
hjdhnx 已提交
363
        js_mode = int(new_conf.JS_MODE or 0)
H
hjdhnx 已提交
364
        js0_password = new_conf.JS0_PASSWORD
H
hjdhnx 已提交
365 366 367
        pys = getPys() if use_py else False
        alists = getAlist()
        alists_str = json.dumps(alists,ensure_ascii=False)
H
hjdhnx 已提交
368
        rules = getRules('js',js_mode)
H
hjdhnx 已提交
369
        rules = get_multi_rules(rules)
H
hjdhnx 已提交
370 371
        host0 = getHost(0)
        jxs = getJxs(host=host0)
H
hjdhnx 已提交
372
        set_local = render_template('config.txt',js0_password=js0_password,pys=pys,rules=rules,alists=alists,alists_str=alists_str,live_url=get_live_url(new_conf,0),mode=0,js_mode=js_mode,host=host0,jxs=jxs)
H
hjdhnx 已提交
373
        # print(set_local)
H
hjdhnx 已提交
374 375
        host1 = getHost(1)
        jxs = getJxs(host=host1)
H
hjdhnx 已提交
376
        set_area = render_template('config.txt',js0_password=js0_password,pys=pys,rules=rules,alists=alists,alists_str=alists_str,live_url=get_live_url(new_conf,1),mode=1,js_mode=js_mode,host=host1,jxs=jxs)
377 378
        host2 = getHost(2) or host1
        # print('远程地址:'+host2)
H
hjdhnx 已提交
379
        jxs = getJxs(host=host2)
H
hjdhnx 已提交
380
        set_online = render_template('config.txt',js0_password=js0_password,pys=pys,rules=rules,alists=alists,alists_str=alists_str,live_url=get_live_url(new_conf,2),mode=1,js_mode=js_mode,host=host2,jxs=jxs)
H
hjdhnx 已提交
381
        ali_token = new_conf.ALI_TOKEN
H
hjdhnx 已提交
382
        # parses = []
H
hjdhnx 已提交
383
        with open('txt/pycms0.json','w+',encoding='utf-8') as f:
H
hjdhnx 已提交
384
            customConfig = getCustonDict(host0,ali_token,js0_password)
H
hjdhnx 已提交
385
            set_dict = custom_merge(parseText(set_local), customConfig)
H
hjdhnx 已提交
386
            merged_hide(set_dict)
H
hjdhnx 已提交
387
            set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
H
hjdhnx 已提交
388 389 390 391 392
            # if not parses:
            #     print('生成静态配置时初始化排序parses')
            #     parses = sort_parses_by_order(set_dict['parses'])
            # set_dict['parses'] = parses
            set_dict['parses'] = sort_parses_by_order(set_dict['parses'],host0)
H
hjdhnx 已提交
393
            # set_dict = json.loads(set_local)
H
hjdhnx 已提交
394 395
            f.write(json.dumps(set_dict,ensure_ascii=False,indent=4))
        with open('txt/pycms1.json','w+',encoding='utf-8') as f:
H
hjdhnx 已提交
396
            customConfig = getCustonDict(host1,ali_token,js0_password)
H
hjdhnx 已提交
397
            set_dict = custom_merge(parseText(set_area), customConfig)
H
hjdhnx 已提交
398
            merged_hide(set_dict)
H
hjdhnx 已提交
399
            set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
H
hjdhnx 已提交
400
            set_dict['parses'] = sort_parses_by_order(set_dict['parses'],host1)
H
hjdhnx 已提交
401
            # set_dict = json.loads(set_area)
H
hjdhnx 已提交
402 403 404
            f.write(json.dumps(set_dict,ensure_ascii=False,indent=4))

        with open('txt/pycms2.json','w+',encoding='utf-8') as f:
H
hjdhnx 已提交
405
            customConfig = getCustonDict(host2,ali_token,js0_password)
H
hjdhnx 已提交
406
            set_dict = custom_merge(parseText(set_online), customConfig)
H
hjdhnx 已提交
407
            merged_hide(set_dict)
H
hjdhnx 已提交
408
            set_dict['sites'] = sort_sites_by_order(set_dict['sites'], js_mode)
H
hjdhnx 已提交
409
            set_dict['parses'] = sort_parses_by_order(set_dict['parses'],host2)
H
hjdhnx 已提交
410
            # set_dict = json.loads(set_online)
H
hjdhnx 已提交
411 412 413 414 415 416
            f.write(json.dumps(set_dict,ensure_ascii=False,indent=4))
        files = [os.path.abspath(rf'txt\pycms{i}.json') for i in range(3)]
        # print(files)
        return R.success('猫配置生成完毕,文件位置在:\n'+'\n'.join(files))
    except Exception as e:
        return R.failed(f'配置文件生成错误:\n{e}')
H
hjdhnx 已提交
417 418 419 420 421

@home.route("/info",methods=['get'])
def info_all():
    data = storage_service.query_all()
    return R.ok(data=data)