瀏覽代碼

程序化创意、代码优化、多进程启动

liyuyi@c-top.com.cn 4 年之前
父節點
當前提交
5f1c21f1ee

+ 1 - 1
advertiser_strategy_operate.py

@@ -8,7 +8,7 @@ from utils.CommonFunction import *
 from utils.DataBaseConfig import *
 from utils.DataBaseConfig import *
 from utils.LogConfig import *
 from utils.LogConfig import *
 
 
-log_handler = TimedRotatingFileHandler("logs/advertiser_strategy_operate/advertiser_strategy_operate.log",
+log_handler = TimedRotatingFileHandler("logs/advertiser_strategy_operate.log",
                                        when="midnight", backupCount=100, encoding='utf-8')
                                        when="midnight", backupCount=100, encoding='utf-8')
 log_handler.setFormatter(log_formatter)
 log_handler.setFormatter(log_formatter)
 logger = logging.getLogger('advertiser_strategy_operate_logger')
 logger = logging.getLogger('advertiser_strategy_operate_logger')

+ 10 - 4
ai_ads_main.py

@@ -6,6 +6,7 @@ import tornado.web
 from ai_callback_handler import *
 from ai_callback_handler import *
 from advertiser_strategy_operate import *
 from advertiser_strategy_operate import *
 from ai_time_task_creative_handler import *
 from ai_time_task_creative_handler import *
+import platform
 
 
 
 
 def create_application():
 def create_application():
@@ -17,14 +18,19 @@ def create_application():
         (r"/ai_auto_creative", AiAutoCreative),
         (r"/ai_auto_creative", AiAutoCreative),
         (r"/ai_high_quality_material", AiHighQualityMaterial),
         (r"/ai_high_quality_material", AiHighQualityMaterial),
         (r"/ai_check_and_up_to_full_creative", AiCheckAndUpTOFullCreative),
         (r"/ai_check_and_up_to_full_creative", AiCheckAndUpTOFullCreative),
+        (r"/ai_programme_high_quality_material", AiProgramCreativeHighQualityMaterial),
+        (r"/ai_programme_new_material", AiProgramCreativeNewMaterial),
     ])
     ])
     return web_application
     return web_application
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-p', '--port', type=int, default=31012)
-    args = parser.parse_args()
     application = create_application()
     application = create_application()
-    application.listen(args.port)
+    http_server = tornado.httpserver.HTTPServer(application)
+    http_server.bind(31012, None)
+    if platform.system() == 'Windows':
+        http_server.start()
+    else:
+        http_server.start(num_processes=5)
     tornado.ioloop.IOLoop.instance().start()
     tornado.ioloop.IOLoop.instance().start()
+

+ 37 - 21
ai_callback_handler.py

@@ -38,18 +38,35 @@ class AiCallBackAddCreative(tornado.web.RequestHandler):
                                      charset=charset)
                                      charset=charset)
             cursor = db_con.cursor()
             cursor = db_con.cursor()
             for item in data['callbackData']:
             for item in data['callbackData']:
-                # TODO 1、更新message 和 status 到表中  2、需要判断是否为 程序化,来更新不同的表
-                if item['code'] == 0:
-                    creative_uuid = item['creative_uuid']
-                    creative_id = item['creative_id']
-                    unit_id = item['unit_id']
-                    logger.info("on single update callback info: %s" % item)
+                if item['type'] == 1:
+                    # 自定义创意
+                    creative_uuid = item.get('creative_uuid')
+                    creative_id = item.get('creative_id')
+                    unit_id = item.get('unit_id')
+                    status = item.get('code')
+                    message = item.get('message')
                     cursor.execute("""UPDATE ctop_ai_kuaishou_creative_level_operation_record
                     cursor.execute("""UPDATE ctop_ai_kuaishou_creative_level_operation_record
-                                    SET unit_id= %s, creative_id=%s
-                                    WHERE creative_uuid = %s""", (unit_id, creative_id, creative_uuid))
-                else:
-                    logger.error("on single update callback info: %s" % item)
-
+                                       SET unit_id= %s, creative_id=%s, status=%s, message=%s
+                                       WHERE creative_uuid = %s""",
+                                   (unit_id, creative_id, status, message, creative_uuid))
+                    if item['code'] == 0:
+                        logger.info("on single update callback info: %s" % item)
+                    else:
+                        logger.error("on single update callback info: %s" % item)
+                if item['type'] == 2:
+                    # 程序化创意2.0
+                    creative_uuid = item.get('creative_uuid')
+                    unit_id = item.get('unit_id')
+                    status = item.get('code')
+                    message = item.get('message')
+                    cursor.execute("""UPDATE ctop_ai_kuaishou_program_creative_level_operation_record
+                                      SET unit_id= %s,  status=%s, message=%s
+                                      WHERE creative_uuid = %s""",
+                                   (unit_id, status, message, creative_uuid))
+                    if item['code'] == 0:
+                        logger.info("on single update callback info: %s" % item)
+                    else:
+                        logger.error("on single update callback info: %s" % item)
             db_con.commit()
             db_con.commit()
             db_con.close()
             db_con.close()
         except Exception:
         except Exception:
