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
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)
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)
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')
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)
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)
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')
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'))
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')
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, })
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, })