123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- # coding=utf-8
- """ ad.json 操作
- 支持版本 6.*
- """
- import os
- import json
- from common.logging import Logging
- import strategy_generator
- class AD_TYPE(object):
- """ 广告类型
- BANNER: 横幅
- INTERSTITIAL: 插屏
- VIDEO: 视频
- """
- BANNER, INTERSTITIAL, VIDEO = range(3)
- @staticmethod
- def key_string(type):
- return {
- AD_TYPE.BANNER: "banners",
- AD_TYPE.INTERSTITIAL: "interstitials",
- AD_TYPE.VIDEO: "videos",
- }[type]
- class AD_PLATFROM(object):
- """ 广告平台 """
- ADMOB, FACEBOOK, UNITY, CRITEO, UNKNOWN = range(5)
- @staticmethod
- def string(platform):
- return {
- AD_PLATFROM.ADMOB: "admob",
- AD_PLATFROM.FACEBOOK: "facebook",
- AD_PLATFROM.UNITY: "unity",
- AD_PLATFROM.CRITEO: "criteo",
- AD_PLATFROM.UNKNOWN: "unknown"
- }[platform]
- class RED_SDK_AD_PLATFORM(object):
- """ RedSdk的配置文件中,所使用到的平台的ID """
- ADMOB = 0
- FACEBOOK = 1
- CHARTBOOST = 2
- APPLOVIN = 3
- VUNGLE = 4
- UNITY = 5
- IRONSOURCE = 7
- TAPJOY = 8
- FACEBOOK_BID = 9
- CRITEO = 10
- @staticmethod
- def string(platform):
- return {
- RED_SDK_AD_PLATFORM.ADMOB: "Admob",
- RED_SDK_AD_PLATFORM.FACEBOOK: "Facebook",
- RED_SDK_AD_PLATFORM.CHARTBOOST: "Chartboost",
- RED_SDK_AD_PLATFORM.APPLOVIN: "Applovin",
- RED_SDK_AD_PLATFORM.VUNGLE: "Vungle",
- RED_SDK_AD_PLATFORM.UNITY: "Unity",
- RED_SDK_AD_PLATFORM.IRONSOURCE: "Ironsource",
- RED_SDK_AD_PLATFORM.TAPJOY: "Tapjoy",
- RED_SDK_AD_PLATFORM.FACEBOOK_BID: "Facebook_bid",
- RED_SDK_AD_PLATFORM.CRITEO: "Criteo",
- }[platform]
- class AdPool:
- """ 广告池子配置
- "admob": {
- "am_5": 9,
- "am_4": 7,
- "am_3": 5,
- "am_2": 3,
- "am_1": 2
- }
- dic_pool_items: {} 原始json文件
- arr_ordered_pool_items: [] 从大到小的广告配置项 {ad_id:adid, priority:3}
- """
- def __init__(self, pool_item_dic=None):
- """
- :param pool_item_dic: {} 原始配置
- """
- self.ori_json = {}
- self.ordered_pool_item_arr = []
- if pool_item_dic is not None:
- self.ori_json = pool_item_dic
- self.__parse(pool_item_dic)
- def __parse(self, pool_item_dic):
- pool_arr = []
- for ad_id in pool_item_dic:
- priority = pool_item_dic[ad_id]
- pool_arr.append({
- "ad_id": ad_id,
- "priority": priority
- })
- self.ordered_pool_item_arr = sorted(pool_arr, key=lambda e: e.__getitem__("priority"), reverse=True)
- def max_priority(self):
- """ :return: int """
- return self.ordered_pool_item_arr[0]["priority"]
- def max_priority_ad_id(self):
- """ :return: string """
- return self.ordered_pool_item_arr[0]["ad_id"]
- def add_ad_id(self, adId, priority):
- self.ori_json[adId] = priority
- self.__parse(self.ori_json)
- def print_desc(self):
- for item in self.ordered_pool_item_arr:
- print "{}:\t{}".format(item["priority"], item["ad_id"])
- class AdStrategy:
- """ 广告策略配置
- {
- "root": "am_3",
- "strategy": {
- "am_4": {
- "fail": 2,
- "platform": "admob",
- "suc": 2
- },
- "am_5": {
- "fail": 1,
- "platform": "admob",
- "suc": 2,
- "fail_next": "am_4"
- },
- "am_3": {
- "fail": 1,
- "platform": "admob",
- "suc": 1,
- "fail_next": "am_2",
- "suc_next": "am_5"
- },
- "am_2": {
- "fail": 1,
- "platform": "admob",
- "suc": 2,
- "fail_next": "am_1"
- },
- "am_1": {
- "fail": 2,
- "platform": "admob",
- "suc": 2
- }
- }
- }
- """
- def __init__(self, platform=AD_PLATFROM.UNKNOWN, strategy_dic=None, is_admob_5_floor_strategy=False):
- self.platform = platform
- self.is_admob_5_floor_strategy = is_admob_5_floor_strategy
- self.root_ad_id = ""
- self.strategy_json = {}
- self.ordered_ad_id_arr = []
- self.ori_json = {}
- if strategy_dic is not None:
- self.ori_json = strategy_dic
- self.__parse(strategy_dic)
- def __parse(self, strategy_dic):
- self.root_ad_id = strategy_dic["root"]
- self.strategy_json = strategy_dic["strategy"]
- self.is_admob_5_floor_strategy = (strategy_dic["strategy"][self.root_ad_id]["suc"] == 1)
- if self.is_admob_5_floor_strategy:
- self.ordered_ad_id_arr = [""] * 5
- self.ordered_ad_id_arr[2] = self.root_ad_id
- self.ordered_ad_id_arr[3] = self.strategy_json[self.ordered_ad_id_arr[2]]["fail_next"]
- self.ordered_ad_id_arr[4] = self.strategy_json[self.ordered_ad_id_arr[3]]["fail_next"]
- self.ordered_ad_id_arr[1] = self.strategy_json[self.ordered_ad_id_arr[2]]["suc_next"]
- self.ordered_ad_id_arr[0] = self.strategy_json[self.ordered_ad_id_arr[1]]["fail_next"]
- else:
- self.ordered_ad_id_arr = []
- self.ordered_ad_id_arr.append(self.root_ad_id)
- now_ad_id = self.root_ad_id
- while self.strategy_json[now_ad_id]["fail"] != 2:
- now_ad_id = self.strategy_json[now_ad_id]["fail_next"]
- self.ordered_ad_id_arr.append(now_ad_id)
- def update(self, ordered_ad_id_arr):
- """ 按从大到小的顺序排好
- ori_json 原始的json文件
- ordered_ad_ids: 从小到大 [fb_4, fb_3, fb_2]
- """
- dic = strategy_generator.generate_ordered_floor_strategy(ordered_ad_id_arr, AD_PLATFROM.string(self.platform))
- self.ori_json["root"] = dic["root"]
- self.ori_json["strategy"] = dic["strategy"]
- self.__parse(self.ori_json)
- def get_desc(self):
- string = self.ordered_ad_id_arr[0]
- for i in range(1, len(self.ordered_ad_id_arr)):
- string = "{} --> {}".format(string, self.ordered_ad_id_arr[i])
- return string
- def print_desc(self):
- print self.get_desc()
- class AdPage:
- """ 广告配置页面 | 版位
- page_name 页面名称
- """
- def __init__(self, page_name, page_dic=None):
- self.page_name = page_name
- self.ori_json = {}
- if page_dic is not None:
- self.ori_json = page_dic
- self.__parse(page_dic)
- def __parse(self, page_dic):
- self.pools = page_dic["pools"]
- self.ctrl = page_dic["ctrl"]
- def add_pool(self, pool_name):
- if not self.pools.__contains__(pool_name):
- self.pools.append(pool_name)
- class AdBidders:
- """ 竞价广告配置 """
- def __init__(self, bidder_dic=None):
- self.ori_json = {}
- if bidder_dic is not None:
- self.ori_json = bidder_dic
- def add_bidder(self, platform, adId):
- self.ori_json[AD_PLATFROM.string(platform)] = adId
- class AdPlatformId:
- """ 广告平台的app_id配置 """
- def __init__(self, platform_dic=None, platform=None, app_id=None):
- self.ori_json = {}
- self.platform = ""
- self.app_id = ""
- if platform_dic is not None:
- self.ori_json = platform_dic
- self.platform = platform_dic["p"]
- self.app_id = platform_dic["aid"]
- if platform is not None and app_id is not None:
- self.platform = platform
- self.app_id = app_id
- self.ori_json = {
- "p": platform,
- "aid": app_id
- }
- def get_desc(self):
- return "%s:\t\t%s" % (RED_SDK_AD_PLATFORM.string(self.platform), self.app_id)
- class AdPageCtrl:
- """ 广告页面配置 版位
- 参数列表:
- key: string
- value: number
- is_deprecated: bool
- config_name: string
- """
- def __init__(self, key, value):
- self.key = key
- self.value = value
- self.is_deprecated = False
- if self.key == "d":
- self.config_name = "展示天数"
- elif self.key == "level":
- self.config_name = "展示关数"
- else:
- self.is_deprecated = True
- self.config_name = "未配置或已废弃"
- def get_desc(self):
- return "{}: {}".format(self.config_name, self.value)
- class AdJson6:
- def __init__(self):
- self.ori_json = {}
- def read(self, file_path):
- if not os.path.exists(file_path):
- Logging.error("文件不存在: %s" % file_path)
- self.ori_json = json.load(open(file_path))
- if not self.ori_json.has_key("ad"):
- Logging.error("不存在ad根节点: %s" % file_path)
- check_keys = ["platform_ids", "global", "banners", "interstitials", "videos"]
- for key in check_keys:
- if not self.ori_json["ad"].has_key(key):
- Logging.error("ad节点下不存在子节点: %s: %s" % (key, file_path))
- def __dic_ad_type(self, ad_type):
- return self.ori_json["ad"][AD_TYPE.key_string(ad_type)]
- # 获取池子的配置
- def get_pool(self, ad_type, ad_platform):
- if ad_type == AD_TYPE.BANNER:
- Logging.error("error: banner不支持获取池")
- return None
- platform_str = AD_PLATFROM.string(ad_platform)
- if not self.__dic_ad_type(ad_type)["pools"].__contains__(platform_str):
- return None
- return AdPool(self.__dic_ad_type(ad_type)["pools"][platform_str])
- def add_pool(self, ad_type, ad_platform, ad_pool):
- self.__dic_ad_type(ad_type)["pools"][AD_PLATFROM.string(ad_platform)] = ad_pool.ori_json
- def remove_pool(self, ad_type, ad_platform):
- self.__dic_ad_type(ad_type)["pools"].__delitem__(AD_PLATFROM.string(ad_platform))
- def get_strategy(self, ad_type, ad_platform):
- platform_str = AD_PLATFROM.string(ad_platform)
- if ad_type == AD_TYPE.BANNER:
- return AdStrategy(ad_platform, self.__dic_ad_type(ad_type)["load_strategy"])
- if ad_type == AD_TYPE.INTERSTITIAL:
- if not self.__dic_ad_type(ad_type)["pools_load_strategy"].__contains__(platform_str):
- return None
- return AdStrategy(ad_platform, self.__dic_ad_type(ad_type)["pools_load_strategy"][platform_str])
- def add_strategy(self, ad_type, ad_platform, strategy):
- if ad_type == AD_TYPE.BANNER:
- Logging.error("error: banner不支持添加策略")
- if ad_type == AD_TYPE.INTERSTITIAL:
- self.__dic_ad_type(ad_type)["pools_load_strategy"][AD_PLATFROM.string(ad_platform)] = strategy.ori_json
- def remove_strategy(self, ad_type, ad_platform):
- self.__dic_ad_type(ad_type)["pools_load_strategy"].__delitem__(AD_PLATFROM.string(ad_platform))
- def get_bidders(self, ad_type):
- if ad_type == AD_TYPE.BANNER:
- Logging.error("error: banner不支持")
- dic_ad_type = self.__dic_ad_type(ad_type)
- if not dic_ad_type.has_key("bidders"):
- dic_ad_type["bidders"] = {}
- return AdBidders(dic_ad_type["bidders"])
- def get_ad_pages(self, ad_type):
- if ad_type == AD_TYPE.BANNER:
- Logging.error("error: banner不支持")
- pages = self.__dic_ad_type(ad_type)["pages"]
- arr = []
- for page_name in pages:
- dic_page = pages[page_name]
- ad_page = AdPage(page_name, dic_page)
- arr.append(ad_page)
- return arr
- def get_platform_ids(self):
- platform_id_arr = self.ori_json["ad"]["platform_ids"]
- arr = []
- for platform_id_dic in platform_id_arr:
- platform_id = AdPlatformId(platform_id_dic)
- arr.append(platform_id)
- return arr
- def add_platform_id(self, ad_platform, app_id):
- platform_id = AdPlatformId(platform=ad_platform, app_id=app_id)
- self.ori_json["ad"]["platform_ids"].append(platform_id.ori_json)
- def write(self, to_path):
- json.dump(self.ori_json, open(to_path, "w"))
- def print_desc(self):
- print "参数配置"
- param = json.loads(self.ori_json["parameters"])
- print "\t关卡工具发送比例: {}%".format(int(param["LSR"]) / 10)
- print "\tGT工具发送比例: {}%".format(int(param["GTSR"]) / 10)
- print "平台ID:"
- platforms = self.get_platform_ids()
- for p in platforms:
- print "\t{}".format(p.get_desc())
- print "全局配置:"
- global_json = self.ori_json["ad"]["global"]
- print "\tBanner刷新时间: \t{}".format(global_json["bci"])
- print "\t两次广告展示间隔: \t{}".format(global_json["showGap"])
- print "Banner广告配置:"
- print "\t展示条件:"
- banner_ctrl_dic = self.ori_json["ad"]["banners"]["ctrl"]
- for key in banner_ctrl_dic:
- value = banner_ctrl_dic[key]
- ad_page_ctrl = AdPageCtrl(key, value)
- print "\t\t{}".format(ad_page_ctrl.get_desc())
- print "\t加载策略:"
- banner_load_strategy = AdStrategy(AD_PLATFROM.ADMOB, self.ori_json["ad"]["banners"]["load_strategy"])
- print "\t\t{}".format(banner_load_strategy.get_desc())
- ad_type_names = ["插屏", "奖励视频"]
- ad_types = [AD_TYPE.INTERSTITIAL, AD_TYPE.VIDEO]
- for i in range(2):
- print "{}展示配置:".format(ad_type_names[i])
- inter_pools = self.ori_json["ad"][AD_TYPE.key_string(ad_types[i])]["pools"]
- arr_pool_ad_ids = []
- for pool_name in inter_pools:
- pool_config = inter_pools[pool_name]
- for ad_id in pool_config:
- priority = pool_config[ad_id]
- arr_pool_ad_ids.append({
- "ad_id": ad_id,
- "p": priority
- })
- arr_pool_ad_ids = sorted(arr_pool_ad_ids, key=lambda e: e.__getitem__("p"), reverse=True)
- print "\t瀑布流池子配置:"
- for ad_id_info in arr_pool_ad_ids:
- print "\t\t{}:\t{}".format(ad_id_info["p"], ad_id_info["ad_id"])
- print "\tBidders:"
- bidders = self.get_bidders(ad_types[i])
- if len(bidders.ori_json) >= 1:
- for platform_str in bidders.ori_json:
- ad_id = bidders.ori_json[platform_str]
- print "\t\t{}:\t{}".format(platform_str, ad_id)
- print "\t页面版位配置:"
- inter_pages = self.get_ad_pages(ad_types[i])
- for page in inter_pages:
- print "\t\t{}".format(page.page_name)
- string = "\t\t\t池子:\t"
- string = "{}{}".format(string, page.pools[0])
- for i in range(1, len(page.pools)):
- string = "{}, {}".format(string, page.pools[i])
- print string
- string = "\t\t\t展示条件:"
- for key in page.ctrl:
- value = page.ctrl[key]
- ctrl_info = AdPageCtrl(key, value)
- if not ctrl_info.is_deprecated:
- string = "{}\t{}".format(string, ctrl_info.get_desc())
- print string
- if __name__ == '__main__':
- ad_json = AdJson6()
- ad_json.read("/Users/zhuge/Temp/20201217/ad.json")
- ad_json.print_desc()
- new_facebook_id = "fb_ad_new"
- facebook_pool = ad_json.get_pool(AD_TYPE.INTERSTITIAL, AD_PLATFROM.FACEBOOK)
- facebook_pool.print_desc()
- max_facebook_adid = facebook_pool.max_priority_ad_id()
- print max_facebook_adid
- max_facebook_priority = facebook_pool.max_priority()
- facebook_pool.add_ad_id(new_facebook_id, max_facebook_priority + 1)
- facebook_pool.print_desc()
- strategy = ad_json.get_strategy(AD_TYPE.BANNER, AD_PLATFROM.ADMOB)
- strategy.print_desc()
- strategy = ad_json.get_strategy(AD_TYPE.INTERSTITIAL, AD_PLATFROM.FACEBOOK)
- strategy.print_desc()
- strategy.ordered_ad_id_arr.insert(0, new_facebook_id)
- strategy.update(list(reversed(strategy.ordered_ad_id_arr)))
- strategy.print_desc()
- unity_ids = [
- "unity_inter_I1_lv1",
- "unity_inter_I1_lv2",
- "unity_inter_I2_lv1",
- "unity_inter_I2_lv2"
- ]
- unity_id_priorites = [
- 4, 6, 8, 10
- ]
- pools = {
- unity_ids[0]: unity_id_priorites[0],
- unity_ids[1]: unity_id_priorites[1],
- unity_ids[2]: unity_id_priorites[2],
- unity_ids[3]: unity_id_priorites[3]
- }
- pool = AdPool()
- pool.print_desc()
- for i in range(0, 4):
- pool.add_ad_id(unity_ids[i], unity_id_priorites[i])
- pool.print_desc()
- ad_json.add_pool(AD_TYPE.INTERSTITIAL, AD_PLATFROM.UNITY, pool)
- strategy = AdStrategy(AD_PLATFROM.UNITY)
- strategy.update(unity_ids)
- strategy.print_desc()
- ad_json.add_strategy(AD_TYPE.INTERSTITIAL, AD_PLATFROM.UNITY, strategy)
- pages = ad_json.get_ad_pages(AD_TYPE.INTERSTITIAL)
- for page in pages:
- page.add_pool("unity")
- pages = ad_json.get_ad_pages(AD_TYPE.VIDEO)
- for page in pages:
- page.add_pool("unity")
- facebook_pool = ad_json.get_pool(AD_TYPE.INTERSTITIAL, AD_PLATFROM.FACEBOOK)
- max_ecpm_facebook_ad_id = facebook_pool.max_priority_ad_id()
- ad_json.remove_pool(AD_TYPE.INTERSTITIAL, AD_PLATFROM.FACEBOOK)
- ad_json.remove_strategy(AD_TYPE.INTERSTITIAL, AD_PLATFROM.FACEBOOK)
- ad_bidders = ad_json.get_bidders(AD_TYPE.INTERSTITIAL)
- ad_bidders.add_bidder(AD_PLATFROM.FACEBOOK, "fb_bidding_id")
- ad_bidders.add_bidder(AD_PLATFROM.CRITEO, "crite_inter_i1_lv1")
- pages = ad_json.get_ad_pages(AD_TYPE.INTERSTITIAL)
- for page in pages:
- page.add_pool(AD_PLATFROM.string(AD_PLATFROM.CRITEO))
- ad_json.add_platform_id(RED_SDK_AD_PLATFORM.CRITEO, "criteo")
- ad_json.write("/Users/zhuge/Temp/20201217/ad_t.json")
- ad_json.print_desc()
|