@@ -82,19 +99,18 @@ class AiCallBackAddGroup(tornado.web.RequestHandler):
                                      charset=charset)
                                      charset=charset)
             cursor = db_con.cursor()
             cursor = db_con.cursor()
             for item in data['callbackData']:
             for item in data['callbackData']:
-                # TODO 更新message 和 status 到表中
+                group_uuid = item.get('group_uuid')
+                unit_id = item.get('unit_id')
+                group_create_time = item.get('group_create_time')
+                status = item.get('code')
+                message = item.get('message')
+                cursor.execute("""UPDATE ctop_ai_kuaishou_unit_level_operation_record
+                                  SET unit_id= %s, group_create_time=%s,status=%s,message=%s
+                                  WHERE group_uuid = %s""", (unit_id, group_create_time, status, message, group_uuid))
                 if item['code'] == 0:
                 if item['code'] == 0:
-                    group_uuid = item['group_uuid']
-                    unit_id = item['unit_id']
-                    group_create_time = item['group_create_time']
                     logger.info("on single update callback info: %s" % item)
                     logger.info("on single update callback info: %s" % item)
-
-                    cursor.execute("""UPDATE ctop_ai_kuaishou_unit_level_operation_record
-                                    SET unit_id= %s, group_create_time=%s
-                                    WHERE group_uuid = %s""", (unit_id, group_create_time, group_uuid))
                 else:
                 else:
                     logger.error("on single update callback info: %s" % item)
                     logger.error("on single update callback info: %s" % item)
-
             db_con.commit()
             db_con.commit()
             db_con.close()
             db_con.close()
         except Exception:
         except Exception:
@@ -104,4 +120,4 @@ class AiCallBackAddGroup(tornado.web.RequestHandler):
 
 
         # 返回接口结果
         # 返回接口结果
         self.write(json.dumps(res))
         self.write(json.dumps(res))
-        self.flush()
+        self.flush()

+ 33 - 21
ai_strategy_request_func.py

@@ -26,6 +26,7 @@ def ai_strategy_request_parse(data):
     :param data:
     :param data:
     :return:
     :return:
     """
     """
+    print(data)
     if data["operation_type"] == 1:
     if data["operation_type"] == 1:
         inst = ParseAddCampaignOrAddGroupRequest(data)
         inst = ParseAddCampaignOrAddGroupRequest(data)
         # 1 获取客户策略信息
         # 1 获取客户策略信息
@@ -69,7 +70,7 @@ class ParseAddCampaignOrAddGroupRequest(object):
     def __init__(self, request_data):
     def __init__(self, request_data):
         self.ai_strategy_uuid = str(uuid.uuid4())
         self.ai_strategy_uuid = str(uuid.uuid4())
         self.request_data = request_data
         self.request_data = request_data
-        self.video = self.request_data['video']
+        self.video = self.request_data['video']['data']
         self.account_id = self.request_data['account_id']
         self.account_id = self.request_data['account_id']
         self.campaign_info = self.request_data['campaign_info']
         self.campaign_info = self.request_data['campaign_info']
         self.campaign_id = self.request_data['campaign_info'].get('campaign_id', None)
         self.campaign_id = self.request_data['campaign_info'].get('campaign_id', None)
@@ -96,7 +97,7 @@ class ParseAddCampaignOrAddGroupRequest(object):
         """ % self.account_id
         """ % self.account_id
         advertiser_strategy_df = pd.read_sql(sql, engine)
         advertiser_strategy_df = pd.read_sql(sql, engine)
 
 
-        self.advertiser_strategy_id = advertiser_strategy_df['id'].values[0]
+        self.advertiser_strategy_id = int(advertiser_strategy_df['id'].values[0])
         self.advertiser_strategy = advertiser_strategy_df.T.to_dict()[0]
         self.advertiser_strategy = advertiser_strategy_df.T.to_dict()[0]
 
 
     def write_intelligence_strategy_table(self):
     def write_intelligence_strategy_table(self):
@@ -114,7 +115,10 @@ class ParseAddCampaignOrAddGroupRequest(object):
                 'create_time': datetime.datetime.now()
                 'create_time': datetime.datetime.now()
             }
             }
         df = pd.DataFrame.from_dict(intelligence_strategy_dict, orient='index').T
         df = pd.DataFrame.from_dict(intelligence_strategy_dict, orient='index').T
+        print(df.dtypes)
+        print("$$$$$$$$$$$$$")
         df.to_sql(name="ctop_ai_kuaishou_intelligence_strategy", con=engine, if_exists='append', index=False)
         df.to_sql(name="ctop_ai_kuaishou_intelligence_strategy", con=engine, if_exists='append', index=False)
+        print("^^^^^^^^^^^^^^^^^^^^")
 
 
     def update_intelligence_strategy_table(self, request_content=None, message=None):
     def update_intelligence_strategy_table(self, request_content=None, message=None):
         """
         """
