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

from flask import Blueprint,request,render_template,jsonify,make_response,redirect
from time import time
H
hjdhnx 已提交
10 11
from utils.web import getParmas,get_interval
from utils.cfg import cfg
H
hjdhnx 已提交
12 13 14 15 16 17 18 19
from js.rules import getRuleLists,getJxs
from base.R import R
from utils.log import logger
from utils import parser
from controllers.cms import CMS
from base.database import db
from models.ruleclass import RuleClass
from models.playparse import PlayParse
H
hjdhnx 已提交
20
from js.rules import getRules
H
hjdhnx 已提交
21
from controllers.service import storage_service
H
hjdhnx 已提交
22
from concurrent.futures import ThreadPoolExecutor,as_completed,thread  # 引入线程池
H
hjdhnx 已提交
23 24
vod = Blueprint("vod", __name__)

H
hjdhnx 已提交
25

H
hjdhnx 已提交
26 27 28 29 30 31 32
def search_one(rule, wd, before: str = ''):
    t1 = time()
    if not before:
        with open('js/模板.js', encoding='utf-8') as f:
            before = f.read()
    js_path = f'js/{rule}.js'
    try:
H
hjdhnx 已提交
33 34 35 36 37 38
        ctx, js_code = parser.runJs(js_path, before=before)
        if not js_code:
            return None
        ruleDict = ctx.rule.to_dict()
        ruleDict['id'] = rule  # 把路由请求的id装到字典里,后面播放嗅探才能用
        logger.info(f'规则{rule}装载耗时:{get_interval(t1)}毫秒')
H
hjdhnx 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
        cms = CMS(ruleDict, db, RuleClass, PlayParse, cfg)
        data = cms.searchContent(wd, show_name=True)
        return data
    except Exception as e:
        print(f'{rule}发生错误:{e}')
        return None

def multi_search2(wd):
    t1 = time()
    lsg = storage_service()
    try:
        timeout = round(int(lsg.getItem('SEARCH_TIMEOUT', 5000)) / 1000, 2)
    except:
        timeout = 5
    rules = getRules('js')['list']
    rule_names = list(map(lambda x: x['name'], rules))
    rules_exclude = ['drpy']
    new_rules = list(filter(lambda x: x.get('searchable', 0) and x.get('name', '') not in rules_exclude, rules))
    search_sites = [new_rule['name'] for new_rule in new_rules]
    nosearch_sites = set(rule_names) ^ set(search_sites)
    nosearch_sites.remove('drpy')
    # print(nosearch_sites)
    logger.info(f'开始聚搜{wd},共计{len(search_sites)}个规则,聚搜超时{timeout}秒')
    logger.info(f'不支持聚搜的规则,共计{len(nosearch_sites)}个规则:{",".join(nosearch_sites)}')
    # print(search_sites)
    res = []
    with open('js/模板.js', encoding='utf-8') as f:
        before = f.read()
    logger.info(f'聚搜准备工作耗时:{get_interval(t1)}毫秒')
    t2 = time()
    thread_pool = ThreadPoolExecutor(len(search_sites))  # 定义线程池来启动多线程执行此任务
    obj_list = []
    try:
        for site in search_sites:
            obj = thread_pool.submit(search_one, site, wd, before)
            obj_list.append(obj)
        thread_pool.shutdown(wait=True)  # 等待所有子线程并行完毕
        vod_list = [obj.result() for obj in obj_list]
        for vod in vod_list:
            if vod and isinstance(vod, dict) and vod.get('list') and len(vod['list']) > 0:
                res.extend(vod['list'])
        result = {
            'list': res
        }
        logger.info(f'drpy聚搜{len(search_sites)}个源耗时{get_interval(t2)}毫秒,含准备共计耗时{get_interval(t1)}毫秒')
    except Exception as e:
        result = {
            'list': []
        }
        logger.info(f'drpy聚搜{len(search_sites)}个源耗时{get_interval(t2)}毫秒,含准备共计耗时:{get_interval(t1)}毫秒,发生错误:{e}')
    return jsonify(result)

