Example #1
0
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
Example #2
0
    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()),
        )
Example #3
0
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
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
    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,
            )
Example #7
0
    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(
Example #8
0
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),
        ))