@@ -170,8 +174,6 @@ class ParseAddCampaignOrAddGroupRequest(object):
             'campaign_name': self.campaign_info['campaign_name'],
             'campaign_name': self.campaign_info['campaign_name'],
             'campaign_type': self.advertiser_strategy['campaign_type'],
             'campaign_type': self.advertiser_strategy['campaign_type'],
             'operation_type': self.operation_type,
             'operation_type': self.operation_type,
-            'status': 1,
-            'message': None,
             'create_time': datetime.datetime.now()
             'create_time': datetime.datetime.now()
         }
         }
         res = 0
         res = 0
@@ -179,22 +181,26 @@ class ParseAddCampaignOrAddGroupRequest(object):
             self.campaign_id = res_data['data']['campaign_id']
             self.campaign_id = res_data['data']['campaign_id']
             campaign_info_to_db['campaign_id'] = self.campaign_id
             campaign_info_to_db['campaign_id'] = self.campaign_id
             campaign_info_to_db['campaign_create_time'] = res_data['data']['campaign_create_time']
             campaign_info_to_db['campaign_create_time'] = res_data['data']['campaign_create_time']
+            campaign_info_to_db['status'] = res_data['code']
             campaign_info_to_db['message'] = res_data['message']
             campaign_info_to_db['message'] = res_data['message']
             logger.info("广告计划创建成功,campaign_id = %s,  ai_strategy_uuid = %s" %
             logger.info("广告计划创建成功,campaign_id = %s,  ai_strategy_uuid = %s" %
                         (self.campaign_id, self.ai_strategy_uuid))
                         (self.campaign_id, self.ai_strategy_uuid))
 
 
         else:
         else:
             campaign_info_to_db['message'] = res_data['message']
             campaign_info_to_db['message'] = res_data['message']
-            campaign_info_to_db['status'] = -1
+            campaign_info_to_db['status'] = res_data['code']
             logger.error("广告计划创建失败:%s,  ai_strategy_uuid = %s" % (res_data['message'], self.ai_strategy_uuid))
             logger.error("广告计划创建失败:%s,  ai_strategy_uuid = %s" % (res_data['message'], self.ai_strategy_uuid))
             res = -1
             res = -1
 
 
         # 写入计划层级的操作表
         # 写入计划层级的操作表
+        print("%%%%%%%%%%%%%%%%%%%%%%%%%%%")
         df = pd.DataFrame.from_dict(campaign_info_to_db, orient='index').T
         df = pd.DataFrame.from_dict(campaign_info_to_db, orient='index').T
+        print(df.dtypes)
         df.to_sql(name="ctop_ai_kuaishou_campaign_level_operation_record",
         df.to_sql(name="ctop_ai_kuaishou_campaign_level_operation_record",
                   con=engine,
                   con=engine,
                   if_exists='append',
                   if_exists='append',
                   index=False)
                   index=False)
+        print("^^^^^^^^^^^^^^^^^^^^^^^^")
         return res
         return res
 
 
     def get_group_params(self):
     def get_group_params(self):
@@ -205,9 +211,10 @@ class ParseAddCampaignOrAddGroupRequest(object):
                      'sticker_title', 'overlay_type', 'expose_tag', 'new_expose_tag', 'site_id',
                      'sticker_title', 'overlay_type', 'expose_tag', 'new_expose_tag', 'site_id',
                      'click_track_url', 'impression_url', 'ad_photo_played_t3s_url', 'actionbar_click_url',
                      'click_track_url', 'impression_url', 'ad_photo_played_t3s_url', 'actionbar_click_url',
                      'creative_category', 'creative_tag', 'image_cnt',
                      'creative_category', 'creative_tag', 'image_cnt',
-                     'create_time', 'effective_time', 'expiry_time']
+                     'create_time', 'effective_time', 'expiry_time', 'timer_task_status']
         for col in drop_cols:
         for col in drop_cols:
-            del group_params[col]
+            if col in group_params.keys():
+                del group_params[col]
 
 
         # 2 从请求的信息中更新组层级信息, 如组的名称、测试定向、测试出价等, update客户策略信息
         # 2 从请求的信息中更新组层级信息, 如组的名称、测试定向、测试出价等, update客户策略信息
         if (self.group_info is not None) and (len(self.group_info) > 0):
         if (self.group_info is not None) and (len(self.group_info) > 0):
@@ -288,17 +295,18 @@ class ParseAddCampaignOrAddGroupRequest(object):
         # 3 程序化创意部分字段发生改变,需要重命名
         # 3 程序化创意部分字段发生改变,需要重命名
         #   creative_name  --> package_name(程序化创意名称)
         #   creative_name  --> package_name(程序化创意名称)
         #   action_bar_text --> action_bar(行动号召按钮)
         #   action_bar_text --> action_bar(行动号召按钮)