H
hjdhnx 已提交
91

H
hjdhnx 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
def multi_search(wd):
    lsg = storage_service()
    t1 = time()
    try:
        timeout = round(int(lsg.getItem('SEARCH_TIMEOUT',5000))/1000,2)
    except:
        timeout = 5
    rules = getRules('js')['list']
    rule_names = list(map(lambda x:x['name'],rules))
    rules_exclude = ['drpy']
    new_rules = list(filter(lambda x: x.get('searchable', 0) and x.get('name', '') not in rules_exclude, rules))
    search_sites = [new_rule['name'] for new_rule in new_rules]
    nosearch_sites = set(rule_names) ^ set(search_sites)
    nosearch_sites.remove('drpy')
    # print(nosearch_sites)
    logger.info(f'开始聚搜{wd},共计{len(search_sites)}个规则,聚搜超时{timeout}秒')
    logger.info(f'不支持聚搜的规则,共计{len(nosearch_sites)}个规则:{",".join(nosearch_sites)}')
    # print(search_sites)
    res = []
    with open('js/模板.js', encoding='utf-8') as f:
        before = f.read()
    with ThreadPoolExecutor(max_workers=len(search_sites)) as executor:
        to_do = []
        for site in search_sites:
            future = executor.submit(search_one, site, wd, before)
            to_do.append(future)
H
hjdhnx 已提交
118
        try:
H
hjdhnx 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132
            for future in as_completed(to_do, timeout=timeout):  # 并发执行
                ret = future.result()
                # print(ret)
                if ret and isinstance(ret,dict) and ret.get('list'):
                    res.extend(ret['list'])
        except Exception as e:
            print(f'发生错误:{e}')
            import atexit
            atexit.unregister(thread._python_exit)
            executor.shutdown = lambda wait: None
    logger.info(f'drpy聚搜{len(search_sites)}个源共计耗时{get_interval(t1)}毫秒')
    return jsonify({
        "list": res
    })
H
hjdhnx 已提交
133

H
hjdhnx 已提交
134 135
@vod.route('/vod')
def vod_home():
H
hjdhnx 已提交
136 137
    t0 = time()
    rule = getParmas('rule')
H
hjdhnx 已提交
138 139 140 141 142
    ac = getParmas('ac')
    ids = getParmas('ids')
    if ac and ids and ids.find('#') > -1:  # 聚搜的二级
        id_list = ids.split(',')
        rule = id_list[0].split('#')[1]
H
hjdhnx 已提交
143
        # print(rule)
H
hjdhnx 已提交
144

H
hjdhnx 已提交
145
    ext = getParmas('ext')
H
hjdhnx 已提交
146
    filters = getParmas('f')
H
hjdhnx 已提交
147 148
    tp = getParmas('type')
    # print(f'type:{tp}')
H
hjdhnx 已提交
149 150
    # if not ext.startswith('http') and not rule:
    if not rule:
H
hjdhnx 已提交
151 152
        return R.failed('规则字段必填')
    rule_list = getRuleLists()
H
hjdhnx 已提交
153 154
    # if not ext.startswith('http') and not rule in rule_list:
    if not ext and not rule in rule_list:
H
hjdhnx 已提交
155 156 157 158
        msg = f'服务端本地仅支持以下规则:{",".join(rule_list)}'
        return R.failed(msg)
    # logger.info(f'检验耗时:{get_interval(t0)}毫秒')
    t1 = time()
H
hjdhnx 已提交
159 160
    # js_path = f'js/{rule}.js' if not ext.startswith('http') else ext
    js_path = f'js/{rule}.js' if not ext else ext
