def _recursive_custom_from_dfp(data): """ Convert dfp dictionary to custom targeting model @param targeting: dict @return: TargetingCriterion """ children = data.get('children', []) if children: operator = data['logicalOperator'] target_list = [_recursive_custom_from_dfp(c) for c in children] return TargetingCriterion(target_list, operator) else: # Base case values = [] if data.get('audienceSegmentIds'): node_key = 'AudienceSegmentCriteria' _id_key = 'audienceSegmentIds' value_ids = data[_id_key] for vid in value_ids: values.append( Custom( id=vid, id_key=_id_key, node_key=node_key, )) else: node_key = 'CustomCriteria' _id_key = 'valueIds' value_ids = data[_id_key] key_id = data['keyId'] for vid in value_ids: values.append( Custom( id=vid, id_key=_id_key, parent_id=key_id, node_key=node_key, )) targeting = TargetingCriterion(values, TargetingCriterion.OPERATOR.OR) if data['operator'] == 'IS': return targeting else: return ~targeting
def test_to_doc(self): # Test to doc test_doc = CRITERION1.to_doc() answer_doc = { '_metadata': {u'cls': 'TargetingCriterion'}, 'OR': [ { '_metadata': {u'cls': 'AdUnit'}, 'external_name': None, 'external_id': None, 'id': '1', 'include_descendants': True, 'name': 'home', 'parent_id': None, } ], } self.assertEqual(test_doc, answer_doc) # test from doc self.assertEqual( CRITERION1, TargetingCriterion.from_doc(answer_doc), ) # test to doc/from doc inversions self.assertEqual( CRITERION1, TargetingCriterion.from_doc(CRITERION1.to_doc()), ) self.assertEqual( CRITERION2, TargetingCriterion.from_doc(CRITERION2.to_doc()), ) self.assertEqual( CRITERION3, TargetingCriterion.from_doc(CRITERION3.to_doc()), ) self.assertEqual( CRITERION4, TargetingCriterion.from_doc(CRITERION4.to_doc()), )
def _make_criterion_from_lists(includes, excludes): """ Give a list of items to include and exclude, construct the corresponding TargetingCriterion @param includes: list @param excludes: list @return: TargetingCriterion|None """ incl = TargetingCriterion(includes, TargetingCriterion.OPERATOR.OR) excl = TargetingCriterion(excludes, TargetingCriterion.OPERATOR.OR) if includes and excludes: return incl & (~excl) elif includes: return incl elif excludes: return ~excl else: return None
def test_flatten(self): answer_targets = [] answer_op = TargetingCriterion.OPERATOR.OR criterion = TargetingCriterion( answer_targets, answer_op, ) test_flatten = criterion.flatten() answer_flatten = [] self.assertEqual(answer_flatten, test_flatten) criterion = TargetingCriterion( [CRITERION1, CRITERION2], TargetingCriterion.OPERATOR.NOT, ) test_flatten = criterion.flatten() answer_flatten = [ADUNIT1, ADUNIT2] self.assertEqual(answer_flatten, test_flatten)
def test_get_data(self): answer_targets = [] answer_op = TargetingCriterion.OPERATOR.OR criterion = TargetingCriterion( answer_targets, answer_op, ) test_op, test_targets = criterion.get_data() self.assertEqual(answer_targets, test_targets) self.assertEqual(answer_op, test_op) answer_targets = [ADUNIT1, ADUNIT2] answer_op = TargetingCriterion.OPERATOR.AND criterion = TargetingCriterion( answer_targets, answer_op, ) test_op, test_targets = criterion.get_data() self.assertEqual(answer_targets, test_targets) self.assertEqual(answer_op, test_op)
def test_init(self): criterion1 = TargetingCriterion( [ADUNIT1], TargetingCriterion.OPERATOR.OR, ) criterion2 = TargetingCriterion( ADUNIT1, ) self.assertEqual(criterion1, criterion2) with self.assertRaises(ParselmouthException): TargetingCriterion(CRITERION1) with self.assertRaises(ParselmouthException): TargetingCriterion([CRITERION1]) with self.assertRaises(ParselmouthException): TargetingCriterion([CRITERION1], 'XOR') with self.assertRaises(ParselmouthException): TargetingCriterion( CRITERION1, TargetingCriterion.OPERATOR.OR, )
id='2', name='page', ) ADUNIT3 = AdUnit( id='3', name='hockey', ) ADUNIT4 = AdUnit( id='4', name='baseball', ) CRITERION1 = TargetingCriterion( [ADUNIT1], TargetingCriterion.OPERATOR.OR, ) CRITERION2 = TargetingCriterion( [ADUNIT2], TargetingCriterion.OPERATOR.OR, ) CRITERION3 = TargetingCriterion( [ADUNIT1, ADUNIT2], TargetingCriterion.OPERATOR.OR, ) CRITERION4 = TargetingCriterion( [ADUNIT1, ADUNIT2], TargetingCriterion.OPERATOR.AND, ) CRITERION5 = TargetingCriterion(
def transform_technology_targeting_from_dfp(targeting): """ Convert DFP technology targeting data to TargetingCriterion @param targeting: dict @return: TargetingCriterion """ if not targeting: return None target_data = { 'include': [], 'exclude': [], } for tech_type, _map in TECHNOLOGY_KEY_MAP.items(): target = targeting.get(_map['target_name']) if not target: continue _map_type = _map['type'] if _map_type == 'list': _list_name = _map['list_name'] browser_list = [] for item in target[_list_name]: tech_target = Technology( id=item['id'], name=item.get('name'), type=tech_type, ) browser_list.append(tech_target) # The isTargeted key determines whether # to target this entire list or not if target['isTargeted']: target_data['include'] += browser_list else: target_data['exclude'] += browser_list elif _map_type == 'categorical': # Get lists of items to be included and excluded for _cat_key in ['include', 'exclude']: dfp_key = _map[_cat_key] raw_data = target.get(dfp_key, []) for item in raw_data: tech_target = Technology( id=item['id'], name=item.get('name'), type=tech_type, ) target_data[_cat_key].append(tech_target) # Build TargetingCriterion from list of includes and excludes includes = target_data['include'] inc = TargetingCriterion(includes, TargetingCriterion.OPERATOR.OR) excludes = target_data['exclude'] exl = TargetingCriterion(excludes, TargetingCriterion.OPERATOR.OR) if includes and excludes: return inc & (~exl) elif includes: return inc elif excludes: return ~exl else: return None
units=1000000, ), start=datetime(2014, 4, 23, 15, 50, tzinfo=timezone('America/New_York')), last_modified=datetime(2014, 4, 23, 15, 50, tzinfo=timezone('America/New_York')), status='DRAFT', targeting=TargetingData( custom=None, day_part=None, geography=None, inventory=TargetingCriterion( [AdUnit(id='adunit', include_descendants=True)], TargetingCriterion.OPERATOR.OR, ), user_domain=None, technology=None, video_content=None, video_position=None, ), target_platform='ANY', type='standard', value_cost_per_unit=Cost( budget_micro_amount=0.0, budget_currency_code='USD', ), )
def test_custom_targeting_utils(self): custom1 = Custom( id='1', name='rich', id_key='audienceSegmentIds', node_key='AudienceSegmentCriteria', ) custom2 = Custom( id='2', parent_id='gender', name='female', id_key='valueIds', node_key='CustomCriteria', ) custom3 = Custom( id='3', parent_id='gender', name='male', id_key='valueIds', node_key='CustomCriteria', ) custom1_target = TargetingCriterion(custom1) dfp_custom1 = { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'audienceSegmentIds': ['1'], 'operator': 'IS', 'xsi_type': 'AudienceSegmentCriteria', }, ], } self.assertEqual( dfp_custom1, transform_custom_targeting_to_dfp(custom1_target), ) # Test reflexivity self.assertEqual( dfp_custom1, transform_custom_targeting_to_dfp( transform_custom_targeting_from_dfp( dfp_custom1, ), ), ) custom2_or_custom3 = TargetingCriterion( [custom2, custom3], TargetingCriterion.OPERATOR.OR, ) dfp_custom2_or_custom3 = { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['2', '3'], 'keyId': 'gender', 'operator': 'IS', 'xsi_type': 'CustomCriteria', }, ], } self.assertEqual( dfp_custom2_or_custom3, transform_custom_targeting_to_dfp(custom2_or_custom3), ) custom2_and_not_custom3 = TargetingCriterion(custom2) & ~TargetingCriterion(custom3) dfp_custom2_and_not_custom3 = { 'logicalOperator': 'AND', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['2'], 'keyId': 'gender', 'operator': 'IS', 'xsi_type': 'CustomCriteria', }, ], }, { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['3'], 'keyId': 'gender', 'operator': 'IS_NOT', 'xsi_type': 'CustomCriteria', }, ], }, ], } self.assertEqual( dfp_custom2_and_not_custom3, transform_custom_targeting_to_dfp(custom2_and_not_custom3), ) custom1_and_custom2_and_not_custom3 = custom1_target & custom2_and_not_custom3 dfp_custom1_and_custom2_and_not_custom3 = { 'logicalOperator': 'AND', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'audienceSegmentIds': ['1'], 'operator': 'IS', 'xsi_type': 'AudienceSegmentCriteria', }, ], }, { 'logicalOperator': 'AND', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['2'], 'keyId': 'gender', 'operator': 'IS', 'xsi_type': 'CustomCriteria', }, ], }, { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['3'], 'keyId': 'gender', 'operator': 'IS_NOT', 'xsi_type': 'CustomCriteria', }, ], }, ], } ], } self.assertEqual( dfp_custom1_and_custom2_and_not_custom3, transform_custom_targeting_to_dfp(custom1_and_custom2_and_not_custom3), ) custom1_or_custom2_and_not_custom3 = custom1_target | custom2_and_not_custom3 dfp_custom1_or_custom2_and_not_custom3 = { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'audienceSegmentIds': ['1'], 'operator': 'IS', 'xsi_type': 'AudienceSegmentCriteria', }, ], }, { 'logicalOperator': 'AND', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['2'], 'keyId': 'gender', 'operator': 'IS', 'xsi_type': 'CustomCriteria', }, ], }, { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['3'], 'keyId': 'gender', 'operator': 'IS_NOT', 'xsi_type': 'CustomCriteria', }, ], }, ], } ], } self.assertEqual( dfp_custom1_or_custom2_and_not_custom3, transform_custom_targeting_to_dfp(custom1_or_custom2_and_not_custom3), ) custom1_or_custom2_or_custom3 = custom1_target | custom2_or_custom3 dfp_custom1_or_custom2_or_custom3 = { 'logicalOperator': 'OR', 'xsi_type': 'CustomCriteriaSet', 'children': [ { 'valueIds': ['2', '3'], 'keyId': 'gender', 'operator': 'IS', 'xsi_type': 'CustomCriteria', }, { 'audienceSegmentIds': ['1'], 'operator': 'IS', 'xsi_type': 'AudienceSegmentCriteria', }, ], } self.assertEqual( dfp_custom1_or_custom2_or_custom3, transform_custom_targeting_to_dfp(custom1_or_custom2_or_custom3), )
def test_inventory_targeting_utils(self): adunit1_or_adunit2 = TargetingCriterion( [AdUnit(id='1'), AdUnit(id='2')], TargetingCriterion.OPERATOR.OR, ) dfp_adunit1_or_adunit2 = { 'targetedAdUnits': [ { 'includeDescendants': True, 'adUnitId': '1', }, { 'includeDescendants': True, 'adUnitId': '2', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_adunit1_or_adunit2, transform_inventory_targeting_to_dfp(adunit1_or_adunit2), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( adunit1_or_adunit2, transform_inventory_targeting_from_dfp(dfp_adunit1_or_adunit2), )) not_adunit3 = TargetingCriterion( [TargetingCriterion([AdUnit(id='3')], TargetingCriterion.OPERATOR.OR)], TargetingCriterion.OPERATOR.NOT, ) dfp_not_adunit3 = { 'excludedAdUnits': [ { 'includeDescendants': True, 'adUnitId': '3', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_not_adunit3, transform_inventory_targeting_to_dfp(not_adunit3), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( not_adunit3, transform_inventory_targeting_from_dfp(dfp_not_adunit3), )) adunit1_or_adunit2_and_not_adunit3 = TargetingCriterion( [adunit1_or_adunit2, not_adunit3], TargetingCriterion.OPERATOR.AND, ) dfp_adunit1_or_adunit2_and_not_adunit3 = { 'targetedAdUnits': [ { 'includeDescendants': True, 'adUnitId': '1', }, { 'includeDescendants': True, 'adUnitId': '2', }, ], 'excludedAdUnits': [ { 'includeDescendants': True, 'adUnitId': '3', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_adunit1_or_adunit2_and_not_adunit3, transform_inventory_targeting_to_dfp(adunit1_or_adunit2_and_not_adunit3), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( adunit1_or_adunit2_and_not_adunit3, transform_inventory_targeting_from_dfp(dfp_adunit1_or_adunit2_and_not_adunit3), ))
def test_technology_targeting_utils(self): tech1 = Technology( id='1', type=TechnologyTargetTypes.browser, name='chrome', ) tech2 = Technology( id='2', type=TechnologyTargetTypes.device_category, name='mobile', ) tech3 = Technology( id='3', type=TechnologyTargetTypes.device_category, name='desktop', ) tech1_target = TargetingCriterion(tech1) dfp_tech1 = { 'browserTargeting': { 'browsers': [ { 'id': '1', }, ], 'isTargeted': True, }, } self.assertTrue(check_equal( dfp_tech1, transform_technology_targeting_to_dfp(tech1_target), )) not_tech1 = ~tech1_target dfp_not_tech1 = { 'browserTargeting': { 'browsers': [ { 'id': '1', }, ], 'isTargeted': False, }, } self.assertTrue(check_equal( dfp_not_tech1, transform_technology_targeting_to_dfp(not_tech1), )) tech2_or_tech3 = TargetingCriterion( [tech2, tech3], TargetingCriterion.OPERATOR.OR, ) dfp_tech1_or_tech2 = { 'deviceCategoryTargeting': { 'targetedDeviceCategories': [ { 'id': '2', }, { 'id': '3', }, ], }, } self.assertTrue(check_equal( dfp_tech1_or_tech2, transform_technology_targeting_to_dfp(tech2_or_tech3), )) tech2_and_not_tech3 = TargetingCriterion(tech2) & ~TargetingCriterion(tech3) dfp_tech2_and_not_tech3 = { 'deviceCategoryTargeting': { 'targetedDeviceCategories': [ { 'id': '2', }, ], 'excludedDeviceCategories': [ { 'id': '3', }, ], }, } self.assertTrue(check_equal( dfp_tech2_and_not_tech3, transform_technology_targeting_to_dfp(tech2_and_not_tech3), )) tech1_and_tech2_and_not_tech3 = TargetingCriterion(tech1) & tech2_and_not_tech3 dfp_tech1_and_tech2_and_not_tech3 = { 'deviceCategoryTargeting': { 'targetedDeviceCategories': [ { 'id': '2', }, ], 'excludedDeviceCategories': [ { 'id': '3', }, ], }, 'browserTargeting': { 'browsers': [ { 'id': '1', }, ], 'isTargeted': True, }, } self.assertTrue(check_equal( dfp_tech1_and_tech2_and_not_tech3, transform_technology_targeting_to_dfp(tech1_and_tech2_and_not_tech3), )) # Test reflexivity self.assertTrue(check_equal( dfp_tech1_and_tech2_and_not_tech3, transform_technology_targeting_to_dfp( transform_technology_targeting_from_dfp( dfp_tech1_and_tech2_and_not_tech3, ), ), ))
def test_geography_targeting_utils(self): geo1 = Geography( id='1', type='country', name='France', ) geo2 = Geography( id='2', type='country', name='Germany', ) geo3 = Geography( id='3', type='country', name='Greece', ) geo1_or_geo2 = TargetingCriterion( [geo1, geo2], TargetingCriterion.OPERATOR.OR, ) dfp_geo1_or_geo2 = { 'targetedLocations': [ { 'type': 'country', 'displayName': 'France', 'id': '1', }, { 'type': 'country', 'displayName': 'Germany', 'id': '2', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_geo1_or_geo2, transform_geography_targeting_to_dfp(geo1_or_geo2), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( geo1_or_geo2, transform_geography_targeting_from_dfp(dfp_geo1_or_geo2), )) not_geo3 = TargetingCriterion( [TargetingCriterion([geo3], TargetingCriterion.OPERATOR.OR)], TargetingCriterion.OPERATOR.NOT, ) dfp_not_geo3 = { 'excludedLocations': [ { 'type': 'country', 'displayName': 'Greece', 'id': '3', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_not_geo3, transform_geography_targeting_to_dfp(not_geo3), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( not_geo3, transform_geography_targeting_from_dfp(dfp_not_geo3), )) geo1_or_geo2_and_not_geo3 = TargetingCriterion( [geo1_or_geo2, not_geo3], TargetingCriterion.OPERATOR.AND, ) dfp_geo1_or_geo2_and_not_geo3 = { 'targetedLocations': [ { 'type': 'country', 'displayName': 'France', 'id': '1', }, { 'type': 'country', 'displayName': 'Germany', 'id': '2', }, ], 'excludedLocations': [ { 'type': 'country', 'displayName': 'Greece', 'id': '3', }, ], } # Check transform_inventory_targeting_to_dfp self.assertTrue(check_equal( dfp_geo1_or_geo2_and_not_geo3, transform_geography_targeting_to_dfp(geo1_or_geo2_and_not_geo3), )) # Check transform_inventory_targeting_from_dfp self.assertTrue(check_equal( geo1_or_geo2_and_not_geo3, transform_geography_targeting_from_dfp(dfp_geo1_or_geo2_and_not_geo3), ))