-        #   description --> captions(作品广告语)
+        #   description --> captions(作品广告语) string[]
         #   click_track_url --> click_url(点击监测链接)
         #   click_track_url --> click_url(点击监测链接)
         creative_params['package_name'] = creative_params.pop('creative_name')
         creative_params['package_name'] = creative_params.pop('creative_name')
         creative_params['action_bar'] = creative_params.pop('action_bar_text')
         creative_params['action_bar'] = creative_params.pop('action_bar_text')
-        creative_params['captions'] = creative_params.pop('description')
+        description = creative_params.pop('description')
+        creative_params['captions'] = str([description])
         creative_params['click_url'] = creative_params.pop('click_track_url')
         creative_params['click_url'] = creative_params.pop('click_track_url')
 
 
         # 4 拼装json的 创意参数
         # 4 拼装json的 创意参数
         creative_params_to_request = creative_params.copy()
         creative_params_to_request = creative_params.copy()
         # 4-1 拼接发送请求json时, 以下字段需要转为 list 类型
         # 4-1 拼接发送请求json时, 以下字段需要转为 list 类型
-        cols_to_list = ['creative_tag']
+        cols_to_list = ['creative_tag', 'captions']
         for col in cols_to_list:
         for col in cols_to_list:
             creative_params_to_request[col] = eval(creative_params_to_request[col]) \
             creative_params_to_request[col] = eval(creative_params_to_request[col]) \
                 if creative_params_to_request[col] is not None else None
                 if creative_params_to_request[col] is not None else None
@@ -422,10 +430,10 @@ class ParseAddCampaignOrAddGroupRequest(object):
             cover_image_tokens = []
             cover_image_tokens = []
             if i+5 < len(self.video):
             if i+5 < len(self.video):
                 for j in range(i, i+5, 1):
                 for j in range(i, i+5, 1):
-                    if self.video[j]['material_type'] == 1:
+                    if self.video[j]['material_type'] == 2:
                         horizontal_photo_ids.append(self.video[j]['photo_id'])
                         horizontal_photo_ids.append(self.video[j]['photo_id'])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
-                    if self.video[j]['material_type'] == 2:
+                    if self.video[j]['material_type'] == 1:
                         vertical_photo_ids.append(self.video[j]['photo_id'])
                         vertical_photo_ids.append(self.video[j]['photo_id'])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                 if len(cover_image_tokens) >= 5:
                 if len(cover_image_tokens) >= 5:
@@ -436,9 +444,9 @@ class ParseAddCampaignOrAddGroupRequest(object):
                 single_creative_params_to_db = creative_params_to_db.copy()
                 single_creative_params_to_db = creative_params_to_db.copy()
                 single_creative_params_to_db['creative_uuid'] = creative_uuid
                 single_creative_params_to_db['creative_uuid'] = creative_uuid
                 single_creative_params_to_db['package_name'] = package_name
                 single_creative_params_to_db['package_name'] = package_name