H
hjdhnx 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    with open('js/模板.js', encoding='utf-8') as f:
        before = f.read()
    # logger.info(f'js读取耗时:{get_interval(t1)}毫秒')
    logger.info(f'参数检验js读取共计耗时:{get_interval(t0)}毫秒')
    t2 = time()
    ctx, js_code = parser.runJs(js_path,before=before)
    if not js_code:
        return R.failed('爬虫规则加载失败')

    # rule = ctx.eval('rule')
    # print(type(ctx.rule.lazy()),ctx.rule.lazy().toString())
    ruleDict = ctx.rule.to_dict()
    ruleDict['id'] = rule  # 把路由请求的id装到字典里,后面播放嗅探才能用
    # print(ruleDict)
    # print(rule)
    # print(type(rule))
    # print(ruleDict)
    logger.info(f'js装载耗时:{get_interval(t2)}毫秒')
    # print(ruleDict)
    # print(rule)
    cms = CMS(ruleDict,db,RuleClass,PlayParse,cfg)
    wd = getParmas('wd')
    quick = getParmas('quick')
    play = getParmas('play') # 类型为4的时候点击播放会带上来
    flag = getParmas('flag') # 类型为4的时候点击播放会带上来
H
hjdhnx 已提交
186
    # myfilter = getParmas('filter')
H
hjdhnx 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
    t = getParmas('t')
    pg = getParmas('pg','1')
    pg = int(pg)
    q = getParmas('q')
    play_url = getParmas('play_url')

    if play:
        jxs = getJxs()
        play_url = play.split('play_url=')[1]
        play_url = cms.playContent(play_url, jxs,flag)
        if isinstance(play_url, str):
            # return redirect(play_url)
            # return jsonify({'parse': 0, 'playUrl': play_url, 'jx': 0, 'url': play_url})
            # return jsonify({'parse': 0, 'playUrl': play_url, 'jx': 0, 'url': ''})
            return jsonify({'parse': 0, 'playUrl': '', 'jx': 0, 'url': play_url})
        elif isinstance(play_url, dict):
            return jsonify(play_url)
        else:
            return play_url

    if play_url:  # 播放
        jxs = getJxs()
        play_url = cms.playContent(play_url,jxs)
        if isinstance(play_url,str):
            return redirect(play_url)
        elif isinstance(play_url,dict):
            return jsonify(play_url)
        else:
            return play_url

H
hjdhnx 已提交
217 218 219 220 221 222 223
    if ac and t:  # 一级
        fl = {}
        if filters and filters.find('{') > -1 and filters.find('}') > -1:
            fl = json.loads(filters)
        # print(filters,type(filters))
        # print(fl,type(fl))
        data = cms.categoryContent(t,pg,fl)
H
hjdhnx 已提交
224 225 226 227
        # print(data)
        return jsonify(data)
    if ac and ids: # 二级
        id_list = ids.split(',')
H
hjdhnx 已提交
228
        show_name = False
H
hjdhnx 已提交
229 230
        if ids.find('#') > -1:
            id_list = list(map(lambda x:x.split('#')[0],id_list))
H
hjdhnx 已提交
231
            show_name = True
H
hjdhnx 已提交
232 233
        # print('app:377',len(id_list))
        # print(id_list)
H
hjdhnx 已提交
234
        data = cms.detailContent(pg,id_list,show_name)
H
hjdhnx 已提交
235 236 237
        # print(data)
        return jsonify(data)
    if wd: # 搜索
H
hjdhnx 已提交
238 239 240
        if rule == 'drpy':
            # print(f'准备单独处理聚合搜索:{wd}')
            return multi_search(wd)
H
hjdhnx 已提交
241
            # return multi_search2(wd)
H
hjdhnx 已提交
242 243 244 245
        else:
            data = cms.searchContent(wd)
            # print(data)
            return jsonify(data)
H
hjdhnx 已提交
246 247 248
    # return jsonify({'rule':rule,'js_code':js_code})
    home_data = cms.homeContent(pg)
    return jsonify(home_data)