Browse Source

客户策略增删查改

liyuyi@c-top.com.cn 4 years ago
parent
commit
2d3de03fc0

+ 1 - 1
.idea/encodings.xml

@@ -2,6 +2,6 @@
 <project version="4">
 <project version="4">
   <component name="Encoding">
   <component name="Encoding">
     <file url="file://$PROJECT_DIR$/ai_callback_add_group_handler.py" charset="GBK" />
     <file url="file://$PROJECT_DIR$/ai_callback_add_group_handler.py" charset="GBK" />
-    <file url="file://$PROJECT_DIR$/logs/add_group_log/ai_strategy_request.log.2021-01-14" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/logs/ai_callback/ai_strategy_request.log.2021-01-14" charset="GBK" />
   </component>
   </component>
 </project>
 </project>

+ 179 - 0
advertiser_strategy_operate.py

@@ -0,0 +1,179 @@
+import datetime
+import json
+import traceback
+from logging.handlers import TimedRotatingFileHandler
+import pandas as pd
+from utils.BaseClass import *
+from utils.CommonFunction import *
+from utils.DataBaseConfig import *
+from utils.LogConfig import *
+
+log_handler = TimedRotatingFileHandler("logs/advertiser_strategy_operate/advertiser_strategy_operate.log",
+                                       when="midnight", backupCount=100)
+log_handler.setFormatter(log_formatter)
+logger = logging.getLogger('advertiser_strategy_operate_logger')
+logger.addHandler(log_handler)
+logger.setLevel(logging.DEBUG)
+print('id of logger %s' % id(logger))
+
+
+class AddAdvertiserStrategy(BaseHandler):
+    """
+    新增客户策略
+    """
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+
+        # TODO customCrowd 是否不需要了
+        # "111" 字符串类型 ,可以写入到整型的字段中
+        # 整数类型 ,可以写入到字符串类型的字段中
+        # 数组类型, 需要转化为字符串类型 然后写入字符串类型的字段中
+
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+
+        drop_cols = ['beginTime', 'budget', 'budgetMode', 'customCrowd', 'endTime', 'scheduleTime']
+        # 1-1 判断 account_id 是否存在可用策略,如果存在则不能新增
+        try:
+            account_id = data.get('accountId')
+            sql = """
+            select * from ctop_ai_kuaishou_advertiser_strategy where account_id = %s and status = 1
+            """ % account_id
+            df = pd.read_sql(sql, engine)
+            if df.empty:
+                self.write(json.dumps({"message": "该账户已经存在有效策略!", "code": -1}))
+                self.flush()
+            else:
+                for col in drop_cols:
+                    del data[col]
+
+                transfer_data = {}
+                for key, value in data.items():
+                    transfer_key = get_lower_case_name(key)
+                    transfer_data[transfer_key] = str(value) if isinstance(value, list) else value
+
+                df = pd.DataFrame.from_dict(transfer_data, orient='index').T
+                df.to_sql(name="ctop_ai_kuaishou_advertiser_strategy", con=engine, if_exists='append', index=False)
+                logger.info("策略添加成功!")
+                self.write(json.dumps({"message": "策略添加成功!", "code": 0}))
+                self.flush()
+        except:
+            logger.error(traceback.format_exc())
+            self.write(json.dumps({"message": traceback.format_exc(), "code": -2}))
+            self.flush()
+
+
+class ModifyAdvertiserStrategy(tornado.web.RequestHandler):
+    """
+    修改客户策略
+    """
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+        try:
+            transfer_data = {}
+            for key, value in data.items():
+                transfer_key = get_lower_case_name(key)
+                transfer_data[transfer_key] = str(value) if isinstance(value, list) else value
+
+            # 1-1 将已有的策略更新为无效,且更新该策略的失效时间
+            db_con = pymysql.connect(host=host,
+                                     port=port,
+                                     user=user,
+                                     password=passwd,
+                                     database=db,
+                                     charset=charset)
+            cursor = db_con.cursor()
+            cursor.execute("""UPDATE ctop_ai_kuaishou_advertiser_strategy
+                                SET status= %s, expiry_time=%s
+                                WHERE account_id = %s""", (0, datetime.datetime.now(), transfer_data['account_id']))
+            db_con.commit()
+            db_con.close()
+            
+
+            # 1-2 插入修改完成的策略
+            df = pd.DataFrame.from_dict(transfer_data, orient='index').T
+            df.to_sql(name="ctop_ai_kuaishou_advertiser_strategy", con=engine, if_exists='append', index=False)
+            logger.info("策略修改成功!")
+            self.write(json.dumps({"message": "策略修改成功!", "code": 0}))
+            self.flush()
+        except:
+            logger.error(traceback.format_exc())
+            self.write(json.dumps({"message": traceback.format_exc(), "code": -2}))
+            self.flush()
+
+
+class QueryAdvertiserStrategy(tornado.web.RequestHandler):
+    """
+    查询客户策略
+    """
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+
+        account_id = data.get('accountId', 'null')
+        # project_id = data.get('projectId', 'null')
+        sql = """
+        select * from ctop_ai_kuaishou_advertiser_strategy 
+        where (1 = (CASE WHEN '%s' = 'null'  THEN 1 ELSE 0 END) OR  account_id = %s)
+        and status = 1
+        """ % (account_id, account_id)
+
+        df = pd.read_sql(sql, engine)
+        if df.empty:
+            logger.info("没有查询到策略!")
+            self.write(json.dumps({"message": "没有查询到策略!", "code": -1}))
+            self.flush()
+        else:
+            res = []
+            for index, row in df.iterrows():
+                res.append(row.to_dict())
+            logger.info("策略查询完成!")
+            self.write(json.dumps(res))
+            self.flush()
+
+
+
+class DeleteAdvertiserStrategy(tornado.web.RequestHandler):
+    """
+    删除客户策略,把已有的策略状态更新为 "0-停用", 并把失效时间更新为now()
+    """
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+
+        try:
+            db_con = pymysql.connect(host=host,
+                                     port=port,
+                                     user=user,
+                                     password=passwd,
+                                     database=db,
+                                     charset=charset)
+            cursor = db_con.cursor()
+            cursor.execute("""UPDATE ctop_ai_kuaishou_advertiser_strategy
+                                            SET status= %s, expiry_time=%s
+                                            WHERE account_id = %s""",
+                           (0, datetime.datetime.now(), data['accountId']))
+            db_con.commit()
+            db_con.close()
+            logger.info("策略删除(失效)成功!")
+            self.write(json.dumps({"message": "策略删除成功!", "code": 0}))
+            self.flush()
+        except Exception:
+            logger.error(traceback.format_exc())
+            self.write(json.dumps({"message": traceback.format_exc(), "code": -2}))
+            self.flush()

