""" @author: luojunhui """ import json import uuid import time import random import hashlib import urllib.parse from applications.functions.log import logging from static.config import db_article from applications.functions.common import request_for_info from applications.functions.forward import forward_requests class Response(object): """ 召回逻辑 """ NEW_STRATEGY = "strategy_v2" def __init__(self, trace_id, mysql_client, mini_program_type, strategy="strategy_v1"): """ 长文: 25, 29, 31 投流: 33 企微: 27 :param trace_id: :param mysql_client: :param mini_program_type: """ self.trace_id = trace_id self.mysql_client = mysql_client self.mini_program_type = mini_program_type self.strategy = strategy self.mini_map = { 25: { "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png", "id": "wxbdd2a2e93d9a6e25", "name": "票圈视频", "index": 25 }, 29: { "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png", "id": "wxbdd2a2e93d9a6e25", "name": "票圈视频", "index": 29 }, 31: { "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png", "id": "wxbdd2a2e93d9a6e25", "name": "票圈视频", "index": 31 }, 36: { "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png", "id": "wxbdd2a2e93d9a6e25", "name": "票圈视频", "index": 36 }, 27: { "avatar": "https://rescdn.yishihui.com/0temp/xymhfqdd.png", "id": "wx7187c217efef24a7", "name": "幸运美好福气多多", "index": 27, }, # 33: { # "avatar": "https://rescdn.yishihui.com/0temp/ssnnfqd.jpeg", # "id": "wx5e67713277549b6f", # "name": "年年岁岁福气多", # "index": 33, # }, 33: { "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png", "id": "wxbdd2a2e93d9a6e25", "name": "票圈视频", "index": 33 } } # self.test_id_set = {'gh_080bb43aa0dc', 'gh_e0eb490115f5', 'gh_6d9f36e3a7be', 'gh_29074b51f2b7', 'gh_6d205db62f04', # 'gh_d49df5e974ca', 'gh_d4dffc34ac39', 'gh_89ef4798d3ea', 'gh_b15de7c99912', 'gh_9eef14ad6c16', # 'gh_0c89e11f8bf3', 'gh_f902cea89e48', 'gh_6b7c2a257263', 'gh_183d80deffb8', 'gh_9f8dc5b0c74e', # 'gh_1b27dd1beeca', 'gh_e24da99dc899', 'gh_dd4c857bbb36', 'gh_7e5818b2dd83'} async def get_result(self): """ 获取结果 :return: """ select_sql = f""" SELECT gh_id, recall_video_id1, recall_video_id2, recall_video_id3, kimi_title, content_status, process_times FROM {db_article} WHERE trace_id = '{self.trace_id}'; """ info_tuple = await self.mysql_client.async_select(select_sql) gh_id, vid1, vid2, vid3, kimi_title, content_status, process_times = info_tuple[ 0 ] response = { "gh_id": gh_id, "vid_list": [vid1, vid2, vid3], "kimi_title": kimi_title, "content_status": content_status, "process_times": process_times, } print(response) return response def create_gzh_path(self, video_id, shared_uid, gh_id): """ :param gh_id: 公众号账号的gh_id :param video_id: 视频 id :param shared_uid: 分享 id """ def generate_source_id(): """ generate_source_id :return: """ timestamp = str(int(time.time() * 1000)) random_str = str(random.randint(1000, 9999)) hash_input = f"{timestamp}-{random_str}" return hashlib.md5(hash_input.encode()).hexdigest() root_share_id = str(uuid.uuid4()) if self.mini_program_type == 2: source_id = ( "touliu_tencentGzhArticle_{}_".format(gh_id) + generate_source_id() ) elif self.mini_program_type == 1: source_id = "longArticles_" + generate_source_id() elif self.mini_program_type == 3: source_id = "WeCom_" + generate_source_id() else: source_id = "Error mini_program_type {}".format(self.mini_program_type) url = f"pages/user-videos?id={video_id}&su={shared_uid}&fromGzh=1&rootShareId={root_share_id}&shareId={root_share_id}&rootSourceId={source_id}" # 自动把 root_share_id 加入到白名单 # auto_white(root_share_id) return ( root_share_id, source_id, f"pages/category?jumpPage={urllib.parse.quote(url, safe='')}", ) def choose_mini_program(self, mini_id): """ 获取小程序分享卡片 :return: """ mini_info = self.mini_map[mini_id] return ( mini_info["avatar"], mini_info["id"], mini_info["name"], mini_info["index"], ) async def generate_card(self, video_id, kimi_title, index, gh_id, mini_id): """ 生成分享卡片 :return: """ response = request_for_info(video_id) productionCover = response["data"][0]["shareImgPath"] productionName = kimi_title videoUrl = response["data"][0]["videoPath"] user_id = response["data"][0]["user"]["uid"] programAvatar, programId, programName, pqMiniId = self.choose_mini_program( mini_id ) root_share_id, source_id, productionPath = self.create_gzh_path( video_id, user_id, gh_id ) source = "Web" logging( code="1002", info="root_share_id --{}, productionPath -- {}".format( root_share_id, productionPath ), function="process", trace_id=self.trace_id, ) result = { "productionCover": productionCover, "productionName": productionName, "programAvatar": programAvatar, "programId": programId, "programName": programName, "source": source, "rootShareId": root_share_id, "productionPath": productionPath, "videoUrl": videoUrl, "mini_id": mini_id, "paragraphPosition": index * 0.25, } # if gh_id in self.test_id_set and index == 1: # 只针对插入的第一个小程序位置做改变 if index == 1: result['paragraphPosition'] = 0.01 update_result_sql = f""" UPDATE {db_article} SET result{index} = %s, success = %s WHERE trace_id = %s; """ await self.mysql_client.async_insert( sql=update_result_sql, params=(json.dumps(result, ensure_ascii=False), 1, self.trace_id), ) logging( code="2000", info="统计 root_share_id && video_id", function="process", trace_id=self.trace_id, data={ "rootShareId": root_share_id, "videoId": video_id, "sourceId": source_id, }, ) return result async def generate_cards(self, video_list, kimi_title, gh_id): """ 生成一组卡片 :param video_list: :param kimi_title: :param gh_id: :return: """ L = [] LONG_ARTICLES_MINI_ID = 25 TOULIU_MINI_ID = 33 WECOME_MINI_ID = 27 if self.mini_program_type == 1: # mini_id_list = [25, 29, 31] # video_count = len(video_list) # mini_choice_index = random.sample(range(3), video_count) # mini_choice_item = [mini_id_list[i] for i in mini_choice_index] for index, video_id in enumerate(video_list, 1): # random_num = random.randint(1, 10) # if random_num in [1, 2, 3, 4, 5, 6]: # mini_id = 25 # elif random_num in [7, 8]: # mini_id = 29 # else: # mini_id = 31 result = await self.generate_card( video_id=video_id, kimi_title=kimi_title, index=index, gh_id=gh_id, mini_id=LONG_ARTICLES_MINI_ID, ) L.append(result) elif self.mini_program_type == 2: for index, video_id in enumerate(video_list, 1): result = await self.generate_card( video_id=video_id, kimi_title=kimi_title, index=index, gh_id=gh_id, mini_id=TOULIU_MINI_ID, ) L.append(result) elif self.mini_program_type == 3: for index, video_id in enumerate(video_list, 1): result = await self.generate_card( video_id=video_id, kimi_title=kimi_title, index=index, gh_id=gh_id, mini_id=WECOME_MINI_ID, ) L.append(result) return L async def deal(self): """ Recall Deal :return: """ if self.strategy == self.NEW_STRATEGY: response = await forward_requests( params={ "traceId": self.trace_id, "miniprogramUseType": self.mini_program_type, "strategy": self.strategy }, api="recall_videos" ) return response response = await self.get_result() status_code = response.get("content_status") process_times = response.get("process_times") if status_code == 0: if process_times > 3: result = { "traceId": self.trace_id, "code": 0, "error": "匹配失败,处理超过五次,文章敏感", } else: result = { "traceId": self.trace_id, "code": 0, "Message": "该请求还没处理", } elif status_code == 1: result = { "traceId": self.trace_id, "code": 1, "Message": "该请求正在处理中", } elif status_code == 2: unEmptyList = [i for i in response["vid_list"] if i] cards = await self.generate_cards( unEmptyList, response.get("kimi_title"), response["gh_id"] ) if cards: result = {"traceId": self.trace_id, "miniprogramList": cards} else: result = { "traceId": self.trace_id, "code": 0, "error": "匹配失败,视频下载失败返回vid为0", } elif status_code == 3: result = { "traceId": self.trace_id, "code": 0, "error": "匹配失败,处理超过五次,文章敏感", } else: result = {"traceId": self.trace_id, "Message": "UnKnow Error"} logging( code="1002", info="返回结果", function="process", data=result, trace_id=self.trace_id, ) return result