response.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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.log import logging
  11. class Response(object):
  12. """
  13. Response
  14. """
  15. def __init__(self, params, mysql_client, config):
  16. """
  17. Response 接口
  18. """
  19. self.trace_id = None
  20. self.mini_program_type = None
  21. self.mysql_client = mysql_client
  22. self.params = params
  23. self.article_match_video_table = config.article_match_video_table
  24. self.mini_program_map = json.loads(config.getConfigValue("miniMap"))
  25. def check_params(self):
  26. """
  27. 请求参数校验
  28. :return:
  29. """
  30. try:
  31. self.mini_program_type = self.params['miniprogramUseType']
  32. self.trace_id = self.params['traceId']
  33. return None
  34. except Exception as e:
  35. return {
  36. "error": "params error",
  37. "msg": str(e),
  38. "info": self.params
  39. }
  40. async def get_videos_result(self):
  41. """
  42. 获取结果
  43. :return:
  44. """
  45. select_sql = f"""
  46. SELECT gh_id, content_status, response, process_times
  47. FROM {self.article_match_video_table}
  48. WHERE trace_id = '{self.trace_id}';
  49. """
  50. info_tuple = await self.mysql_client.async_select(select_sql)
  51. gh_id, content_status, response, process_times = info_tuple[0]
  52. return {
  53. "ghId": gh_id,
  54. "contentStatus": content_status,
  55. "response": response,
  56. "processTimes": process_times
  57. }
  58. def create_gzh_path(self, video_id, shared_uid, gh_id):
  59. """
  60. :param gh_id: 公众号账号的gh_id
  61. :param video_id: 视频 id
  62. :param shared_uid: 分享 id
  63. """
  64. def generate_source_id():
  65. """
  66. generate_source_id
  67. :return:
  68. """
  69. timestamp = str(int(time.time() * 1000))
  70. random_str = str(random.randint(1000, 9999))
  71. hash_input = f"{timestamp}-{random_str}"
  72. return hashlib.md5(hash_input.encode()).hexdigest()
  73. root_share_id = str(uuid.uuid4())
  74. if self.mini_program_type == 2:
  75. source_id = (
  76. "touliu_tencentGzhArticle_{}_".format(gh_id) + generate_source_id()
  77. )
  78. elif self.mini_program_type == 1:
  79. source_id = "longArticles_" + generate_source_id()
  80. elif self.mini_program_type == 3:
  81. source_id = "WeCom_" + generate_source_id()
  82. else:
  83. source_id = "Error mini_program_type {}".format(self.mini_program_type)
  84. url = f"pages/user-videos?id={video_id}&su={shared_uid}&fromGzh=1&rootShareId={root_share_id}&shareId={root_share_id}&rootSourceId={source_id}"
  85. # 自动把 root_share_id 加入到白名单
  86. # auto_white(root_share_id)
  87. return (
  88. root_share_id,
  89. source_id,
  90. f"pages/category?jumpPage={urllib.parse.quote(url, safe='')}",
  91. )
  92. async def generate_single_card(self, index, gh_id, mini_id, item):
  93. """
  94. 生成单个分享卡片
  95. :param item: 单个视频结果
  96. :param mini_id: 小程序 appType
  97. :param gh_id: 公众号 id
  98. :param index: 视频位置
  99. :return:
  100. """
  101. str_mini_id = str(mini_id)
  102. mini_info = self.mini_program_map[str_mini_id]
  103. avatar, app_id, app_name = mini_info['avatar'], mini_info['id'], mini_info['name']
  104. root_share_id, root_source_id, production_path = self.create_gzh_path(
  105. video_id=item['videoId'],
  106. shared_uid=item['uid'],
  107. gh_id=gh_id
  108. )
  109. logging(
  110. code="1002",
  111. info="root_share_id --{}, productionPath -- {}".format(
  112. root_share_id, production_path
  113. ),
  114. function="process",
  115. trace_id=self.trace_id,
  116. )
  117. result = {
  118. "productionCover": item['videoCover'],
  119. "productionName": item['kimiTitle'],
  120. "programAvatar": avatar,
  121. "programId": app_id,
  122. "programName": app_name,
  123. "source": item['source'],
  124. "rootShareId": root_share_id,
  125. "productionPath": production_path,
  126. "videoUrl": item['videoPath'],
  127. "mini_id": mini_id,
  128. "paragraphPosition": index * 0.25
  129. }
  130. if index == 1:
  131. result['paragraphPosition'] = 0.01
  132. item['rootSourceId'] = root_source_id
  133. return result, item
  134. async def generate_cards(self, result):
  135. """
  136. 生成返回卡片
  137. :return:
  138. """
  139. gh_id = result['ghId']
  140. response = json.loads(result['response'])
  141. touliu_mini_program_id = 33
  142. we_com_mini_program_id = 27
  143. match self.mini_program_type:
  144. case 1:
  145. L = []
  146. new_item_list = []
  147. for index, item in enumerate(response, 1):
  148. random_num = random.randint(1, 10)
  149. if random_num in [1, 2, 3, 4, 5, 6]:
  150. long_articles_mini_program_id = 25
  151. elif random_num in [7, 8]:
  152. long_articles_mini_program_id = 29
  153. else:
  154. long_articles_mini_program_id = 31
  155. card, new_item = await self.generate_single_card(index, gh_id, long_articles_mini_program_id, item)
  156. L.append(card)
  157. new_item_list.append(new_item)
  158. return L, new_item_list
  159. case 2:
  160. L = []
  161. new_item_list = []
  162. for index, item in enumerate(response, 1):
  163. card, new_item = await self.generate_single_card(index, gh_id, touliu_mini_program_id, item)
  164. L.append(card)
  165. new_item_list.append(new_item)
  166. return L, new_item_list
  167. case 3:
  168. L = []
  169. new_item_list = []
  170. for index, item in enumerate(response, 1):
  171. card, new_item = await self.generate_single_card(index, gh_id, we_com_mini_program_id, item)
  172. L.append(card)
  173. new_item_list.append(card)
  174. return L, new_item_list
  175. async def job(self):
  176. """
  177. 执行方法
  178. :return:
  179. """
  180. response = await self.get_videos_result()
  181. status_code = response.get('contentStatus')
  182. process_times = response.get('processTimes')
  183. match status_code:
  184. case 0:
  185. if process_times > 3:
  186. result = {
  187. "traceId": self.trace_id,
  188. "code": 0,
  189. "error": "匹配失败,处理超过 3 次"
  190. }
  191. else:
  192. result = {
  193. "traceId": self.trace_id,
  194. "code": 0,
  195. "Message": "该请求还没处理"
  196. }
  197. return result
  198. case 1:
  199. return {
  200. "traceId": self.trace_id,
  201. "code": 1,
  202. "Message": "该请求正在处理中"
  203. }
  204. case 2:
  205. card_list, new_items = await self.generate_cards(result=response)
  206. update_sql = f"""
  207. UPDATE {self.article_match_video_table}
  208. SET response = %s, success_status = %s
  209. WHERE trace_id = %s;
  210. """
  211. await self.mysql_client.async_insert(
  212. sql=update_sql,
  213. params=(json.dumps(new_items, ensure_ascii=False), 1, self.trace_id)
  214. )
  215. return {"traceId": self.trace_id, "miniprogramList": card_list}
  216. case 3:
  217. return {
  218. "traceId": self.trace_id,
  219. "code": 3,
  220. "error": "匹配失败,超过三次"
  221. }
  222. case 4:
  223. return {}
  224. async def deal(self):
  225. """
  226. api process starts from here
  227. :return:
  228. """
  229. params_error = self.check_params()
  230. if params_error:
  231. return params_error
  232. else:
  233. return await self.job()