+ 4 - 1
ai_auto_creative_handler.py

@@ -4,7 +4,10 @@ import traceback
 import pandas as pd
 import pandas as pd
 import requests
 import requests
 import tornado.web
 import tornado.web
-from db_config import *
+from utils.DataBaseConfig import *
+from utils.UrlConfig import *
+from utils.LogConfig import *
+
 
 
 
 
 class AiAutoCreative(tornado.web.RequestHandler):
 class AiAutoCreative(tornado.web.RequestHandler):

+ 0 - 66
ai_callback_add_creative_handler.py

@@ -1,66 +0,0 @@
-import json
-import traceback
-
-import pymysql
-import tornado.web
-
-from db_config import *
-
-
-class AiCallBackAddCreative(tornado.web.RequestHandler):
-    def initialize(self, logger):
-        self.logger = logger
-
-    def post(self):
-        res = {'code': 0,
-               'data': None,
-               'message': "SUCCESS"}
-
-        data = self.request.body
-        data = str(data, 'utf8')
-        data = json.loads(data, encoding='utf8')
-        self.logger.info("***************************************  NEW REQUEST ***************************************")
-        self.logger.info("raw data from request is %s" % data)
-
-        try:
-            inst = UpdateCreativeLevelRecordTable(data, self.logger)
-            inst.update_table_info()
-        except Exception:
-            res['code'] = -1
-            res['message'] = 'FAIL'
-            self.logger.error(traceback.format_exc())
-
-        # 返回接口结果
-        self.write(json.dumps(res))
-        self.flush()
-
-
-class UpdateCreativeLevelRecordTable(object):
-    def __init__(self, request_data,logger):
-        self.data = request_data
-        self.logger = logger
-
-    def update_table_info(self):
-        db_con = pymysql.connect(host=host,
-                                 port=port,
-                                 user=user,
-                                 password=passwd,
-                                 database=db,
-                                 charset=charset)
-        cursor = db_con.cursor()
-        for item in self.data['callbackData']:
-            if item['code'] == 0:
-                creative_uuid = item['creative_uuid']
-                creative_id = item['creative_id']
-                unit_id = item['unit_id']
-                self.logger.info("on single update callback info: %s" % item)
-
-                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:
-                self.logger.error("on single update callback info: %s" % item)
-
-        db_con.commit()
-        db_con.close()
-

+ 0 - 63
ai_callback_add_group_handler.py

@@ -1,63 +0,0 @@
-import json
-import traceback
-import pymysql
-import tornado.web
-from db_config import *
-
-
-class AiCallBackAddGroup(tornado.web.RequestHandler):
-    def initialize(self, logger):
-        self.logger = logger
-
-    def post(self):
-        res = {'code': 0,
-               'message': "SUCCESS"}
-
-        data = self.request.body
-        data = str(data, 'utf8')
-        data = json.loads(data, encoding='utf8')
-        self.logger.info("***************************************  NEW REQUEST ***************************************")
-        self.logger.info("raw data from request is %s" % data)
-
-        try:
-            inst = UpdateGroupLevelRecordTable(data, self.logger)
-            inst.update_table_info()
-        except Exception:
-            res['code'] = -1
-            res['message'] = 'FAIL'
-            self.logger.error(traceback.format_exc())
-
-        # ·µ»Ø½Ó¿Ú½á¹û
-        self.write(json.dumps(res))
-        self.flush()
-
-
-class UpdateGroupLevelRecordTable(object):
-    def __init__(self, request_data, logger):
-        self.data = request_data
-        self.logger = logger
-
-    def update_table_info(self):
-        db_con = pymysql.connect(host=host,
-                                 port=port,
-                                 user=user,
-                                 password=passwd,
-                                 database=db,
-                                 charset=charset)
-        cursor = db_con.cursor()
-        for item in self.data['callbackData']:
-            if item['code'] == 0:
-                group_uuid = item['group_uuid']
-                unit_id = item['unit_id']
-                group_create_time = item['group_create_time']
-                self.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:
-                self.logger.error("on single update callback info: %s" % item)
-
-        db_con.commit()
-        db_con.close()
-

