blacklist和override的代码实现比较复杂,应该是从产品的需求来看代码,这部分实现严格符合产品需求
1.部分字段才能生成blacklist和override
KEYS = ['country', 'region', 'city']
KEYS += ['connectiontype', 'device_carrier', 'has_device_id', 'device_os']
KEYS += ['os_version', 'device_model', 'device_make', 'placement_name']
KEYS += ['category', 'gender', 'age_range']
KEYS += ['placement_type']
BLACKLIST_KEYS = KEYS + ['creative_name', 'ad_size']
OVERRIDE_KEYS = KEYS + ['exchange_name']
#BLACKLIST_KEYS 是可以生成blacklist的字段
#OVERRIDE_KEYS 是可以生成override的字段
#_verify_blacklist_dimension_params 和 _verify_override_dimension_params对输入的维度参数进行校验
2.操作的维度在数据中保存的是OrderedDict
为了保证显示出来的rule的dimensions和创建时是一致的,所以存的时候采用collections.OrderedDict.
从获取到的原始参数中取出json格式dimensions,转化成OrderedDict:
dimensions = json.loads(escapeall(makes(kw.get('dimensions'))).strip(), object_pairs_hook=collections.OrderedDict)
object_pairs_hook: (https:
3.blacklist的dimensions的对比
对于blacklist,只有dims完全匹配才算是匹配成功,所以直接对整体进行比较,比较的是generate_rule_token(dimensions)的结果.
def generate_rule_token(dimensions):
info = ''
for key in sorted(dimensions):
info += key + dimensions.get(key)
return hashlib.sha224(info).hexdigest()
4.override的dimensions的对比
override的dimensions匹配和blacklist匹配不同,
比如一条rule的override为{‘a’:1, ‘b’:2},
{‘a’:1}: 不匹配
{‘a’:1, ‘b’:2}:匹配
{‘a’:1, ‘b’:2 ,’c’:3}匹配
判断逻辑:
def compare_dimensions(override_dims, query_dims):
'''
compare override's dimensions and query dimensions
'''
if not set(override_dims.keys()).issubset(set(query_dims.keys())):
return False
for key in set(override_dims.keys()):
if override_dims.get(key) != query_dims.get(key):
return False
return True
5.创建override和blacklist之前必须先判断该campaign下的dimesions相同的记录是否已经存在
6.blacklist中的status和override的status
blacklist status:(因为要和ON/OFF对应,所以有点奇怪)
0,该条rule是起作用的,对应到前端就是OFF
1,rule不起作用,相当于删除,对应到前端就是ON
override
0,删除,不起作用
1,起作用
7.Paypal
集成paypal的时候,paypal要求把收到的数据原封不动的返回,有这样一个校验过程,一般来说,在咱们的controller中拿到的参数是已经被cherrypy处理过的了,得到的是dict,参数的顺序会发生变化,不满足要求,从原始的请求中获取原始的参数:
request_uri = sub[0]['REQUEST_URI']
if request_uri == '/dsp/account/paypal_notify': # 只有请求的是paypal接口时采取原始参数
root.dsp.account.wsgi_input = sub[0]['wsgi.input'].read()
sub[0]['wsgi.input'].seek(0)
#在读取完request中的参数后必须 seek(0),回到文件头,否则cherrypy会取不到参数,造成controller中也没有参数