Example #1
0
def _handle_user_request(request, slug):
    """Helper performing all pre-response operations on behalf of a user request."""
    shortened = get_object_or_404(ShortenedUrl, slug=slug)
    campaign = shortened.campaign

    if campaign:
        set_visit(
            request,
            campaign.client.fb_app_id,
            start_event={'campaign_id': campaign.campaign_id},
            cycle=True,
        )

        if shortened.event_type:
            delayed_save.delay(
                Event(
                    visit_id=request.visit.visit_id,
                    event_type=shortened.event_type,
                    campaign_id=campaign.campaign_id,
                    content=slug,
                )
            )

        campaignstatus.handle_request(request, campaign)

    return shortened
Example #2
0
    def test_visit_expiration(self):
        request0 = self.get_request()
        set_visit(request0, 1)
        session_id0 = request0.visit.session_id
        self.assertTrue(session_id0)

        # Make session old:
        session0 = Session.objects.get(session_key=session_id0)
        session0.expire_date = datetime.datetime(1, 1, 1, 0, 0, tzinfo=timezone.utc)
        session0.save()

        self.factory.cookies[settings.SESSION_COOKIE_NAME] = session_id0
        request1 = self.get_request()
        set_visit(request1, 1)
        session_id1 = request1.visit.session_id
        self.assertTrue(session_id1)
        self.assertEqual(session_id1, request1.session.session_key)

        # Play with session to ensure this it's valid:
        request1.session['foo'] = 'bar'
        request1.session.save()
        self.assertEqual(session_id1, request1.session.session_key)
        self.assertEqual(request1.session['foo'], 'bar')

        self.assertNotEqual(request1.visit, request0.visit)
        self.assertNotEqual(session_id1, session_id0)
        self.assertEqual(models.relational.Visit.objects.count(), 2)
Example #3
0
 def test_uuid_cookie(self):
     request = self.get_request()
     response = HttpResponse()
     utils.set_visit(request, 1)
     visitor = request.visit.visitor
     response1 = self.middleware.process_response(request, response)
     self.assertEqual(response1, response)
     cookie = response.cookies[settings.VISITOR_COOKIE_NAME]
     self.assertEqual(cookie.value, visitor.uuid)
Example #4
0
 def test_new_visit(self):
     request = self.get_request(HTTP_USER_AGENT='testbot',
                                HTTP_REFERER='http://client.com/foo')
     set_visit(request, 1)
     self.assertTrue(request.visit.session_id)
     self.assertEqual(request.visit.app_id, 1)
     self.assertEqual(request.visit.user_agent, 'testbot')
     self.assertEqual(request.visit.referer, 'http://client.com/foo')
     start_event = request.visit.events.get()
     self.assertEqual(start_event.event_type, 'session_start')
Example #5
0
    def test_swap_visitor(self):
        request = self.get_request()
        set_visit(request, 1)
        session_id = request.visit.session_id
        visitor0 = request.visit.visitor
        self.assertTrue(session_id)

        self.factory.cookies[settings.SESSION_COOKIE_NAME] = session_id
        # Don't persist visitor UUID
        request = self.get_request()
        set_visit(request, 1)
        self.assertEqual(request.visit.session_id, session_id)
        self.assertNotEqual(request.visit.visitor, visitor0)
Example #6
0
    def test_second_visit_cookies_failed(self):
        self.assertFalse(self.events.exists())

        request = self.get_request()
        request.META['HTTP_REFERER'] = 'https://test.edgeflip.com/'
        utils.set_visit(request, 1)

        self.middleware.process_request(request)
        self.assertNotIn('testcookie', request.session)
        self.assertNotIn('sessionverified', request.session)

        self.middleware.process_response(request, HttpResponse())
        self.assertFalse(self.events.exists())
        self.assertEqual(request.session.get('testcookie'), 'worked')
        self.assertNotIn('sessionverified', request.session)
Example #7
0
    def test_second_visit_cookies_work(self):
        self.assertEqual(self.events.count(), 0)

        request = self.get_request()
        request.META['HTTP_REFERER'] = 'https://test.edgeflip.com/'
        request.session.set_test_cookie()
        utils.set_visit(request, 1)

        self.middleware.process_request(request)
        self.assertTrue(request.session.get('sessionverified'))
        self.assertNotIn('testcookie', request.session)

        self.middleware.process_response(request, HttpResponse())
        self.assertEqual(self.events.count(), 1)
        self.assertTrue(request.session.get('sessionverified'))
        self.assertEqual(request.session.get('testcookie'), 'worked')
Example #8
0
    def test_no_test_cookie_on_ajax(self):
        self.assertEqual(self.events.count(), 0)

        request = self.get_request()
        request.META['HTTP_REFERER'] = 'https://test.edgeflip.com/'
        request.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
        request.session.set_test_cookie()
        utils.set_visit(request, 1)

        self.middleware.process_request(request)
        self.assertNotIn('testcookie', request.session)
        self.assertTrue(request.session.get('sessionverified'))

        self.middleware.process_response(request, HttpResponse())
        self.assertEqual(self.events.count(), 1)
        self.assertNotIn('testcookie', request.session)
        self.assertTrue(request.session.get('sessionverified'))