+ 101 - 0
ai_callback_handler.py

@@ -0,0 +1,101 @@
+import json
+import traceback
+from logging.handlers import TimedRotatingFileHandler
+from utils.BaseClass import *
+from utils.DataBaseConfig import *
+from utils.LogConfig import *
+
+log_handler = TimedRotatingFileHandler("logs/ai_callback/ai_callback.log",
+                                       when="midnight", backupCount=100)
+log_handler.setFormatter(log_formatter)
+logger = logging.getLogger('ai_callback_logger')
+logger.addHandler(log_handler)
+logger.setLevel(logging.DEBUG)
+print('id of logger %s' % id(logger))
+
+
+class AiCallBackAddCreative(tornado.web.RequestHandler):
+    def post(self):
+        res = {'code': 0,
+               'message': "SUCCESS"}
+
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+
+        try:
+            db_con = pymysql.connect(host=host,
+                                     port=port,
+                                     user=user,
+                                     password=passwd,
+                                     database=db,
+                                     charset=charset)
+            cursor = db_con.cursor()
+            for item in data['callbackData']:
+                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)
+                    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)
+
+            db_con.commit()
+            db_con.close()
+        except Exception:
+            res['code'] = -1
+            res['message'] = 'FAIL'
+            logger.error(traceback.format_exc())
+
+        # 返回接口结果
+        self.write(json.dumps(res))
+        self.flush()
+
+
+class AiCallBackAddGroup(tornado.web.RequestHandler):
+    def post(self):
+        res = {'code': 0,
+               'message': "SUCCESS"}
+
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+        self.logger.info("***************************************  NEW REQUEST ***************************************")
+        self.logger.info("raw data from request is %s" % data)
+
+        try:
+            db_con = pymysql.connect(host=host,
+                                     port=port,
+                                     user=user,
+                                     password=passwd,
+                                     database=db,
+                                     charset=charset)
+            cursor = db_con.cursor()
+            for item in data['callbackData']:
+                if item['code'] == 0:
+                    group_uuid = item['group_uuid']
+                    unit_id = item['unit_id']
+                    group_create_time = item['group_create_time']
+                    self.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:
+                    self.logger.error("on single update callback info: %s" % item)
+
+            db_con.commit()
+            db_con.close()
+        except Exception:
+            res['code'] = -1
+            res['message'] = 'FAIL'
+            self.logger.error(traceback.format_exc())
+
+        # 返回接口结果
+        self.write(json.dumps(res))
+        self.flush()

+ 1 - 1
ai_check_and_upto_full_creative_handler.py

@@ -4,7 +4,7 @@ import traceback
 import pandas as pd
 import pandas as pd
 import requests
 import requests
 import tornado.web
 import tornado.web
-from db_config import *
+from utils.DataBaseConfig import *
 
 
 
 
 class AiCheckAndUpTOFullCreative(tornado.web.RequestHandler):
 class AiCheckAndUpTOFullCreative(tornado.web.RequestHandler):

+ 1 - 3
ai_historical_high_quality_material_handler.py

@@ -4,12 +4,10 @@ import json
 import traceback
 import traceback
 import requests
 import requests
 import tornado.web
 import tornado.web
-from db_config import *
+from utils.DataBaseConfig import *
 
 
 
 
 class AiHistoricalHighQualityMaterial(tornado.web.RequestHandler):
 class AiHistoricalHighQualityMaterial(tornado.web.RequestHandler):
-    def initialize(self, logger):
-        self.logger = logger
 
 
     def post(self):
     def post(self):
         data = self.request.body
         data = self.request.body

+ 122 - 67
ai_historical_missing_material_handler.py

@@ -4,93 +4,148 @@ import traceback
 import pandas as pd
 import pandas as pd
 import requests
 import requests
 import tornado.web
 import tornado.web