-                single_creative_params_to_db['horizontal_photo_ids'] = horizontal_photo_ids
-                single_creative_params_to_db['vertical_photo_ids'] = vertical_photo_ids
-                single_creative_params_to_db['cover_image_tokens'] = cover_image_tokens
+                single_creative_params_to_db['horizontal_photo_ids'] = str(horizontal_photo_ids)
+                single_creative_params_to_db['vertical_photo_ids'] = str(vertical_photo_ids)
+                single_creative_params_to_db['cover_image_tokens'] = str(cover_image_tokens)
                 single_creative_params_to_db['create_time'] = datetime.datetime.now()
                 single_creative_params_to_db['create_time'] = datetime.datetime.now()
                 df = pd.DataFrame.from_dict(single_creative_params_to_db, orient='index').T
                 df = pd.DataFrame.from_dict(single_creative_params_to_db, orient='index').T
                 df.to_sql(name="ctop_ai_kuaishou_program_creative_level_operation_record",
                 df.to_sql(name="ctop_ai_kuaishou_program_creative_level_operation_record",
@@ -453,11 +461,13 @@ class ParseAddCampaignOrAddGroupRequest(object):
                 single_creative_params_to_request['vertical_photo_ids'] = vertical_photo_ids
                 single_creative_params_to_request['vertical_photo_ids'] = vertical_photo_ids
                 single_creative_params_to_request['image_md5s'] = cover_image_tokens
                 single_creative_params_to_request['image_md5s'] = cover_image_tokens
             else:
             else:
+                # material_type=1 竖版
+                # material_type=2 横版
                 for j in range(i, len(self.video)):
                 for j in range(i, len(self.video)):
-                    if self.video[j]['material_type'] == 1:
+                    if self.video[j]['material_type'] == 2:
                         horizontal_photo_ids.append(self.video[j]['photo_id'])
                         horizontal_photo_ids.append(self.video[j]['photo_id'])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
-                    if self.video[j]['material_type'] == 2:
+                    if self.video[j]['material_type'] == 1:
                         vertical_photo_ids.append(self.video[j]['photo_id'])
                         vertical_photo_ids.append(self.video[j]['photo_id'])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                         cover_image_tokens.append(self.video[j]['imageList'][0])
                 if len(cover_image_tokens) >= 5:
                 if len(cover_image_tokens) >= 5:
@@ -468,9 +478,9 @@ class ParseAddCampaignOrAddGroupRequest(object):
                 single_creative_params_to_db = creative_params_to_db.copy()
                 single_creative_params_to_db = creative_params_to_db.copy()
                 single_creative_params_to_db['creative_uuid'] = creative_uuid
                 single_creative_params_to_db['creative_uuid'] = creative_uuid
                 single_creative_params_to_db['package_name'] = package_name
                 single_creative_params_to_db['package_name'] = package_name
-                single_creative_params_to_db['horizontal_photo_ids'] = horizontal_photo_ids
-                single_creative_params_to_db['vertical_photo_ids'] = vertical_photo_ids
-                single_creative_params_to_db['cover_image_tokens'] = cover_image_tokens
+                single_creative_params_to_db['horizontal_photo_ids'] = str(horizontal_photo_ids)
+                single_creative_params_to_db['vertical_photo_ids'] = str(vertical_photo_ids)
+                single_creative_params_to_db['cover_image_tokens'] = str(cover_image_tokens)
                 single_creative_params_to_db['create_time'] = datetime.datetime.now()
                 single_creative_params_to_db['create_time'] = datetime.datetime.now()
                 df = pd.DataFrame.from_dict(single_creative_params_to_db, orient='index').T
                 df = pd.DataFrame.from_dict(single_creative_params_to_db, orient='index').T
                 df.to_sql(name="ctop_ai_kuaishou_program_creative_level_operation_record",
                 df.to_sql(name="ctop_ai_kuaishou_program_creative_level_operation_record",
@@ -488,7 +498,9 @@ class ParseAddCampaignOrAddGroupRequest(object):
             single_group_params_to_request['programCreative'] = single_creative_params_to_request
             single_group_params_to_request['programCreative'] = single_creative_params_to_request
             cnt += 1
             cnt += 1
 
 
-        self.res_data['group_list'].append(single_group_params_to_request)
+            self.res_data['group_list'].append(single_group_params_to_request)
+        self.res_data['account_id'] = self.account_id
+        self.res_data['campaign_id'] = self.campaign_id
 
 
 
 
 # TODO 修改操作
 # TODO 修改操作

+ 12 - 28
ai_time_task_creative_handler.py

@@ -4,14 +4,13 @@ import json
 import traceback
 import traceback
 from logging.handlers import TimedRotatingFileHandler
 from logging.handlers import TimedRotatingFileHandler
 from utils.BaseClass import *
 from utils.BaseClass import *
-from utils.CommonFunction import get_lower_case_name, get_new_video_info, get_missing_video_info, \
+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_top_video_info, get_campaign_and_group_name_rule
 from utils.ConstantConfig import *
 from utils.ConstantConfig import *
 from utils.LogConfig import *
 from utils.LogConfig import *
 from ai_strategy_request_func import ai_strategy_request_parse
 from ai_strategy_request_func import ai_strategy_request_parse
 from utils.DataBaseConfig import *
 from utils.DataBaseConfig import *
 
 
-
 log_handler = TimedRotatingFileHandler("logs/ai_auto_create.log",
 log_handler = TimedRotatingFileHandler("logs/ai_auto_create.log",
                                        when="midnight", backupCount=100)
                                        when="midnight", backupCount=100)
 log_handler.setFormatter(log_formatter)
 log_handler.setFormatter(log_formatter)
@@ -310,7 +309,7 @@ class AiProgramCreativeHighQualityMaterial(tornado.web.RequestHandler):
         campaign_id = data.get('campaign_id')
         campaign_id = data.get('campaign_id')
 
 
         try:
         try:
-            video_info = get_top_video_info(account_id, high_quality_video_cnt,
+            video_info = get_top_video_info(account_id, programme_high_quality_video_cnt,
                                             (datetime.datetime.now() + datetime.timedelta(
                                             (datetime.datetime.now() + datetime.timedelta(
                                              days=-high_quality_video_days)).strftime("%Y-%m-%d"),
                                              days=-high_quality_video_days)).strftime("%Y-%m-%d"),
                                             str(datetime.date.today()), get_high_quality_video_url)
                                             str(datetime.date.today()), get_high_quality_video_url)
@@ -344,28 +343,11 @@ class AiProgramCreativeHighQualityMaterial(tornado.web.RequestHandler):
             self.flush()
             self.flush()
 
 
 
 
-# TODO 获取最新的素材 更换素材请求接口
 class AiProgramCreativeNewMaterial(tornado.web.RequestHandler):
 class AiProgramCreativeNewMaterial(tornado.web.RequestHandler):
     """
     """
-    使用历史跑量素材创建程序化创意
-    跑量素材150个(近14天的素材)
-    计划名称--跑量素材程序化
+    使用近期创意数关联小于10(当天创意关联数小于10的,150个素材)的素材创建程序化创意
+    计划名称--新素材程序化
     timeTask: 每天上午10点执行 --(0 0 10 * * ?)
     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):
     def post(self):
         data = self.request.body
         data = self.request.body
@@ -378,11 +360,13 @@ class AiProgramCreativeNewMaterial(tornado.web.RequestHandler):
         campaign_id = data.get('campaign_id')
         campaign_id = data.get('campaign_id')
 
 
         try:
         try:
-            # TODO 获取最新的素材 更换素材请求接口
-            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"),
-                                            str(datetime.date.today()), get_high_quality_video_url)
+            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"),
+                                                end_time=str(datetime.date.today()),
+                                                video_cnt=programme_new_video_cnt,
+                                                related_creative_max_cnt=related_creative_max_cnt)
             if video_info['code'] != 0:
             if video_info['code'] != 0:
                 logger.info("the res of video is %s" % video_info['message'])
                 logger.info("the res of video is %s" % video_info['message'])
                 logger.info("没有获取到视频,不发送ai策略请求!")
                 logger.info("没有获取到视频,不发送ai策略请求!")
@@ -401,7 +385,7 @@ class AiProgramCreativeNewMaterial(tornado.web.RequestHandler):
                                                     campaign_name=campaign_name,
                                                     campaign_name=campaign_name,
                                                     group_name=group_name,
                                                     group_name=group_name,
                                                     ai_strategy_remark="程序化上新素材",
                                                     ai_strategy_remark="程序化上新素材",
-                                                    name_replace="程序化上新素材",
+                                                    name_replace="程序化上新素材",
                                                     unit_type=7)
                                                     unit_type=7)
                     request = ai_strategy_request_parse(request_data)
                     request = ai_strategy_request_parse(request_data)
                     logger.info("ai策略的返回信息:%s" % request)
                     logger.info("ai策略的返回信息:%s" % request)

