|
@@ -4,6 +4,7 @@ import traceback
|
|
|
import uuid
|
|
|
|
|
|
import pandas as pd
|
|
|
+import pymysql
|
|
|
import requests
|
|
|
import simplejson
|
|
|
import tornado.web
|
|
@@ -22,7 +23,6 @@ class AiStrategyRequestParse(tornado.web.RequestHandler):
|
|
|
self.logger.info("*************************************** NEW REQUEST ***************************************")
|
|
|
self.logger.info("raw data from request is %s" % data)
|
|
|
|
|
|
- create_group_and_creative_response_data = None
|
|
|
# 1、新增广告组操作
|
|
|
try:
|
|
|
if data["operation_type"] == 1:
|
|
@@ -33,7 +33,7 @@ class AiStrategyRequestParse(tornado.web.RequestHandler):
|
|
|
if inst.add_campaign() == -1:
|
|
|
raise Exception('广告计划创建失败')
|
|
|
|
|
|
- inst.get_group_dict()
|
|
|
+ inst.assemble_group_and_creative_params()
|
|
|
create_group_and_creative_res = inst.res_data
|
|
|
inst.update_intelligence_strategy_table()
|
|
|
self.logger.info("create group and creative request info: %s" % create_group_and_creative_res)
|
|
@@ -67,8 +67,8 @@ class ParseAddCampaignOrAddGroupRequest(object):
|
|
|
self.account_id = self.request_data['account_id']
|
|
|
self.campaign_info = self.request_data['campaign_info']
|
|
|
self.campaign_id = self.request_data['campaign_info'].get('campaign_id', None)
|
|
|
- self.group_info = self.request_data['group_info']
|
|
|
- self.creative_info = self.request_data['creative_info']
|
|
|
+ self.group_info = self.request_data.get('group_info', None)
|
|
|
+ self.creative_info = self.request_data.get('creative_info',None)
|
|
|
self.operation_type = self.request_data['operation_type']
|
|
|
|
|
|
self.advertiser_strategy_id = None
|
|
@@ -132,26 +132,18 @@ class ParseAddCampaignOrAddGroupRequest(object):
|
|
|
# 如果手动请求的数据结构中,"campaign" 中的 campaign_id 为空则调用该新增计划方法
|
|
|
def add_campaign(self):
|
|
|
"""
|
|
|
- 新增广告计划
|
|
|
+ 新增广告计划, 创建成功之后写入计划层级操作表中
|
|
|
:return:
|
|
|
"""
|
|
|
- # 1、校验请求信息中 有没有 与客户策略信息 中存在冲突的地方 -- 计划层级只判断 campaign_type
|
|
|
- if self.campaign_info['campaign_type'] != self.advertiser_strategy['campaign_type']:
|
|
|
- self.logger.info("客户策略的campaign_type: %d 和 AI策略的campaign_type:%d 不一致!" %
|
|
|
- (self.advertiser_strategy['campaign_type'],
|
|
|
- self.campaign_info['campaign_type']))
|
|
|
- return -1
|
|
|
-
|
|
|
- create_campaign_req_data = {
|
|
|
- 'account_id': self.account_id,
|
|
|
- 'campaign_name': self.campaign_info['campaign_name'],
|
|
|
- 'type': self.campaign_info['campaign_type']
|
|
|
- }
|
|
|
+ create_campaign_req_data = \
|
|
|
+ {'account_id': self.account_id,
|
|
|
+ 'campaign_name': self.campaign_info['campaign_name'],
|
|
|
+ 'type': self.advertiser_strategy['campaign_type']}
|
|
|
|
|
|
request = requests.post(url=create_campaign_url,
|
|
|
headers=headers,
|
|
|
data=json.JSONEncoder().encode(create_campaign_req_data))
|
|
|
- res_data = simplejson.loads(request.text)
|
|
|
+ res_data = json.loads(request.text)
|
|
|
|
|
|
# res_data = {
|
|
|
# "code": 0,
|
|
@@ -161,6 +153,7 @@ class ParseAddCampaignOrAddGroupRequest(object):
|
|
|
# "campaign_create_time": "2021-01-13 13:50:16"
|
|
|
# },
|
|
|
# "message": "SUCCESS"}
|
|
|
+
|
|
|
if res_data['code'] == 0:
|
|
|
self.campaign_id = res_data['data']['campaign_id']
|
|
|
campaign_info_to_db = {
|
|
@@ -169,54 +162,40 @@ class ParseAddCampaignOrAddGroupRequest(object):
|
|
|
'ai_strategy_uuid': self.ai_strategy_uuid,
|
|
|
'campaign_name': self.campaign_info['campaign_name'],
|
|
|
'campaign_id': self.campaign_id,
|
|
|
- 'campaign_type': self.campaign_info['campaign_type'],
|
|
|
+ 'campaign_type': self.advertiser_strategy['campaign_type'],
|
|
|
'operation_type': self.operation_type,
|
|
|
'campaign_create_time': res_data['data']['campaign_create_time'],
|
|
|
'create_time': datetime.datetime.now()
|
|
|
}
|
|
|
df = pd.DataFrame.from_dict(campaign_info_to_db, orient='index').T
|
|
|
- df.to_sql(name="ctop_ai_kuaishou_campaign_level_operation_record", con=engine, if_exists='append', index=False)
|
|
|
+ df.to_sql(name="ctop_ai_kuaishou_campaign_level_operation_record",
|
|
|
+ con=engine,
|
|
|
+ if_exists='append',
|
|
|
+ index=False)
|
|
|
else:
|
|
|
- self.logger.info("广告计划创建失败:%s" % res_data['message'])
|
|
|
+ self.logger.info("广告计划创建失败:%s, ai_strategy_uuid is %s" %
|
|
|
+ (res_data['message'], self.ai_strategy_uuid))
|
|
|
return -1
|
|
|
|
|
|
- def get_group_dict(self):
|
|
|
+ def get_group_basic_params(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+ def get_creative_basic_params(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+ def assemble_group_and_creative_params(self):
|
|
|
"""
|
|
|
拼接组和创意层级参数
|
|
|
写入数据库
|
|
|
- 返回 table_id
|
|
|
:return:
|
|
|
"""
|
|
|
- # 1、TODO 校验请求信息中 有没有 与客户策略信息 中存在冲突的地方 -- 暂时不实现
|
|
|
- # 客户策略 和 请求信息 都有值 才会进行校验比对操作 -- 不得高于,不得不等于,不得超过集合
|
|
|
- # 因此分为3类 字段
|
|
|
- # is_equal_cols = ['template_id','bid_type']
|
|
|
- # is_less_than_cols = []
|
|
|
- # is_contain_cols = []
|
|
|
- #
|
|
|
- # for col in is_equal_cols:
|
|
|
- # if (self.advertiser_strategy[col] is not None) and \
|
|
|
- # (self.group_info.get(col, None) is not None) and \
|
|
|
- # (self.group_info.get(col) != self.advertiser_strategy[col]):
|
|
|
- # return -1
|
|
|
- #
|
|
|
- # for col in is_less_than_cols:
|
|
|
- # if (self.advertiser_strategy[col] is not None) and \
|
|
|
- # (self.group_info.get(col, None) is not None) and \
|
|
|
- # (self.group_info.get(col) > self.advertiser_strategy[col]):
|
|
|
- # return -1
|
|
|
- #
|
|
|
- # for col in is_contain_cols:
|
|
|
- # if (self.advertiser_strategy[col] is not None) and \
|
|
|
- # (self.group_info.get(col, None) is not None) and \
|
|
|
- # (self.group_info.get(col) > self.advertiser_strategy[col]):
|
|
|
- # return -1
|
|
|
-
|
|
|
+ # 1、组层级基本信息
|
|
|
drop_cols = ['id', 'account_id', 'status', 'campaign_type',
|
|
|
'site_id', 'click_track_url', 'impression_url', 'ad_photo_played_t3s_url',
|
|
|
'actionbar_click_url',
|
|
|
'create_time', 'effective_time', 'expiry_time']
|
|
|
- cols_to_list = ['app_store', 'scene_id', 'region', 'district_ids', 'ages_range', 'device_brand',
|
|
|
+
|
|
|
+ group_cols_to_list = ['app_store', 'scene_id', 'region', 'district_ids', 'ages_range', 'device_brand',
|
|
|
'device_price', 'business_interest', 'fans_star', 'interest_video', 'app_interest',
|
|
|
'app_ids', 'population', 'exclude_population', 'paid_audience', 'behavior_interest']
|
|
|
|
|
@@ -224,91 +203,105 @@ class ParseAddCampaignOrAddGroupRequest(object):
|
|
|
for col in drop_cols:
|
|
|
del basic_group_info[col]
|
|
|
|
|
|
-
|
|
|
- # 3、从请求的信息中更新计划层级信息
|
|
|
- if len(self.group_info) > 0:
|
|
|
+ # 3、从请求的信息中更新组层级信息, 如组的名称、测试定向、测试出价等, update客户策略信息
|
|
|
+ if (self.group_info is not None) and (len(self.group_info) > 0):
|
|
|
for key, value in self.group_info.items():
|
|
|
basic_group_info.update({key: value})
|
|
|
|
|
|
-
|
|
|
+ # 发送的请求,这几个字段需要转为 [] 数组
|
|
|
+ group_info_to_res_data = basic_group_info.copy()
|
|
|
+ for col in group_cols_to_list:
|
|
|
+ group_info_to_res_data[col] = eval(group_info_to_res_data[col]) \
|
|
|
+ if group_info_to_res_data[col] is not None else None
|
|
|
+
|
|
|
+ # 写入组层级操作记录数据表基本信息
|
|
|
+ group_info_to_db = basic_group_info.copy()
|
|
|
+ group_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
|
|
|
+ group_info_to_db['account_id'] = self.account_id
|
|
|
+ group_info_to_db['campaign_id'] = self.campaign_id
|
|
|
+ group_info_to_db['operation_type'] = self.operation_type
|
|
|
+
|
|
|
+ # 2、创意层级基本信息
|
|
|
+ creative_cols = ['creative_name', 'action_bar_text', 'description', 'short_slogan',
|
|
|
+ 'sticker_title', 'overlay_type', 'expose_tag', 'new_expose_tag', 'site_id',
|
|
|
+ 'click_track_url', 'impression_url', 'ad_photo_played_t3s_url', 'actionbar_click_url'
|
|
|
+ 'creative_category', 'creative_tag']
|
|
|
+ basic_creative_info = {}
|
|
|
+ for col in creative_cols:
|
|
|
+ basic_creative_info[col] = self.advertiser_strategy.get(col)
|
|
|
+
|
|
|
+ # 2.1从请求的信息中更新创意层级的信息,如广告语
|
|
|
+ if (self.creative_info is not None) and (len(self.creative_info) > 0):
|
|
|
+ for key, value in self.creative_info.items():
|
|
|
+ basic_creative_info.update({key: value})
|
|
|
+
|
|
|
+ # 2.2
|
|
|
+ creative_info_to_res_data = basic_creative_info.copy()
|
|
|
+ creative_cols_to_list = ['creative_tag']
|
|
|
+ for col in creative_cols_to_list:
|
|
|
+ creative_info_to_res_data[col] = eval(creative_info_to_res_data[col]) \
|
|
|
+ if creative_info_to_res_data[col] is not None else None
|
|
|
+
|
|
|
+ # 2.3 写入创意层级操作记录数据表基本信息
|
|
|
+ creative_info_to_db = basic_creative_info.copy()
|
|
|
+ creative_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
|
|
|
+ creative_info_to_db['account_id'] = self.account_id
|
|
|
+ creative_info_to_db['campaign_id'] = self.campaign_id
|
|
|
+ creative_info_to_db['operation_type'] = self.operation_type
|
|
|
+
|
|
|
+ # 拼接最终请求数据
|
|
|
self.res_data['group_list'] = []
|
|
|
group_cnt = 1
|
|
|
for video in self.video:
|
|
|
- single_group_info = {'group_uuid': str(uuid.uuid4())}
|
|
|
- single_group_info.update(basic_group_info)
|
|
|
- single_group_info['unit_name'] = self.group_info['unit_name'] + '-' + str(group_cnt)
|
|
|
-
|
|
|
- # 组信息写入数据表中
|
|
|
- single_group_info_to_db = single_group_info.copy()
|
|
|
- single_group_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
|
|
|
- single_group_info_to_db['account_id'] = self.account_id
|
|
|
- single_group_info_to_db['campaign_id'] = self.campaign_id
|
|
|
+ group_uuid = str(uuid.uuid4())
|
|
|
+ group_name = basic_group_info['group_name'] + '-' + str(group_cnt)
|
|
|
+
|
|
|
+ # 写入数据表中组信息
|
|
|
+ single_group_info_to_db = group_info_to_db.copy()
|
|
|
+ single_group_info_to_db['group_uuid'] = group_uuid
|
|
|
+ single_group_info_to_db['group_name'] = group_name
|
|
|
single_group_info_to_db['create_time'] = datetime.datetime.now()
|
|
|
- single_group_info_to_db['operation_type'] = self.operation_type
|
|
|
df = pd.DataFrame.from_dict(single_group_info_to_db, orient='index').T
|
|
|
- engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
|
|
|
df.to_sql(name="ctop_ai_kuaishou_unit_level_operation_record",
|
|
|
con=engine,
|
|
|
if_exists='append',
|
|
|
index=False)
|
|
|
|
|
|
- # 发送的请求,这几个字段需要转为 [] 数组
|
|
|
- for col in cols_to_list:
|
|
|
- single_group_info[col] = eval(single_group_info[col]) if single_group_info[col] is not None else None
|
|
|
-
|
|
|
- single_group_info['creative_list'] = []
|
|
|
+ # 拼装返回json的组信息
|
|
|
+ single_group_info_to_res_data = group_info_to_res_data.copy()
|
|
|
+ single_group_info_to_res_data['group_uuid'] = group_uuid
|
|
|
+ single_group_info_to_res_data['group_name'] = group_name
|
|
|
+ single_group_info_to_res_data['creative_list'] = []
|
|
|
group_cnt += 1
|
|
|
|
|
|
+ # 拼装组下面创意的信息
|
|
|
creative_cnt = 1
|
|
|
- for image in video['imageList'][:image_cnt]:
|
|
|
- single_creative_info = {
|
|
|
- 'creative_uuid': str(uuid.uuid4()),
|
|
|
- 'is_sticky': 0,
|
|
|
- 'creative_name': self.creative_info['creative_name'] + '_' + str(creative_cnt),
|
|
|
- 'photo_id': video['photo_id'],
|
|
|
- 'image_md5': image,
|
|
|
- 'image_tokens': self.creative_info.get('image_tokens'),
|
|
|
- 'action_bar_text': self.creative_info['action_bar_text'],
|
|
|
- 'description': self.creative_info['description'],
|
|
|
- 'short_slogan': self.creative_info.get('short_slogan'),
|
|
|
- 'sticker_title': self.creative_info.get('sticker_title'),
|
|
|
- 'overlay_type': self.creative_info.get('overlay_type'),
|
|
|
- 'expose_tag': self.creative_info.get('expose_tag'),
|
|
|
- 'new_expose_tag': self.creative_info.get('new_expose_tag'),
|
|
|
- 'site_id': self.creative_info.get('site_id'),
|
|
|
- 'click_track_url': self.advertiser_strategy.get('click_track_url'),
|
|
|
- 'impression_url': self.advertiser_strategy.get('impression_url'),
|
|
|
- 'ad_photo_played_t3s_url': self.advertiser_strategy.get('ad_photo_played_t3s_url'),
|
|
|
- 'actionbar_click_url': self.advertiser_strategy.get('actionbar_click_url'),
|
|
|
- 'creative_category': self.creative_info.get('creative_category'),
|
|
|
- 'creative_tag': self.creative_info.get('creative_tag')}
|
|
|
-
|
|
|
- single_group_info['creative_list'].append(single_creative_info)
|
|
|
-
|
|
|
- # 创意层级写入数据表中
|
|
|
- single_creative_info_to_db = single_creative_info.copy()
|
|
|
- single_creative_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
|
|
|
- single_creative_info_to_db['account_id'] = self.account_id
|
|
|
- single_creative_info_to_db['campaign_id'] = self.campaign_id
|
|
|
+ for image_md5 in video['imageList'][: self.advertiser_strategy['image_cnt']]:
|
|
|
+ creative_uuid = str(uuid.uuid4())
|
|
|
+ creative_name = self.creative_info['creative_name'] + '_' + str(creative_cnt)
|
|
|
+
|
|
|
+ single_creative_info_to_db = creative_info_to_db.copy()
|
|
|
+ single_creative_info_to_db['creative_uuid'] = creative_uuid
|
|
|
+ single_creative_info_to_db['creative_name'] = creative_name
|
|
|
+ single_creative_info_to_db['photo_id'] = video['photo_id']
|
|
|
+ single_creative_info_to_db['image_md5'] = image_md5
|
|
|
single_creative_info_to_db['create_time'] = datetime.datetime.now()
|
|
|
- single_creative_info_to_db['operation_type'] = self.operation_type
|
|
|
-
|
|
|
- cols_to_str = ['creative_tag']
|
|
|
- for col in cols_to_str:
|
|
|
- single_creative_info_to_db[col] = str(single_creative_info_to_db[col]) \
|
|
|
- if single_creative_info_to_db[col] is not None else None
|
|
|
-
|
|
|
-
|
|
|
df = pd.DataFrame.from_dict(single_creative_info_to_db, orient='index').T
|
|
|
- engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
|
|
|
df.to_sql(name="ctop_ai_kuaishou_creative_level_operation_record",
|
|
|
con=engine,
|
|
|
if_exists='append',
|
|
|
index=False)
|
|
|
|
|
|
+ single_creative_info_to_res_data = creative_info_to_res_data.copy()
|
|
|
+ single_creative_info_to_res_data['creative_uuid'] = creative_uuid
|
|
|
+ single_creative_info_to_res_data['creative_name'] = creative_name
|
|
|
+ single_creative_info_to_res_data['photo_id'] = video['photo_id']
|
|
|
+ single_creative_info_to_res_data['image_md5'] = image_md5
|
|
|
+ single_group_info_to_res_data['creative_list'].append(single_creative_info_to_res_data)
|
|
|
+
|
|
|
creative_cnt += 1
|
|
|
# 组和创意信息添加到最终返回数据 group_list 中
|
|
|
- self.res_data['group_list'].append(single_group_info)
|
|
|
+ self.res_data['group_list'].append(single_group_info_to_res_data)
|
|
|
|
|
|
self.res_data['account_id'] = self.account_id
|
|
|
self.res_data['campaign_id'] = self.campaign_id
|