ai_time_task_creative_handler.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import datetime
  2. import traceback
  3. from logging.handlers import TimedRotatingFileHandler
  4. from utils.BaseClass import *
  5. from utils.CommonFunction import *
  6. from utils.ConstantConfig import *
  7. from utils.LogConfig import *
  8. log_handler = TimedRotatingFileHandler("logs/ai_auto_create/ai_auto_create.log",
  9. when="midnight", backupCount=100)
  10. log_handler.setFormatter(log_formatter)
  11. logger = logging.getLogger('ai_time_task_creative_logger')
  12. logger.addHandler(log_handler)
  13. logger.setLevel(logging.DEBUG)
  14. print('id of ai_time_task_creative_logger %s' % id(logger))
  15. class AiHistoricalMissingMaterial(tornado.web.RequestHandler):
  16. """
  17. 补充历史遗漏素材(关联创意个数为0个素材)
  18. """
  19. def post(self):
  20. data = self.request.body
  21. data = str(data, 'utf8')
  22. data = json.loads(data, encoding='utf8')
  23. logger.info("*************************************** NEW REQUEST ***************************************")
  24. logger.info("raw data from request is %s" % data)
  25. account_id = data.get('account_id')
  26. campaign_id = data.get('campaign_id')
  27. try:
  28. video_info = get_missing_video_info(account_id, historical_missing_video_cnt, get_missing_video_url)
  29. if video_info is None:
  30. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  31. self.flush()
  32. else:
  33. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  34. if (campaign_name is None) or (group_name is None):
  35. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  36. self.flush()
  37. else:
  38. request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  39. "补充遗漏素材", "补充遗漏素材")
  40. print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
  41. request = requests.post(ai_strategy_request_url, request_data)
  42. print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
  43. logger.info("ai策略的返回信息:%s" % request.text)
  44. self.write(request.text)
  45. self.flush()
  46. except Exception:
  47. logger.error(traceback.format_exc())
  48. self.write(json.dumps(traceback.format_exc()))
  49. self.flush()
  50. class AiAutoCreative(tornado.web.RequestHandler):
  51. """
  52. 每5分钟,检查一次是否有上新素材,有的话,就自动创建
  53. """
  54. def post(self):
  55. data = self.request.body
  56. data = str(data, 'utf8')
  57. data = json.loads(data, encoding='utf8')
  58. logger.info("*************************************** NEW REQUEST ***************************************")
  59. logger.info("raw data from request is %s" % data)
  60. account_id = data.get('account_id')
  61. campaign_id = data.get('campaign_id')
  62. try:
  63. video_info = get_new_video_info(account_id, get_new_video_url)
  64. if video_info is None:
  65. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  66. self.flush()
  67. else:
  68. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  69. if (campaign_name is None) or (group_name is None):
  70. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  71. self.flush()
  72. else:
  73. request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  74. "自动上新", "上新")
  75. request = requests.post(ai_strategy_request_url, request_data)
  76. logger.info("ai策略的返回信息:%s" % request.text)
  77. self.write(request.text)
  78. self.flush()
  79. except Exception:
  80. logger.error(traceback.format_exc())
  81. self.write(json.dumps(traceback.format_exc()))
  82. self.flush()
  83. class AiHighQualityMaterial(tornado.web.RequestHandler):
  84. """
  85. 补充历史跑量素材
  86. """
  87. def post(self):
  88. data = self.request.body
  89. data = str(data, 'utf8')
  90. data = json.loads(data, encoding='utf8')
  91. logger.info("*************************************** NEW REQUEST ***************************************")
  92. logger.info("raw data from request is %s" % data)
  93. account_id = data.get('account_id')
  94. campaign_id = data.get('campaign_id')
  95. try:
  96. video_info = get_top_video_info(account_id, high_quality_video_cnt,
  97. (datetime.datetime.now() + datetime.timedelta(days=-high_quality_video_days)).strftime("%Y-%m-%d"),
  98. str(datetime.date.today()), get_high_quality_video_url)
  99. if video_info is None:
  100. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  101. self.flush()
  102. else:
  103. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  104. if (campaign_name is None) or (group_name is None):
  105. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  106. self.flush()
  107. else:
  108. request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  109. "跑量素材", "跑量素材")
  110. request = requests.post(ai_strategy_request_url, request_data)
  111. logger.info("ai策略的返回信息:%s" % request.text)
  112. self.write(request.text)
  113. self.flush()
  114. except Exception:
  115. logger.error(traceback.format_exc())
  116. self.write(json.dumps(traceback.format_exc()))
  117. self.flush()
  118. class AiCheckAndUpTOFullCreative(tornado.web.RequestHandler):
  119. """
  120. 每天22:00 调用该任务,检查当天创意是否创建达到上限,否则使用历史跑量素材填满
  121. """
  122. def post(self):
  123. data = self.request.body
  124. data = str(data, 'utf8')
  125. data = json.loads(data, encoding='utf8')
  126. logger.info("*************************************** NEW REQUEST ***************************************")
  127. logger.info("raw data from request is %s" % data)
  128. account_id = data.get('account_id')
  129. campaign_id = data.get('campaign_id')
  130. try:
  131. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  132. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  133. # 1-1 获取当天计划中包含“跑量素材”计划的,计划id
  134. sql = """
  135. select campaign_id, campaign_name from ctop_kuaishou_campaign
  136. where account_id = %s
  137. and put_create_time >= '%s'
  138. and put_create_time <= '%s'
  139. """ % (account_id, start_time, end_time)
  140. df = pd.read_sql(sql, engine)
  141. for row in df.itertuples():
  142. if '跑量素材' in getattr(row, 'campaign_name'):
  143. campaign_id = getattr(row, 'campaign_id')
  144. break
  145. # 2-1 从客户策略表中获取该账户下 每个素材搭配的封面个数, 来计算需要补充的素材个数
  146. sql = """
  147. select image_cnt from ctop_ai_kuaishou_advertiser_strategy
  148. where account_id = %s
  149. and status = 1
  150. limit 1
  151. """ % account_id
  152. df = pd.read_sql(sql, engine)
  153. image_cnt = df['image_cnt'].values[0]
  154. # 3-1 从 ctop_kuaishou_creative 获取当天该账户到此刻 已经创建的创意个数
  155. video_cnt = 0
  156. sql = """
  157. select count(1) creative_cnt from ctop_kuaishou_creative
  158. where account_id = %s
  159. and creative_id is not NULL
  160. and creative_create_time <= '%s'
  161. and creative_create_time >= '%s'
  162. """ % (account_id, end_time, start_time)
  163. df = pd.read_sql(sql, engine)
  164. creative_cnt = df['creative_cnt'].values[0]
  165. if creative_cnt >= 2000:
  166. video_cnt = 0
  167. else:
  168. video_cnt = (2000 - creative_cnt) // image_cnt
  169. # 4-1 获取视频信息
  170. if video_cnt == 0:
  171. logger.info("创意已经建满,不需要补充素材!")
  172. self.write(json.dumps("message: 创意已经建满,不需要补充素材!"))
  173. self.flush()
  174. else:
  175. now = datetime.datetime.now()
  176. video_info = get_top_video_info(account_id,
  177. video_cnt,
  178. (now + datetime.timedelta(days=-2*high_quality_video_days)).strftime("%Y-%m-%d"),
  179. (now + datetime.timedelta(days=-high_quality_video_days)).strftime("%Y-%m-%d"),
  180. get_high_quality_video_url)
  181. if video_info is None:
  182. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  183. self.flush()
  184. else:
  185. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  186. if (campaign_name is None) or (group_name is None):
  187. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  188. self.flush()
  189. else:
  190. request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  191. "跑量素材", "跑量素材")
  192. request = requests.post(ai_strategy_request_url, request_data)
  193. logger.info("ai策略的返回信息:%s" % request.text)
  194. self.write(request.text)
  195. self.flush()
  196. except Exception:
  197. logger.error(traceback.format_exc())
  198. self.write(json.dumps(traceback.format_exc()))
  199. self.flush()
  200. def get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,ai_strategy_remark, name_replace):
  201. res = {
  202. "video": video_info,
  203. "operation_type": 1,
  204. "account_id": account_id,
  205. "ai_strategy_remark": ai_strategy_remark,
  206. "campaign_info":
  207. {"campaign_id": campaign_id,
  208. "campaign_name": campaign_name.replace('自定义', name_replace) + str(datetime.datetime.now())},
  209. 'group_info':
  210. {'group_name': group_name.replace('自定义', name_replace) + str(datetime.datetime.now()),
  211. 'begin_time': str(datetime.date.today())},
  212. 'creative_info': {'is_sticky': 0}
  213. }
  214. return res