Example #9
0
    def test_update_visitor_fbid(self):
        request = self.get_request(HTTP_USER_AGENT='testbot',
                                   HTTP_REFERER='http://client.com/foo')
        set_visit(request, 1)
        session_id = request.visit.session_id
        visitor0 = request.visit.visitor
        self.assertTrue(session_id)
        self.assertIsNone(visitor0.fbid)
        self.assertEqual(request.visit.user_agent, 'testbot')
        self.assertEqual(request.visit.referer, 'http://client.com/foo')

        self.factory.cookies[settings.SESSION_COOKIE_NAME] = session_id
        self.factory.cookies[settings.VISITOR_COOKIE_NAME] = visitor0.uuid
        request = self.get_request(HTTP_USER_AGENT='MESSBOT',
                                   HTTP_REFERER='http://client.com/BAR')
        set_visit(request, 1, fbid=9)
        self.assertEqual(request.visit.session_id, session_id)
        self.assertEqual(request.visit.visitor, visitor0)
        self.assertEqual(request.visit.visitor.fbid, 9)
        # user_agent and referrer shouldn't update:
        self.assertEqual(request.visit.user_agent, 'testbot')
        self.assertEqual(request.visit.referer, 'http://client.com/foo')
Example #10
0
def objects(request, fb_object_id, content_id):
    """FBObject endpoint provided to Facebook to crawl and users to click."""
    fb_object = get_object_or_404(models.relational.FBObject, fb_object_id=fb_object_id)
    client = fb_object.client
    content = get_object_or_404(client.clientcontent, content_id=content_id)
    fb_attrs = fb_object.fbobjectattribute_set.for_datetime().get()
    choice_set_slug = request.GET.get('cssslug', '')
    campaign_id = request.GET.get('campaign_id', '')
    action_ids = request.GET.get('fb_action_ids', '').split(',')

    try:
        action_id = int(action_ids[0].strip())
    except ValueError:
        action_id = None

    # Determine user redirect URL:
    if campaign_id.isdigit():
        campaign_fbobjects = fb_object.campaignfbobjects.filter(campaign_id=campaign_id)
    else:
        campaign_fbobjects = fb_object.campaignfbobjects.all()
    source_urls = campaign_fbobjects.values_list('source_url', flat=True).distinct()

    if any(source_urls):
        # FBObject is in use by campaign(s) with dynamic-definition ("source") URL(s)
        try:
            (redirect_url,) = source_urls
        except ValueError:
            LOG.exception("Ambiguous FBObject source %r", tuple(source_urls))
            redirect_url = next(source_url for source_url in source_urls if source_url)
    else:
        # Traditionally-configured FBObject -- use ClientContent URL for redirect
        if not content.url:
            return http.HttpResponseNotFound()
        redirect_url = content.url

    if action_id:
        parsed_url = urlparse.urlparse(redirect_url)
        query_params = urlparse.parse_qsl(parsed_url.query)
        query_params.append(('fb_action_ids', action_id))
        redirect_url = parsed_url._replace(query=urllib.urlencode(query_params)).geturl()

    full_redirect_path = "{}?{}".format(
        reverse('targetshare:outgoing', args=[client.fb_app_id, redirect_url]),
        urllib.urlencode({'campaignid': campaign_id}),
    )

    # Build FBObject parameters for document:
    fb_object_url = 'https://%s%s?%s' % (
        request.get_host(),
        reverse('targetshare:objects', kwargs={
            'fb_object_id': fb_object_id,
            'content_id': content_id,
        }),
        urllib.urlencode({
            'cssslug': choice_set_slug,
            'campaign_id': campaign_id,
        }),
    )
    obj_params = {
        'page_title': fb_attrs.page_title,
        'fb_action_type': fb_attrs.og_action,
        'fb_object_type': fb_attrs.og_type,
        'fb_object_url': fb_object_url,
        'fb_app_name': client.fb_app.name,
        'fb_app_id': client.fb_app_id,
        'fb_object_title': fb_attrs.og_title,
        'fb_object_image': fb_attrs.og_image,
        'fb_object_description': fb_attrs.og_description,
        'fb_org_name': fb_attrs.org_name,
    }
    content_str = '%(fb_app_name)s:%(fb_object_type)s %(fb_object_url)s' % obj_params

    if 'facebookexternalhit' in request.META.get('HTTP_USER_AGENT', ''):
        LOG.info(
            'Facebook crawled object %s with content %s from IP %s',
            fb_object_id, content_id, utils.get_client_ip(request)
        )
    else:
        utils.set_visit(request, client.fb_app_id, start_event={
            'client_content': content,
            'campaign_id': campaign_id,
        })
        db.delayed_save.delay(
            models.relational.Event(
                visit=request.visit,
                client_content=content,
                content=content_str,
                activity_id=action_id,
                event_type='clickback',
                campaign_id=campaign_id,
            )
        )

    return render(request, 'targetshare/fb_object.html', {
        'fb_params': obj_params,
        'redirect_url': full_redirect_path,
        'content': content_str,
        'client': client,
    })
