recall_deal.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. """
  2. @author: luojunhui
  3. """
  4. import json
  5. import uuid
  6. import time
  7. import random
  8. import hashlib
  9. import urllib.parse
  10. from applications.functions.log import logging
  11. from applications.static.config import db_article
  12. from applications.functions.common import request_for_info
  13. class RecallDeal(object):
  14. """
  15. 召回逻辑
  16. """
  17. def __init__(self, trace_id, mysql_client, mini_program_type):
  18. self.trace_id = trace_id
  19. self.mysql_client = mysql_client
  20. self.mini_program_type = mini_program_type
  21. async def get_result(self):
  22. """
  23. 获取结果
  24. :return:
  25. """
  26. select_sql = f"""
  27. SELECT gh_id, recall_video_id1, recall_video_id2, recall_video_id3, kimi_title, content_status, process_times
  28. FROM {db_article}
  29. WHERE trace_id = '{self.trace_id}';
  30. """
  31. info_tuple = await self.mysql_client.async_select(select_sql)
  32. gh_id, vid1, vid2, vid3, kimi_title, content_status, process_times = info_tuple[0]
  33. response = {
  34. "gh_id": gh_id,
  35. "vid_list": [vid1, vid2, vid3],
  36. "kimi_title": kimi_title,
  37. "content_status": content_status,
  38. "process_times": process_times
  39. }
  40. return response
  41. def create_gzh_path(self, video_id, shared_uid, gh_id):
  42. """
  43. :param gh_id: 公众号账号的gh_id
  44. :param video_id: 视频 id
  45. :param shared_uid: 分享 id
  46. """
  47. def generate_source_id():
  48. """
  49. generate_source_id
  50. :return:
  51. """
  52. timestamp = str(int(time.time() * 1000))
  53. random_str = str(random.randint(1000, 9999))
  54. hash_input = f"{timestamp}-{random_str}"
  55. return hashlib.md5(hash_input.encode()).hexdigest()
  56. root_share_id = str(uuid.uuid4())
  57. if self.mini_program_type == 2:
  58. source_id = "touliu_tencentGzhArticle_{}_".format(gh_id) + generate_source_id()
  59. elif self.mini_program_type == 1:
  60. source_id = "longArticles_" + generate_source_id()
  61. elif self.mini_program_type == 3:
  62. source_id = "WeCom_" + generate_source_id()
  63. else:
  64. source_id = "Error mini_program_type {}".format(self.mini_program_type)
  65. url = f"pages/user-videos?id={video_id}&su={shared_uid}&fromGzh=1&rootShareId={root_share_id}&shareId={root_share_id}&rootSourceId={source_id}"
  66. # 自动把 root_share_id 加入到白名单
  67. # auto_white(root_share_id)
  68. return root_share_id, source_id, f"pages/category?jumpPage={urllib.parse.quote(url, safe='')}"
  69. def choose_mini_program(self):
  70. """
  71. 获取小程序分享卡片
  72. :return:
  73. """
  74. if self.mini_program_type == 1:
  75. # 正常长文业务
  76. programAvatar = "https://rescdn.yishihui.com/0temp/ssyqsh.png"
  77. programId = "wx59d9e2c05f00f880"
  78. programName = "刷刷有趣生活"
  79. elif self.mini_program_type == 2:
  80. # 投流业务
  81. programAvatar = "https://rescdn.yishihui.com/0temp/zfyfyc.jpeg"
  82. programId = "wxcddf231abd0dabdc"
  83. programName = "祝福有福有财"
  84. elif self.mini_program_type == 3:
  85. # 企业微信
  86. programAvatar = "https://rescdn.yishihui.com/0temp/xymhfqdd.png"
  87. programId = "wx7187c217efef24a7"
  88. programName = "幸运美好福气多多"
  89. else:
  90. programAvatar = "https://rescdn.yishihui.com/0temp/ssyqsh.png"
  91. programId = "wx59d9e2c05f00f880"
  92. programName = "刷刷有趣生活"
  93. return programAvatar, programId, programName
  94. async def generate_card(self, video_id, kimi_title, index, gh_id):
  95. """
  96. 生成分享卡片
  97. :return:
  98. """
  99. response = request_for_info(video_id)
  100. productionCover = response['data'][0]['shareImgPath']
  101. productionName = kimi_title
  102. videoUrl = response['data'][0]['videoPath']
  103. user_id = response['data'][0]['user']['uid']
  104. programAvatar, programId, programName = self.choose_mini_program()
  105. root_share_id, source_id, productionPath = self.create_gzh_path(video_id, user_id, gh_id)
  106. source = "Web"
  107. logging(
  108. code="1002",
  109. info="root_share_id --{}, productionPath -- {}".format(root_share_id, productionPath),
  110. function="process",
  111. trace_id=self.trace_id
  112. )
  113. result = {
  114. "productionCover": productionCover,
  115. "productionName": productionName,
  116. "programAvatar": programAvatar,
  117. "programId": programId,
  118. "programName": programName,
  119. "source": source,
  120. "rootShareId": root_share_id,
  121. "productionPath": productionPath,
  122. "videoUrl": videoUrl,
  123. "paragraphPosition": index * 0.25
  124. }
  125. update_result_sql = f"""
  126. UPDATE {db_article}
  127. SET
  128. result{index} = %s,
  129. success = %s
  130. WHERE
  131. trace_id = %s;
  132. """
  133. await self.mysql_client.async_insert(
  134. sql=update_result_sql,
  135. params=(json.dumps(result, ensure_ascii=False), 1, self.trace_id)
  136. )
  137. logging(
  138. code="2000",
  139. info="统计 root_share_id && video_id",
  140. function="process",
  141. trace_id=self.trace_id,
  142. data={
  143. "rootShareId": root_share_id,
  144. "videoId": video_id,
  145. "sourceId": source_id
  146. }
  147. )
  148. return result
  149. async def deal(self):
  150. """
  151. Recall Deal
  152. :return:
  153. """
  154. response = await self.get_result()
  155. status_code = response.get("content_status")
  156. process_times = response.get("process_times")
  157. if status_code == 0:
  158. if process_times > 5:
  159. result = {
  160. "traceId": self.trace_id,
  161. "code": 0,
  162. "error": "匹配失败,处理超过五次,文章敏感"
  163. }
  164. else:
  165. result = {
  166. "traceId": self.trace_id,
  167. "code": 0,
  168. "Message": "该请求还没处理"
  169. }
  170. elif status_code == 1:
  171. result = {
  172. "traceId": self.trace_id,
  173. "code": 1,
  174. "Message": "该请求正在处理中"
  175. }
  176. elif status_code == 2:
  177. L = []
  178. unEmptyList = [i for i in response['vid_list'] if i]
  179. for index, best_video_id in enumerate(unEmptyList, 1):
  180. card = await self.generate_card(best_video_id, response.get("kimi_title"), index, response['gh_id'])
  181. L.append(card)
  182. if L:
  183. result = {
  184. "traceId": self.trace_id,
  185. "miniprogramList": L
  186. }
  187. else:
  188. result = {
  189. "traceId": self.trace_id,
  190. "code": 0,
  191. "error": "匹配失败,视频下载失败返回vid为0"
  192. }
  193. elif status_code == 3:
  194. result = {
  195. "traceId": self.trace_id,
  196. "code": 0,
  197. "error": "匹配失败,处理超过五次,文章敏感"
  198. }
  199. else:
  200. result = {
  201. "traceId": self.trace_id,
  202. "Message": "UnKnow Error"
  203. }
  204. logging(
  205. code="1002",
  206. info="返回结果",
  207. function="process",
  208. data=result,
  209. trace_id=self.trace_id
  210. )
  211. return result