ai_time_task_creative_handler.py 11 KB

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