+from logging.handlers import TimedRotatingFileHandler
+from utils.DataBaseConfig import *
+from utils.BaseClass import *
+from utils.DataBaseConfig import *
+from utils.LogConfig import *
+from utils.UrlConfig import *
+from utils.CommonFunction import *
+from utils.ConstantConfig import *
 
 
-from db_config import *
+log_handler = TimedRotatingFileHandler("logs/ai_auto_create/ai_auto_create.log",
+                                       when="midnight", backupCount=100)
+log_handler.setFormatter(log_formatter)
+logger = logging.getLogger('ai_auto_create_logger')
+logger.addHandler(log_handler)
+logger.setLevel(logging.DEBUG)
+print('id of logger %s' % id(logger))
 
 
 
 
 class AiHistoricalMissingMaterial(tornado.web.RequestHandler):
 class AiHistoricalMissingMaterial(tornado.web.RequestHandler):
-    def initialize(self, logger):
-        self.logger = logger
-
     def post(self):
     def post(self):
         data = self.request.body
         data = self.request.body
         data = str(data, 'utf8')
         data = str(data, 'utf8')
         data = json.loads(data, encoding='utf8')
         data = json.loads(data, encoding='utf8')
-        self.logger.info("***************************************  NEW REQUEST ***************************************")
-        self.logger.info("raw data from request is %s" % data)
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
 
 
         account_id = data.get('account_id')
         account_id = data.get('account_id')
         campaign_id = data.get('campaign_id')
         campaign_id = data.get('campaign_id')
         try:
         try:
-            inst = GetRequestData(account_id, campaign_id)
-            if inst.data is not None:
-                request = requests.post(ai_strategy_request_url, inst.data)
-                self.logger.info("ai策略的返回信息:%s" % request.text)
-                self.write(request.text)
+            video_info = get_video_info(account_id, historical_missing_video_cnt, get_historical_missing_video_url)
+            if video_info is None:
+                self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
                 self.flush()
                 self.flush()
             else:
             else:
-                self.write(json.dumps({"message": "没有获取到视频新,不发送ai策略请求!"}))
+                campaign_name, group_name = get_campaign_and_group_name_rule(account_id)
+                if (campaign_name is None) or (group_name is None):
+                    self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
+                    self.flush()
+                else:
+                    request_data = {
+                        "video": video_info,
+                        "operation_type": 1,
+                        "account_id": account_id,
+                        "ai_strategy_remark": "补充遗漏素材",
+                        "campaign_info":
+                            {"campaign_id": campaign_id,
+                             "campaign_name": campaign_name.replace('自定义', '补充遗漏素材') + str(datetime.datetime.now())},
+                        'group_info':
+                            {'group_name': group_name.replace('自定义', '补充遗漏素材') + str(datetime.datetime.now()),
+                             'begin_time': str(datetime.date.today())},
+                        'creative_info': {'is_sticky': 0}
+                    }
+                    request = requests.post(ai_strategy_request_url, request_data)
+                    logger.info("ai策略的返回信息:%s" % request.text)
+                    self.write(request.text)
+                    self.flush()
+        except Exception:
+            logger.error(traceback.format_exc())
+            self.write(json.dumps(traceback.format_exc()))
+            self.flush()
+
+
+class AiAutoCreative(tornado.web.RequestHandler):
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
+
+        account_id = data.get('account_id')
+        campaign_id = data.get('campaign_id')
+        try:
+            video_info = get_video_info(account_id, get_new_video_url)
+            if video_info is None:
+                self.write(json.dumps({"message": "没有获取到视频,不发送ai策略请求!"}))
                 self.flush()
                 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):
+                    self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
+                    self.flush()
+                else:
+                    request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
+                                                    "自动上新", "上新")
+                    request = requests.post(ai_strategy_request_url, request_data)
+                    logger.info("ai策略的返回信息:%s" % request.text)
+                    self.write(request.text)
+                    self.flush()
         except Exception:
         except Exception:
-            self.logger.error(traceback.format_exc())
+            logger.error(traceback.format_exc())
             self.write(json.dumps(traceback.format_exc()))
             self.write(json.dumps(traceback.format_exc()))
             self.flush()
             self.flush()
 
 
 
 
