def banner_create(request): form = FacebookBannerInstanceForm(request, request.POST or None) if request.method == 'POST': if not form.is_valid(): return JSONResponse(form.errors, status=400) banner_instance = form.save() # The create form is submitted via an AJAX call. If the user wants to # include their profile picture on a banner, we return a 202 Accepted to # indicate we are processing the image. If they don't, we just return # a 201 Created to signify that the banner instance has been created # and it is safe to continue. if request.POST['next_action'] == 'share': next = absolutify(reverse('facebook.banners.share', args=[banner_instance.id])) else: next = absolutify(reverse('facebook.banner_list')) if form.cleaned_data['use_profile_image']: generate_banner_instance_image.delay(banner_instance.id) payload = { 'check_url': reverse('facebook.banners.create_image_check', args=[banner_instance.id]), 'next': next } return JSONResponse(payload, status=202) # 202 Accepted else: # No processing needed. banner_instance.processed = True banner_instance.save() return JSONResponse({'next': next}, status=201) # 201 Created return jingo.render(request, 'facebook/banner_create.html', {'form': form})
def test_cdn(self): with patch.object(settings, 'CDN_DOMAIN', None): url = absolutify('/some/url', cdn=True) eq_(url, 'http://badge.mo.com/some/url') with patch.object(settings, 'CDN_DOMAIN', 'cdn.badge.mo.com'): url = absolutify('/some/url', cdn=True) eq_(url, 'http://cdn.badge.mo.com/some/url')
def render(self): """Render the image grid for the banner selector.""" banner_ids = [ int(banner_id) for banner_id, label in self.choices if banner_id != '' ] banners = dict( (banner.id, banner) for banner in FacebookBanner.objects.filter(id__in=banner_ids)) inputs = [] locale = get_language() for radio_input in self: # Ignore empty choice. # TODO: Could probably use a better workaround. if radio_input.choice_value == '': continue banner = banners[int(radio_input.choice_value)] # Construct image tag. img = '<img%s>' % flatatt( { 'class': 'banner-choice', 'src': absolutify(banner.thumbnail_for_locale(locale).url), 'width': 100, 'height': 72, 'alt': banner.alt_text }) # Add attributes to the input tag. url = banner.image_for_locale(locale).url radio_input.attrs['data-image'] = absolutify(url) if 'id' in self.attrs: label_for = ' for="%s_%s"' % (radio_input.attrs['id'], radio_input.index) else: label_for = '' # Bring it all together! inputs.append('<label%(label_for)s>\n%(input)s\n%(img)s\n' '</label>' % { 'label_for': label_for, 'input': radio_input.tag(), 'img': img }) return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % tag for tag in inputs]))
def code(self): """Return the code to embed this banner..""" return jingo.env.from_string(BANNER_TEMPLATE).render({ 'url': self.affiliate_link(), 'img': absolutify(self.image.image.url), 'alt_text': _locale(self.badge.name, self.image.locale) })
def banner_share(request, instance_id): banner_instance = get_object_or_404(FacebookBannerInstance, id=instance_id, user=request.user) protocol = 'https' if request.is_secure() else 'http' next = absolutify(reverse('facebook.post_banner_share'), protocol=protocol) return jingo.render(request, 'facebook/banner_share.html', {'banner_instance': banner_instance, 'next': next})
def render(self): """Render the image grid for the banner selector.""" banner_ids = [int(banner_id) for banner_id, label in self.choices if banner_id != ''] banners = dict((banner.id, banner) for banner in FacebookBanner.objects.filter(id__in=banner_ids)) inputs = [] locale = get_language() for radio_input in self: # Ignore empty choice. # TODO: Could probably use a better workaround. if radio_input.choice_value == '': continue banner = banners[int(radio_input.choice_value)] # Construct image tag. img = '<img%s>' % flatatt({ 'class': 'banner-choice', 'src': absolutify(banner.thumbnail_for_locale(locale).url), 'width': 100, 'height': 72, 'alt': banner.alt_text }) # Add attributes to the input tag. url = banner.image_for_locale(locale).url radio_input.attrs['data-image'] = absolutify(url) if 'id' in self.attrs: label_for = ' for="%s_%s"' % (radio_input.attrs['id'], radio_input.index) else: label_for = '' # Bring it all together! inputs.append('<label%(label_for)s>\n%(input)s\n%(img)s\n' '</label>' % { 'label_for': label_for, 'input': radio_input.tag(), 'img': img }) return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % tag for tag in inputs]))
def banner_share(request, instance_id): banner_instance = get_object_or_404(FacebookBannerInstance, id=instance_id, user=request.user) protocol = 'https' if request.is_secure() else 'http' next = absolutify(reverse('facebook.post_banner_share'), protocol=protocol) return jingo.render(request, 'facebook/banner_share.html', { 'banner_instance': banner_instance, 'next': next })
def load_app(request): """ Create or authenticate the Facebook user and direct them to the correct area of the app upon their entry. """ signed_request = request.POST.get('signed_request', None) if signed_request is None: # App wasn't loaded within a canvas, redirect to the home page. return redirect('home') decoded_request = decode_signed_request(signed_request, settings.FACEBOOK_APP_SECRET) if decoded_request is None: return redirect('home') # If user is using Safari, we need to apply the cookie workaround. useragent = request.META.get('HTTP_USER_AGENT', '') using_safari = 'Safari' in useragent and not 'Chrome' in useragent workaround_applied = SAFARI_WORKAROUND_KEY in request.COOKIES if using_safari and not workaround_applied: return fb_redirect(request, absolutify(reverse('facebook.safari_workaround')), top_window=True) user, created = (FacebookUser.objects. get_or_create_user_from_decoded_request(decoded_request)) if user is None: # User has yet to authorize the app, redirect to the pre-auth promo. return fb_redirect(request, absolutify(reverse('facebook.pre_auth_promo'))) # Attach country data to the user object. This can only be retrieved from # the decoded request, so we add it here and login saves it. user.country = decoded_request['user'].get('country', user.country) # User has been authed, let's log them in. login(request, user) return fb_redirect(request, absolutify(reverse('facebook.banner_list')))
def test_no_safari_workaround(self, fb_redirect, update_user_info): """ If the user is not using Safari, do not redirect to the workaround. """ with self.activate('en-US'): workaround_url = absolutify(reverse('facebook.safari_workaround')) fb_redirect.return_value = HttpResponse('blah') payload = create_payload(user_id=1) response = self.load_app(payload, HTTP_USER_AGENT='Safari/5.04 Chrome/7.5') eq_(response, fb_redirect.return_value) ok_(fb_redirect.call_args[0][1] != workaround_url)
def banner_create(request): form = FacebookBannerInstanceForm(request, request.POST or None) if request.method == 'POST': if not form.is_valid(): return JSONResponse(form.errors, status=400) banner_instance = form.save() # The create form is submitted via an AJAX call. If the user wants to # include their profile picture on a banner, we return a 202 Accepted to # indicate we are processing the image. If they don't, we just return # a 201 Created to signify that the banner instance has been created # and it is safe to continue. if request.POST['next_action'] == 'share': next = absolutify( reverse('facebook.banners.share', args=[banner_instance.id])) else: next = absolutify(reverse('facebook.banner_list')) if form.cleaned_data['use_profile_image']: generate_banner_instance_image.delay(banner_instance.id) payload = { 'check_url': reverse('facebook.banners.create_image_check', args=[banner_instance.id]), 'next': next } return JSONResponse(payload, status=202) # 202 Accepted else: # No processing needed. banner_instance.processed = True banner_instance.save() return JSONResponse({'next': next}, status=201) # 201 Created return jingo.render(request, 'facebook/banner_create.html', {'form': form})
def size_color_to_image_map(self): """ Return a dictionary that maps sizes and colors to these banner images. """ banner_images = {} for img in self: if img.size not in banner_images: banner_images[img.size] = {} banner_images[img.size][img.localized('color')] = { 'image_url': absolutify(img.image.url, cdn=True), 'pk': img.pk } return banner_images
def browserid_home(request): """Display the home page with a BrowserID login.""" register_form = BrowserIDRegisterForm(request.POST or None) if request.method == 'POST': # Attempting to register response = browserid_register(request, register_form) if response is not None: return response params = {'browserid_verify': reverse('browserid.verify'), 'register_form': register_form, 'share_url': absolutify('/', protocol='https'), 'tweet_text': urlquote_plus(TWEET_TEXT), 'browserid_no_assertion': BROWSERID_NO_ASSERTION, 'browserid_verify_fail': BROWSERID_VERIFY_FAIL} return render(request, 'shared/home/browserid.html', params)
def test_no_profile_image(self): """ If the user did not check `use_profile_image`, create the banner instance and return a 201 Created. """ banner = FacebookBannerLocaleFactory.create(locale='en-us').banner response = self.banner_create(banner=banner.id, text='asdf', next_action='', use_profile_image=False) ok_(FacebookBannerInstance.objects.filter(banner=banner, user=self.user) .exists()) eq_(response.status_code, 201) response_data = json.loads(response.content) with self.activate('en-US'): eq_(response_data['next'], absolutify(reverse('facebook.banner_list')))
def home(request, register_form=None, login_form=None): """Display the home page.""" # Redirect logged-in users if request.user.is_authenticated(): return redirect('badges.new.step1') if register_form is None: register_form = RegisterForm() if login_form is None: login_form = LoginForm() params = {'register_form': register_form, 'login_form': login_form, 'share_url': absolutify('/'), 'tweet_text': urlquote_plus(TWEET_TEXT)} return jingo.render(request, 'badges/home.html', params)
def test_safari_workaround_done(self, fb_redirect, update_user_info): """ If the user is using Safari and hasthe workaround cookie, do not send them to the workaround page. """ with self.activate('en-US'): workaround_url = absolutify(reverse('facebook.safari_workaround')) fb_redirect.return_value = HttpResponse('blah') payload = create_payload(user_id=1) self.client.cookies[SAFARI_WORKAROUND_KEY] = '1' response = self.load_app(payload, HTTP_USER_AGENT='Safari/5.04') del self.client.cookies[SAFARI_WORKAROUND_KEY] # Ensure that the redirect URL is NOT the safari workaround url eq_(response, fb_redirect.return_value) ok_(fb_redirect.call_args[0][1] != workaround_url)
def test_save_and_share(self): """ If the user clicks the `Save and Share` button, the `next` link should point to the share page for the new banner instance. """ banner = FacebookBannerLocaleFactory.create(locale='en-us').banner response = self.banner_create(banner=banner.id, text='asdf', next_action='share', use_profile_image=False) instance = FacebookBannerInstance.objects.get(banner=banner, user=self.user) response_data = json.loads(response.content) with self.activate('en-US'): eq_(response_data['next'], absolutify(reverse('facebook.banners.share', args=[instance.id])))
def load_app(request): """ Create or authenticate the Facebook user and direct them to the correct area of the app upon their entry. """ # Temporary measure to handle when Facebook does a GET to the main URL when # a logged-out user views the app. In the future we should show a promo # page instead. if request.method != "POST": return request_authorization(request) signed_request = request.POST.get("signed_request", None) if signed_request is None: # App wasn't loaded within a canvas, redirect to the home page. return redirect("home") decoded_request = decode_signed_request(signed_request, settings.FACEBOOK_APP_SECRET) if decoded_request is None: return redirect("home") # If user is using Safari, we need to apply the cookie workaround. useragent = request.META.get("HTTP_USER_AGENT", "") using_safari = "Safari" in useragent and not "Chrome" in useragent workaround_applied = SAFARI_WORKAROUND_KEY in request.COOKIES if using_safari and not workaround_applied: return fb_redirect(request, absolutify(reverse("facebook.safari_workaround"))) user, created = FacebookUser.objects.get_or_create_user_from_decoded_request(decoded_request) if user is None: # User has yet to authorize the app, offer authorization. return request_authorization(request) # Attach country data to the user object. This can only be retrieved from # the decoded request, so we add it here and login saves it. user.country = decoded_request["user"].get("country", user.country) # User has been authed, let's log them in. login(request, user) # Normally the FacebookAuthenticationMiddleware activates the locale for # the user, but since it does not run for this view, we need to activate it # manually. activate_locale(request, user.locale) return banner_list(request)
def browserid_home(request): """Display the home page with a BrowserID login.""" register_form = BrowserIDRegisterForm(request.POST or None) if request.method == 'POST': # Attempting to register response = browserid_register(request, register_form) if response is not None: return response params = { 'browserid_verify': reverse('browserid.verify'), 'register_form': register_form, 'share_url': absolutify('/', https=True), 'tweet_text': urlquote_plus(TWEET_TEXT), 'browserid_no_assertion': BROWSERID_NO_ASSERTION, 'browserid_verify_fail': BROWSERID_VERIFY_FAIL } return render(request, 'shared/home/browserid.html', params)
def home(request, register_form=None, login_form=None): """Display the home page.""" # Redirect logged-in users if request.user.is_authenticated(): return redirect('badges.new.step1') # en-US users see the BrowserID view instead if get_language() in settings.BROWSERID_LOCALES: return browserid_home(request) if register_form is None: register_form = RegisterForm() if login_form is None: login_form = LoginForm() params = {'register_form': register_form, 'login_form': login_form, 'share_url': absolutify('/', protocol='https'), 'tweet_text': urlquote_plus(TWEET_TEXT)} return render(request, 'shared/home/normal.html', params)
def home(request, register_form=None, login_form=None): """Display the home page.""" # Redirect logged-in users if request.user.is_authenticated(): return redirect('badges.new.step1') # en-US users see the BrowserID view instead if get_language() in settings.BROWSERID_LOCALES: return browserid_home(request) if register_form is None: register_form = RegisterForm() if login_form is None: login_form = LoginForm() params = { 'register_form': register_form, 'login_form': login_form, 'share_url': absolutify('/', https=True), 'tweet_text': urlquote_plus(TWEET_TEXT) } return render(request, 'shared/home/normal.html', params)
def test_use_profile_image(self, delay): """ If the user checked `use_profile_image`, create a banner instance, trigger the celery task and return a 202 Accepted. """ banner = FacebookBannerLocaleFactory.create(locale='en-us').banner response = self.banner_create(banner=banner.id, text='asdf', next_action='', use_profile_image=True) # Asserts that banner instance exists. instance = FacebookBannerInstance.objects.get(banner=banner, user=self.user) delay.assert_called_with(instance.id) # Assert response contians the expected links. eq_(response.status_code, 202) response_data = json.loads(response.content) with self.activate('en-US'): eq_(response_data['next'], absolutify(reverse('facebook.banner_list'))) eq_(response_data['check_url'], reverse('facebook.banners.create_image_check', args=[instance.id]))
import urllib from django.conf import settings from django.contrib.auth.models import User from django.utils.hashcompat import md5_constructor from jingo import register from jinja2 import Markup from shared.utils import absolutify from users.models import UserProfile GRAVATAR_URL = getattr(settings, 'GRAVATAR_URL', 'http://www.gravatar.com') DEFAULT_GRAVATAR = absolutify(settings.DEFAULT_GRAVATAR, https=True) @register.function def gravatar_url(arg, size=80): if isinstance(arg, User): email = arg.email else: # Treat as email email = arg url = '%s/avatar/%s?%s' % ( GRAVATAR_URL, md5_constructor(email.lower()).hexdigest(), urllib.urlencode({'s': str(size), 'default': DEFAULT_GRAVATAR})) return url
def test_protocol(self): url = absolutify('/some/url', protocol='https') eq_(url, 'https://badge.mo.com/some/url')
def invite(request): protocol = 'https' if request.is_secure() else 'http' next = absolutify(reverse('facebook.post_invite'), protocol=protocol) return jingo.render(request, 'facebook/invite.html', {'next': next})
import urllib from django.conf import settings from django.contrib.auth.models import User from django.utils.hashcompat import md5_constructor from jingo import register from jinja2 import Markup from shared.utils import absolutify from users.models import UserProfile GRAVATAR_URL = getattr(settings, 'GRAVATAR_URL', 'http://www.gravatar.com') DEFAULT_GRAVATAR = absolutify(settings.DEFAULT_GRAVATAR, protocol='https') @register.function def gravatar_url(arg, size=80): if isinstance(arg, User): email = arg.email else: # Treat as email email = arg url = '%s/avatar/%s?%s' % ( GRAVATAR_URL, md5_constructor(email.lower()).hexdigest(), urllib.urlencode({'s': str(size), 'default': DEFAULT_GRAVATAR})) return url
def preview(self): """Return the HTML to preview this banner.""" return Markup('<img src="%s?from_affiliates" alt="%s">' % (absolutify(self.image.image.url), _locale(self.badge.name, self.image.locale)))
def invite(request): protocol = "https" if request.is_secure() else "http" next = absolutify(reverse("facebook.post_invite"), protocol=protocol) return jingo.render(request, "facebook/invite.html", {"next": next})
def render(self): return jingo.env.from_string(BANNER_TEMPLATE).render({ 'url': self.affiliate_link(), 'img': absolutify(self.image.image.url) })
from django.conf.urls.defaults import patterns, url from shared.utils import absolutify # Reverse won't let us use placeholder values (so Javascript can replace the # banner_img_id), so we store this link as a string. AFFILIATE_LINK = absolutify('/link/banner/%s/%s/{{ banner_img_id }}', https=True) urlpatterns = patterns( 'banners.views', url(r'^banners/customize/(?P<banner_pk>\d+)$', 'customize', name='banners.customize'), url(r'^link/banner/(?P<user_id>\d+)/(?P<banner_id>\d+)/(?P<banner_img_id>\d+)$', 'old_link', name='banners.link.old'), url(r'^link/banner/(?P<banner_instance_id>\d+)$', 'link', name='banners.link'), )
import urllib from django.conf import settings from django.contrib.auth.models import User from django.utils.hashcompat import md5_constructor from jingo import register from jinja2 import Markup from shared.utils import absolutify from users.models import UserProfile GRAVATAR_URL = getattr(settings, 'GRAVATAR_URL', 'http://www.gravatar.com') DEFAULT_GRAVATAR = absolutify(settings.DEFAULT_GRAVATAR, https=True) @register.function def gravatar_url(arg, size=80): if isinstance(arg, User): email = arg.email else: # Treat as email email = arg url = '%s/avatar/%s?%s' % (GRAVATAR_URL, md5_constructor( email.lower()).hexdigest(), urllib.urlencode({ 's': str(size), 'default': DEFAULT_GRAVATAR })) return url
from django.conf.urls.defaults import patterns, url from shared.utils import absolutify # Reverse won't let us use placeholder values (so Javascript can replace the # banner_img_id), so we store this link as a string. AFFILIATE_LINK = absolutify('/link/banner/%s/%s/{{ banner_img_id }}', protocol='https') urlpatterns = patterns('banners.views', url(r'^banners/customize/(?P<banner_pk>\d+)$', 'customize', name='banners.customize'), url(r'^link/banner/(?P<user_id>\d+)/(?P<banner_id>\d+)/(?P<banner_img_id>\d+)$', 'old_link', name='banners.link.old'), url(r'^link/banner/(?P<banner_instance_id>\d+)$', 'link', name='banners.link'), )
def test_basic(self): url = absolutify('/some/url') eq_(url, 'http://badge.mo.com/some/url')
def affiliate_link(self): link = reverse('banners.link', kwargs={'banner_instance_id': self.pk}) return absolutify(link)
def banner_share(request, instance_id): banner_instance = get_object_or_404(FacebookBannerInstance, id=instance_id, user=request.user) protocol = "https" if request.is_secure() else "http" next = absolutify(reverse("facebook.post_banner_share"), protocol=protocol) return jingo.render(request, "facebook/banner_share.html", {"banner_instance": banner_instance, "next": next})
def test_https(self): url = absolutify('/some/url', https=True) eq_(url, 'https://badge.mo.com/some/url')
def activation_link(self): return absolutify(reverse('facebook.links.activate', args=[self.activation_code]))
def test_relative_protocol(self): """If protocol is a blank string, use a protocol-relative URL.""" url = absolutify('/some/url', protocol='') eq_(url, '//badge.mo.com/some/url')
from django.conf.urls.defaults import patterns, url from shared.utils import absolutify # Reverse won't let us use placeholder values (so Javascript can replace the # banner_img_id), so we store this link as a string. AFFILIATE_LINK = absolutify('/link/banner/%s/%s/{{ banner_img_id }}', protocol='https') urlpatterns = patterns( 'banners.views', url(r'^banners/customize/(?P<banner_pk>\d+)$', 'customize', name='banners.customize'), url(r'^link/banner/(?P<user_id>\d+)/(?P<banner_id>\d+)/(?P<banner_img_id>\d+)$', 'old_link', name='banners.link.old'), url(r'^link/banner/(?P<banner_instance_id>\d+)$', 'link', name='banners.link'), )
def link(self): return absolutify(reverse('facebook.banners.link', args=[self.id]))
from django.conf.urls.defaults import patterns, url from shared.utils import absolutify # Reverse won't let us use placeholder values (so Javascript can replace the # banner_img_id), so we store this link as a string. AFFILIATE_LINK = absolutify('/link/banner/%s/%s/{{ banner_img_id }}', https=True) urlpatterns = patterns('banners.views', url(r'^banners/customize/(?P<banner_pk>\d+)$', 'customize', name='banners.customize'), url(r'^link/banner/(?P<user_id>\d+)/(?P<banner_id>\d+)/(?P<banner_img_id>\d+)$', 'old_link', name='banners.link.old'), url(r'^link/banner/(?P<banner_instance_id>\d+)$', 'link', name='banners.link'), )
import urllib from django.conf import settings from django.contrib.auth.models import User from django.utils.hashcompat import md5_constructor from jingo import register from jinja2 import Markup from shared.utils import absolutify from users.models import UserProfile GRAVATAR_URL = getattr(settings, 'GRAVATAR_URL', 'http://www.gravatar.com') DEFAULT_GRAVATAR = absolutify(settings.DEFAULT_GRAVATAR, protocol='https') @register.function def gravatar_url(arg, size=80): if isinstance(arg, User): email = arg.email else: # Treat as email email = arg url = '%s/avatar/%s?%s' % (GRAVATAR_URL, md5_constructor( email.lower()).hexdigest(), urllib.urlencode({ 's': str(size), 'default': DEFAULT_GRAVATAR })) return url
def test_https(self): """Test that https=True forces an https url.""" url = absolutify('/some/url', https=True) eq_(url, 'https://badge.mo.com/some/url')