def new_user_view(request, template=None): if request.user.is_anonymous(): # This is the AnonymousUser and they shouldn't be here # so push them to the dashboard. return HttpResponseRedirect(reverse('dashboard')) try: # If they have a profile, then this doesn't throw an error # and we can let them see the new user view again, but it's # not particularly interesting. request.user.profile except Profile.DoesNotExist: # They aren't anonymous and don't have a profile, so create # a profile for them. # # We could do more with this, but we're not at the moment. Profile.objects.create(user=request.user) next_url = request.GET.get('next', reverse('dashboard')) if not is_safe_url(next_url): next_url = reverse('dashboard') return render(request, template, { 'next_url': next_url, })
def login_success(self): """Send to new-user-view if new user, otherwise send on their way""" response = super(FjordVerify, self).login_success() # If this user has never logged in before, send them to our # super secret "Welcome!" page. try: self.user.profile return response except Profile.DoesNotExist: url = reverse('new-user-view') redirect_to = self.request.REQUEST.get('next') # Do not accept redirect URLs pointing to a different host. if redirect_to: netloc = urlparse.urlparse(redirect_to).netloc if netloc and netloc != self.request.get_host(): redirect_to = None if redirect_to: url = url + '?next=' + redirect_to return JSONResponse({ 'email': self.user.email, 'redirect': url, })
def _requires_firefox(request, *args, **kwargs): # Note: This is sort of a lie. What's going on here is that # parse_ua only parses Firefox-y browsers. So if it's UNKNOWN # at this point, then it's not Firefox-y. If parse_ua ever # changes, then this will cease to be true. if request.BROWSER.browser == UNKNOWN: return HttpResponseRedirect(reverse('download-firefox')) return func(request, *args, **kwargs)
def _wrapped_view(request, *args, **kwargs): # Do this here to avoid circular imports from fjord.base.models import Profile try: request.user.profile except AttributeError: pass except Profile.DoesNotExist: url = reverse('new-user-view') + '?next=' + request.path return HttpResponseRedirect(url) return fun(request, *args, **kwargs)
def generate_dashboard_url(request, output_format='atom', viewname='dashboard'): """For a given request, generates the dashboard url for the given format""" qd = request.GET.copy() # Remove anything from the querystring that isn't good for a feed: # page, start_date, end_date, etc. for mem in qd.keys(): if mem not in ('happy', 'locale', 'platform', 'product', 'version', 'q'): del qd[mem] qd['format'] = output_format return reverse(viewname) + '?' + qd.urlencode()
def spot_translate(request, responseid): # FIXME: This is gengo-machine specific for now. resp = get_object_or_404(Response, id=responseid) system = request.POST.get('system', None) total_jobs = 0 if system and system in get_translation_systems(): total_jobs += len(create_translation_tasks(resp, system=system)) # FIXME: If there's no system specified, we should tell the user # something. I'm going to defer fixing that for now since the user # would have to be doing "sneaky" things to hit that situation. messages.success(request, '%s %s translation jobs added' % (total_jobs, system)) return HttpResponseRedirect(reverse('response_view', args=(responseid, )))
def spot_translate(request, responseid): # FIXME: This is gengo-machine specific for now. resp = get_object_or_404(Response, id=responseid) system = request.POST.get('system', None) total_jobs = 0 if system and system in get_translation_systems(): total_jobs += len(create_translation_tasks(resp, system=system)) # FIXME: If there's no system specified, we should tell the user # something. I'm going to defer fixing that for now since the user # would have to be doing "sneaky" things to hit that situation. messages.success(request, '%s %s translation jobs added' % ( total_jobs, system)) return HttpResponseRedirect( reverse('response_view', args=(responseid,)))
def generate_dashboard_url(request, output_format='atom', viewname='dashboard'): """For a given request, generates the dashboard url for the given format """ qd = request.GET.copy() # Remove anything from the querystring that isn't good for a feed: # page, start_date, end_date, etc. for mem in qd.keys(): if mem not in ('happy', 'locale', 'platform', 'product', 'version', 'q'): del qd[mem] qd['format'] = output_format return reverse(viewname) + '?' + qd.urlencode()
def generate_atom_feed(request, search): """Generates ATOM feed for first 100 results""" search_query = request.GET.get('q', None) if search_query: title = _(u'Firefox Input: {query}').format(query=search_query) else: title = _(u'Firefox Input') # Build the non-atom dashboard url and maintain all the # querystring stuff we have dashboard_url = request.build_absolute_uri() dashboard_url = dashboard_url.replace('format=atom', '') dashboard_url = dashboard_url.replace('&&', '&') if dashboard_url.endswith(('?', '&')): dashboard_url = dashboard_url[:-1] feed = Atom1FeedWithRelatedLinks( title=title, link=dashboard_url, description=_('Search Results From Firefox Input'), author_name=_('Firefox Input'), ) for response in search[:100]: categories = { 'sentiment': _('Happy') if response.happy else _('Sad'), 'platform': response.platform, 'locale': response.locale } categories = (':'.join(item) for item in categories.items()) link_url = reverse('response_view', args=(response.id,)) link_url = request.build_absolute_uri(link_url) feed.add_item( title=_('Response id: {id}').format(id=response.id), description=response.description, link=link_url, pubdate=response.created, categories=categories, link_related=response.url_domain, ) return HttpResponse( feed.writeString('utf-8'), content_type='application/atom+xml')
def generate_atom_feed(request, search): """Generates ATOM feed for first 100 results""" search_query = request.GET.get('q', None) if search_query: title = _(u'Firefox Input: {query}').format(query=search_query) else: title = _(u'Firefox Input') # Build the non-atom dashboard url and maintain all the # querystring stuff we have dashboard_url = request.build_absolute_uri() dashboard_url = dashboard_url.replace('format=atom', '') dashboard_url = dashboard_url.replace('&&', '&') if dashboard_url.endswith(('?', '&')): dashboard_url = dashboard_url[:-1] feed = Atom1FeedWithRelatedLinks( title=title, link=dashboard_url, description=_('Search Results From Firefox Input'), author_name=_('Firefox Input'), ) for response in search[:100]: categories = { 'sentiment': _('Happy') if response.happy else _('Sad'), 'platform': response.platform, 'locale': response.locale } categories = (':'.join(item) for item in categories.items()) link_url = reverse('response_view', args=(response.id, )) link_url = request.build_absolute_uri(link_url) feed.add_item( title=_('Response id: {id}').format(id=response.id), description=response.description, link=link_url, pubdate=response.created, categories=categories, link_related=response.url_domain, ) return HttpResponse(feed.writeString('utf-8'), content_type='application/atom+xml')
def feedback_router(request, product_slug=None, version=None, channel=None, *args, **kwargs): """Figure out which flow to use for a product and route accordingly .. Note:: 1. We never want to cache this view 2. Pages returned from this view will get an:: X-Frame-Options: DENY HTTP header. That's important because these pages have magic powers and should never be used in frames. Please do not change this! """ # The old Firefox for Android would POST form data to /feedback/. If we see # that, we fix the request up and then handle it as a feedback post. if '_type' in request.POST: request = fix_oldandroid(request) return _handle_feedback_post(request, request.locale) # FIXME - validate these better product_slug = smart_str(product_slug, fallback=None) version = smart_str(version) channel = smart_str(channel).lower() view_fun = get_config(product_slug)['view'] if product_slug not in models.Product.objects.get_product_map(): # If the product doesn't exist, redirect them to the picker. return HttpResponseRedirect(reverse('picker')) # Convert the product_slug to a product and send them on their way. product = models.Product.objects.from_slug(product_slug) return view_fun(request, request.locale, product, version, channel, *args, **kwargs)
def url(viewname, *args, **kwargs): """Performs our localized reverse""" return reverse(viewname, args=args, kwargs=kwargs)
def sad_redirect(request): """Support older redirects from Input v1 era""" return HttpResponseRedirect(reverse('picker') + '?happy=0')
def _handle_feedback_post(request, locale=None, product=None, version=None, channel=None): """Saves feedback post to db accounting for throttling :arg request: request we're handling the post for :arg locale: locale specified in the url :arg product: None or the Product :arg version: validated and sanitized version specified in the url :arg channel: validated and sanitized channel specified in the url """ if getattr(request, 'limited', False): # If we're throttled, then return the thanks page, but don't # add the response to the db. return HttpResponseRedirect(reverse('thanks')) # Get the form and run is_valid() so it goes through the # validation and cleaning machinery. We don't really care if it's # valid, though, since we will take what we got and do the best we # can with it. Error validation is now in JS. form = ResponseForm(request.POST) form.is_valid() get_data = request.GET.copy() data = form.cleaned_data description = data.get('description', u'').strip() if not description: # If there's no description, then there's nothing to do here, # so thank the user and move on. return HttpResponseRedirect(reverse('thanks')) opinion = models.Response( # Data coming from the user happy=data['happy'], url=clean_url(data.get('url', u'').strip()), description=description, # Pulled from the form data or the url locale=data.get('locale', locale), # Data from mobile devices which is probably only # applicable to mobile devices manufacturer=data.get('manufacturer', ''), device=data.get('device', ''), ) # Add user_agent and inferred data. user_agent = request.META.get('HTTP_USER_AGENT', '') if user_agent: browser = request.BROWSER opinion.user_agent = user_agent opinion.browser = browser.browser opinion.browser_version = browser.browser_version opinion.browser_platform = browser.platform if browser.platform == 'Windows': opinion.browser_platform += ' ' + browser.platform_version # source is src or utm_source source = ( get_data.pop('src', [u''])[0] or get_data.pop('utm_source', [u''])[0] ) if source: opinion.source = source[:100] campaign = get_data.pop('utm_campaign', [u''])[0] if campaign: opinion.campaign = campaign[:100] # If they sent "happy=1"/"happy=0" in the querystring, it will get # picked up by the javascript in the form and we can just drop it # here. get_data.pop('happy', None) platform = u'' if product: # If we have a product at this point, then it came from the # url and it's a Product instance and we need to turn it into # the product.db_name which is a string. product_db_name = product.db_name else: # Check the POST data for the product. product_db_name = data.get('product', '') # For the version, we try the url data, then the POST data. version = version or data.get('version', '') # At this point, we have a bunch of values, but we might be # missing some values, too. We're going to cautiously infer data # from the user agent where we're very confident it's appropriate # to do so. if request.BROWSER != UNKNOWN: # If we don't have a product, try to infer that from the user # agent information. if not product_db_name: product_db_name = models.Response.infer_product(request.BROWSER) # If we have a product and it matches the user agent browser, # then we can infer the version and platform from the user # agent if they're missing. if product_db_name: product = models.Product.objects.get(db_name=product_db_name) if product.browser and product.browser == request.BROWSER.browser: if not version: version = request.BROWSER.browser_version if not platform: platform = models.Response.infer_platform( product_db_name, request.BROWSER) # Make sure values are at least empty strings--no Nones. opinion.product = product_db_name or u'' opinion.version = version or u'' opinion.channel = channel or u'' opinion.platform = platform or u'' opinion.save() # If there was an email address, save that separately. if data.get('email_ok') and data.get('email'): e = models.ResponseEmail(email=data['email'], opinion=opinion) e.save() statsd.incr('feedback.emaildata.optin') # If there's browser data, save that separately. if data.get('browser_ok'): # This comes in as a JSON string. Because we're using # JSONObjectField, we need to convert it back to Python and # then save it. This is kind of silly, but it does guarantee # we have valid JSON. try: browser_data = data['browser_data'] browser_data = json.loads(browser_data) except ValueError: # Handles empty string and any non-JSON value. statsd.incr('feedback.browserdata.badvalue') except KeyError: # Handles the case where it's missing from the data # dict. If it's missing, we don't want to do anything # including metrics. pass else: # If browser_data isn't an empty dict, then save it. if browser_data: rti = models.ResponsePI( data=browser_data, opinion=opinion) rti.save() statsd.incr('feedback.browserdata.optin') if get_data: # There was extra context in the query string, so we grab that # with some restrictions and save it separately. slop = {} # We capture at most the first 20 key/val pairs get_data_items = sorted(get_data.items())[:20] for key, val in get_data_items: # Keys can be at most 20 characters long. key = key[:20] if len(val) == 1: val = val[0] # Values can be at most 20 characters long. val = val[:100] slop[key.encode('utf-8')] = val.encode('utf-8') context = models.ResponseContext(data=slop, opinion=opinion) context.save() statsd.incr('feedback.contextdata.optin') if data['happy']: statsd.incr('feedback.happy') else: statsd.incr('feedback.sad') request.session['response_id'] = opinion.id return HttpResponseRedirect(reverse('thanks'))
def sad_redirect(request): """Support older redirects from Input v1 era""" return HttpResponseRedirect(reverse('feedback') + '?happy=0')
def test_locale(self): # Note: This depends on the 'about' view and the 'es' # locale. If we change those, then it breaks this test. assert reverse('about-view', locale='es') == '/es/about'
def build_redirect_url(redirect): return reverse('redirect-view') + '?' + urllib.urlencode({'r': redirect})
def sad_redirect(request): # TODO: Remove this when the addon gets fixed and is pointing to # the correct urls. return HttpResponseRedirect(reverse('feedback') + '#sad')
def url(viewname, *args, **kwargs): """Helper for Django's ``reverse`` in templates.""" return reverse(viewname, args=args, kwargs=kwargs)
def build_redirect_url(redirect): return reverse("redirect-view") + "?" + urllib.urlencode({"r": redirect})
def _handle_feedback_post(request, locale=None, product=None, version=None, channel=None): """Saves feedback post to db accounting for throttling :arg request: request we're handling the post for :arg locale: locale specified in the url :arg product: None or the Product :arg version: validated and sanitized version specified in the url :arg channel: validated and sanitized channel specified in the url """ if getattr(request, 'limited', False): # If we're throttled, then return the thanks page, but don't # add the response to the db. return HttpResponseRedirect(reverse('thanks')) # Get the form and run is_valid() so it goes through the # validation and cleaning machinery. We don't really care if it's # valid, though, since we will take what we got and do the best we # can with it. Error validation is now in JS. form = ResponseForm(request.POST) form.is_valid() get_data = request.GET.copy() data = form.cleaned_data description = data.get('description', u'').strip() if not description: # If there's no description, then there's nothing to do here, # so thank the user and move on. return HttpResponseRedirect(reverse('thanks')) opinion = models.Response( # Data coming from the user happy=data['happy'], url=clean_url(data.get('url', u'').strip()), description=description, # Pulled from the form data or the url locale=data.get('locale', locale), # Data from mobile devices which is probably only # applicable to mobile devices manufacturer=data.get('manufacturer', ''), device=data.get('device', ''), ) # Add user_agent and inferred data. user_agent = request.META.get('HTTP_USER_AGENT', '') if user_agent: browser = request.BROWSER opinion.user_agent = user_agent opinion.browser = browser.browser opinion.browser_version = browser.browser_version opinion.browser_platform = browser.platform if browser.platform == 'Windows': opinion.browser_platform += ' ' + browser.platform_version # source is src or utm_source source = (get_data.pop('src', [u''])[0] or get_data.pop('utm_source', [u''])[0]) if source: opinion.source = source[:100] campaign = get_data.pop('utm_campaign', [u''])[0] if campaign: opinion.campaign = campaign[:100] platform = u'' if product: # If we have a product at this point, then it came from the # url and it's a Product instance and we need to turn it into # the product.db_name which is a string. product_db_name = product.db_name else: # Check the POST data for the product. product_db_name = data.get('product', '') # For the version, we try the url data, then the POST data. version = version or data.get('version', '') # At this point, we have a bunch of values, but we might be # missing some values, too. We're going to cautiously infer data # from the user agent where we're very confident it's appropriate # to do so. if request.BROWSER != UNKNOWN: # If we don't have a product, try to infer that from the user # agent information. if not product_db_name: product_db_name = models.Response.infer_product(request.BROWSER) # If we have a product and it matches the user agent browser, # then we can infer the version and platform from the user # agent if they're missing. if product_db_name: product = models.Product.objects.get(db_name=product_db_name) if product.browser and product.browser == request.BROWSER.browser: if not version: version = request.BROWSER.browser_version if not platform: platform = models.Response.infer_platform( product_db_name, request.BROWSER) # Make sure values are at least empty strings--no Nones. opinion.product = product_db_name or u'' opinion.version = version or u'' opinion.channel = channel or u'' opinion.platform = platform or u'' opinion.save() # If there was an email address, save that separately. if data.get('email_ok') and data.get('email'): e = models.ResponseEmail(email=data['email'], opinion=opinion) e.save() statsd.incr('feedback.emaildata.optin') # If there's browser data, save that separately. if data.get('browser_ok'): # This comes in as a JSON string. Because we're using # JSONObjectField, we need to convert it back to Python and # then save it. This is kind of silly, but it does guarantee # we have valid JSON. try: browser_data = data['browser_data'] browser_data = json.loads(browser_data) except ValueError: # Handles empty string and any non-JSON value. statsd.incr('feedback.browserdata.badvalue') except KeyError: # Handles the case where it's missing from the data # dict. If it's missing, we don't want to do anything # including metrics. pass else: # If browser_data isn't an empty dict, then save it. if browser_data: rti = models.ResponsePI(data=browser_data, opinion=opinion) rti.save() statsd.incr('feedback.browserdata.optin') if get_data: # There was extra context in the query string, so we grab that # with some restrictions and save it separately. slop = {} # We capture at most the first 20 key/val pairs get_data_items = sorted(get_data.items())[:20] for key, val in get_data_items: # Keys can be at most 20 characters long. key = key[:20] if len(val) == 1: val = val[0] # Values can be at most 20 characters long. val = val[:100] slop[key.encode('utf-8')] = val.encode('utf-8') context = models.ResponseContext(data=slop, opinion=opinion) context.save() statsd.incr('feedback.contextdata.optin') if data['happy']: statsd.incr('feedback.happy') else: statsd.incr('feedback.sad') request.session['opinion_id'] = opinion.id return HttpResponseRedirect(reverse('thanks'))
def happy_redirect(request): # TODO: Remove this when the addon gets fixed and is pointing to # the correct urls. return HttpResponseRedirect(reverse("feedback") + "#happy")
def test_locale(self): # Note: This depends on the 'about' view and the 'es' # locale. If we change those, then it breaks this test. eq_(reverse('about-view', locale='es'), '/es/about')
def _handle_feedback_post(request, locale=None, product=None, version=None, channel=None): """Saves feedback post to db accounting for throttling :arg request: request we're handling the post for :arg locale: locale specified in the url :arg product: validated and sanitized product slug specified in the url :arg version: validated and sanitized version specified in the url :arg channel: validated and sanitized channel specified in the url """ if getattr(request, 'limited', False): # If we're throttled, then return the thanks page, but don't # add the response to the db. return HttpResponseRedirect(reverse('thanks')) # Get the form and run is_valid() so it goes through the # validation and cleaning machinery. We don't really care if it's # valid, though, since we will take what we got and do the best we # can with it. Error validation is now in JS. form = ResponseForm(request.POST) form.is_valid() get_data = request.GET.copy() data = form.cleaned_data description = data.get('description', u'').strip() if not description: # If there's no description, then there's nothing to do here, # so thank the user and move on. return HttpResponseRedirect(reverse('thanks')) # Do some data validation of product, channel and version # coming from the url. if product: # If there was a product in the url, that's a product slug, so # we map it to a db_name which is what we want to save to the # db. product = models.Product.get_product_map()[product] # src, then source, then utm_source source = get_data.pop('src', [u''])[0] if not source: source = get_data.pop('utm_source', [u''])[0] campaign = get_data.pop('utm_campaign', [u''])[0] # If the product came in on the url, then we only want to populate # the platfrom from the user agent data iff the product specified # by the url is the same as the browser product. platform = u'' if product is None or product == request.BROWSER.browser: # Most platforms aren't different enough between versions to care. # Windows is. platform = request.BROWSER.platform if platform == 'Windows': platform += ' ' + request.BROWSER.platform_version product = product or u'' opinion = models.Response( # Data coming from the user happy=data['happy'], url=clean_url(data.get('url', u'')), description=data['description'].strip(), # Inferred data from user agent user_agent=request.META.get('HTTP_USER_AGENT', ''), browser=request.BROWSER.browser, browser_version=request.BROWSER.browser_version, platform=platform, # Pulled from the form data or the url locale=data.get('locale', locale), # Data from mobile devices which is probably only # applicable to mobile devices manufacturer=data.get('manufacturer', ''), device=data.get('device', ''), ) if source: opinion.source = source[:100] if campaign: opinion.campaign = campaign[:100] if product: # If we picked up the product from the url, we use url # bits for everything. product = product or u'' version = version or u'' channel = channel or u'' elif opinion.browser != UNKNOWN: # If we didn't pick up a product from the url, then we # infer as much as we can from the user agent. product = data.get( 'product', models.Response.infer_product(platform)) version = data.get( 'version', request.BROWSER.browser_version) # Assume everything we don't know about is stable channel. channel = u'stable' else: product = channel = version = u'' opinion.product = product or u'' opinion.version = version or u'' opinion.channel = channel or u'' opinion.save() # If there was an email address, save that separately. if data.get('email_ok') and data.get('email'): e = models.ResponseEmail(email=data['email'], opinion=opinion) e.save() if get_data: # There was extra context in the query string, so we grab that # with some restrictions and save it separately. slop = {} # We capture at most the first 20 key/val pairs get_data_items = sorted(get_data.items())[:20] for key, val in get_data_items: # Keys can be at most 20 characters long. key = key[:20] if len(val) == 1: val = val[0] # Values can be at most 20 characters long. val = val[:100] slop[key.encode('utf-8')] = val.encode('utf-8') context = models.ResponseContext(data=slop, opinion=opinion) context.save() if data['happy']: statsd.incr('feedback.happy') else: statsd.incr('feedback.sad') return HttpResponseRedirect(reverse('thanks'))
def happy_redirect(request): """Support older redirects from Input v1 era""" return HttpResponseRedirect(reverse('feedback') + '?happy=1')
def _handle_feedback_post(request, locale=None, product=None, version=None, channel=None): """Saves feedback post to db accounting for throttling :arg request: request we're handling the post for :arg locale: locale specified in the url :arg product: None or the Product :arg version: validated and sanitized version specified in the url :arg channel: validated and sanitized channel specified in the url """ if getattr(request, 'limited', False): # If we're throttled, then return the thanks page, but don't # add the response to the db. return HttpResponseRedirect(reverse('thanks')) # Get the form and run is_valid() so it goes through the # validation and cleaning machinery. We don't really care if it's # valid, though, since we will take what we got and do the best we # can with it. Error validation is now in JS. form = ResponseForm(request.POST) form.is_valid() get_data = request.GET.copy() data = form.cleaned_data description = data.get('description', u'').strip() if not description: # If there's no description, then there's nothing to do here, # so thank the user and move on. return HttpResponseRedirect(reverse('thanks')) opinion = models.Response( # Data coming from the user happy=data['happy'], url=clean_url(data.get('url', u'')), description=description, # Pulled from the form data or the url locale=data.get('locale', locale), # Data from mobile devices which is probably only # applicable to mobile devices manufacturer=data.get('manufacturer', ''), device=data.get('device', ''), ) # Add user_agent and inferred data. user_agent = request.META.get('HTTP_USER_AGENT', '') if user_agent: browser = request.BROWSER opinion.user_agent = user_agent opinion.browser = browser.browser opinion.browser_version = browser.browser_version opinion.browser_platform = browser.platform if browser.platform == 'Windows': opinion.browser_platform += ' ' + browser.platform_version # source is src or utm_source source = ( get_data.pop('src', [u''])[0] or get_data.pop('utm_source', [u''])[0] ) if source: opinion.source = source[:100] campaign = get_data.pop('utm_campaign', [u''])[0] if campaign: opinion.campaign = campaign[:100] platform = u'' # Figure out product, version, channel and platform. We either get # them from the url, from the user_agent, or we don't set them at # all. if product: # If there was a product in the url, then we get a Product # instance as an argument and we want the db_name from that. product = product.db_name # FIXME: We should be able to "match" the product with the # user agent browser and if they're the same, then set # platform == browser_platform. However, it's tricky since # our "products" are "interesting". elif opinion.browser != UNKNOWN: # If we didn't pick up a product from the url, then we # infer as much as we can from the user agent. product = data.get( 'product', models.Response.infer_product(opinion.browser_platform)) version = data.get( 'version', request.BROWSER.browser_version) # Assume everything we don't know about is stable channel. channel = u'stable' # Try to infer the platform from the product. if product and not platform: platform = models.Response.infer_platform(product, request.BROWSER) opinion.product = product or u'' opinion.version = version or u'' opinion.channel = channel or u'' opinion.platform = platform or u'' opinion.save() # If there was an email address, save that separately. if data.get('email_ok') and data.get('email'): e = models.ResponseEmail(email=data['email'], opinion=opinion) e.save() if get_data: # There was extra context in the query string, so we grab that # with some restrictions and save it separately. slop = {} # We capture at most the first 20 key/val pairs get_data_items = sorted(get_data.items())[:20] for key, val in get_data_items: # Keys can be at most 20 characters long. key = key[:20] if len(val) == 1: val = val[0] # Values can be at most 20 characters long. val = val[:100] slop[key.encode('utf-8')] = val.encode('utf-8') context = models.ResponseContext(data=slop, opinion=opinion) context.save() if data['happy']: statsd.incr('feedback.happy') else: statsd.incr('feedback.sad') return HttpResponseRedirect(reverse('thanks'))
def test_no_locale(self): # Note: This depends on the 'about' view. If we change that, # then it breaks this test. But it seems silly to do a bunch # of work to set up a better less fragile test plus it's # unlikely we'll change the 'about' view. assert reverse('about-view') == '/en-US/about'
def test_no_locale(self): # Note: This depends on the 'about' view. If we change that, # then it breaks this test. But it seems silly to do a bunch # of work to set up a better less fragile test plus it's # unlikely we'll change the 'about' view. eq_(reverse('about-view'), '/en-US/about')
def happy_redirect(request): """Support older redirects from Input v1 era""" return HttpResponseRedirect(reverse('picker') + '?happy=1')