-class GetRequestData(object):
-    def __init__(self, account_id, campaign_id):
-        self.video = None
-        self.account_id = account_id
-        self.campaign_id = campaign_id
-        self.data = None
-        self.campaign_name = None
-        self.group_name = None
-        self.get_video_info()
-        self.get_campaign_and_group_name_rule()
-        self.get_request_data()
+class AiHistoricalHighQualityMaterial(tornado.web.RequestHandler):
+    def post(self):
+        data = self.request.body
+        data = str(data, 'utf8')
+        data = json.loads(data, encoding='utf8')
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
 
 
-    def get_video_info(self):
-        video_request_data = {"accountId": self.account_id,
-                              "videoCnt": historical_missing_video_cnt}
-        request = requests.post(get_historical_missing_video_url,
-                                headers=headers,
-                                data=json.JSONEncoder().encode(video_request_data))
-        self.video = request
+        account_id = data.get('account_id')
+        campaign_id = data.get('campaign_id')
+        try:
+            video_info = get_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)
+            if video_info is None:
+                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):
+                    self.write(json.dumps({"message": "没有获取到广告计划命名规则 或 广告组命名规则,不发送ai策略请求!"}))
+                    self.flush()
+                else:
+                    request_data = get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,
+                                                    "跑量素材", "跑量素材")
+                    request = requests.post(ai_strategy_request_url, request_data)
+                    logger.info("ai策略的返回信息:%s" % request.text)
+                    self.write(request.text)
+                    self.flush()
+        except Exception:
+            logger.error(traceback.format_exc())
+            self.write(json.dumps(traceback.format_exc()))
+            self.flush()
 
 
-    def get_campaign_and_group_name_rule(self):
-        if self.video['code'] == 0:
-            sql = """
-                    select campaign_name, unit_name 
-                    from ctop_ai_kuaishou_advertiser_strategy 
-                    where account_id = %d 
-                    and status = 1
-                    limit 1
-                    """ % self.account_id
-            df = pd.read_sql(sql, engine)
-            self.campaign_name = df['campaign_name'].values[0]
-            self.group_name = df['unit_name'].values[0]
 
 
-    def get_request_data(self):
-        if self.video['code'] == 0:
-            self.data = {
-                         "video": self.video['data'],
-                         "operation_type": 1,
-                         "account_id": self.account_id,
-                         "ai_strategy_remark": "补充遗漏素材",
-                         "campaign_info":
-                             {
-                             "campaign_id": self.campaign_id,
-                             "campaign_name": self.campaign_name.replace('自定义', '补充遗漏素材')
-                                              + str(datetime.datetime.now())
-                             },
-                         'group_info':
-                             {
-                             'group_name': self.group_name.replace('自定义', '补充遗漏素材')
-                                           + str(datetime.datetime.now()),
-                             'begin_time': str(datetime.date.today())
-                             },
-                         'creative_info':
-                             {
-                             'is_sticky': 0
-                             }
-                         }
+def get_request_data(account_id, campaign_id, video_info, campaign_name, group_name,ai_strategy_remark, name_replace):
+    res = {
+        "video": video_info,
+        "operation_type": 1,
+        "account_id": account_id,
+        "ai_strategy_remark": ai_strategy_remark,
+        "campaign_info":
+            {"campaign_id": campaign_id,
+             "campaign_name": campaign_name.replace('自定义', name_replace) + str(datetime.datetime.now())},
+        'group_info':
+            {'group_name': group_name.replace('自定义', name_replace) + str(datetime.datetime.now()),
+             'begin_time': str(datetime.date.today())},
+        'creative_info': {'is_sticky': 0}
+    }
+    return res

+ 20 - 23
ai_strategy_request_handler.py

@@ -2,31 +2,35 @@ import datetime
 import json
 import json
 import traceback
 import traceback
 import uuid
 import uuid
-
+from logging.handlers import TimedRotatingFileHandler
 import pandas as pd
 import pandas as pd
-import pymysql
 import requests
 import requests
-import simplejson
-import tornado.web
+from utils.BaseClass import *
+from utils.DataBaseConfig import *
+from utils.LogConfig import *
+from utils.UrlConfig import *
 
 
-from db_config import *
+log_handler = TimedRotatingFileHandler("logs/ai_strategy_request/ai_strategy_request.log",
+                                       when="midnight", backupCount=100)
+log_handler.setFormatter(log_formatter)
+logger = logging.getLogger('ai_strategy_request_logger')
+logger.addHandler(log_handler)
+logger.setLevel(logging.DEBUG)
+print('id of logger %s' % id(logger))
 
 
 
 
 class AiStrategyRequestParse(tornado.web.RequestHandler):
 class AiStrategyRequestParse(tornado.web.RequestHandler):
-    def initialize(self, logger):
-        self.logger = logger
-
     def post(self):
     def post(self):
         data = self.request.body
         data = self.request.body
         data = str(data, 'utf8')
         data = str(data, 'utf8')
         data = json.loads(data, encoding='utf8')
         data = json.loads(data, encoding='utf8')
-        self.logger.info("***************************************  NEW REQUEST ***************************************")
-        self.logger.info("raw data from request is %s" % data)
+        logger.info("***************************************  NEW REQUEST ***************************************")
+        logger.info("raw data from request is %s" % data)
 
 
         # 1、新增广告组操作
         # 1、新增广告组操作
         try:
         try:
             if data["operation_type"] == 1:
             if data["operation_type"] == 1:
-                inst = ParseAddCampaignOrAddGroupRequest(data,self.logger)
+                inst = ParseAddCampaignOrAddGroupRequest(data)
                 inst.get_advertiser_strategy_info()
                 inst.get_advertiser_strategy_info()
                 inst.write_intelligence_strategy_table()
                 inst.write_intelligence_strategy_table()
                 if inst.campaign_id == "" or inst.campaign_id is None:
                 if inst.campaign_id == "" or inst.campaign_id is None:
@@ -36,14 +40,14 @@ class AiStrategyRequestParse(tornado.web.RequestHandler):
                 inst.assemble_group_and_creative_params()
                 inst.assemble_group_and_creative_params()
                 create_group_and_creative_res = inst.res_data
                 create_group_and_creative_res = inst.res_data
                 inst.update_intelligence_strategy_table()
                 inst.update_intelligence_strategy_table()