File diff suppressed because it is too large
+ 0 - 80
logs/advertiser_strategy_operate/advertiser_strategy_operate.log


+ 0 - 103
logs/ai_auto_create/ai_auto_create.log

@@ -1,103 +0,0 @@
-01/25/2021 09:52:44 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 09:52:44 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 09:53:26 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 09:56:07 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 09:56:07 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 09:56:33 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 09:58:49 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 09:58:49 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 09:58:54 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 10:00:45 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 10:00:45 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 10:00:52 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 10:05:24 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 10:05:24 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 10:05:30 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 10:08:40 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 10:08:40 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 10:08:51 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 10:35:31 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 10:35:38 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 10:37:06 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 10:48:08 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 10:48:08 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 10:48:30 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 11:11:45 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:11:45 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:11:57 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 11:21:56 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:21:56 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:22:46 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:22:46 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:23:15 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:23:15 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:29:58 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}
-01/25/2021 11:36:06 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:36:06 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:36:09 AM ERROR Traceback (most recent call last):
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connection.py", line 170, in _new_conn
-    (self._dns_host, self.port), self.timeout, **extra_kw
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\util\connection.py", line 96, in create_connection
-    raise err
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\util\connection.py", line 86, in create_connection
-    sock.connect(sa)
-ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
-
-During handling of the above exception, another exception occurred:
-
-Traceback (most recent call last):
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connectionpool.py", line 706, in urlopen
-    chunked=chunked,
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connectionpool.py", line 394, in _make_request
-    conn.request(method, url, **httplib_request_kw)
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connection.py", line 234, in request
-    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
-  File "D:\anaconda3\envs\ai_ads\lib\http\client.py", line 1277, in request
-    self._send_request(method, url, body, headers, encode_chunked)
-  File "D:\anaconda3\envs\ai_ads\lib\http\client.py", line 1323, in _send_request
-    self.endheaders(body, encode_chunked=encode_chunked)
-  File "D:\anaconda3\envs\ai_ads\lib\http\client.py", line 1272, in endheaders
-    self._send_output(message_body, encode_chunked=encode_chunked)
-  File "D:\anaconda3\envs\ai_ads\lib\http\client.py", line 1032, in _send_output
-    self.send(msg)
-  File "D:\anaconda3\envs\ai_ads\lib\http\client.py", line 972, in send
-    self.connect()
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connection.py", line 200, in connect
-    conn = self._new_conn()
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connection.py", line 182, in _new_conn
-    self, "Failed to establish a new connection: %s" % e
-urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x000001113762D2C8>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
-
-During handling of the above exception, another exception occurred:
-
-Traceback (most recent call last):
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\adapters.py", line 449, in send
-    timeout=timeout
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\connectionpool.py", line 756, in urlopen
-    method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\urllib3\util\retry.py", line 573, in increment
-    raise MaxRetryError(_pool, url, error or ResponseError(cause))
-urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.1.8', port=8080): Max retries exceeded with url: /jeecg-boot/kuaishou/material/getHistoryTopVideoList (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001113762D2C8>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。'))
-
-During handling of the above exception, another exception occurred:
-
-Traceback (most recent call last):
-  File "E:\ai_ads\ai_time_task_creative_handler.py", line 200, in post
-    get_high_quality_video_url)
-  File "E:\ai_ads\utils\CommonFunction.py", line 37, in get_top_video_info
-    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\api.py", line 119, in post
-    return request('post', url, data=data, json=json, **kwargs)
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\api.py", line 61, in request
-    return session.request(method=method, url=url, **kwargs)
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\sessions.py", line 542, in request
-    resp = self.send(prep, **send_kwargs)
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\sessions.py", line 655, in send
-    r = adapter.send(request, **kwargs)
-  File "D:\anaconda3\envs\ai_ads\lib\site-packages\requests\adapters.py", line 516, in send
-    raise ConnectionError(e, request=request)
-requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.1.8', port=8080): Max retries exceeded with url: /jeecg-boot/kuaishou/material/getHistoryTopVideoList (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001113762D2C8>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。'))
-
-01/25/2021 11:39:28 AM INFO ***************************************  NEW REQUEST ***************************************
-01/25/2021 11:39:28 AM INFO raw data from request is {'account_id': 9743727}
-01/25/2021 11:39:45 AM INFO ai策略的返回信息:{'code': 0, 'message': {'code': 0, 'message': '异步执行中,等待回调...'}}

