| 
					
				 | 
			
			
				@@ -1,74 +1,130 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import traceback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import datetime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from utils import RedisHelper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from config import set_config 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from log import Log 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+log_ = Log() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 config_ = set_config() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 redis_helper = RedisHelper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def ad_recommend_predict(app_type, mid, video_id): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def get_params(ab_exp_info, ab_test_code): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    根据实验分组给定对应的参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param ab_exp_info: AB实验组参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param ab_test_code: 用户对应的ab组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :return: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    abtest_id, abtest_config_tag = None, None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ad_abtest_id_list = [key.split('-')[0] for key in config_.AD_ABTEST_CONFIG] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 获取广告实验配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    config_value_dict = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ab_exp_info: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_exp_list = ab_exp_info.get('ab_test002', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ab_exp_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for ab_item in ab_exp_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ab_exp_code = ab_item.get('abExpCode', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if not ab_exp_code: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if ab_exp_code in ad_abtest_id_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    config_value = ab_item.get('configValue', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if config_value: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        config_value_dict[str(ab_exp_code)] = eval(str(config_value)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if len(config_value_dict) > 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for ab_exp_code, config_value in config_value_dict.items(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for tag, value in config_value.items(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if ab_test_code in value: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    abtest_id = ab_exp_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    abtest_config_tag = tag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return abtest_id, abtest_config_tag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def ad_recommend_predict(app_type, mid, video_id, ab_exp_info, ab_test_code): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     广告推荐预测 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     :param app_type: app_type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     :param mid: mid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     :param video_id: video_id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param ab_exp_info: AB实验组参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param ab_test_code: 用户对应的ab组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     :return: ad_predict, type-int, 1-不发放广告,2-发放广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    now_date = datetime.datetime.today() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    now_dt = datetime.datetime.strftime(now_date, '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # 判断mid所属分组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{mid}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if mid_group is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        mid_group = 'mean_group' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        now_date = datetime.datetime.today() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        now_dt = datetime.datetime.strftime(now_date, '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # 获取实验参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        abtest_id, abtest_config_tag = get_params(ab_exp_info=ab_exp_info, ab_test_code=ab_test_code) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if abtest_id is None or abtest_config_tag is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        abtest_param = config_.AD_ABTEST_CONFIG.get(f'{abtest_id}-{abtest_config_tag}') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if abtest_param is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # 判断用户是否在免广告用户组列表中 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if mid_group in config_.NO_AD_MID_GROUP_LIST: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 在免广告用户组列表中,则不出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ad_predict = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        result = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'mid_group': mid_group, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'ad_predict': ad_predict 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 获取用户组分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{now_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if not redis_helper.key_exists(group_share_rate_key): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{redis_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 获取视频分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{now_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if not redis_helper.key_exists(video_share_rate_key): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{redis_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if video_share_rate is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        user_data_key = abtest_param.get('user') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        video_data_key = abtest_param.get('video') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 计算 mid-video 分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        mid_video_share_rate = float(group_share_rate) * float(video_share_rate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # 判断mid所属分组 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{mid}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if mid_group is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mid_group = 'mean_group' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 获取对应的阈值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        threshold_key_name = f"{config_.KEY_NAME_PREFIX_AD_THRESHOLD}{app_type}:{mid_group}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        threshold = redis_helper.get_data_from_redis(key_name=threshold_key_name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if threshold is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            threshold = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            threshold = float(threshold) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # 阈值判断 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if mid_video_share_rate > threshold: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # 大于阈值,出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ad_predict = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # 否则,不出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # 判断用户是否在免广告用户组列表中 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if mid_group in config_.NO_AD_MID_GROUP_LIST: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 在免广告用户组列表中,则不出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ad_predict = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        result = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'mid_group': mid_group, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'group_share_rate': group_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'video_share_rate': video_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'mid_video_share_rate': mid_video_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'threshold': threshold, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            'ad_predict': ad_predict} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'mid_group': mid_group, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'ad_predict': ad_predict 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 获取用户组分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{now_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if not redis_helper.key_exists(group_share_rate_key): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{redis_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 获取视频分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if not redis_helper.key_exists(video_share_rate_key): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{redis_dt}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if video_share_rate is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 计算 mid-video 分享率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if group_share_rate is None or video_share_rate is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mid_video_share_rate = float(group_share_rate) * float(video_share_rate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 获取对应的阈值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            threshold_key_name = f"{config_.KEY_NAME_PREFIX_AD_THRESHOLD}{abtest_id}:{abtest_config_tag}:{mid_group}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            threshold = redis_helper.get_data_from_redis(key_name=threshold_key_name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if threshold is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                threshold = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                threshold = float(threshold) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 阈值判断 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if mid_video_share_rate > threshold: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # 大于阈值,出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ad_predict = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # 否则,不出广告 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ad_predict = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'mid_group': mid_group, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'group_share_rate': group_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'video_share_rate': video_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'mid_video_share_rate': mid_video_share_rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'threshold': threshold, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'ad_predict': ad_predict} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except Exception as e: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log_.error(traceback.format_exc()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return None 
			 |