-                self.logger.info("create group and creative request info: %s" % create_group_and_creative_res)
+                logger.info("create group and creative request info: %s" % create_group_and_creative_res)
 
 
                 request = requests.post(create_group_and_creative_url,
                 request = requests.post(create_group_and_creative_url,
                                         headers=headers,
                                         headers=headers,
                                         data=json.JSONEncoder().encode(create_group_and_creative_res)
                                         data=json.JSONEncoder().encode(create_group_and_creative_res)
                                         )
                                         )
                 create_group_and_creative_response_data = json.loads(request.text)
                 create_group_and_creative_response_data = json.loads(request.text)
-                self.logger.info("请求返回:%s" % create_group_and_creative_response_data)
+                logger.info("请求返回:%s" % create_group_and_creative_response_data)
                 self.write(json.dumps({'account_id': inst.account_id,
                 self.write(json.dumps({'account_id': inst.account_id,
                                        'ai_strategy_id': inst.ai_strategy_uuid,
                                        'ai_strategy_id': inst.ai_strategy_uuid,
                                        'message': create_group_and_creative_response_data}))
                                        'message': create_group_and_creative_response_data}))
@@ -52,17 +56,16 @@ class AiStrategyRequestParse(tornado.web.RequestHandler):
                 self.write(json.dumps({"message": "operation_type 不支持"}))
                 self.write(json.dumps({"message": "operation_type 不支持"}))
                 self.flush()
                 self.flush()
         except Exception:
         except Exception:
-            self.logger.error(traceback.format_exc())
+            logger.error(traceback.format_exc())
             self.write(json.dumps(traceback.format_exc()))
             self.write(json.dumps(traceback.format_exc()))
             self.flush()
             self.flush()
 
 
 
 
 # 该类解析的是 手动请求的新增广告计划或者新增广告组的数据
 # 该类解析的是 手动请求的新增广告计划或者新增广告组的数据
 class ParseAddCampaignOrAddGroupRequest(object):
 class ParseAddCampaignOrAddGroupRequest(object):
-    def __init__(self, request_data, logger):
+    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.logger = logger
         self.video = self.request_data['video']
         self.video = self.request_data['video']
         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']
@@ -173,16 +176,10 @@ class ParseAddCampaignOrAddGroupRequest(object):
                       if_exists='append',
                       if_exists='append',
                       index=False)
                       index=False)
         else:
         else:
-            self.logger.info("广告计划创建失败:%s,  ai_strategy_uuid is %s" %
+            logger.info("广告计划创建失败:%s,  ai_strategy_uuid is %s" %
                              (res_data['message'], self.ai_strategy_uuid))
                              (res_data['message'], self.ai_strategy_uuid))
             return -1
             return -1
 
 
-    def get_group_basic_params(self):
-        pass
-
-    def get_creative_basic_params(self):
-        pass
-
     def assemble_group_and_creative_params(self):
     def assemble_group_and_creative_params(self):
         """
         """
         拼接组和创意层级参数
         拼接组和创意层级参数

+ 0 - 58
db_config.py

@@ -1,58 +0,0 @@
-from sqlalchemy import create_engine
-
-# 线上数据库连接字符串
-# host = "139.186.151.174"
-# port = 3306
-# user = "hcst"
-# passwd = "hcst@2020"
-# db = 'jeecg-boot'
-# charset = 'utf8'
-# db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("readonly", "hcst@2021", "139.186.27.96", 4000, "jeecg-boot")
-
-# 测试数据库连接字符串
-host = "139.186.151.174"
-port = 3306
-user = "hcst"
-passwd = "hcst@2020"
-db = 'jeecg-boot'
-charset = 'utf8'
-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'})
-
-
-headers = {'Content-Type': 'application/json'}
-# 创建计划url
-create_campaign_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/create/campaignCreate"
-
-# 获取上新视频url
-get_new_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getNewVideoList"
-
-# 获取历史视频url
-get_history_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList"
-
-# 创建组和创意url
-create_group_and_creative_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/create/createUnitAndCreative"
-
-# 获取历史遗漏视频url
-get_historical_missing_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList"
-
-# 获取历史高质量视频url
-get_historical_high_quality_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryTopVideoList"
-
-# ai 策略请求url
-ai_strategy_request_url = 'http://127.0.0.1:31012/ai_strategy_request'
-
-
-# 补充历史遗落素材的个数
-historical_missing_video_cnt = 100
-
-# 近多少天的爆量视频
-high_quality_video_days = 14
-
-
-high_quality_video_cnt = 100
-
-# 账户当天创意上新数
-full_creative_cnt = 2000
-
-

File diff suppressed because it is too large
+ 0 - 172
logs/add_group_log/ai_callback_add_creative.log


File diff suppressed because it is too large
+ 0 - 316
logs/add_group_log/ai_callback_add_group.log


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


+ 12 - 0
logs/ai_strategy_request/ai_strategy_request.log

