import pandas as pd from utils.UrlConfig import * import json import logging import traceback import random import tornado.web from concurrent_log import ConcurrentTimedRotatingFileHandler from utils.CommonFunction import get_history_video_info, get_new_video_info, get_missing_video_info, \ get_top_video_info, get_campaign_and_group_name_rule,get_app_detail, get_request_data from utils.ConstantConfig import * from ai_strategy_request_func import ai_strategy_request_parse from utils.DataBaseConfig import * log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m/%d/%Y %I:%M:%S %p') log_handler = ConcurrentTimedRotatingFileHandler("logs/ai_auto_create.log", when="midnight", backupCount=100) log_handler.setFormatter(log_formatter) logger = logging.getLogger('ai_time_task_creative_logger') logger.addHandler(log_handler) logger.setLevel(logging.DEBUG) print('id of ai_time_task_creative_logger %s' % id(logger)) logger.info("ai_time_task_creative_server started!") class AiHistoricalMissingMaterial(tornado.web.RequestHandler): """ 补充历史遗漏素材(关联创意个数为0个素材) -- 测试通过 在AD后台创建成功,检查AD信息和数据库表 没有问题 """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: sql = """ select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) app_id_cnt = 0 for app_id in app_id_array: campaign_id = None # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl','error') start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) campaign_df = pd.read_sql(sql, engine) for row in campaign_df.itertuples(): if ('遗漏素材' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')): campaign_id = getattr(row, 'campaign_id') break # 3、获取通用视频1个 general_video_info = get_missing_video_info(account_id=account_id, cnt=1, url=get_missing_video_url, start_time=missing_video_start_time, end_time=missing_video_end_time, app_version='all') if general_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' % (account_id, app_id, general_video_info['message'])) # 4、获取app_id对应的视频1个 special_video_info = get_missing_video_info(account_id=account_id, cnt=1, url=get_missing_video_url, start_time=missing_video_start_time, end_time=missing_video_end_time, app_version=app_version) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) # 5、video_info 合并 full_video_info = [] if general_video_info['code'] == 0: full_video_info.extend(general_video_info['data']) if special_video_info['code'] == 0: full_video_info.extend(special_video_info['data']) # 6、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 if full_video_info: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=full_video_info, campaign_name=app_version + '-优选广告位-' + '遗漏素材', group_name=app_version + '-优选广告位-不限-自定义-' + '遗漏素材', ai_strategy_remark="补充遗漏素材", unit_type=4, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) app_id_cnt += 1 if app_id_cnt >= 50: break self.write(json.dumps({"message": "account_id=%s, 多应用的补充遗漏素材请求已走完!" % account_id})) self.flush() else: video_info = get_missing_video_info(account_id, missing_video_cnt, get_missing_video_url, missing_video_start_time, missing_video_end_time) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="补充遗漏素材", name_replace="补充遗漏素材") request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush() class AiAutoCreative(tornado.web.RequestHandler): """ 每5分钟,检查一次是否有上新素材,有的话,就自动创建 -- 需要上定时任务测试 """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: sql = """ select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) for app_id in app_id_array: campaign_id = None # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl', 'error') start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) campaign_df = pd.read_sql(sql, engine) for row in campaign_df.itertuples(): if ('素材自动上新' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')): campaign_id = getattr(row, 'campaign_id') break # 3、获取通用视频 general_video_info = get_new_video_info(account_id=account_id, url=get_new_video_url, app_version='all') if general_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' % (account_id, app_id, general_video_info['message'])) # 4、获取app_id对应的视频 special_video_info = get_new_video_info(account_id=account_id, url=get_new_video_url, app_version=app_version) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) # 5、video_info 合并 full_video_info = [] if general_video_info['code'] == 0: full_video_info.extend(general_video_info['data']) if special_video_info['code'] == 0: full_video_info.extend(special_video_info['data']) # 6、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 if full_video_info: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=full_video_info, campaign_name=app_version + '-优选广告位-' + '素材自动上新', group_name=app_version + '-优选广告位-不限-自定义-' + '素材自动上新', ai_strategy_remark="素材自动上新", unit_type=4, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) else: logger.info("account_id=%s, app_id=%s, 没有获取到视频,不发送ai策略请求!" % (account_id, app_id)) self.write(json.dumps({"message": "account_id=%s, 多应用的素材自动上新请求已走完!" % account_id})) self.flush() else: start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') # 1-1 获取当天计划中包含“自动上新”计划的,计划id sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) df = pd.read_sql(sql, engine) for row in df.itertuples(): if '素材自动上新' in getattr(row, 'campaign_name'): campaign_id = getattr(row, 'campaign_id') break video_info = get_new_video_info(account_id, get_new_video_url) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="自动上新", name_replace="素材自动上新") request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush() class AiHighQualityMaterial(tornado.web.RequestHandler): """ 补充历史高质量素材 -- 测试通过 在AD后台创建成功,检查AD信息和数据库表 没有问题 """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: sql = """select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) app_id_cnt = 0 for app_id in app_id_array: campaign_id = None # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id,没有则设置 campaign_name app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl', 'error') start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) campaign_df = pd.read_sql(sql, engine) for row in campaign_df.itertuples(): if ('高质量素材' in getattr(row, 'campaign_name')) and (app_version in getattr(row, 'campaign_name')): campaign_id = getattr(row, 'campaign_id') break # 3、获取1个通用视频 general_video_info = get_top_video_info(account_id=account_id, url=get_high_quality_video_url, start_time=(datetime.datetime.now() + datetime.timedelta(days=-high_quality_video_days)). strftime("%Y-%m-%d %H:%M:%S"), end_time=datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), cnt=1, app_version='all') if general_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of general_video_info is %s' % (account_id, app_id, general_video_info['message'])) # 4、获取app_id对应的1个视频 special_video_info = get_top_video_info(account_id=account_id, url=get_high_quality_video_url, start_time=(datetime.datetime.now() + datetime.timedelta(days=-high_quality_video_days)). strftime("%Y-%m-%d %H:%M:%S"), end_time=datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), cnt=1, app_version=app_version) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) # 5、video_info 合并 full_video_info = [] if general_video_info['code'] == 0: full_video_info.extend(general_video_info['data']) if special_video_info['code'] == 0: full_video_info.extend(special_video_info['data']) # 6、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 if full_video_info: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=full_video_info, campaign_name=app_version + '-优选广告位-' + '高质量素材', group_name=app_version + '-优选广告位-不限-自定义-' + '高质量素材', ai_strategy_remark="高质量素材复建", unit_type=4, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) app_id_cnt += 1 if app_id_cnt >= 50: break self.write(json.dumps({"message": "account_id=%s, 多应用的高质量素材复建请求已走完!" % account_id})) self.flush() else: video_info = get_top_video_info(account_id, high_quality_video_cnt, (datetime.datetime.now() + datetime.timedelta( days=-high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), get_high_quality_video_url) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="高质量素材复建", name_replace="高质量素材") request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush() class AiCheckAndUpTOFullCreative(tornado.web.RequestHandler): """ 每天22:00 调用该任务,检查当天创意是否创建达到上限,否则使用历史高质量素材填满 """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') now = datetime.datetime.now() # 1-1 从客户策略表中获取该账户下 每个素材搭配的封面个数, 来计算需要补充的素材个数 sql = """ select image_cnt from ctop_ai_kuaishou_advertiser_strategy where account_id = %s and status = 0 limit 1 """ % account_id df = pd.read_sql(sql, engine) image_cnt = int(df['image_cnt'].values[0]) # 2-1 从 ctop_kuaishou_creative 获取当天该账户到此刻 已经创建的创意个数 video_cnt = 0 sql = """ select count(1) creative_cnt from ctop_kuaishou_creative where account_id = %s and creative_id is not NULL and creative_create_time <= '%s' and creative_create_time >= '%s' """ % (account_id, end_time, start_time) df = pd.read_sql(sql, engine) creative_cnt = int(df['creative_cnt'].values[0]) if creative_cnt >= 2000: video_cnt = 0 else: video_cnt = (2000 - creative_cnt) // image_cnt # 3-1 获取视频信息 if video_cnt == 0: logger.info("创意已经建满,不需要补充素材!") self.write(json.dumps("message: 创意已经建满,不需要补充素材!")) self.flush() else: logger.info("需要补充的视频数量:%s" % video_cnt) sql = """select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: needed_app_id_cnt = video_cnt app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) app_id_cnt = 0 for app_id in app_id_array: campaign_id = None # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s,the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue # 2、依据 appVersion 的值,来判断当天是否已经有对应的计划,如果有则获取 campaign_id, 没有则设置 campaign_name app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl', 'error') start_time = (datetime.date.today()).strftime('%Y-%m-%d %H:%M:%S') end_time = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) campaign_df = pd.read_sql(sql, engine) for row in campaign_df.itertuples(): if ('高质量素材' in getattr(row, 'campaign_name')) and ( app_version in getattr(row, 'campaign_name')): campaign_id = getattr(row, 'campaign_id') break # 3、获取app_id对应的1个视频 special_video_info = get_top_video_info(account_id=account_id, url=get_high_quality_video_url, start_time=(now + datetime.timedelta(days=-2*high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), end_time=(now + datetime.timedelta(days=-high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), cnt=1, app_version=app_version) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) continue # 6、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=special_video_info['data'], campaign_name=app_version + '-优选广告位-' + '高质量素材', group_name=app_version + '-优选广告位-不限-自定义-' + '高质量素材', ai_strategy_remark="用高质量素材补满创意", unit_type=4, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) app_id_cnt += 1 if app_id_cnt >= needed_app_id_cnt: break self.write(json.dumps({"message": "account_id=%s, 多应用的高质量素材补满创意的请求已走完!" % account_id})) self.flush() else: # 1-1 获取当天计划中包含“高质量素材”计划的,计划id sql = """ select campaign_id, campaign_name from ctop_kuaishou_campaign where account_id = %s and put_create_time >= '%s' and put_create_time <= '%s' """ % (account_id, start_time, end_time) df = pd.read_sql(sql, engine) for row in df.itertuples(): if '高质量素材' in getattr(row, 'campaign_name'): campaign_id = getattr(row, 'campaign_id') break video_info = get_top_video_info(account_id, video_cnt, (now + datetime.timedelta(days=-2*high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), (now + datetime.timedelta(days=-high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), get_high_quality_video_url) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="用高质量素材补满创意", name_replace="高质量素材") request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush() class AiProgramCreativeHighQualityMaterial(tornado.web.RequestHandler): """ 使用历史跑量素材创建程序化创意 跑量素材150个(近14天的素材) 计划名称--跑量素材程序化 timeTask: 每天上午10点执行 --(0 0 10 * * ?) ---------------------------------------- 拼装参数和写入数据库时,需要修改名称(程序化与非程序化不一致): creative_name --> package_name(程序化创意名称) action_bar_text --> action_bar(行动号召按钮) description --> captions(作品广告语) click_track_url --> click_url 写入数据库时: image_md5s --> cover_image_tokens 程序化与非程序化的逻辑不一样: 需要5个视频4张封面一组,拼装程序化创意参数需要单独抽取一个方法出来 所有操作记录表中,添加status信息(已提交,成功,失败),和回调时的 message信息 """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: sql = """select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) app_id_cnt = 0 for app_id in app_id_array: # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl', 'error') # 2、获取特定视频 special_video_info = get_top_video_info(account_id=account_id, url=get_high_quality_video_url, start_time=(datetime.datetime.now() + datetime.timedelta(days=-high_quality_video_days)). strftime("%Y-%m-%d %H:%M:%S"), end_time=datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), cnt=5, app_version=app_version) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) continue # 3、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=special_video_info['data'], campaign_name=app_version + '-优选广告位-' + '程序化高质量素材', group_name=app_version + '-优选广告位-不限-程序化-' + '高质量素材', ai_strategy_remark="程序化高质量素材", unit_type=7, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) app_id_cnt += 1 if app_id_cnt >= 30: break self.write(json.dumps({"message": "account_id=%s, 多应用的高质量素材程序化创意的请求已走完!" % account_id})) self.flush() else: video_info = get_top_video_info(account_id, programme_high_quality_video_cnt, (datetime.datetime.now() + datetime.timedelta( days=-high_quality_video_days)).strftime("%Y-%m-%d %H:%M:%S"), datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), get_high_quality_video_url) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="程序化高质量素材", name_replace="程序化高质量素材", unit_type=7) request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush() class AiProgramCreativeNewMaterial(tornado.web.RequestHandler): """ 使用2天内 创意数关联小于10(当天创意关联数小于10的,150个素材)的素材创建程序化创意 计划名称--新素材程序化 timeTask: 每天上午10点执行 --(0 0 10 * * ?) """ def post(self): data = self.request.body data = str(data, 'utf8') data = json.loads(data, encoding='utf8') logger.info("*************************************** NEW REQUEST ***************************************") account_id = data.get('account_id') campaign_id = data.get('campaign_id') logger.info("账户信息=%s, 当前进程=%s, 当前进程的主进程=%s, raw data from request is %s" % (account_id, os.getpid(), os.getppid(), data)) try: sql = """select account_id, single_appid, app_id_array, general_track from ctop_ai_kuaishou_advertiser_strategy where account_id=%s and status=0 order by create_time desc limit 1 """ % account_id df = pd.read_sql(sql, engine) if df['general_track'].values[0] == 0: app_id_array = eval(df['app_id_array'].values[0]) random.shuffle(app_id_array) app_id_cnt = 0 for app_id in app_id_array: # 1、获取该 app_id 的应该详情 app_id_info = get_app_detail(account_id=account_id, url=get_app_detail_url, app_id=app_id) if app_id_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of get_app_detail is %s' % (account_id, app_id, app_id_info['message'])) continue app_version = app_id_info['data'].get('appVersion', 'error') track_url = app_id_info['data'].get('trackUrl', 'error') # 2、获取特定视频 special_video_info = get_history_video_info(account_id=account_id, url=get_history_video_url, start_time=(datetime.datetime.now() + datetime.timedelta(days=-200)). strftime("%Y-%m-%d %H:%M:%S"), end_time=datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), video_cnt=5, related_creative_max_cnt=related_creative_max_cnt, app_version=app_version ) if special_video_info['code'] != 0: logger.info('account_id=%s, app_id=%s, the res of special_video_info is %s' % (account_id, app_id, special_video_info['message'])) continue # 3、拼装request_data,调用ai_strategy_request_parse方法 # 广告计划名称:渠道包 - 游戏名称 - 版位 - 日期 # 广告组名称:渠道包 - 游戏名称 - 优选 - 不限(定向)-自定义 / 程序化 - 日期 request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=special_video_info['data'], campaign_name=app_version + '-优选广告位-' + '程序化上新素材', group_name=app_version + '-优选广告位-不限-程序化-' + '上新素材', ai_strategy_remark="程序化上新素材", unit_type=7, app_id=app_id, click_track_url=track_url) request = ai_strategy_request_parse(request_data) logger.info("account_id=%s, app_id=%s, ai策略的返回信息:%s" % (account_id, app_id, request)) app_id_cnt += 1 if app_id_cnt >= 30: break self.write(json.dumps({"message": "account_id=%s, 多应用的上新素材程序化创意的请求已走完!" % account_id})) self.flush() else: video_info = get_history_video_info(account_id=account_id, url=get_history_video_url, start_time=(datetime.datetime.now() + datetime.timedelta(days=-2)). strftime("%Y-%m-%d %H:%M:%S"), end_time=datetime.date.today().strftime("%Y-%m-%d %H:%M:%S"), video_cnt=programme_new_video_cnt, related_creative_max_cnt=related_creative_max_cnt) if video_info['code'] != 0: logger.info("the res of video is %s" % video_info['message']) logger.info("没有获取到视频,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"})) self.flush() else: campaign_name, group_name = get_campaign_and_group_name_rule(account_id) if (campaign_name is None) or (group_name is None): logger.info("没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!") self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"})) self.flush() else: request_data = get_request_data(account_id=account_id, campaign_id=campaign_id, video_info=video_info['data'], campaign_name=campaign_name, group_name=group_name, ai_strategy_remark="程序化上新素材", name_replace="程序化上新素材", unit_type=7) request = ai_strategy_request_parse(request_data) logger.info("ai策略的返回信息:%s" % request) self.write(json.dumps(request)) self.flush() except Exception: logger.error(traceback.format_exc()) self.write(json.dumps(traceback.format_exc())) self.flush()