ai_time_task_creative_handler.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. import pandas as pd
  2. from utils.UrlConfig import *
  3. import json
  4. import logging
  5. import traceback
  6. import tornado.web
  7. from concurrent_log import ConcurrentTimedRotatingFileHandler
  8. from utils.CommonFunction import get_history_video_info, get_new_video_info, get_missing_video_info, \
  9. get_top_video_info, get_campaign_and_group_name_rule,get_app_detail
  10. from utils.ConstantConfig import *
  11. from ai_strategy_request_func import ai_strategy_request_parse
  12. from utils.DataBaseConfig import *
  13. log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m/%d/%Y %I:%M:%S %p')
  14. log_handler = ConcurrentTimedRotatingFileHandler("logs/ai_auto_create.log", when="midnight", backupCount=100)
  15. log_handler.setFormatter(log_formatter)
  16. logger = logging.getLogger('ai_time_task_creative_logger')
  17. logger.addHandler(log_handler)
  18. logger.setLevel(logging.DEBUG)
  19. print('id of ai_time_task_creative_logger %s' % id(logger))
  20. logger.info("ai_time_task_creative_server started!")
  21. class AiHistoricalMissingMaterial(tornado.web.RequestHandler):
  22. """
  23. 补充历史遗漏素材(关联创意个数为0个素材) -- 测试通过 在AD后台创建成功,检查AD信息和数据库表 没有问题
  24. """
  25. def post(self):
  26. data = self.request.body
  27. data = str(data, 'utf8')
  28. data = json.loads(data, encoding='utf8')
  29. logger.info("*************************************** NEW REQUEST ***************************************")
  30. account_id = data.get('account_id')
  31. campaign_id = data.get('campaign_id')
  32. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  33. (account_id, os.getpid(), os.getppid(), data))
  34. try:
  35. sql = """
  36. select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy
  37. where account_id=%s and status=1 order by create_time desc limit 1
  38. """ % account_id
  39. df = pd.read_sql(sql, engine)
  40. if df['general_track'].values[0] == 0:
  41. for app_id in df['app_id_array'].values[0]:
  42. # 1、获取该 app_id 的应该详情
  43. app_id_info = get_app_detail(account_id=account_id,
  44. url=get_app_detail_url,
  45. app_id=app_id)
  46. if app_id_info['code'] != 0:
  47. logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' %
  48. (account_id, app_id, app_id_info['message']))
  49. continue
  50. # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name
  51. app_version = app_id_info['data'].get('appVersion', 'error')
  52. track_url = app_id_info['data'].get('trackUrl','error')
  53. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  54. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  55. sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign
  56. where account_id = %s
  57. and put_create_time >= '%s'
  58. and put_create_time <= '%s'
  59. """ % (account_id, start_time, end_time)
  60. campaign_df = pd.read_sql(sql, engine)
  61. for row in campaign_df.itertuples():
  62. if ('遗漏素材' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')):
  63. campaign_id = getattr(row, 'campaign_id')
  64. break
  65. # 3、获取通用视频5个
  66. general_video_info = get_missing_video_info(account_id=account_id,
  67. cnt=5,
  68. url=get_missing_video_url,
  69. start_time=missing_video_start_time,
  70. end_time=missing_video_end_time,
  71. app_version='all')
  72. if general_video_info['code'] != 0:
  73. logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' %
  74. (account_id, app_id, general_video_info['message']))
  75. # 4、获取app_id对应的视频50个
  76. special_video_info = get_missing_video_info(account_id=account_id,
  77. cnt=50,
  78. url=get_missing_video_url,
  79. start_time=missing_video_start_time,
  80. end_time=missing_video_end_time,
  81. app_version=app_version)
  82. if special_video_info['code'] != 0:
  83. logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' %
  84. (account_id, app_id, special_video_info['message']))
  85. # 5、video_info 合并
  86. full_video_info = []
  87. if general_video_info['code'] == 0:
  88. full_video_info.extend(general_video_info['data'])
  89. if special_video_info['code'] == 0:
  90. full_video_info.extend(special_video_info['data'])
  91. # 6、拼装request_data,调用ai_strategy_request_parse方法
  92. # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期
  93. # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期
  94. if full_video_info:
  95. request_data = get_request_data(account_id=account_id,
  96. campaign_id=campaign_id,
  97. video_info=full_video_info,
  98. campaign_name=app_version + '-优选广告位-' + '遗漏素材',
  99. group_name=app_version + '-优选广告位-不限-自定义-' + '遗漏素材',
  100. ai_strategy_remark="补充遗漏素材",
  101. unit_type=4,
  102. app_id=app_id,
  103. click_track_url=track_url)
  104. request = ai_strategy_request_parse(request_data)
  105. logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request))
  106. else:
  107. logger.info("account_id=%s, app_id=%s, 没有获取到视频,不发送ai策略请求!" % (account_id, app_id))
  108. # TODO 返回信息如何组织内容
  109. self.write(json.dumps({"account_id=%s, 多应用的补充遗漏素材请求已走完!" % account_id}))
  110. self.flush()
  111. else:
  112. video_info = get_missing_video_info(account_id,
  113. missing_video_cnt,
  114. get_missing_video_url,
  115. missing_video_start_time,
  116. missing_video_end_time)
  117. if video_info['code'] != 0:
  118. logger.info("the res of video is %s" % video_info['message'])
  119. logger.info("没有获取到视频,不发送ai策略请求!")
  120. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  121. self.flush()
  122. else:
  123. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  124. if (campaign_name is None) or (group_name is None):
  125. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  126. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  127. self.flush()
  128. else:
  129. request_data = get_request_data(account_id=account_id,
  130. campaign_id=campaign_id,
  131. video_info=video_info['data'],
  132. campaign_name=campaign_name,
  133. group_name=group_name,
  134. ai_strategy_remark="补充遗漏素材",
  135. name_replace="补充遗漏素材")
  136. request = ai_strategy_request_parse(request_data)
  137. logger.info("ai策略的返回信息:%s" % request)
  138. self.write(json.dumps(request))
  139. self.flush()
  140. except Exception:
  141. logger.error(traceback.format_exc())
  142. self.write(json.dumps(traceback.format_exc()))
  143. self.flush()
  144. class AiAutoCreative(tornado.web.RequestHandler):
  145. """
  146. 每5分钟,检查一次是否有上新素材,有的话,就自动创建 -- 需要上定时任务测试
  147. """
  148. def post(self):
  149. data = self.request.body
  150. data = str(data, 'utf8')
  151. data = json.loads(data, encoding='utf8')
  152. logger.info("*************************************** NEW REQUEST ***************************************")
  153. account_id = data.get('account_id')
  154. campaign_id = data.get('campaign_id')
  155. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  156. (account_id, os.getpid(), os.getppid(), data))
  157. try:
  158. sql = """
  159. select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy
  160. where account_id=%s and status=1 order by create_time desc limit 1
  161. """ % account_id
  162. df = pd.read_sql(sql, engine)
  163. if df['general_track'].values[0] == 0:
  164. for app_id in df['app_id_array'].values[0]:
  165. # 1、获取该 app_id 的应该详情
  166. app_id_info = get_app_detail(account_id=account_id,
  167. url=get_app_detail_url,
  168. app_id=app_id)
  169. if app_id_info['code'] != 0:
  170. logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' %
  171. (account_id, app_id, app_id_info['message']))
  172. continue
  173. # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name
  174. app_version = app_id_info['data'].get('appVersion', 'error')
  175. track_url = app_id_info['data'].get('trackUrl', 'error')
  176. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  177. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  178. sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign
  179. where account_id = %s
  180. and put_create_time >= '%s'
  181. and put_create_time <= '%s'
  182. """ % (account_id, start_time, end_time)
  183. campaign_df = pd.read_sql(sql, engine)
  184. for row in campaign_df.itertuples():
  185. if ('素材自动上新' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')):
  186. campaign_id = getattr(row, 'campaign_id')
  187. break
  188. # 3、获取通用视频
  189. general_video_info = get_new_video_info(account_id=account_id,
  190. url=get_new_video_url,
  191. app_version='all')
  192. if general_video_info['code'] != 0:
  193. logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' %
  194. (account_id, app_id, general_video_info['message']))
  195. # 4、获取app_id对应的视频
  196. special_video_info = get_new_video_info(account_id=account_id,
  197. url=get_new_video_url,
  198. app_version=app_version)
  199. if special_video_info['code'] != 0:
  200. logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' %
  201. (account_id, app_id, special_video_info['message']))
  202. # 5、video_info 合并
  203. full_video_info = []
  204. if general_video_info['code'] == 0:
  205. full_video_info.extend(general_video_info['data'])
  206. if special_video_info['code'] == 0:
  207. full_video_info.extend(special_video_info['data'])
  208. # 6、拼装request_data,调用ai_strategy_request_parse方法
  209. # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期
  210. # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期
  211. if full_video_info:
  212. request_data = get_request_data(account_id=account_id,
  213. campaign_id=campaign_id,
  214. video_info=full_video_info,
  215. campaign_name=app_version + '-优选广告位-' + '素材自动上新',
  216. group_name=app_version + '-优选广告位-不限-自定义-' + '素材自动上新',
  217. ai_strategy_remark="素材自动上新",
  218. unit_type=4,
  219. app_id=app_id,
  220. click_track_url=track_url)
  221. request = ai_strategy_request_parse(request_data)
  222. logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request))
  223. else:
  224. logger.info("account_id=%s, app_id=%s, 没有获取到视频,不发送ai策略请求!" % (account_id, app_id))
  225. self.write(json.dumps({"account_id=%s, 多应用的素材自动上新请求已走完!" % account_id}))
  226. self.flush()
  227. else:
  228. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  229. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  230. # 1-1 获取当天计划中包含“自动上新”计划的,计划id
  231. sql = """
  232. select campaign_id, campaign_name from ctop_kuaishou_campaign
  233. where account_id = %s
  234. and put_create_time >= '%s'
  235. and put_create_time <= '%s'
  236. """ % (account_id, start_time, end_time)
  237. df = pd.read_sql(sql, engine)
  238. for row in df.itertuples():
  239. if '素材自动上新' in getattr(row, 'campaign_name'):
  240. campaign_id = getattr(row, 'campaign_id')
  241. break
  242. video_info = get_new_video_info(account_id, get_new_video_url)
  243. if video_info['code'] != 0:
  244. logger.info("the res of video is %s" % video_info['message'])
  245. logger.info("没有获取到视频,不发送ai策略请求!")
  246. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  247. self.flush()
  248. else:
  249. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  250. if (campaign_name is None) or (group_name is None):
  251. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  252. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  253. self.flush()
  254. else:
  255. request_data = get_request_data(account_id=account_id,
  256. campaign_id=campaign_id,
  257. video_info=video_info['data'],
  258. campaign_name=campaign_name,
  259. group_name=group_name,
  260. ai_strategy_remark="自动上新",
  261. name_replace="素材自动上新")
  262. request = ai_strategy_request_parse(request_data)
  263. logger.info("ai策略的返回信息:%s" % request)
  264. self.write(json.dumps(request))
  265. self.flush()
  266. except Exception:
  267. logger.error(traceback.format_exc())
  268. self.write(json.dumps(traceback.format_exc()))
  269. self.flush()
  270. class AiHighQualityMaterial(tornado.web.RequestHandler):
  271. """
  272. 补充历史高质量素材 -- 测试通过 在AD后台创建成功,检查AD信息和数据库表 没有问题
  273. """
  274. def post(self):
  275. data = self.request.body
  276. data = str(data, 'utf8')
  277. data = json.loads(data, encoding='utf8')
  278. logger.info("*************************************** NEW REQUEST ***************************************")
  279. account_id = data.get('account_id')
  280. campaign_id = data.get('campaign_id')
  281. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  282. (account_id, os.getpid(), os.getppid(), data))
  283. try:
  284. sql = """select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy
  285. where account_id=%s and status=1 order by create_time desc limit 1
  286. """ % account_id
  287. df = pd.read_sql(sql, engine)
  288. if df['general_track'].values[0] == 0:
  289. for app_id in df['app_id_array'].values[0]:
  290. # 1、获取该 app_id 的应该详情
  291. app_id_info = get_app_detail(account_id=account_id,
  292. url=get_app_detail_url,
  293. app_id=app_id)
  294. if app_id_info['code'] != 0:
  295. logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' %
  296. (account_id, app_id, app_id_info['message']))
  297. continue
  298. # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name
  299. app_version = app_id_info['data'].get('appVersion', 'error')
  300. track_url = app_id_info['data'].get('trackUrl', 'error')
  301. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  302. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  303. sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign
  304. where account_id = %s
  305. and put_create_time >= '%s'
  306. and put_create_time <= '%s'
  307. """ % (account_id, start_time, end_time)
  308. campaign_df = pd.read_sql(sql, engine)
  309. for row in campaign_df.itertuples():
  310. if ('高质量素材' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')):
  311. campaign_id = getattr(row, 'campaign_id')
  312. break
  313. # 3、获取通用视频
  314. general_video_info = get_top_video_info(account_id=account_id,
  315. url=get_high_quality_video_url,
  316. start_time=(datetime.datetime.now() +
  317. datetime.timedelta(days=-high_quality_video_days)).
  318. strftime("%Y-%m-%d"),
  319. end_time=str(datetime.date.today()),
  320. app_version='all')
  321. if general_video_info['code'] != 0:
  322. logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' %
  323. (account_id, app_id, general_video_info['message']))
  324. # 4、获取app_id对应的视频
  325. special_video_info = get_top_video_info(account_id=account_id,
  326. url=get_high_quality_video_url,
  327. start_time=(datetime.datetime.now() +
  328. datetime.timedelta(days=-high_quality_video_days)).
  329. strftime("%Y-%m-%d"),
  330. end_time=str(datetime.date.today()),
  331. app_version=app_version)
  332. if special_video_info['code'] != 0:
  333. logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' %
  334. (account_id, app_id, special_video_info['message']))
  335. # 5、video_info 合并
  336. full_video_info = []
  337. if general_video_info['code'] == 0:
  338. full_video_info.extend(general_video_info['data'])
  339. if special_video_info['code'] == 0:
  340. full_video_info.extend(special_video_info['data'])
  341. # 6、拼装request_data,调用ai_strategy_request_parse方法
  342. # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期
  343. # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期
  344. if full_video_info:
  345. request_data = get_request_data(account_id=account_id,
  346. campaign_id=campaign_id,
  347. video_info=full_video_info,
  348. campaign_name=app_version + '-优选广告位-' + '高质量素材',
  349. group_name=app_version + '-优选广告位-不限-自定义-' + '高质量素材',
  350. ai_strategy_remark="高质量素材复建",
  351. unit_type=4,
  352. app_id=app_id,
  353. click_track_url=track_url)
  354. request = ai_strategy_request_parse(request_data)
  355. logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request))
  356. else:
  357. logger.info("account_id=%s, app_id=%s, 没有获取到视频,不发送ai策略请求!" % (account_id, app_id))
  358. self.write(json.dumps({"account_id=%s, 多应用的高质量素材复建请求已走完!" % account_id}))
  359. self.flush()
  360. else:
  361. video_info = get_top_video_info(account_id, high_quality_video_cnt,
  362. (datetime.datetime.now() + datetime.timedelta(
  363. days=-high_quality_video_days)).strftime("%Y-%m-%d"),
  364. str(datetime.date.today()), get_high_quality_video_url)
  365. if video_info['code'] != 0:
  366. logger.info("the res of video is %s" % video_info['message'])
  367. logger.info("没有获取到视频,不发送ai策略请求!")
  368. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  369. self.flush()
  370. else:
  371. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  372. if (campaign_name is None) or (group_name is None):
  373. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  374. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  375. self.flush()
  376. else:
  377. request_data = get_request_data(account_id=account_id,
  378. campaign_id=campaign_id,
  379. video_info=video_info['data'],
  380. campaign_name=campaign_name,
  381. group_name=group_name,
  382. ai_strategy_remark="高质量素材复建",
  383. name_replace="高质量素材")
  384. request = ai_strategy_request_parse(request_data)
  385. logger.info("ai策略的返回信息:%s" % request)
  386. self.write(json.dumps(request))
  387. self.flush()
  388. except Exception:
  389. logger.error(traceback.format_exc())
  390. self.write(json.dumps(traceback.format_exc()))
  391. self.flush()
  392. class AiCheckAndUpTOFullCreative(tornado.web.RequestHandler):
  393. """
  394. 每天22:00 调用该任务,检查当天创意是否创建达到上限,否则使用历史高质量素材填满 -- 测试通过 在AD后台创建成功,检查AD信息和数据库表 没有问题
  395. """
  396. def post(self):
  397. data = self.request.body
  398. data = str(data, 'utf8')
  399. data = json.loads(data, encoding='utf8')
  400. logger.info("*************************************** NEW REQUEST ***************************************")
  401. account_id = data.get('account_id')
  402. campaign_id = data.get('campaign_id')
  403. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  404. (account_id, os.getpid(), os.getppid(), data))
  405. try:
  406. start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S')
  407. end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
  408. # 1-1 获取当天计划中包含“高质量素材”计划的,计划id
  409. sql = """
  410. select campaign_id, campaign_name from ctop_kuaishou_campaign
  411. where account_id = %s
  412. and put_create_time >= '%s'
  413. and put_create_time <= '%s'
  414. """ % (account_id, start_time, end_time)
  415. df = pd.read_sql(sql, engine)
  416. for row in df.itertuples():
  417. if '高质量素材' in getattr(row, 'campaign_name'):
  418. campaign_id = getattr(row, 'campaign_id')
  419. break
  420. # 2-1 从客户策略表中获取该账户下 每个素材搭配的封面个数, 来计算需要补充的素材个数
  421. sql = """
  422. select image_cnt from ctop_ai_kuaishou_advertiser_strategy
  423. where account_id = %s
  424. and status = 1
  425. limit 1
  426. """ % account_id
  427. df = pd.read_sql(sql, engine)
  428. image_cnt = int(df['image_cnt'].values[0])
  429. # 3-1 从 ctop_kuaishou_creative 获取当天该账户到此刻 已经创建的创意个数
  430. video_cnt = 0
  431. sql = """
  432. select count(1) creative_cnt from ctop_kuaishou_creative
  433. where account_id = %s
  434. and creative_id is not NULL
  435. and creative_create_time <= '%s'
  436. and creative_create_time >= '%s'
  437. """ % (account_id, end_time, start_time)
  438. df = pd.read_sql(sql, engine)
  439. creative_cnt = int(df['creative_cnt'].values[0])
  440. if creative_cnt >= 2000:
  441. video_cnt = 0
  442. else:
  443. video_cnt = (2000 - creative_cnt) // image_cnt
  444. # 4-1 获取视频信息
  445. if video_cnt == 0:
  446. logger.info("创意已经建满,不需要补充素材!")
  447. self.write(json.dumps("message: 创意已经建满,不需要补充素材!"))
  448. self.flush()
  449. else:
  450. logger.info("需要补充的视频数量:%s" % video_cnt)
  451. now = datetime.datetime.now()
  452. video_info = get_top_video_info(account_id,
  453. video_cnt,
  454. (now + datetime.timedelta(days=-2*high_quality_video_days)).strftime("%Y-%m-%d"),
  455. (now + datetime.timedelta(days=-high_quality_video_days)).strftime("%Y-%m-%d"),
  456. get_high_quality_video_url)
  457. if video_info['code'] != 0:
  458. logger.info("the res of video is %s" % video_info['message'])
  459. logger.info("没有获取到视频,不发送ai策略请求!")
  460. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  461. self.flush()
  462. else:
  463. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  464. if (campaign_name is None) or (group_name is None):
  465. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  466. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  467. self.flush()
  468. else:
  469. request_data = get_request_data(account_id=account_id,
  470. campaign_id=campaign_id,
  471. video_info=video_info['data'],
  472. campaign_name=campaign_name,
  473. group_name=group_name,
  474. ai_strategy_remark="用高质量素材补满创意",
  475. name_replace="高质量素材")
  476. request = ai_strategy_request_parse(request_data)
  477. logger.info("ai策略的返回信息:%s" % request)
  478. self.write(json.dumps(request))
  479. self.flush()
  480. except Exception:
  481. logger.error(traceback.format_exc())
  482. self.write(json.dumps(traceback.format_exc()))
  483. self.flush()
  484. class AiProgramCreativeHighQualityMaterial(tornado.web.RequestHandler):
  485. """
  486. 使用历史跑量素材创建程序化创意
  487. 跑量素材150个(近14天的素材)
  488. 计划名称--跑量素材程序化
  489. timeTask: 每天上午10点执行 --(0 0 10 * * ?)
  490. ----------------------------------------
  491. 拼装参数和写入数据库时,需要修改名称(程序化与非程序化不一致):
  492. creative_name --> package_name(程序化创意名称)
  493. action_bar_text --> action_bar(行动号召按钮)
  494. description --> captions(作品广告语)
  495. click_track_url --> click_url
  496. 写入数据库时:
  497. image_md5s --> cover_image_tokens
  498. 程序化与非程序化的逻辑不一样:
  499. 需要5个视频4张封面一组,拼装程序化创意参数需要单独抽取一个方法出来
  500. 所有操作记录表中,添加status信息(已提交,成功,失败),和回调时的 message信息
  501. """
  502. def post(self):
  503. data = self.request.body
  504. data = str(data, 'utf8')
  505. data = json.loads(data, encoding='utf8')
  506. logger.info("*************************************** NEW REQUEST ***************************************")
  507. account_id = data.get('account_id')
  508. campaign_id = data.get('campaign_id')
  509. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  510. (account_id, os.getpid(), os.getppid(), data))
  511. try:
  512. video_info = get_top_video_info(account_id, programme_high_quality_video_cnt,
  513. (datetime.datetime.now() + datetime.timedelta(
  514. days=-high_quality_video_days)).strftime("%Y-%m-%d"),
  515. str(datetime.date.today()), get_high_quality_video_url)
  516. if video_info['code'] != 0:
  517. logger.info("the res of video is %s" % video_info['message'])
  518. logger.info("没有获取到视频,不发送ai策略请求!")
  519. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  520. self.flush()
  521. else:
  522. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  523. if (campaign_name is None) or (group_name is None):
  524. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  525. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  526. self.flush()
  527. else:
  528. request_data = get_request_data(account_id=account_id,
  529. campaign_id=campaign_id,
  530. video_info=video_info['data'],
  531. campaign_name=campaign_name,
  532. group_name=group_name,
  533. ai_strategy_remark="程序化高质量素材",
  534. name_replace="程序化高质量素材",
  535. unit_type=7)
  536. request = ai_strategy_request_parse(request_data)
  537. logger.info("ai策略的返回信息:%s" % request)
  538. self.write(json.dumps(request))
  539. self.flush()
  540. except Exception:
  541. logger.error(traceback.format_exc())
  542. self.write(json.dumps(traceback.format_exc()))
  543. self.flush()
  544. class AiProgramCreativeNewMaterial(tornado.web.RequestHandler):
  545. """
  546. 使用近期创意数关联小于10(当天创意关联数小于10的,150个素材)的素材创建程序化创意
  547. 计划名称--新素材程序化
  548. timeTask: 每天上午10点执行 --(0 0 10 * * ?)
  549. """
  550. def post(self):
  551. data = self.request.body
  552. data = str(data, 'utf8')
  553. data = json.loads(data, encoding='utf8')
  554. logger.info("*************************************** NEW REQUEST ***************************************")
  555. account_id = data.get('account_id')
  556. campaign_id = data.get('campaign_id')
  557. logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" %
  558. (account_id, os.getpid(), os.getppid(), data))
  559. try:
  560. video_info = get_history_video_info(account_id=account_id,
  561. url=get_history_video_url,
  562. start_time=(datetime.datetime.now() + datetime.timedelta(days=-2)).
  563. strftime("%Y-%m-%d"),
  564. end_time=str(datetime.date.today()),
  565. video_cnt=programme_new_video_cnt,
  566. related_creative_max_cnt=related_creative_max_cnt)
  567. if video_info['code'] != 0:
  568. logger.info("the res of video is %s" % video_info['message'])
  569. logger.info("没有获取到视频,不发送ai策略请求!")
  570. self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
  571. self.flush()
  572. else:
  573. campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
  574. if (campaign_name is None) or (group_name is None):
  575. logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!")
  576. self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
  577. self.flush()
  578. else:
  579. request_data = get_request_data(account_id=account_id,
  580. campaign_id=campaign_id,
  581. video_info=video_info['data'],
  582. campaign_name=campaign_name,
  583. group_name=group_name,
  584. ai_strategy_remark="程序化上新素材",
  585. name_replace="程序化上新素材",
  586. unit_type=7)
  587. request = ai_strategy_request_parse(request_data)
  588. logger.info("ai策略的返回信息:%s" % request)
  589. self.write(json.dumps(request))
  590. self.flush()
  591. except Exception:
  592. logger.error(traceback.format_exc())
  593. self.write(json.dumps(traceback.format_exc()))
  594. self.flush()
  595. def get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
  596. ai_strategy_remark, name_replace='',
  597. unit_type=4, click_track_url=None, app_id=None):
  598. res = {
  599. "video": video_info,
  600. "operation_type": 1,
  601. "account_id": account_id,
  602. "ai_strategy_remark": ai_strategy_remark,
  603. "campaign_info":
  604. {"campaign_id": campaign_id,
  605. "campaign_name": (campaign_name.replace('自定义', name_replace) + str(datetime.datetime.now()))
  606. if not name_replace else (campaign_name + str(datetime.datetime.now()))},
  607. 'group_info':
  608. {'group_name': (group_name.replace('自定义', name_replace) + str(datetime.datetime.now()))
  609. if not name_replace else (group_name + str(datetime.datetime.now())),
  610. 'begin_time': str(datetime.date.today()),
  611. 'unit_type': unit_type,
  612. 'app_id': app_id},
  613. 'creative_info': {'is_sticky': 0,
  614. 'click_track_url': click_track_url}
  615. }
  616. return res