Example #1
0
    def test_campaign_payments_more(self):
        payment_percentage_cutoff = 0.5
        cpv, cpc = 10, 20
        timestamp = 3600

        # Add campaign
        cmp_doc = {"campaign_id": "campaign_id",
                   "time_start": 0,
                   "time_end": timestamp + 100,
                   "max_cpc": cpc,
                   "max_cpm": cpv,
                   "budget": 1000,
                   "filters": {'require': {},
                               'exclude': {}}}

        yield db_utils.update_campaign(cmp_doc)

        # Add 3 banners for this campaign
        for i in range(3):
            yield db_utils.update_banner({'banner_id': 'banner_id' + str(i),
                                          'campaign_id': cmp_doc['campaign_id']})

        # Add events for users
        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event2_user_id1",
            "event_type": stats_consts.EVENT_TYPE_VIEW,
            "timestamp": timestamp + 1,
            "user_id": 'user_id1',
            "banner_id": 'banner_id1',
            "event_value": 0.2,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1.0})

        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event2_user_id2",
            "event_type": stats_consts.EVENT_TYPE_CONVERSION,
            "timestamp": timestamp + 2,
            "user_id": 'user_id2',
            "banner_id": 'banner_id1',
            "event_value": 0.5,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1.0})

        yield stats_legacy.calculate_events_payments(cmp_doc,
                                                     timestamp,
                                                     payment_percentage_cutoff=payment_percentage_cutoff)

        # Check user values
        user2_value_doc = yield db_utils.get_user_value_in_campaign(cmp_doc['campaign_id'], "user_id2")
        self.assertEqual(user2_value_doc['payment'], 10)
        self.assertEqual(user2_value_doc['human_score'], 1)

        # User scores should be empty.
        _iter = yield db_utils.get_sorted_user_score_iter(cmp_doc['campaign_id'], timestamp, limit=1)
        user_score_doc = yield _iter.next()
        self.assertIsNone(user_score_doc)
Example #2
0
    def test_uservalue(self):
        # Test adding user value
        for i in range(100):
            yield db_utils.update_user_value_in_campaign(campaign_id="campaign_id",
                                                         user_id=i,
                                                         payment=i * 10,
                                                         human_score=10)

        _iter = yield db_utils.get_user_value_iter("campaign_id")
        user_values = []
        while True:
            user_value_doc = yield _iter.next()
            if user_value_doc is None:
                break
            user_values.append(user_value_doc)
            self.assertEqual(user_value_doc['human_score'], 10)
            self.assertEqual(user_value_doc['payment'], user_value_doc['user_id'] * 10)
        self.assertEqual(len(user_values), 100)

        # Test update user value
        for i in range(100):
            yield db_utils.update_user_value_in_campaign(campaign_id="campaign_id",
                                                         user_id=i,
                                                         payment=i * 20,
                                                         human_score=10)

        # Test get user value.
        for i in range(100):
            user_value_doc = yield db_utils.get_user_value_in_campaign("campaign_id", i)
            self.assertEqual(user_value_doc["payment"], i * 20)
Example #3
0
def get_user_payment_score(campaign_id, user_id, amount=5):
    """
    Payment score for user
    1. Find most similar user.
    2. Calculate scores for similar users (payment stats and human score)
    3. Get average of user payment score.

    :param campaign_id:
    :param user_id:
    :param amount: Limit to how many users we compare
    :return: User payment score.
    """
    logger = logging.getLogger(__name__)
    yield logger.info(
        "Calculating user payment score for user {0} and campaign {1}".format(
            user_id, campaign_id))

    # Find most similar users to user_id
    users = []
    user_value_iter = yield db_utils.get_user_value_iter(campaign_id)
    while True:
        user_value_doc = yield user_value_iter.next()
        if user_value_doc is None:
            break

        uid = user_value_doc['user_id']
        similarity = yield get_users_similarity(uid, user_id)
        if similarity > 0:
            reverse_insort(users, (similarity, uid))
            users = users[:amount]

    # Calculate payment score for user
    score_components = []
    for similarity, uid in users:

        user_stat = yield db_utils.get_user_value_in_campaign(campaign_id, uid)
        if user_stat:
            yield logger.info("Getting user value from user: {0}".format(uid))
            score_components.append(
                float(user_stat['payment']) * float(user_stat['human_score']))

    if not score_components:
        yield logger.warning(
            "No similar users or no scores for similar users. User score value: 0"
        )
        defer.returnValue(0)

    yield logger.debug("User {0} payment score: {1}".format(
        user_id, 1.0 * sum(score_components) / len(score_components)))
    defer.returnValue(1.0 * sum(score_components) / len(score_components))
Example #4
0
def get_best_user_payments_and_humanity(campaign_doc, timestamp, uid):
    """
    Return user information: best payment, total payment and max human score.

    :param campaign_doc:
    :param timestamp:
    :param uid:
    :return: Tuple: max_user_payment, max_human_score, total_user_payments
    """
    logger = logging.getLogger(__name__)
    max_user_payment, max_human_score = 0.0, 0.0

    total_user_payments = defaultdict(lambda: float(0.0))

    user_value_doc = yield db_utils.get_user_value_in_campaign(
        campaign_doc['campaign_id'], uid)
    if user_value_doc:
        max_user_payment = float(user_value_doc['payment'])

    user_events_iter = yield db_utils.get_events_per_user_iter(
        campaign_doc['campaign_id'], timestamp, uid)
    while True:
        event_doc = yield user_events_iter.next()
        if not event_doc:
            break

        event_type = event_doc['event_type']

        banner_doc = yield db_utils.get_banner(event_doc['banner_id'])
        if not stats_utils.filter_event(
                event_doc, campaign_doc,
                banner_doc) and event_type in stats_consts.PAID_EVENT_TYPES:
            event_payment = stats_utils.get_default_event_payment(
                event_doc, campaign_doc['max_cpc'], campaign_doc['max_cpm'])

            total_user_payments[event_type] += float(event_payment)

            max_user_payment = max([max_user_payment, event_payment])
            max_human_score = max([max_human_score, event_doc['human_score']])

    yield logger.info(
        "User {0} max_user_payment, max_human_score, total_user_payments: {1}".
        format(uid, (max_user_payment, max_human_score, total_user_payments)))
    defer.returnValue((max_user_payment, max_human_score, total_user_payments))
