def email_for_subscription(alert, start_date, frequency): """ Returns a (place_name, text, html) tuple for the given EmailAlert object and date. """ start_datetime = datetime.datetime(start_date.year, start_date.month, start_date.day) yesterday = datetime.date.today() - datetime.timedelta(days=1) end_datetime = datetime.datetime.combine(yesterday, datetime.time(23, 59, 59, 9999)) # the end of yesterday # Order by schema__id to group schemas together. qs = NewsItem.objects.select_related().filter(schema__is_public=True, pub_date__range=(start_datetime, end_datetime)).order_by('-schema__importance', 'schema__id') if alert.include_new_schemas: if alert.schemas: qs = qs.exclude(schema__id__in=alert.schemas.split(',')) else: if alert.schemas: qs = qs.filter(schema__id__in=alert.schemas.split(',')) if alert.block: place_name, place_url = alert.block.pretty_name, alert.block.url() place = alert.block search_buffer = make_search_buffer(alert.block.location.centroid, alert.radius) qs = qs.filter(location__bboverlaps=search_buffer) elif alert.location: place_name, place_url = alert.location.name, alert.location.url() place = alert.location qs = qs.filter(newsitemlocation__location__id=alert.location.id) ni_list = list(qs) if not ni_list: raise NoNews schemas_used = set([ni.schema for ni in ni_list]) populate_attributes_if_needed(ni_list, list(schemas_used)) text, html = email_text_for_place(alert, place, place_name, place_url, ni_list, start_date, frequency) return place_name, text, html
def test_populate_attributes_if_needed(self): from ebpub.db.models import NewsItem item = NewsItem.objects.get(title='crime title 1') ni_list = [item] # It's lazy - but just checking length is enough to trigger # attribute population. self.assert_(len(item.attributes) > 1) from ebpub.db.utils import populate_attributes_if_needed schema_list = list(set((ni.schema for ni in ni_list))) populate_attributes_if_needed(ni_list, schema_list) self.assert_(len(item.attributes) > 1) self.assertEqual(item.attributes['arrests'], False) self.assertEqual(item.attributes['case_number'], 'case number 1') # Get another reference to the same NewsItem and verify that # prepopulation and laziness give all the same results. ni2 = NewsItem.objects.get(title='crime title 1') self.failIf(item is ni2) ni2.attributes['beat'] # Triggers loading. for key, val in item.attributes.items(): # ... well, mostly the same. # populate_attributes_if_needed() dereferences Lookups, # which lazy attribute lookup doesn't yet. This is crazy, # but AttributesForTemplate handles both cases. from ebpub.db.models import Lookup if isinstance(val, Lookup): self.assertEqual(val.id, ni2.attributes[key]) elif isinstance(val, list) and isinstance(val[0], Lookup): self.assertEqual(','.join([str(v.id) for v in val]), ni2.attributes[key]) else: self.assertEqual(val, ni2.attributes[key])
def render(self, context): schema_id = self.schema_id_variable.resolve(context) if hasattr(schema_id, 'id'): # It could be a Schema. schema_kwargs = {'schema__id': schema_id.id} elif isinstance(schema_id, basestring): # It could be a slug. schema_kwargs = {'schema__slug': schema_id} else: schema_kwargs = {'schema__id': schema_id} att_value = self.att_value_variable.resolve(context) sf = SchemaField.objects.select_related().get(name=self.att_name, **schema_kwargs) queryset = NewsItem.objects.select_related().filter(**schema_kwargs) if self.newsitem_id_variable is not None: newsitem_id = self.newsitem_id_variable.resolve(context) if hasattr(newsitem_id, 'id'): # It could be a NewsItem. newsitem_id = newsitem_id.id queryset = queryset.exclude(id=newsitem_id) queryset = queryset.by_attribute(sf, att_value).order_by('-item_date') populate_attributes_if_needed(queryset, [sf.schema]) # We're assigning directly to context.dicts[-1] so that the variable # gets set in the top-most context in the context stack. If we didn't # do this, the variable would only be available within the specific # {% block %} from which the template tag was called, because the # {% block %} implementation does a context.push() and context.pop(). context.dicts[-1][self.context_var] = queryset return ''
def render(self, context): schema_id = self.schema_id_variable.resolve(context) if hasattr(schema_id, "id"): # It could be a Schema. schema_kwargs = {"schema__id": schema_id.id} elif isinstance(schema_id, basestring): # It could be a slug. schema_kwargs = {"schema__slug": schema_id} else: schema_kwargs = {"schema__id": schema_id} att_value = self.att_value_variable.resolve(context) sf = SchemaField.objects.select_related().get(name=self.att_name, **schema_kwargs) queryset = NewsItem.objects.select_related().filter(**schema_kwargs) if self.newsitem_id_variable is not None: newsitem_id = self.newsitem_id_variable.resolve(context) if hasattr(newsitem_id, "id"): # It could be a NewsItem. newsitem_id = newsitem_id.id queryset = queryset.exclude(id=newsitem_id) queryset = queryset.by_attribute(sf, att_value).order_by("-item_date") populate_attributes_if_needed(queryset, [sf.schema]) # We're assigning directly to context.dicts[-1] so that the variable # gets set in the top-most context in the context stack. If we didn't # do this, the variable would only be available within the specific # {% block %} from which the template tag was called, because the # {% block %} implementation does a context.push() and context.pop(). context.dicts[-1][self.context_var] = queryset return ""
def items(self, obj): # Note that items() returns "packed" tuples instead of objects. # This is necessary because we return NewsItems and blog entries, # plus different types of NewsItems (bunched vs. unbunched). # Limit the feed to all NewsItems published in the last four days. # We *do* include items from today in this query, but we'll filter # those later in this method so that only today's *uncollapsed* items # (schema.can_collapse=False) will be included in the feed. We don't # want today's *collapsed* items to be included, because more items # might be added to the database before the day is finished, and # that would result in the RSS item being updated multiple times, which # is annoying. today_value = today() start_date = today_value - datetime.timedelta(days=4) end_date = today_value # Note: The pub_date__lt=end_date+(1 day) ensures that we don't miss # stuff that has a pub_date of the afternoon of end_date. A straight # pub_date__range would miss those items. qs = NewsItem.objects.select_related().filter( schema__is_public=True, pub_date__gte=start_date, pub_date__lt=end_date + datetime.timedelta(days=1)).extra( select={ 'pub_date_date': 'date(db_newsitem.pub_date)' }).order_by('-pub_date_date', 'schema__id', 'id') # Filter out ignored schemas -- those whose slugs are specified in # the "ignore" query-string parameter. if 'ignore' in self.request.GET: schema_slugs = self.request.GET['ignore'].split(',') qs = qs.exclude(schema__slug__in=schema_slugs) # Filter wanted schemas -- those whose slugs are specified in the # "only" query-string parameter. if 'only' in self.request.GET: schema_slugs = self.request.GET['only'].split(',') qs = qs.filter(schema__slug__in=schema_slugs) block_radius = self.request.GET.get('radius', BLOCK_RADIUS_DEFAULT) if block_radius not in BLOCK_RADIUS_CHOICES: raise Http404('Invalid radius') ni_list = list(self.newsitems_for_obj(obj, qs, block_radius)) schema_list = list(set([ni.schema for ni in ni_list])) populate_attributes_if_needed(ni_list, schema_list) is_block = isinstance(obj, Block) # Note that this decorates the results by returning tuples instead of # NewsItems. This is necessary because we're bunching. for schema_group in bunch_by_date_and_schema(ni_list, today_value): schema = schema_group[0].schema if schema.can_collapse: yield ('newsitem', obj, schema, schema_group, is_block, block_radius) else: for newsitem in schema_group: yield ('newsitem', obj, schema, newsitem, is_block, block_radius)
def items(self, obj): # Note that items() returns "packed" tuples instead of objects. # This is necessary because we return NewsItems and blog entries, # plus different types of NewsItems (bunched vs. unbunched). # Limit the feed to all NewsItems published in the last four days. # We *do* include items from today in this query, but we'll filter # those later in this method so that only today's *uncollapsed* items # (schema.can_collapse=False) will be included in the feed. We don't # want today's *collapsed* items to be included, because more items # might be added to the database before the day is finished, and # that would result in the RSS item being updated multiple times, which # is annoying. # TODO: re-use ebpub.db.schemafilters for filtering here. # TODO: allow user control over date range today_value = today() start_date = today_value - datetime.timedelta(days=5) # Include future stuff, useful for events end_date = today_value + datetime.timedelta(days=5) qs = ( NewsItem.objects.select_related() .by_request(self.request) .filter(item_date__gte=start_date, item_date__lte=end_date) .order_by("-item_date", "schema__id", "id") ) # Filter out ignored schemas -- those whose slugs are specified in # the "ignore" query-string parameter. if "ignore" in self.request.GET: schema_slugs = self.request.GET["ignore"].split(",") qs = qs.exclude(schema__slug__in=schema_slugs) # Filter wanted schemas -- those whose slugs are specified in the # "only" query-string parameter. if "only" in self.request.GET: schema_slugs = self.request.GET["only"].split(",") qs = qs.filter(schema__slug__in=schema_slugs) block_radius = self.request.GET.get("radius", BLOCK_RADIUS_DEFAULT) if block_radius not in BLOCK_RADIUS_CHOICES: raise Http404("Invalid radius") ni_list = list(self.newsitems_for_obj(obj, qs, block_radius)) schema_list = list(set([ni.schema for ni in ni_list])) populate_attributes_if_needed(ni_list, schema_list) is_block = isinstance(obj, Block) # Note that this decorates the results by returning tuples instead of # NewsItems. This is necessary because we're bunching. for schema_group in bunch_by_date_and_schema(ni_list, today_value): schema = schema_group[0].schema if schema.can_collapse: yield ("newsitem", obj, schema, schema_group, is_block, block_radius) else: for newsitem in schema_group: yield ("newsitem", obj, schema, newsitem, is_block, block_radius)
def email_for_subscription(alert, start_date, frequency): """ Returns a (place_name, text, html) tuple for the given EmailAlert object and date. """ start_datetime = datetime.datetime(start_date.year, start_date.month, start_date.day) yesterday = datetime.date.today() - datetime.timedelta(days=1) end_datetime = datetime.datetime.combine(yesterday, datetime.time(23, 59, 59, 9999)) # the end of yesterday from ebpub.utils.view_utils import get_schema_manager_for_user manager = get_schema_manager_for_user(alert.user) allowed_schemas = manager.allowed_schema_ids() qs = NewsItem.objects.select_related().filter(schema__id__in=allowed_schemas) if alert.include_new_schemas: # We saved an opt-out list. if alert.schemas: qs = qs.exclude(schema__id__in=alert.schemas.split(',')) else: # We saved an opt-in list. if alert.schemas: qs = qs.filter(schema__id__in=alert.schemas.split(',')) if alert.block_center: place = alert._get_block() place_name, place_url = place.pretty_name, place.url() search_buffer = make_search_buffer(place.geom.centroid, alert.radius) qs = qs.filter(location__bboverlaps=search_buffer) elif alert.location: place_name, place_url = alert.location.name, alert.location.url() place = alert.location qs = qs.filter(newsitemlocation__location__id=alert.location.id) # Order by schema__id to group schemas together. news_qs = qs.filter(schema__is_event=False, pub_date__range=(start_datetime, end_datetime), ).order_by('-schema__importance', 'schema__id', '-item_date', '-id') events_qs = qs.filter(schema__is_event=True, pub_date__range=(start_datetime, end_datetime), ).order_by('-schema__importance', 'schema__id', 'item_date', 'id') news_list = list(news_qs) events_list = list(events_qs) if not (news_list or events_list): raise NoNews schemas_used = set([ni.schema for ni in news_list + events_list]) populate_attributes_if_needed(news_list, list(schemas_used)) populate_attributes_if_needed(events_list, list(schemas_used)) newsitem_groups = ({'title': 'Recent', 'newsitems': news_list}, {'title': 'Upcoming', 'newsitems': events_list}) text, html = email_text_for_place(alert, place, place_name, place_url, newsitem_groups, start_date, frequency) return place_name, text, html
def items(self, obj): # Note that items() returns "packed" tuples instead of objects. # This is necessary because we return NewsItems and blog entries, # plus different types of NewsItems (bunched vs. unbunched). # Limit the feed to all NewsItems published in the last four days. # We *do* include items from today in this query, but we'll filter # those later in this method so that only today's *uncollapsed* items # (schema.can_collapse=False) will be included in the feed. We don't # want today's *collapsed* items to be included, because more items # might be added to the database before the day is finished, and # that would result in the RSS item being updated multiple times, which # is annoying. today_value = today() start_date = today_value - datetime.timedelta(days=4) end_date = today_value # Note: The pub_date__lt=end_date+(1 day) ensures that we don't miss # stuff that has a pub_date of the afternoon of end_date. A straight # pub_date__range would miss those items. qs = NewsItem.objects.select_related().filter(schema__is_public=True, pub_date__gte=start_date, pub_date__lt=end_date+datetime.timedelta(days=1)).extra(select={'pub_date_date': 'date(db_newsitem.pub_date)'}).order_by('-pub_date_date', 'schema__id', 'id') # Filter out ignored schemas -- those whose slugs are specified in # the "ignore" query-string parameter. if 'ignore' in self.request.GET: schema_slugs = self.request.GET['ignore'].split(',') qs = qs.exclude(schema__slug__in=schema_slugs) # Filter wanted schemas -- those whose slugs are specified in the # "only" query-string parameter. if 'only' in self.request.GET: schema_slugs = self.request.GET['only'].split(',') qs = qs.filter(schema__slug__in=schema_slugs) block_radius = self.request.GET.get('radius', BLOCK_RADIUS_DEFAULT) if block_radius not in BLOCK_RADIUS_CHOICES: raise Http404('Invalid radius') ni_list = list(self.newsitems_for_obj(obj, qs, block_radius)) schema_list = list(set([ni.schema for ni in ni_list])) populate_attributes_if_needed(ni_list, schema_list) is_block = isinstance(obj, Block) # Note that this decorates the results by returning tuples instead of # NewsItems. This is necessary because we're bunching. for schema_group in bunch_by_date_and_schema(ni_list, today_value): schema = schema_group[0].schema if schema.can_collapse: yield ('newsitem', obj, schema, schema_group, is_block, block_radius) else: for newsitem in schema_group: yield ('newsitem', obj, schema, newsitem, is_block, block_radius)
def render(self, context): schema_id = self.schema_id_variable.resolve(context) newsitem_id = self.newsitem_id_variable.resolve(context) att_value = self.att_value_variable.resolve(context) sf = SchemaField.objects.select_related().get(schema__id=schema_id, name=self.att_name) ni_list = NewsItem.objects.select_related().filter(schema__id=schema_id).exclude(id=newsitem_id).by_attribute(sf, att_value).order_by('-item_date') populate_attributes_if_needed(ni_list, [sf.schema]) # We're assigning directly to context.dicts[-1] so that the variable # gets set in the top-most context in the context stack. If we didn't # do this, the variable would only be available within the specific # {% block %} from which the template tag was called, because the # {% block %} implementation does a context.push() and context.pop(). context.dicts[-1][self.context_var] = ni_list return ''
def schema_detail_special_report(request, schema): """ For display of schemas where is_special_report=True. """ ni_list = NewsItem.objects.filter(schema__id=schema.id) populate_schema(ni_list, schema) populate_attributes_if_needed(ni_list, [schema]) if schema.allow_charting: browsable_locationtype_list = LocationType.objects.filter(is_significant=True) schemafield_list = list(schema.schemafield_set.filter(is_filter=True).order_by('display_order')) else: browsable_locationtype_list = [] schemafield_list = [] templates_to_try = ('db/schema_detail/%s.html' % schema.slug, 'db/schema_detail_special_report.html') return eb_render(request, templates_to_try, { 'schema': schema, 'newsitem_list': ni_list, 'browsable_locationtype_list': browsable_locationtype_list, 'schemafield_list': schemafield_list, 'bodyclass': 'schema-detail-special-report', 'bodyid': schema.slug, })
def place_detail_timeline(request, *args, **kwargs): """ Recent news OR upcoming events for the given Location or Block. """ context, response = _place_detail_normalize_url(request, *args, **kwargs) if response is not None: return response show_upcoming = kwargs.get('show_upcoming') schema_manager = get_schema_manager(request) if show_upcoming: context['breadcrumbs'] = breadcrumbs.place_detail_upcoming(context) else: context['breadcrumbs'] = breadcrumbs.place_detail_timeline(context) is_latest_page = True # Check the query string for the max date to use. Otherwise, fall # back to today. end_date = today() if 'start' in request.GET: try: end_date = parse_date(request.GET['start'], '%m/%d/%Y') is_latest_page = False except ValueError: raise Http404('Invalid date %s' % request.GET['start']) filterchain = FilterChain(request=request, context=context) filterchain.add('location', context['place']) # As an optimization, limit the NewsItems to those on the # last (or next) few days. # And only fetch for relevant schemas - either event-ish or not. if show_upcoming: s_list = schema_manager.filter(is_event=True) start_date = end_date end_date = start_date + datetime.timedelta(days=settings.DEFAULT_DAYS) order_by = 'item_date_date' else: s_list = schema_manager.filter(is_event=False) start_date = end_date - datetime.timedelta(days=settings.DEFAULT_DAYS) order_by = '-item_date_date' filterchain.add('schema', list(s_list)) filterchain.add('date', start_date, end_date) newsitem_qs = filterchain.apply().select_related() # TODO: can this really only be done via extra()? newsitem_qs = newsitem_qs.extra( select={'item_date_date': 'date(db_newsitem.item_date)'}, order_by=(order_by, '-schema__importance', 'schema') )[:constants.NUM_NEWS_ITEMS_PLACE_DETAIL] # We're done filtering, so go ahead and do the query, to # avoid running it multiple times, # per http://docs.djangoproject.com/en/dev/topics/db/optimization ni_list = list(newsitem_qs) schemas_used = list(set([ni.schema for ni in ni_list])) s_list = s_list.filter(is_special_report=False, allow_charting=True).order_by('plural_name') populate_attributes_if_needed(ni_list, schemas_used) if ni_list: next_day = ni_list[-1].item_date - datetime.timedelta(days=1) else: next_day = None hidden_schema_list = [] if not request.user.is_anonymous(): hidden_schema_list = [o.schema for o in HiddenSchema.objects.filter(user_id=request.user.id)] context.update({ 'newsitem_list': ni_list, 'next_day': next_day, 'is_latest_page': is_latest_page, 'hidden_schema_list': hidden_schema_list, 'bodyclass': 'place-detail-timeline', 'bodyid': context.get('place_type') or '', 'filters': filterchain, 'show_upcoming': show_upcoming, }) context['filtered_schema_list'] = s_list context['map_configuration'] = _preconfigured_map(context); response = eb_render(request, 'db/place_detail.html', context) for k, v in context['cookies_to_set'].items(): response.set_cookie(k, v) return response
def schema_detail(request, slug): s = get_object_or_404(get_schema_manager(request), slug=slug) if s.is_special_report: return schema_detail_special_report(request, s) location_type_list = LocationType.objects.filter(is_significant=True).order_by('slug') if s.allow_charting: # For the date range, the end_date is the last non-future date # with at least one NewsItem. try: end_date = NewsItem.objects.filter(schema__id=s.id, item_date__lte=today()).values_list('item_date', flat=True).order_by('-item_date')[0] except IndexError: latest_dates = () date_chart = {} start_date = end_date = None else: start_date = end_date - constants.DAYS_AGGREGATE_TIMEDELTA date_chart = get_date_chart_agg_model([s], start_date, end_date, AggregateDay)[0] latest_dates = [date['date'] for date in date_chart['dates'] if date['count']] # Populate schemafield_list and lookup_list. schemafield_list = list(s.schemafield_set.filter(is_filter=True).order_by('display_order')) # XXX this duplicates part of schema_filter() LOOKUP_MIN_DISPLAYED = 7 LOOKUP_BUFFER = 4 lookup_list = [] for sf in schemafield_list: if not (sf.is_charted and sf.is_lookup): continue top_values = list(AggregateFieldLookup.objects.filter(schema_field__id=sf.id).select_related('lookup').order_by('-total')[:LOOKUP_MIN_DISPLAYED + LOOKUP_BUFFER]) if len(top_values) == LOOKUP_MIN_DISPLAYED + LOOKUP_BUFFER: top_values = top_values[:LOOKUP_MIN_DISPLAYED] has_more = True else: has_more = False lookup_list.append({'sf': sf, 'top_values': top_values, 'has_more': has_more}) location_chartfield_list = [] # Populate location_chartfield_list. for lt in location_type_list: # Collect the locations in the location_type here so we don't have # to query them again in the select_related() below. locations = dict([(loc.id, loc) for loc in lt.location_set.iterator()]) ni_totals = AggregateLocation.objects.filter( schema__id=s.id, location_type__id=lt.id, location__is_public=True).select_related('location').order_by('-total') if ni_totals: # This runs the query. known_count = reduce(operator.add, (n.total for n in ni_totals)) total_count = date_chart.get('total_count', 0) unknown_count = max(0, total_count - known_count) location_chartfield_list.append({'location_type': lt, 'locations': ni_totals[:9], 'unknown': unknown_count}) ni_list = () else: date_chart = {} latest_dates = schemafield_list = lookup_list = location_chartfield_list = () ni_list = list(NewsItem.objects.filter(schema__id=s.id).order_by('-item_date', '-id')[:30]) populate_schema(ni_list, s) populate_attributes_if_needed(ni_list, [s]) textsearch_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_searchable=True).order_by('display_order')) boolean_lookup_list = [sf for sf in SchemaField.objects.filter(schema__id=s.id, is_filter=True, is_lookup=False).order_by('display_order') if sf.is_type('bool')] templates_to_try = ('db/schema_detail/%s.html' % s.slug, 'db/schema_detail.html') # The HIDE_SCHEMA_INTRO_COOKIE_NAME cookie is a comma-separated list of # schema IDs for schemas whose intro text should *not* be displayed. hide_intro = str(s.id) in request.COOKIES.get(HIDE_SCHEMA_INTRO_COOKIE_NAME, '').split(',') context = { 'schema': s, 'schemafield_list': schemafield_list, 'location_type_list': location_type_list, 'date_chart': date_chart, 'lookup_list': lookup_list, 'location_chartfield_list': location_chartfield_list, 'boolean_lookup_list': boolean_lookup_list, 'search_list': textsearch_sf_list, 'newsitem_list': ni_list, 'latest_dates': latest_dates[-3:], 'hide_intro': hide_intro, 'hide_intro_cookie_name': HIDE_SCHEMA_INTRO_COOKIE_NAME, 'start_date': s.min_date, 'end_date': today(), 'bodyclass': 'schema-detail', 'bodyid': slug, 'filters': FilterChain(schema=s), } context['breadcrumbs'] = breadcrumbs.schema_detail(context) return eb_render(request, templates_to_try, context)
def place_detail_overview(request, *args, **kwargs): context, response = _place_detail_normalize_url(request, *args, **kwargs) if response is not None: return response schema_manager = get_schema_manager(request) context['breadcrumbs'] = breadcrumbs.place_detail_overview(context) schema_list = SortedDict([(s.id, s) for s in schema_manager.filter(is_special_report=False).order_by('plural_name')]) # needed = set(schema_list.keys()) # We actually want two lists of schemas, since we care whether # they are news-like or future-event-like. import copy eventish_schema_list = copy.deepcopy(schema_list) newsish_schema_list = copy.deepcopy(schema_list) for s_id, schema in schema_list.items(): if schema.is_event: del(newsish_schema_list[s_id]) else: del(eventish_schema_list[s_id]) filterchain = FilterChain(request=request, context=context) filterchain.add('location', context['place']) # Distinguish between past news and upcoming events. # With some preliminary date limiting too. filterchain_news = filterchain.copy() filterchain_news.add('date', today() - datetime.timedelta(days=90), today()) filterchain_events = filterchain.copy() filterchain_events.add('date', today(), today() + datetime.timedelta(days=60)) # Ordering by ID ensures consistency across page views. newsitem_qs = filterchain_news.apply().order_by('-item_date', '-id') events_qs = filterchain_events.apply().order_by('item_date', 'id') # Mapping of schema id -> [schemafields], for building Lookup charts. sf_dict = {} charted_lookups = SchemaField.objects.filter( is_lookup=True, is_charted=True, schema__is_public=True, schema__is_special_report=False) charted_lookups = charted_lookups.values('id', 'schema_id', 'pretty_name') for sf in charted_lookups.order_by('schema__id', 'display_order'): sf_dict.setdefault(sf['schema_id'], []).append(sf) # Now retrieve newsitems per schema. schema_groups, all_newsitems = [], [] for schema in schema_list.values(): if schema.id in newsish_schema_list: newsitems = newsitem_qs.filter(schema__id=schema.id) elif schema.id in eventish_schema_list: newsitems = events_qs.filter(schema__id=schema.id) else: raise RuntimeError("should never get here") newsitems = list(newsitems[:s.number_in_overview]) populate_schema(newsitems, schema) schema_groups.append({ 'schema': schema, 'latest_newsitems': newsitems, 'has_newsitems': bool(newsitems), 'lookup_charts': sf_dict.get(schema.id), }) all_newsitems.extend(newsitems) schema_list = schema_list.values() populate_attributes_if_needed(all_newsitems, schema_list) schema_list = [s for s in schema_list if s.allow_charting] context['schema_groups'] = schema_groups context['filtered_schema_list'] = schema_list context['bodyclass'] = 'place-detail-overview' if context['is_block']: context['bodyid'] = '%s-%s-%s' % (context['place'].street_slug, context['place'].number(), context['place'].dir_url_bit()) else: context['bodyid'] = context['location'].slug response = eb_render(request, 'db/place_overview.html', context) for k, v in context['cookies_to_set'].items(): response.set_cookie(k, v) return response
idx_start = (page - 1) * constants.FILTER_PER_PAGE idx_end = page * constants.FILTER_PER_PAGE # Get one extra, so we can tell whether there's a next page. ni_list = list(qs[idx_start:idx_end+1]) if page > 1 and not ni_list: raise Http404('No objects on page %s' % page) if len(ni_list) > constants.FILTER_PER_PAGE: has_next = True ni_list = ni_list[:-1] else: has_next = False idx_end = idx_start + len(ni_list) has_previous = page > 1 populate_schema(ni_list, s) populate_attributes_if_needed(ni_list, [s]) # Need map parameters based on location/block, if there is one. loc_filter = filterchain.get('location') if loc_filter: context.update(get_place_info_for_request( request, place=loc_filter.location_object, block_radius=getattr(loc_filter, 'block_radius', None))) else: # Whole city map. context.update({ 'default_lon': settings.DEFAULT_MAP_CENTER_LON, 'default_lat': settings.DEFAULT_MAP_CENTER_LAT, 'default_zoom': settings.DEFAULT_MAP_ZOOM, })