|
@@ -0,0 +1,329 @@
|
|
|
+"""
|
|
|
+@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
|
|
|
+
|
|
|
+
|
|
|
+class Response(object):
|
|
|
+ """
|
|
|
+ 召回逻辑
|
|
|
+ """
|
|
|
+
|
|
|
+ def __init__(self, trace_id, mysql_client, mini_program_type):
|
|
|
+ """
|
|
|
+ 长文: 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.mini_map = {
|
|
|
+ # 25: {
|
|
|
+ # "avatar": "https://rescdn.yishihui.com/0temp/ttmhzfsh.png",
|
|
|
+ # "id": "wx0b7d95eb293b783b",
|
|
|
+ # "name": "天天美好祝福生活",
|
|
|
+ # "index": 25,
|
|
|
+ # },
|
|
|
+ 25: {
|
|
|
+ "avatar": "https://rescdn.yishihui.com/0temp/pqsp.png",
|
|
|
+ "id": "wxbdd2a2e93d9a6e25",
|
|
|
+ "name": "票圈视频",
|
|
|
+ "index": 25
|
|
|
+ },
|
|
|
+ 29: {
|
|
|
+ "avatar": "https://rescdn.yishihui.com/0temp/cyfyld.png",
|
|
|
+ "id": "wx65c76bb4c67934db",
|
|
|
+ "name": "财运福运来到",
|
|
|
+ "index": 29,
|
|
|
+ },
|
|
|
+ 31: {
|
|
|
+ "avatar": "https://rescdn.yishihui.com/0temp/mhzfshxf2.png",
|
|
|
+ "id": "wx2e4478b1641b3b15",
|
|
|
+ "name": "美好祝福生活幸福",
|
|
|
+ "index": 31,
|
|
|
+ },
|
|
|
+ 36: {
|
|
|
+ "avatar": "https://rescdn.yishihui.com/0temp/zfyfyc.jpeg",
|
|
|
+ "id": "wxcddf231abd0dabdc",
|
|
|
+ "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
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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,
|
|
|
+ }
|
|
|
+ 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 = []
|
|
|
+ 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=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=33,
|
|
|
+ )
|
|
|
+ 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=27,
|
|
|
+ )
|
|
|
+ L.append(result)
|
|
|
+ return L
|
|
|
+
|
|
|
+ async def deal(self):
|
|
|
+ """
|
|
|
+ Recall Deal
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ 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
|