Example #5
0
def calculate_payments_for_new_users(campaign_doc, timestamp):
    """
    Calculate payments for new uses. Use CPM as default payment.

    :param campaign_doc:
    :param timestamp:
    :return:
    """
    logger = logging.getLogger(__name__)
    yield logger.info("Calculating payment score for new user.")

    # For new users add payments as cpv
    uids = yield db_utils.get_distinct_users_from_events(
        campaign_doc['campaign_id'], timestamp)

    yield logger.debug("Found {0} distinct user ids".format(len(uids)))

    for uid in uids:
        max_human_score = 0

        user_events_iter = yield db_utils.get_events_per_user_iter(
            campaign_doc['campaign_id'], timestamp, uid)

        while True:
            event_doc = yield user_events_iter.next()
            if not event_doc:
                break

            banner_doc = yield db_utils.get_banner(event_doc['banner_id'])
            if not stats_utils.filter_event(event_doc, campaign_doc,
                                            banner_doc):
                max_human_score = max(
                    [max_human_score, event_doc['human_score']])

        user_value_doc = yield db_utils.get_user_value_in_campaign(
            campaign_doc['campaign_id'], uid)

        if user_value_doc is None or user_value_doc['payment'] <= campaign_doc[
                'max_cpm']:
            yield logger.info("Updating user value for {0}".format(uid))
            yield db_utils.update_user_value_in_campaign(
                campaign_doc['campaign_id'], uid, campaign_doc['max_cpm'],
                max_human_score)
Example #6
0
    def test_campaign_payments(self):
        payment_percentage_cutoff = 0.5
        cpv, cpc = 10, 20
        timestamp = 3600

        cmp_doc = {"campaign_id": "campaign_id",
                   "time_start": 0,
                   "time_end": 3600 + 100,
                   "max_cpc": cpc,
                   "max_cpm": cpv,
                   "budget": 100000,
                   "filters": {'require': {},
                               'exclude': {}}}

        yield db_utils.update_campaign(cmp_doc)

        # Add 3 banners for this campaign
        for i in range(3):
            yield db_utils.update_banner({'banner_id': 'banner_id' + str(i),
                                          'campaign_id': cmp_doc['campaign_id']})

        # Add events for users
        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event1_user_id1",
            "event_type": stats_consts.EVENT_TYPE_CLICK,
            "timestamp": timestamp + 2,
            "user_id": 'user_id1',
            "banner_id": 'banner_id1',
            "event_value": 0.1,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1})

        yield stats_legacy.calculate_events_payments(cmp_doc,
                                                     timestamp,
                                                     payment_percentage_cutoff=payment_percentage_cutoff)
        # Check user values
        user_value_doc = yield db_utils.get_user_value_in_campaign(cmp_doc['campaign_id'], "user_id1")
        self.assertEqual(user_value_doc['payment'], 20)
        self.assertEqual(user_value_doc['human_score'], 1)

        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event2_user_id1",
            "event_type": stats_consts.EVENT_TYPE_VIEW,
            "timestamp": timestamp + 2,
            "user_id": 'user_id1',
            "banner_id": 'banner_id1',
            "event_value": 0.2,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1})

        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event2_user_id2",
            "event_type": stats_consts.EVENT_TYPE_CONVERSION,
            "timestamp": timestamp + 2,
            "user_id": 'user_id2',
            "banner_id": 'banner_id1',
            "event_value": 0.5,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1})

        yield stats_legacy.calculate_events_payments(cmp_doc, 3600,
                                                     payment_percentage_cutoff=payment_percentage_cutoff)

        # Check user values
        user2_value_doc = yield db_utils.get_user_value_in_campaign("campaign_id", "user_id2")
        self.assertEqual(user2_value_doc['payment'], 10)
        self.assertEqual(user2_value_doc['human_score'], 1)

        # Mock total use score

        yield db_utils.update_event({
            'campaign_id': cmp_doc['campaign_id'],
            "event_id": "event2_user_id3",
            "event_type": stats_consts.EVENT_TYPE_CONVERSION,
            "timestamp": timestamp + 2,
            "user_id": 'user_id3',
            "banner_id": 'banner_id1',
            "event_value": 0.5,
            "our_keywords": {},
            "their_keywords": {},
            "human_score": 1.0})

        with patch('adpay.stats.legacy.get_total_user_score', MagicMock(return_value=0)):

            yield stats_legacy.calculate_events_payments(cmp_doc, 3600,
                                                         payment_percentage_cutoff=payment_percentage_cutoff)

        # Check user values
        user2_value_doc = yield db_utils.get_user_value_in_campaign("campaign_id", "user_id3")
        self.assertEqual(user2_value_doc['payment'], 10)
        self.assertEqual(user2_value_doc['human_score'], 1)