def signup(request, *args, **kwargs): place = url_to_place(*args, **kwargs) manager = get_schema_manager(request) if isinstance(place, Block): FormClass, type_code = BlockAlertForm, 'b' else: FormClass, type_code = LocationAlertForm, 'l' email_required = request.user.is_anonymous() if request.method == 'POST': form = FormClass(request.POST, email_required=email_required, request=request) if form.is_valid(): return finish_signup(request, place, form.cleaned_data) else: schema_list = manager.filter(is_special_report=False).order_by('plural_name') schema_ids = [s.id for s in schema_list] form = FormClass( initial={ 'email': 'Enter your e-mail address', 'radius': block_radius_value(request)[1], 'frequency': '1', 'include_new_schemas': True, 'selected_schemas': schema_ids, 'displayed_schemas': schema_ids, }, email_required=email_required, request=request) context = get_place_info_for_request(request, *args, **kwargs) context['map_configuration'] = _preconfigured_map(context); context['form'] = form #context['schema_list'] = schema_list return eb_render(request, 'alerts/signup_form.html', context)
def update_from_query_params(self, request): """ Update the filters based on query parameters. After this is called, it's recommended to redirect to a normalized form of the URL, eg. self.sort(); self.make_url() This takes care to preserve query parameters that aren't used by any of the NewsitemFilters. """ # Make a mutable copy so we can leave only the params that FilterChain # doesn't know about. params = request.GET.copy() def pop_key(key): # request.GET.pop() returns a sequence. # We only want a single value, stripped. val = params.pop(key, [''])[0] return val.strip() address = pop_key('address') if address: xy_radius, block_radius, cookies_to_set = block_radius_value(request) params.pop('radius', None) result = None try: result = SmartGeocoder().geocode(address) except AmbiguousResult, e: raise BadAddressException(address, block_radius, address_choices=e.choices) except (GeocodingException, ParsingError): raise BadAddressException(address, block_radius, address_choices=())
def update_from_request(self, filter_sf_dict): """Update the list of filters based on the request params. After this is called, it's recommended to redirect to a normalized form of the URL, which you can get via self.sort(); self.make_url() ``filter_sf_dict`` is a mapping of name -> SchemaField which have either is_filter or is_searchable True. We remove SchemaFields that we create filters for. (This is so that templates can display input widgets for the ones we're not already filtering by.) TODO: This should not bail out on the first error, it should do as much as possible and signal multiple errors. (Use the forms framework?) """ request, context = self.request, self.context qs = self.qs params = request.GET.copy() def pop_key(key, single=False): """ Pop the value(s) from params, treat it as a comma-separated list of values, and split that into a list. So ?foo=bar,baz is equivalent to ?foo=bar&foo=baz. If single==True, return only the first one; in the example we'd return 'bar'. Otherwise, by default, return the list; in the example we'd return ['bar', 'baz'] """ result = [] # Doesn't seem to be a way to get a list of values *and* # remove it in one call; so use both getlist() and pop(). values = params.getlist(key) or [u''] params.pop(key, None) for value in values: value = value.replace(u'+', u' ') # XXX does django do this already? values = [s.strip() for s in value.split(u',')] result.extend(values) result = [r for r in result if r] if single: return result[0] if result else u'' return result # Address. address = pop_key('address', single=True) if address: xy_radius, block_radius, cookies_to_set = block_radius_value(request) pop_key('radius') # Just to remove it, block_radius_value() used it. result = None try: result = SmartGeocoder().geocode(address) except AmbiguousResult, e: raise BadAddressException(address, block_radius, address_choices=e.choices) except (GeocodingException, ParsingError): raise BadAddressException(address, block_radius, address_choices=())
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if 'block' not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()['multiple_cities']: self.city_slug = args.pop(0) else: self.city_slug = '' self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError( "not enough args, need a street and a block range") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError('bad radius %r' % block_radius) except IndexError: self.block_radius = context.get('block_radius') if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value( request) radius_param = urllib.quote(',' + radius_slug(block_radius)) radius_url = request.get_full_path() + radius_param raise FilterError('missing radius', url=radius_url) if 'block' in kwargs: # needs block_radius to already be there. self._update_block(kwargs['block']) if self.location_object is not None: block = self.location_object else: m = re.search('^%s$' % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError('Invalid block URL: %r' % self.block_range) url_to_block_args = m.groups() block = url_to_block(self.city_slug, self.street_slug, *url_to_block_args) self._update_block(block) self._got_args = True
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if 'block' not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()['multiple_cities']: self.city_slug = args.pop(0) else: self.city_slug = '' self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError("not enough args") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError('bad radius %r' % block_radius) except IndexError: self.block_radius = context.get('block_radius') if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value(request) radius_url = u'%s,%s/' % (request.path.rstrip('/'), radius_slug(block_radius)) raise FilterError('missing radius', url=radius_url) if 'block' in kwargs: # needs block_radius to already be there. self._update_block(kwargs['block']) m = re.search('^%s$' % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError('Invalid block URL: %r' % self.block_range) self.url_to_block_args = m.groups() self._got_args = True if self.location_object is not None: block = self.location_object else: block = url_to_block(self.city_slug, self.street_slug, *self.url_to_block_args) self._update_block(block)
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if "block" not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()["multiple_cities"]: self.city_slug = args.pop(0) else: self.city_slug = "" self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError("not enough args, need a street and a block range") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError("bad radius %r" % block_radius) except IndexError: self.block_radius = context.get("block_radius") if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value(request) radius_param = urllib.quote("," + radius_slug(block_radius)) radius_url = request.get_full_path() + radius_param raise FilterError("missing radius", url=radius_url) if "block" in kwargs: # needs block_radius to already be there. self._update_block(kwargs["block"]) if self.location_object is not None: block = self.location_object else: m = re.search("^%s$" % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError("Invalid block URL: %r" % self.block_range) url_to_block_args = m.groups() block = url_to_block(self.city_slug, self.street_slug, *url_to_block_args) self._update_block(block) self._got_args = True
def update_from_query_params(self, request): """ Update the filters based on query parameters. After this is called, it's recommended to redirect to a normalized form of the URL, eg. self.sort(); self.make_url() This takes care to preserve query parameters that aren't used by any of the NewsitemFilters. """ # Make a mutable copy so we can leave only the params that FilterChain # doesn't know about. params = request.GET.copy() def pop_key(key): # request.GET.pop() returns a sequence. # We only want a single value, stripped. val = params.pop(key, [''])[0] return val.strip() address = pop_key('address') if address: xy_radius, block_radius, cookies_to_set = block_radius_value( request) params.pop('radius', None) result = None try: result = SmartGeocoder().geocode(address) except AmbiguousResult, e: raise BadAddressException(address, block_radius, address_choices=e.choices) except (GeocodingException, ParsingError): raise BadAddressException(address, block_radius, address_choices=())
def update_from_request(self, filter_sf_dict): """Update the list of filters based on the request params. After this is called, it's recommended to redirect to a normalized form of the URL, which you can get via self.sort(); self.make_url() ``filter_sf_dict`` is a mapping of name -> SchemaField which have either is_filter or is_searchable True. We remove SchemaFields that we create filters for. (This is so that templates can display input widgets for the ones we're not already filtering by.) TODO: This should not bail out on the first error, it should do as much as possible and signal multiple errors. (Use the forms framework?) """ request, context = self.request, self.context qs = self.qs params = request.GET.copy() def pop_key(key, single=False): """ Pop the value(s) from params, treat it as a comma-separated list of values, and split that into a list. So ?foo=bar,baz is equivalent to ?foo=bar&foo=baz. If single==True, return only the first one; in the example we'd return 'bar'. Otherwise, by default, return the list; in the example we'd return ['bar', 'baz'] """ result = [] # Doesn't seem to be a way to get a list of values *and* # remove it in one call; so use both getlist() and pop(). values = params.getlist(key) or [u''] params.pop(key, None) for value in values: value = value.replace(u'+', u' ') # XXX does django do this already? values = [s.strip() for s in value.split(u',')] result.extend(values) result = [r for r in result if r] if single: return result[0] if result else u'' return result # IDs. ids = pop_key('id', single=False) if ids: self.replace('id', *ids) # Address. address = pop_key('address', single=True) if address: xy_radius, block_radius, cookies_to_set = block_radius_value( request) pop_key( 'radius') # Just to remove it, block_radius_value() used it. result = None try: result = SmartGeocoder().geocode(address) except AmbiguousResult, e: raise BadAddressException(address, block_radius, address_choices=e.choices) except (GeocodingException, ParsingError): raise BadAddressException(address, block_radius, address_choices=())