File diff suppressed because it is too large
+ 0 - 124
logs/ai_callback/ai_callback.log


File diff suppressed because it is too large
+ 0 - 22
logs/ai_strategy_request/ai_strategy_request.log


File diff suppressed because it is too large
+ 18 - 52
manual_request_json.py


+ 52 - 0
time_task/time_task_ai_historical_missing_material.py

@@ -0,0 +1,52 @@
+from concurrent.futures import ThreadPoolExecutor
+import requests
+import datetime
+import json
+import pandas as pd
+from sqlalchemy import create_engine
+
+
+db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("data", "hcst@2021", "139.186.27.96", 4000, "jeecg-boot")
+engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
+
+
+def send_request(account_id):
+    url = 'http://139.186.27.96:31012/ai_historical_missing_material'
+    request_data = json.dumps({"account_id": account_id})
+    request = requests.post(url, request_data)
+    return json.loads(request.text)
+
+
+# 0、 打印该定时任务被调用的时间
+print(datetime.datetime.now())
+
+# 1、获取已有的账号
+sql = """
+select account_id from ctop_ai_kuaishou_advertiser_strategy where status = 1
+"""
+acc_df = pd.read_sql(sql, engine)
+acc_list = [int(account_id) for account_id in acc_df['account_id'].unique()]
+print(acc_list)
+
+# 2、 5个账户一组进行发送请求
+batch_num = 5
+for i in range(0, len(acc_list), batch_num):
+    if i + batch_num < len(acc_list):
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            results = pool.map(send_request, tuple(acc_list[i: i+batch_num]))
+            for r in results:
+                print('res = %s' % r)
+    else:
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            results = pool.map(send_request, tuple(acc_list[i: len(acc_list)]))
+            for r in results:
+                print('res = %s' % r)
+
+
+
+
+
+
+
+
+

+ 54 - 0
time_task/time_task_ai_program_creative_high_quality_materials.py

@@ -0,0 +1,54 @@
+from concurrent.futures import ThreadPoolExecutor
+import requests
+import datetime
+import json
+import pandas as pd
+from sqlalchemy import create_engine
+
+db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("data", "hcst@2021", "139.186.27.96", 4000, "jeecg-boot")
+engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
+
+
+def send_request(account_id):
+    url = 'http://139.186.27.96:31012/ai_programme_high_quality_material'
+    request_data = json.dumps({"account_id": account_id})
+    request = requests.post(url, request_data)
+    return json.loads(request.text)
+
+
+# 0、 打印该定时任务被调用的时间
+print("*************************", datetime.datetime.now(), "*************************")
+
+# 1、获取已有的账号
+sql = """
+select account_id from ctop_ai_kuaishou_advertiser_strategy where status = 1
+"""
+acc_df = pd.read_sql(sql, engine)
+acc_list = [int(account_id) for account_id in acc_df['account_id'].unique()]
+print(acc_list)
+
+# 2、 5个账户一组进行发送请求
+batch_num = 5
+for i in range(0, len(acc_list), batch_num):
+    if i + batch_num < len(acc_list):
+        print(tuple(acc_list[i:i+batch_num]))
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            results = pool.map(send_request, tuple(acc_list[i: i+batch_num]))
+            for r in results:
+                print('res = %s' % r)
+    else:
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            print(acc_list[i: len(acc_list)])
+            results = pool.map(send_request, tuple(acc_list[i: len(acc_list)]))
+            for r in results:
+                print('res = %s' % r)
+
+
+
+
+
+
+
+
+
+

+ 54 - 0
time_task/time_task_ai_program_creative_new_materials.py