Example #11
0
def faces_email_friends(request, notification_uuid):
    ''' A view that's fairly similar to our Faces/Frame Faces views, except
    that this will not perform any crawls. We've already done the crawling
    in the background, so we can skip that here, and instead leverage the
    friends passed in via GET params.
    '''
    # Campaign setup
    notification_user = get_object_or_404(
        relational.NotificationUser,
        uuid=notification_uuid
    )
    campaign = notification_user.notification.campaign
    content = notification_user.notification.client_content
    client = campaign.client
    utils.set_visit(request, client.fb_app_id, notification_user.fbid, {
        'campaign': campaign,
        'client_content': content,
    })

    # Gather friend data
    user = dynamo.User.items.get_item(fbid=notification_user.fbid)
    friend_fbids = notification_user.events.filter(
        event_type__in=('generated', 'shown')
    ).values_list('friend_fbid', flat=True).distinct()
    all_friends = dynamo.User.items.batch_get(
        keys=LazyList({'fbid': fbid} for fbid in friend_fbids.iterator())
    )
    shown_fbids = set(
        notification_user.events.filter(
            event_type='shown',
        ).values_list('friend_fbid', flat=True).iterator()
    )
    num_face = len(shown_fbids)

    (face_friends, show_faces) = ([], [])
    for friend in all_friends:
        if friend.fbid in shown_fbids:
            show_faces.append(friend)
        else:
            face_friends.append(friend)

    db.delayed_save.delay(
        relational.Event(
            visit_id=request.visit.pk,
            campaign_id=campaign.pk,
            client_content_id=content.pk,
            event_type='faces_email_page_load',
        )
    )

    # FBObj setup
    fb_object = campaign.campaignfbobjects.for_datetime().random_assign()
    db.delayed_save.delay(
        relational.Assignment.make_managed(
            visit_id=request.visit.pk,
            campaign_id=campaign.pk,
            content_id=content.pk,
            feature_row=fb_object,
            chosen_from_rows=campaign.campaignfbobjects.for_datetime(),
        )
    )
    fb_attrs = fb_object.fbobjectattribute_set.get()
    fb_object_url = 'https://%s%s?%s' % (
        request.get_host(),
        reverse('targetshare:objects', kwargs={
            'fb_object_id': fb_object.pk,
            'content_id': content.pk,
        }),
        urllib.urlencode({
            'campaign_id': campaign.pk,
        }),
    )

    fb_params = {
        'fb_action_type': fb_attrs.og_action,
        'fb_object_type': fb_attrs.og_type,
        'fb_object_url': fb_object_url,
        'fb_app_name': client.fb_app.name,
        'fb_app_id': client.fb_app_id,
        'fb_object_title': fb_attrs.og_title,
        'fb_object_image': fb_attrs.og_image,
        'fb_object_description': fb_attrs.og_description
    }
    msg_params = {
        'sharing_prompt': fb_attrs.sharing_prompt,
        'msg1_pre': fb_attrs.msg1_pre,
        'msg1_post': fb_attrs.msg1_post,
        'msg2_pre': fb_attrs.msg2_pre,
        'msg2_post': fb_attrs.msg2_post,
    }
    content_str = '%s:%s %s' % (
        fb_params['fb_app_name'],
        fb_params['fb_object_type'],
        fb_params['fb_object_url']
    )
    db.bulk_create.delay([
        relational.Event(
            visit_id=request.visit.pk,
            campaign_id=event.campaign.pk,
            client_content_id=event.client_content.pk,
            friend_fbid=event.friend_fbid,
            content=content_str,
            event_type=event.event_type,
        )
        for event in notification_user.events.iterator()
    ])
    db.bulk_create.delay([
        relational.Assignment(
            visit_id=request.visit.pk,
            campaign_id=assignment.campaign.pk,
            content_id=assignment.content.pk,
            feature_type=assignment.feature_type,
            feature_row=assignment.feature_row,
            random_assign=assignment.random_assign,
            chosen_from_table=assignment.chosen_from_table,
            chosen_from_rows=assignment.chosen_from_rows,
        )
        for assignment in notification_user.assignments.iterator()
    ])

    page_styles = utils.assign_page_styles(
        request.visit,
        relational.Page.FRAME_FACES,
        campaign,
        content,
    )

    return render(request, 'targetshare/faces_email_friends.html', {
        'fb_params': fb_params,
        'msg_params': msg_params,
        'campaign': campaign,
        'content': content,
        'properties': campaign.campaignproperties.get(),
        'campaign_css': page_styles,
        'all_friends': all_friends,
        'face_friends': face_friends,
        'show_faces': show_faces,
        'user': user,
        'num_face': num_face,
    })