@@ -0,0 +1,12 @@
+01/22/2021 05:39:34 PM INFO ai strategy request service started at 2021-01-22 17:39:34
+01/22/2021 05:45:25 PM INFO ai strategy request service started at 2021-01-22 17:45:25
+01/22/2021 06:02:52 PM INFO ai strategy request service started at 2021-01-22 18:02:52
+01/22/2021 06:07:03 PM INFO ai strategy request service started at 2021-01-22 18:07:03
+01/22/2021 06:14:09 PM INFO ai strategy request service started at 2021-01-22 18:14:09
+01/22/2021 06:26:06 PM INFO ai strategy request service started at 2021-01-22 18:26:06
+01/22/2021 06:54:17 PM INFO ai strategy request service started at 2021-01-22 18:54:17
+01/22/2021 06:54:38 PM INFO ai strategy request service started at 2021-01-22 18:54:38
+01/22/2021 06:54:49 PM INFO ai strategy request service started at 2021-01-22 18:54:49
+01/22/2021 06:55:26 PM INFO ai strategy request service started at 2021-01-22 18:55:26
+01/22/2021 06:56:46 PM INFO ai strategy request service started at 2021-01-22 18:56:46
+01/22/2021 07:01:41 PM INFO ai strategy request service started at 2021-01-22 19:01:41

+ 7 - 67
main.py

@@ -1,80 +1,20 @@
 import argparse
 import argparse
-import logging
-import time
-from logging.handlers import TimedRotatingFileHandler
-
 import tornado.ioloop
 import tornado.ioloop
 import tornado.log
 import tornado.log
 import tornado.options
 import tornado.options
 import tornado.web
 import tornado.web
-
-import ai_callback_add_creative_handler
-import ai_callback_add_group_handler
-import ai_strategy_request_handler
+from ai_strategy_request_handler import *
+from advertiser_strategy_operate import *
+from ai_callback_handler import *
 
 
 
 
 def create_application():
 def create_application():
-    # 日志的格式
-    log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s',
-                                      '%m/%d/%Y %I:%M:%S %p')
-
-    # ai策略请求解析的日志对象-----------------------------------------------------------
-    ai_strategy_request_log_handler = TimedRotatingFileHandler("logs/ai_strategy_request/ai_strategy_request.log",
-                                                   when="midnight",
-                                                   backupCount=100)
-
-    ai_strategy_request_log_handler.setFormatter(log_formatter)
-    ai_strategy_request_logger = logging.getLogger('ai_strategy_request_logger')
-    ai_strategy_request_logger.addHandler(ai_strategy_request_log_handler)
-    ai_strategy_request_logger.setLevel(logging.DEBUG)
-
-    print("ai_strategy_request_logger's id is {}".format(id(ai_strategy_request_logger)))
-    msg = "ai strategy request service started at {t}".\
-           format(t=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
-    ai_strategy_request_logger.info(msg)
-
-    # 创建广告组回调日志对象-----------------------------------------------------------
-    ai_callback_add_group_log_handler = TimedRotatingFileHandler("logs/add_group_log/ai_callback_add_group.log",
-                                                               when="midnight",
-                                                               backupCount=100)
-
-    ai_callback_add_group_log_handler.setFormatter(log_formatter)
-    ai_callback_add_group_logger = logging.getLogger('ai_callback_add_group_logger')
-    ai_callback_add_group_logger.addHandler(ai_callback_add_group_log_handler)
-    ai_callback_add_group_logger.setLevel(logging.DEBUG)
-
-    print("ai_callback_add_group_logger's id is {}".format(id(ai_callback_add_group_logger)))
-    msg = "ai callback add group logger service started at {t}". \
-        format(t=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
-    ai_callback_add_group_logger.info(msg)
-
-    # 创建广告创意回调日志对象-----------------------------------------------------------
-    ai_callback_add_creative_log_handler = TimedRotatingFileHandler("logs/add_group_log/ai_callback_add_creative.log",
-                                                                 when="midnight",
-                                                                 backupCount=100)
-
-    ai_callback_add_creative_log_handler.setFormatter(log_formatter)
-    ai_callback_add_creative_logger = logging.getLogger('ai_callback_add_creative_logger')
-    ai_callback_add_creative_logger.addHandler(ai_callback_add_creative_log_handler)
-    ai_callback_add_creative_logger.setLevel(logging.DEBUG)
-
-    print("ai_callback_add_creative_logger's id is {}".format(id(ai_callback_add_creative_logger)))
-    msg = "ai callback add creative logger service started at {t}". \
-        format(t=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
-    ai_callback_add_creative_logger.info(msg)
-
     web_application = tornado.web.Application([
     web_application = tornado.web.Application([
-        (r"/ai_strategy_request",
-         ai_strategy_request_handler.AiStrategyRequestParse,
-         {"logger": ai_strategy_request_logger}),
-        (r"/ai_callback_add_group",
-         ai_callback_add_group_handler.AiCallBackAddGroup,
-         {"logger": ai_callback_add_group_logger}),
-        (r"/ai_callback_add_creative",
-         ai_callback_add_creative_handler.AiCallBackAddCreative,
-         {"logger": ai_callback_add_creative_logger}),
+        (r"/ai_strategy_request", AiStrategyRequestParse),
+        (r"/ai_callback_add_group", AiCallBackAddGroup),
+        (r"/ai_callback_add_creative", AiCallBackAddCreative),
+        (r"/add_advertiser_strategy", AddAdvertiserStrategy),
     ])
     ])
-
     return web_application
     return web_application
 
 
 
 

+ 19 - 0
utils/BaseClass.py

@@ -0,0 +1,19 @@
+import tornado.web
+
+
+class BaseHandler(tornado.web.RequestHandler):
+    def set_default_headers(self):
+        self.set_header("Access-Control-Allow-Origin", "*")
+        self.set_header("Access-Control-Allow-Headers", "x-requested-with")
+        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
+
+    def post(self):
+        self.write('some post')
+
+    def get(self):
+        self.write('some get')
+
+    def options(self):
+        # no body
+        self.set_status(204)
+        self.finish()

+ 62 - 0
utils/CommonFunction.py

@@ -0,0 +1,62 @@
+import requests
+from utils.UrlConfig import *
+import json
+import pandas as pd
+from utils.DataBaseConfig import *
+
+
+def get_lower_case_name(name):
+    lst = []
+    for index, char in enumerate(name):
+        if char.isupper() and index != 0:
+            lst.append("_")
+        lst.append(char)
+    return "".join(lst).lower()
+
+
+def get_video_info(account_id, url):
+    request_data = {"accountId": account_id}
+    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data))
+    if request['code'] != 0:
+        return None
+    return request['data']
+
+
+def get_video_info(account_id, cnt, url):
+    request_data = {"accountId": account_id, "videoCnt": cnt}
+    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data))
+    if request['code'] != 0:
+        return None
+    return request['data']
+
+
+def get_video_info(account_id, cnt, url):
+    request_data = {"accountId": account_id, "videoCnt": cnt}
+    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data))
+    if request['code'] != 0:
+        return None
+    return request['data']
+
+
+def get_video_info(account_id, cnt, start_time, end_time, url):
+    request_data = {"accountId": account_id, "num": cnt, "startTime": start_time, "endTime": end_time}
+    request = requests.post(url, headers=headers, data=json.JSONEncoder().encode(request_data))
+    if request['code'] != 0:
+        return None
+    return request['data']
+
+
+def get_campaign_and_group_name_rule(account_id):
+    sql = """select campaign_name, unit_name 
+             from ctop_ai_kuaishou_advertiser_strategy 
+             where account_id = %s 
+             and status = 1
+             limit 1
+               """ % account_id
+    df = pd.read_sql(sql, engine)
+    if df.empty:
+        return None, None
+
+    campaign_name = df['campaign_name'].values[0]
+    group_name = df['unit_name'].values[0]
+    return campaign_name, group_name