@@ -0,0 +1,54 @@
+from concurrent.futures import ThreadPoolExecutor
+import requests
+import datetime
+import json
+import pandas as pd
+from sqlalchemy import create_engine
+
+db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("data", "hcst@2021", "139.186.27.96", 4000, "jeecg-boot")
+engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
+
+
+def send_request(account_id):
+    url = 'http://139.186.27.96:31012/ai_programme_new_material'
+    request_data = json.dumps({"account_id": account_id})
+    request = requests.post(url, request_data)
+    return json.loads(request.text)
+
+
+# 0、 打印该定时任务被调用的时间
+print("*************************", datetime.datetime.now(), "*************************")
+
+# 1、获取已有的账号
+sql = """
+select account_id from ctop_ai_kuaishou_advertiser_strategy where status = 1
+"""
+acc_df = pd.read_sql(sql, engine)
+acc_list = [int(account_id) for account_id in acc_df['account_id'].unique()]
+print(acc_list)
+
+# 2、 5个账户一组进行发送请求
+batch_num = 5
+for i in range(0, len(acc_list), batch_num):
+    if i + batch_num < len(acc_list):
+        print(tuple(acc_list[i:i+batch_num]))
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            results = pool.map(send_request, tuple(acc_list[i: i+batch_num]))
+            for r in results:
+                print('res = %s' % r)
+    else:
+        with ThreadPoolExecutor(max_workers=batch_num) as pool:
+            print(acc_list[i: len(acc_list)])
+            results = pool.map(send_request, tuple(acc_list[i: len(acc_list)]))
+            for r in results:
+                print('res = %s' % r)
+
+
+
+
+
+
+
+
+
+

+ 22 - 0
utils/CommonFunction.py

@@ -14,6 +14,28 @@ def get_lower_case_name(name):
     return "".join(lst).lower()
     return "".join(lst).lower()
 
 
 
 
+def get_history_video_info(account_id, url, start_time, end_time, video_cnt, related_creative_max_cnt):
+    """
+    url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList
+    请求方式:POST
+    remark: 见入参
+    入参:accountId     账户id
+         startDate     开始时间 --(视频的upload_time)
+         endDate       结束时间 --(视频的upload_time)
+         createCount   关联创意数 (小于该值)
+         num           获取数量 (随机num个)
+    """
+    request_data = {"accountId": account_id,
+                    "startDate": start_time,
+                    "endDate": end_time,
+                    "num": video_cnt,
+                    "createCount": related_creative_max_cnt}
+    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data)).text
+    request = json.loads(request)
+    return request
+
+
+
 def get_new_video_info(account_id, url):
 def get_new_video_info(account_id, url):
     """
     """
     url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getNewVideoList
     url:http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getNewVideoList

+ 20 - 0
utils/ConstantConfig.py

@@ -5,6 +5,7 @@ full_creative_cnt = 2000
 
 
 os_env_code_status = os.getenv('LYY_STATUS', 'product')
 os_env_code_status = os.getenv('LYY_STATUS', 'product')
 if os_env_code_status == 'dev':
 if os_env_code_status == 'dev':
+    print("测试环境的 常量信息!")
     # 近多少天的爆量视频
     # 近多少天的爆量视频
     high_quality_video_days = 14
     high_quality_video_days = 14
     high_quality_video_cnt = 2
     high_quality_video_cnt = 2
@@ -14,7 +15,16 @@ if os_env_code_status == 'dev':
     missing_video_end_time = str(datetime.date.today())
     missing_video_end_time = str(datetime.date.today())
     # 补充历史遗漏素材的个数
     # 补充历史遗漏素材的个数
     missing_video_cnt = 2
     missing_video_cnt = 2
+
+    # 程序化创意跑量视频个数
+    programme_high_quality_video_cnt = 13
+    # 程序化创意上新视频个数
+    programme_new_video_cnt = 13
+    # 调用获取历史视频接口时,关联的最大创意个数
+    related_creative_max_cnt = 10
+
 else:
 else:
+    print("生产环境的 常量信息!")
     # 近多少天的爆量视频
     # 近多少天的爆量视频
     high_quality_video_days = 14
     high_quality_video_days = 14
     high_quality_video_cnt = 100
     high_quality_video_cnt = 100
@@ -25,5 +35,15 @@ else:
     # 补充历史遗落素材的个数
     # 补充历史遗落素材的个数
     missing_video_cnt = 100
     missing_video_cnt = 100
 
 
+    # 程序化创意跑量视频个数
+    programme_high_quality_video_cnt = 15
+    # 程序化创意上新视频个数
+    programme_new_video_cnt = 15
+    # 调用获取历史视频接口时,关联的最大创意个数
+    related_creative_max_cnt = 10
+
+
+
+
 
 
 
 

+ 1 - 0
utils/DataBaseConfig.py

@@ -13,6 +13,7 @@ if os_env_code_status == 'dev':
     charset = 'utf8'
     charset = 'utf8'
     db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("hcst", "hcst@2020", "139.186.151.174", 3306, "jeecg-boot")
     db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("hcst", "hcst@2020", "139.186.151.174", 3306, "jeecg-boot")
     engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
     engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
+
 else:
 else:
     # 线上数据库连接字符串
     # 线上数据库连接字符串
     print("生产环境--数据库!")
     print("生产环境--数据库!")