+ 11 - 0
utils/ConstantConfig.py

@@ -0,0 +1,11 @@
+# 补充历史遗落素材的个数
+historical_missing_video_cnt = 100
+
+# 近多少天的爆量视频
+high_quality_video_days = 14
+
+
+high_quality_video_cnt = 100
+
+# 账户当天创意上新数
+full_creative_cnt = 2000

+ 27 - 0
utils/DataBaseConfig.py

@@ -0,0 +1,27 @@
+from sqlalchemy import create_engine
+import pymysql
+
+# 线上数据库连接字符串
+# host = "139.186.151.174"
+# port = 3306
+# user = "hcst"
+# passwd = "hcst@2020"
+# db = 'jeecg-boot'
+# charset = 'utf8'
+# db_con_str = "mysql+pymysql://%s:%s@%s:%d/%s" % ("readonly", "hcst@2021", "139.186.27.96", 4000, "jeecg-boot")
+
+# 测试数据库连接字符串
+host = "139.186.151.174"
+port = 3306
+user = "hcst"
+passwd = "hcst@2020"
+db = 'jeecg-boot'
+charset = 'utf8'
+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'})
+
+
+
+
+
+

+ 3 - 0
utils/LogConfig.py

@@ -0,0 +1,3 @@
+import logging
+
+log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m/%d/%Y %I:%M:%S %p')

+ 24 - 0
utils/UrlConfig.py

@@ -0,0 +1,24 @@
+headers = {'Content-Type': 'application/json'}
+
+# 创建计划url
+create_campaign_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/create/campaignCreate"
+
+# 获取上新视频url
+get_new_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getNewVideoList"
+
+# 获取历史视频url
+get_history_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList"
+
+# 创建组和创意url
+create_group_and_creative_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/create/createUnitAndCreative"
+
+# 获取历史遗漏视频url, 没有关联上创意的视频
+get_missing_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryVideoList"
+
+# 获取历史高质量视频url
+get_high_quality_video_url = "http://192.168.1.8:8080/jeecg-boot/kuaishou/material/getHistoryTopVideoList"
+
+# ai 策略请求url
+ai_strategy_request_url = 'http://127.0.0.1:31012/ai_strategy_request'
+
+# 192.168.1.193