Exemplo n.º 1
0
def bigmap_filter(request, slug):

    s = get_object_or_404(get_schema_manager(request), slug=slug, is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_dict = _get_filter_schemafields(s)

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(filter_sf_dict)
        filters_need_more = filterchain.validate()
    except:
        logger.exception("Unhandled error")
        return HttpResponse(status=404)

    config = _decode_map_permalink(request, show_default_layers=False, filters=filterchain)

    new_url = filterchain.make_url(base_url=reverse("bigmap_filter", args=(slug,)))
    if new_url != request.get_full_path():
        return HttpResponseRedirect(new_url)

    # add in the filter layer
    base_url = reverse("ebpub-schema-filter-geojson", args=(slug,))
    layer_url = filterchain.make_url(base_url=base_url)
    custom_layer = {"url": layer_url, "params": {}, "title": "Custom Filter", "visible": True}
    config["layers"].append(custom_layer)

    if config["is_widget"]:
        return eb_render(request, "richmaps/embed_bigmap.html", {"map_config": simplejson.dumps(config, indent=2)})
    else:
        return eb_render(request, "richmaps/bigmap.html", {"map_config": simplejson.dumps(config, indent=2)})
Exemplo n.º 2
0
def dashboard(request):
    """
    The user's account settings, saved places, alerts, and other
    personalized stuff.
    """
    custom_message = request.session.get('login_message')
    if 'login_message' in request.session:
        del request.session['login_message']

    alert_list = EmailAlert.active_objects.filter(user_id=request.user.id)
    saved_place_list = SavedPlace.objects.filter(user_id=request.user.id)
    hidden_schema_ids = HiddenSchema.objects.filter(
        user_id=request.user.id).values('schema_id')
    hidden_schema_ids = set([x['schema_id'] for x in hidden_schema_ids])

    schema_list = []
    manager = get_schema_manager(request)
    for schema in manager.filter(
            is_special_report=False).order_by('plural_name'):
        schema_list.append({
            'schema': schema,
            'is_hidden': schema.id in hidden_schema_ids
        })
    from ebpub.neighbornews.utils import is_neighbornews_enabled
    return eb_render(
        request, 'accounts/dashboard.html', {
            'custom_message': custom_message,
            'user': request.user,
            'alert_list': alert_list,
            'saved_place_list': saved_place_list,
            'schema_list': schema_list,
            'is_neighbornews_enabled': is_neighbornews_enabled,
        })
Exemplo n.º 3
0
def dashboard(request):
    """
    The user's account settings, saved places, alerts, and other
    personalized stuff.
    """
    custom_message = request.session.get('login_message')
    if 'login_message' in request.session:
        del request.session['login_message']

    alert_list = EmailAlert.active_objects.filter(user_id=request.user.id)
    saved_place_list = SavedPlace.objects.filter(user_id=request.user.id)
    hidden_schema_ids = HiddenSchema.objects.filter(user_id=request.user.id).values('schema_id')
    hidden_schema_ids = set([x['schema_id'] for x in hidden_schema_ids])

    schema_list = []
    manager = get_schema_manager(request)
    for schema in manager.filter(is_special_report=False).order_by('plural_name'):
        schema_list.append({'schema': schema, 'is_hidden': schema.id in hidden_schema_ids})
    from ebpub.neighbornews.utils import is_neighbornews_enabled
    return eb_render(request, 'accounts/dashboard.html', {
        'custom_message': custom_message,
        'user': request.user,
        'alert_list': alert_list,
        'saved_place_list': saved_place_list,
        'schema_list': schema_list,
        'is_neighbornews_enabled': is_neighbornews_enabled,

    })
Exemplo n.º 4
0
def schema_filter(request, slug, args_from_url):
    """
    List NewsItems for one schema, filtered by various criteria in the
    URL (date, location, or values of SchemaFields).
    """
    s = get_object_or_404(get_schema_manager(request), slug=slug, is_special_report=False)
    if not s.allow_charting:
        return HttpResponsePermanentRedirect(s.url())

    context = {
        'bodyclass': 'schema-filter',
        'bodyid': s.slug,
        'schema': s,
        }
    # Breadcrumbs. We can assign this early because it's a generator,
    # so it'll get the full context no matter what.
    context['breadcrumbs'] = breadcrumbs.schema_filter(context)

    filter_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_filter=True).order_by('display_order'))
    textsearch_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_searchable=True).order_by('display_order'))

    # Use SortedDict to preserve the display_order.
    filter_sf_dict = SortedDict([(sf.name, sf) for sf in filter_sf_list] + [(sf.name, sf) for sf in textsearch_sf_list])

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, context=context, schema=s)
    context['filters'] = filterchain
    try:
        filterchain.update_from_request(args_from_url, filter_sf_dict)
        filters_need_more = filterchain.validate()
    except FilterError, e:
        if getattr(e, 'url', None) is not None:
            return HttpResponseRedirect(e.url)
        raise Http404(str(e))
Exemplo n.º 5
0
def list_types_json(request):
    """
    List the known NewsItem types (Schemas).
    """
    schemas = {}
    for schema in get_schema_manager(request).all():
        attributes = {}
        for sf in schema.schemafield_set.all():
            fieldtype = get_datatype(sf)
            attributes[sf.name] = {
                'pretty_name': sf.smart_pretty_name(),
                'type': fieldtype,
                # TODO: what else?
                }
            # TODO: should we enumerate known values of Lookups?
        schemas[schema.slug] = {
                'indefinite_article': schema.indefinite_article,
                'last_updated': schema.last_updated.strftime('%Y-%m-%d'),
                'name': schema.name,
                'plural_name': schema.plural_name,
                'slug': schema.slug,
                'attributes': attributes,
                }

    return APIGETResponse(request, simplejson.dumps(schemas, indent=1),
                          content_type=JSON_CONTENT_TYPE)
Exemplo n.º 6
0
def list_types_json(request):
    """
    List the known NewsItem types (Schemas).
    """
    schemas = {}
    for schema in get_schema_manager(request).all():
        attributes = {}
        for sf in schema.schemafield_set.all():
            fieldtype = get_datatype(sf)
            attributes[sf.name] = {
                'pretty_name': sf.smart_pretty_name(),
                'type': fieldtype,
                # TODO: what else?
            }
            # TODO: should we enumerate known values of Lookups?
        schemas[schema.slug] = {
            'indefinite_article': schema.indefinite_article,
            'last_updated': schema.last_updated.strftime('%Y-%m-%d'),
            'name': schema.name,
            'plural_name': schema.plural_name,
            'slug': schema.slug,
            'attributes': attributes,
        }

    return APIGETResponse(request,
                          simplejson.dumps(schemas, indent=1),
                          content_type=JSON_CONTENT_TYPE)
Exemplo n.º 7
0
def ajax_save_hidden_schema(request):
    """
    Creates a HiddenSchema for request.POST['schema'] and request.user.
    """
    if request.method != 'POST':
        raise http.Http404()
    if 'schema' not in request.POST:
        raise http.Http404('Missing schema')
    if request.user.is_anonymous():
        raise http.Http404('Not logged in')

    # Validate that the HiddenSchema hasn't already been created for this user,
    # to avoid duplicates.
    try:
        manager = get_schema_manager(request)
        schema = manager.get(slug=request.POST['schema'])
        sp = HiddenSchema.objects.get(user_id=request.user.id, schema=schema)
    except Schema.DoesNotExist:
        return http.HttpResponse('0') # Schema doesn't exist.
    except HiddenSchema.DoesNotExist:
        pass
    else:
        return http.HttpResponse('0') # Already exists.

    HiddenSchema.objects.create(user_id=request.user.id, schema=schema)
    return http.HttpResponse('1')
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
 def apply(self):
     schema_ids = [s.id for s in self.schemas]
     if self.request:
         allowed_schema_ids = get_schema_manager(
             self.request).allowed_schema_ids()
         schema_ids = set(schema_ids).intersection(allowed_schema_ids)
         self.qs = self.qs.filter(schema__id__in=schema_ids)
Exemplo n.º 10
0
 def apply(self):
     if isinstance(self.schema, list):
         schemas = self.schema
     else:
         schemas = [self.schema]
     schema_ids = [s.id for s in schemas]
     if self.request:
         allowed_schema_ids = get_schema_manager(self.request).allowed_schema_ids()
         schema_ids = set(schema_ids).intersection(allowed_schema_ids)
         self.qs = self.qs.filter(schema__id__in=schema_ids)
Exemplo n.º 11
0
def bigmap_filter(request, slug, args_from_url):

    s = get_object_or_404(get_schema_manager(request),
                          slug=slug,
                          is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_list = list(
        SchemaField.objects.filter(schema__id=s.id,
                                   is_filter=True).order_by('display_order'))
    textsearch_sf_list = list(
        SchemaField.objects.filter(
            schema__id=s.id, is_searchable=True).order_by('display_order'))

    # Use SortedDict to preserve the display_order.
    filter_sf_dict = SortedDict([(sf.name, sf) for sf in filter_sf_list] +
                                [(sf.name, sf) for sf in textsearch_sf_list])

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(args_from_url, filter_sf_dict)
        filters_need_more = filterchain.validate()
    except:
        return HttpResponse(status=404)

    config = _decode_map_permalink(request,
                                   show_default_layers=False,
                                   filters=filterchain)

    new_url = filterchain.make_url(
        base_url=reverse('bigmap_filter', args=(slug, )))
    if new_url != request.get_full_path():
        return HttpResponseRedirect(new_url)

    # add in the filter layer
    base_url = reverse('ebpub-schema-filter-geojson', args=(slug, ))
    layer_url = filterchain.make_url(base_url=base_url)
    custom_layer = {
        'url': layer_url,
        'params': {},
        'title': "Custom Filter",
        'visible': True
    }
    config['layers'].append(custom_layer)

    if config['is_widget']:
        return eb_render(request, 'richmaps/embed_bigmap.html',
                         {'map_config': simplejson.dumps(config, indent=2)})
    else:
        return eb_render(request, 'richmaps/bigmap.html',
                         {'map_config': simplejson.dumps(config, indent=2)})
Exemplo n.º 12
0
 def __init__(self, *args, **kwargs):
     self.email_required = kwargs.pop('email_required', True)
     request = kwargs.pop('request')
     forms.Form.__init__(self, *args, **kwargs)
     if self.email_required:
         f = forms.EmailField(widget=forms.TextInput(attrs={'id': 'emailinput', 'class': 'textinput placeholder'}))
         self.fields['email'] = f
     qs = get_schema_manager(request).all()
     self.fields['selected_schemas'] = SchemaMultipleChoiceField(
         widget=forms.CheckboxSelectMultiple, queryset=qs)
     self.fields['displayed_schemas'] = SchemaMultipleChoiceField(
         widget=forms.MultipleHiddenInput, queryset=qs)
Exemplo n.º 13
0
def bigmap_filter(request, slug, args_from_url):
    
    s = get_object_or_404(get_schema_manager(request), slug=slug, is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_filter=True).order_by('display_order'))
    textsearch_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_searchable=True).order_by('display_order'))

    # Use SortedDict to preserve the display_order.
    filter_sf_dict = SortedDict([(sf.name, sf) for sf in filter_sf_list] + [(sf.name, sf) for sf in textsearch_sf_list])

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(args_from_url, filter_sf_dict)
        filters_need_more = filterchain.validate()
    except:
        return HttpResponse(status=404)
        
    config = _decode_map_permalink(request, show_default_layers=False, filters=filterchain)

    new_url = filterchain.make_url(base_url=reverse('bigmap_filter', args=(slug,)))
    if new_url != request.get_full_path():
        return HttpResponseRedirect(new_url)    

    
    # add in the filter layer
    base_url = reverse('ebpub-schema-filter-geojson', args=(slug,))
    layer_url = filterchain.make_url(base_url=base_url)
    custom_layer = {
        'url': layer_url,
        'params': {},
        'title': "Custom Filter",
        'visible': True
    }
    config['layers'].append(custom_layer)



    if config['is_widget']: 
        return eb_render(request, 'richmaps/embed_bigmap.html', {
            'map_config': simplejson.dumps(config, indent=2)
        })
    else:         
        return eb_render(request, 'richmaps/bigmap.html', {
            'map_config': simplejson.dumps(config, indent=2)
        })
Exemplo n.º 14
0
def ajax_place_date_chart(request):
    """
    Returns HTML fragment containing a chart of how many news items
    were added for each day over a short period (length defined by
    constants.DAYS_SHORT_AGGREGATE_TIMEDELTA).

    Expects request.GET['pid'] and request.GET['s'] (a Schema ID).
    """
    manager = get_schema_manager(request)
    try:
        schema = manager.get(id=int(request.GET['s']))
    except (KeyError, ValueError, Schema.DoesNotExist):
        raise Http404('Invalid Schema')
    filters = FilterChain(request=request, schema=schema)
    filters.add_by_place_id(request.GET.get('pid', ''))
    qs = filters.apply()

    # These charts are used on eg. the place overview page; there,
    # they should be smaller than the ones on the schema_detail view;
    # we don't have room for a full 30 days.
    date_span = constants.DAYS_SHORT_AGGREGATE_TIMEDELTA
    if schema.is_event:
        # Soonest span that includes some.
        try:
            qs = qs.filter(item_date__gte=today()).order_by('item_date', 'id')
            first_item = qs.values('item_date')[0]
            start_date = first_item['item_date']
        except IndexError:  # No matching items.
            start_date = today()
        end_date = today() + date_span
    else:
        # Most recent span that includes some.
        try:
            qs = qs.filter(item_date__lte=today()).order_by('-item_date', '-id')
            last_item = qs.values('item_date')[0]
            end_date = last_item['item_date']
        except IndexError:  # No matching items.
            end_date = today()
        start_date = end_date - date_span

    filters.add('date', start_date, end_date)
    counts = filters.apply().date_counts()
    date_chart = get_date_chart([schema], start_date, end_date, {schema.id: counts})[0]
    return render_to_response('db/snippets/date_chart.html', {
        'schema': schema,
        'date_chart': date_chart,
        'filters': filters,
    })
Exemplo n.º 15
0
def schema_list(request):
    allowed_schemas = get_schema_manager(request).all()
    schema_list = allowed_schemas.select_related().filter(is_special_report=False).order_by('plural_name')
    schemafield_list = list(SchemaField.objects.filter(is_filter=True).order_by('display_order'))
    browsable_locationtype_list = LocationType.objects.filter(is_significant=True)
    # Populate s_list, which contains a schema and schemafield list for each schema.
    s_list = []
    for s in schema_list:
        s_list.append({
            'schema': s,
            'schemafield_list': [sf for sf in schemafield_list if sf.schema_id == s.id],
        })

    return eb_render(request, 'db/schema_list.html', {
        'schema_list': s_list,
        'browsable_locationtype_list': browsable_locationtype_list,
        'bodyclass': 'schema-list',
    })
Exemplo n.º 16
0
def homepage(request):
    """Front page of the default OpenBlock theme.
    """

    end_date = today()
    start_date = end_date - datetime.timedelta(days=settings.DEFAULT_DAYS)
    end_date += datetime.timedelta(days=1)

    manager = get_schema_manager(request)
    sparkline_schemas = list(manager.filter(allow_charting=True, is_special_report=False))

    # Order by slug to ensure case-insensitive ordering. (Kind of hackish.)
    lt_list = LocationType.objects.filter(is_significant=True).order_by('slug').extra(select={'count': 'select count(*) from db_location where is_public=True and location_type_id=db_locationtype.id'})
    street_count = Street.objects.count()
    more_schemas = manager.filter(allow_charting=False).order_by('name')

    # Get the public records.
    date_charts = get_date_chart_agg_model(sparkline_schemas, start_date, end_date, AggregateDay)
    empty_date_charts, non_empty_date_charts = [], []
    for chart in date_charts:
        if chart['total_count']:
            non_empty_date_charts.append(chart)
        else:
            empty_date_charts.append(chart)
    non_empty_date_charts.sort(lambda a, b: cmp(b['total_count'], a['total_count']))
    empty_date_charts.sort(lambda a, b: cmp(a['schema'].plural_name, b['schema'].plural_name))

    return eb_render(request, 'homepage.html', {
        'location_type_list': lt_list,
        'street_count': street_count,
        'more_schemas': more_schemas,
        'non_empty_date_charts': non_empty_date_charts,
        'empty_date_charts': empty_date_charts,
        'num_days': settings.DEFAULT_DAYS,
        'default_lon': settings.DEFAULT_MAP_CENTER_LON,
        'default_lat': settings.DEFAULT_MAP_CENTER_LAT,
        'default_zoom': settings.DEFAULT_MAP_ZOOM,
        'bodyclass': 'homepage',
        'breadcrumbs': breadcrumbs.home({}),
        'map_configuration': _preconfigured_map({})
    })
Exemplo n.º 17
0
def ajax_place_lookup_chart(request):
    """
    Returns HTML fragment -- expects request.GET['pid'] and request.GET['sf'] (a SchemaField ID).
    """
    allowed_schemas = get_schema_manager(request).allowed_schema_ids()
    try:
        sf = SchemaField.objects.select_related().get(id=int(request.GET['sf']),
                                                      schema__id__in=allowed_schemas)
    except (KeyError, ValueError, SchemaField.DoesNotExist):
        raise Http404('Invalid SchemaField')
    filters = FilterChain(request=request, schema=sf.schema)
    filters.add_by_place_id(request.GET.get('pid', ''))
    qs = filters.apply()
    total_count = qs.count()
    top_values = qs.top_lookups(sf, 10)
    return render_to_response('db/snippets/lookup_chart.html', {
        'lookup': {'sf': sf, 'top_values': top_values},
        'total_count': total_count,
        'schema': sf.schema,
        'filters': filters,
    })
Exemplo n.º 18
0
def bigmap_filter(request, slug):
    """
    Big map with just one Schema (identified by ``slug``) enabled by
    default.
    """
    s = get_object_or_404(get_schema_manager(request),
                          slug=slug,
                          is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_dict = _get_filter_schemafields(s)

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(filter_sf_dict)
        filters_need_more = filterchain.validate()
    except:
        logger.exception("Unhandled error")
        return HttpResponse(status=404)

    config = _decode_map_permalink(request,
                                   show_default_layers=False,
                                   filters=filterchain)

    # TODO: This can leave in permalink params eg. 'i', even if there
    # is also 'ids', because it doesn't recognize those as being the
    # same.
    new_url = filterchain.make_url(
        base_url=reverse('bigmap_filter', args=(slug, )))
    if new_url != request.get_full_path():
        return HttpResponseRedirect(new_url)

    if config['is_widget']:
        return eb_render(request, 'richmaps/embed_bigmap.html',
                         {'map_config': simplejson.dumps(config, indent=2)})
    else:
        return eb_render(request, 'richmaps/bigmap.html',
                         {'map_config': simplejson.dumps(config, indent=2)})
Exemplo n.º 19
0
def bigmap_filter(request, slug):
    """
    Big map with just one Schema (identified by ``slug``) enabled by
    default.
    """
    s = get_object_or_404(get_schema_manager(request), slug=slug, is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_dict = _get_filter_schemafields(s)

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(filter_sf_dict)
        filters_need_more = filterchain.validate()
    except:
        logger.exception("Unhandled error")
        return HttpResponse(status=404)

    config = _decode_map_permalink(request, show_default_layers=False, filters=filterchain)


    # TODO: This can leave in permalink params eg. 'i', even if there
    # is also 'ids', because it doesn't recognize those as being the
    # same.
    new_url = filterchain.make_url(base_url=reverse('bigmap_filter', args=(slug,)))
    if new_url != request.get_full_path():
        return HttpResponseRedirect(new_url)

    if config['is_widget']:
        return eb_render(request, 'richmaps/embed_bigmap.html', {
            'map_config': simplejson.dumps(config, indent=2)
        })
    else:
        return eb_render(request, 'richmaps/bigmap.html', {
            'map_config': simplejson.dumps(config, indent=2)
        })
Exemplo n.º 20
0
def _decode_map_permalink(request, show_default_layers=True, filters=None):
    """
    request parameters: 
    c - map center 
    z - map zoom 
    l - layer info
    p - popup center
    f - popup feature
    start_date - start date (inclusive) %m/%d/%Y
    end_date - end date (inclusive) %m/%d/%Y
    d - duration in days (overridden by end date)

    x - show as 'widget' 
    v- limits what map controls are displayed (widget only)
    w - width of map (widget only)
    h - height of map (widget only)
    """

    params = request.GET

    #
    # enabled item, place layers "l" parameter
    #
    # l=p13,t32,p1 ...
    #
    # p => place layer
    # t => schema layer
    # remaining portion is dbid of place or schema
    #
    schemas = set()
    place_types = set()
    lids = params.get("l", None)
    if lids is not None:
        no_layers_specified = False
        try:
            pat = re.compile('(\w\d+)')
            for lid in pat.findall(lids):
                layer_type = lid[0]
                layer_id = int(lid[1:])
                if layer_type == 'p':
                    place_types.add(layer_id)
                elif layer_type == 't':
                    schemas.add(layer_id)
        except:
            pass
    else:
        no_layers_specified = True

    # map center
    center = params.get("c", None)
    if center:
        try:
            center = [float(x) for x in center.split('_')][0:2]
        except:
            pass

    # map zoom level
    zoom = params.get("z", None)
    if zoom:
        try:
            zoom = float(zoom)
        except:
            pass

    # popup
    popup_info = None
    popup_center = params.get("p", None)
    popup_feature = params.get("f", None)
    if popup_center and popup_feature:
        try:
            popup_center = [float(x) for x in popup_center.split('_')][0:2]
            feature_type = popup_feature[0]
            feature_id = int(popup_feature[1:])
            if feature_type == 'p':
                openblock_type = 'place'
            elif feature_type == 't':
                openblock_type = 'newsitem'

            popup_info = {
                'id': feature_id,
                'openblock_type': openblock_type,
                'lonlat': [popup_center[0], popup_center[1]]
            }
        except:
            popup_center = None
            popup_feature = None

    # start and end date range
    startdate = params.get('start_date')
    if startdate is not None:
        try:
            startdate = datetime.datetime.strptime(startdate,
                                                   '%m/%d/%Y').date()
        except:
            startdate = None

    enddate = params.get('end_date')
    if enddate is not None:
        try:
            enddate = datetime.datetime.strptime(enddate, '%m/%d/%Y').date()
        except:
            enddate = None

    if startdate is None and enddate is None and filters:
        date_filter = filters.get('date') or filters.get('pubdate')
        if date_filter:
            startdate = date_filter.start_date
            enddate = date_filter.end_date

    default_interval = datetime.timedelta(days=7)
    duration = params.get('d')
    if duration is not None:
        try:
            duration = datetime.timedelta(days=int(duration))
        except:
            duration = default_interval
    else:
        duration = default_interval

    if startdate is None and enddate is None:
        enddate = datetime.date.today()
        startdate = enddate - duration
    elif startdate is None:
        startdate = enddate - duration
    elif enddate is None:
        enddate = startdate + duration

    if enddate < startdate:
        enddate = startdate + duration

    # inject date range into filters if none was specified:
    if filters and filters.get('date') is None:
        filters.add('date', startdate, enddate)

    layers = []
    for place_type in PlaceType.objects.filter(is_mappable=True).all():
        layers.append({
            'id':
            'p%d' % place_type.id,
            'title':
            place_type.plural_name,
            'url':
            reverse('place_detail_json', args=[place_type.slug]),
            'params': {
                'limit': 1000
            },
            'minZoom':
            15,
            'bbox':
            True,
            'visible':
            place_type.id in place_types  # off by default
        })

    api_startdate = startdate.strftime("%Y-%m-%d")
    api_enddate = (enddate + datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    for schema in get_schema_manager(request).all():
        layers.append({
            'id':
            't%d' % schema.id,
            'title':
            schema.plural_name,
            'url':
            reverse('map_items_json'),
            'params': {
                'type': schema.slug,
                'limit': 1000,
                'startdate': api_startdate,
                'enddate': api_enddate
            },
            'bbox':
            False,
            'visible': (no_layers_specified and show_default_layers)
            or schema.id in schemas  # default on if no 't' param given
        })

    is_widget = params.get('x', None) is not None

    controls = {}
    control_list = params.get("v", None)
    if control_list is not None:
        if 'l' in control_list:
            controls['layers'] = True
        if 'h' in control_list:
            controls['headline_list'] = True
        if 'p' in control_list:
            controls['permalink'] = True

    width = params.get("w", None)
    if width:
        try:
            width = int(width)
        except:
            width = None

    height = params.get("h", None)
    if height:
        try:
            height = int(height)
        except:
            height = None

    config = {
        'center':
        center
        or [settings.DEFAULT_MAP_CENTER_LON, settings.DEFAULT_MAP_CENTER_LAT],
        'zoom':
        zoom or settings.DEFAULT_MAP_ZOOM,
        'layers':
        layers,
        'is_widget':
        is_widget,
        'permalink_params': {
            'start_date': startdate.strftime('%m/%d/%Y'),
            'end_date': enddate.strftime('%m/%d/%Y'),
        },
    }

    if popup_info:
        config['popup'] = popup_info

    if is_widget:
        config['controls'] = controls
        if width is not None:
            config['width'] = width
        if height is not None:
            config['height'] = height

    return config
Exemplo n.º 21
0
def _decode_map_permalink(request, show_default_layers=True, filters=None):
    """
    request parameters: 
    c - map center 
    z - map zoom 
    l - layer info
    p - popup center
    f - popup feature
    start_date - start date (inclusive) %m/%d/%Y
    end_date - end date (inclusive) %m/%d/%Y
    d - duration in days (overridden by end date)

    x - show as 'widget' 
    v- limits what map controls are displayed (widget only)
    w - width of map (widget only)
    h - height of map (widget only)
    """
    
    params = request.GET
    
    #
    # enabled item, place layers "l" parameter
    #
    # l=p13,t32,p1 ...
    #
    # p => place layer
    # t => schema layer 
    # remaining portion is dbid of place or schema
    #
    schemas = set()
    place_types = set()
    lids = params.get("l", None)
    if lids is not None: 
        no_layers_specified = False
        try:
            pat = re.compile('(\w\d+)')
            for lid in pat.findall(lids):
                layer_type = lid[0]
                layer_id = int(lid[1:])
                if layer_type == 'p': 
                    place_types.add(layer_id)
                elif layer_type == 't': 
                    schemas.add(layer_id)
        except: 
            pass
    else: 
        no_layers_specified = True

    # map center
    center = params.get("c", None)
    if center: 
        try:
            center = [float(x) for x in center.split('_')][0:2]
        except: 
            pass
    
    # map zoom level 
    zoom = params.get("z", None)
    if zoom:
        try:
            zoom = float(zoom)
        except: 
            pass
        
    # popup 
    popup_info = None
    popup_center = params.get("p", None)
    popup_feature = params.get("f", None)
    if popup_center and popup_feature: 
        try:
            popup_center = [float(x) for x in popup_center.split('_')][0:2]
            feature_type = popup_feature[0]
            feature_id = int(popup_feature[1:])
            if feature_type == 'p': 
                openblock_type = 'place'
            elif feature_type == 't': 
                openblock_type = 'newsitem'

            popup_info = {
                'id': feature_id,
                'openblock_type': openblock_type,
                'lonlat': [popup_center[0], popup_center[1]]
            }
        except: 
            popup_center = None
            popup_feature = None
    

    # start and end date range
    startdate = params.get('start_date')
    if startdate is not None:
        try:
            startdate = datetime.datetime.strptime(startdate, '%m/%d/%Y').date()
        except:
            startdate = None

    enddate = params.get('end_date')
    if enddate is not None: 
        try:
            enddate = datetime.datetime.strptime(enddate, '%m/%d/%Y').date()
        except:
            enddate = None

    if startdate is None and enddate is None and filters:
        date_filter = filters.get('date') or filters.get('pubdate')
        if date_filter:
            startdate = date_filter.start_date
            enddate = date_filter.end_date


    default_interval = datetime.timedelta(days=7)
    duration = params.get('d')
    if duration is not None:
        try:
            duration = datetime.timedelta(days=int(duration))
        except:
            duration = default_interval
    else: 
        duration = default_interval

    if startdate is None and enddate is None:
        enddate = datetime.date.today()
        startdate = enddate - duration
    elif startdate is None:
        startdate = enddate - duration
    elif enddate is None:
        enddate = startdate + duration

    if enddate < startdate:
        enddate = startdate + duration

    # inject date range into filters if none was specified:
    if filters and filters.get('date') is None: 
        filters.add('date', startdate, enddate)

    layers = []
    for place_type in PlaceType.objects.filter(is_mappable=True).all():
        layers.append({
            'id': 'p%d' % place_type.id,
            'title': place_type.plural_name,
            'url': reverse('place_detail_json', args=[place_type.slug]),
            'params': {'limit': 1000},
            'minZoom': 15,
            'bbox': True,
            'visible': place_type.id in place_types # off by default
        })

    api_startdate = startdate.strftime("%Y-%m-%d")  
    api_enddate = (enddate + datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    for schema in get_schema_manager(request).all():
        layers.append({
            'id': 't%d' % schema.id,
            'title':  schema.plural_name,
            'url':    reverse('map_items_json'),
            'params': {'type': schema.slug, 'limit': 1000,
                       'startdate': api_startdate,
                       'enddate': api_enddate},
            'bbox': False,
            'visible': (no_layers_specified and show_default_layers) or schema.id in schemas # default on if no 't' param given
        })

    is_widget = params.get('x', None) is not None
        
    controls = {}
    control_list = params.get("v", None)
    if control_list is not None: 
        if 'l' in control_list: 
            controls['layers'] = True
        if 'h' in control_list: 
            controls['headline_list'] = True
        if 'p' in control_list: 
            controls['permalink'] = True

    width = params.get("w", None)
    if width:
        try:
            width = int(width)
        except: 
            width = None

    height = params.get("h", None)
    if height:
        try:
            height = int(height)
        except: 
            height = None

    config = {
      'center': center or [settings.DEFAULT_MAP_CENTER_LON,
                           settings.DEFAULT_MAP_CENTER_LAT],

      'zoom': zoom or settings.DEFAULT_MAP_ZOOM,
      
      'layers': layers, 
      
      'is_widget': is_widget,
      
      'permalink_params': {
        'start_date': startdate.strftime('%m/%d/%Y'),
        'end_date': enddate.strftime('%m/%d/%Y'),
      }, 
    }


    if popup_info:
        config['popup'] = popup_info

    
    if is_widget: 
        config['controls'] = controls
        if width is not None: 
            config['width'] = width
        if height is not None: 
            config['height'] = height
    
    return config
def allowed_schemas(request):
    allowed_schemas = get_schema_manager(request).all()
    return {'allowed_schemas': allowed_schemas}
Exemplo n.º 23
0
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
Exemplo n.º 24
0
def schema_filter_geojson(request, slug, args_from_url):
    s = get_object_or_404(get_schema_manager(request), slug=slug, is_special_report=False)
    if not s.allow_charting:
        return HttpResponse(status=404)

    filter_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_filter=True).order_by('display_order'))
    textsearch_sf_list = list(SchemaField.objects.filter(schema__id=s.id, is_searchable=True).order_by('display_order'))

    # Use SortedDict to preserve the display_order.
    filter_sf_dict = SortedDict([(sf.name, sf) for sf in filter_sf_list] + [(sf.name, sf) for sf in textsearch_sf_list])

    # Determine what filters to apply, based on path and/or query string.
    filterchain = FilterChain(request=request, schema=s)
    try:
        filterchain.update_from_request(args_from_url, filter_sf_dict)
        filters_need_more = filterchain.validate()
    except FilterError:
        return HttpResponse(status=400)
    except BadAddressException:
        return HttpResponse(status=400)
    except BadDateException:
        return HttpResponse(status=400)

    if filters_need_more:
        return HttpResponse(status=400)


    # If there isn't a date filter, add some dates to the queryset,
    # but NOT to the filterchain, because need to give the user the
    # option of choosing dates.
    qs, start_date, end_date = _default_date_filtering(filterchain)

    if s.is_event:
        qs = qs.order_by('item_date', 'id')
    else:
        qs = qs.order_by('-item_date', '-id')

    page = request.GET.get('page', None)
    if page is not None:
        try:
            page = int(page)
            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.
            idx_end += 1
        except ValueError:
            return HttpResponse('Invalid Page', status=400)
    else:
        idx_start, idx_end = 0, 1000
    qs = qs[idx_start:idx_end]

    cache_key = 'schema_filter_geojson:' + _make_cache_key_from_queryset(qs)
    cache_seconds = 60 * 5
    output = cache.get(cache_key, None)
    if output is None:
        output = api_items_geojson(list(qs))
        cache.set(cache_key, output, cache_seconds)

    response = HttpResponse(output, mimetype="application/javascript")
    patch_response_headers(response, cache_timeout=60 * 5)
    return response
Exemplo n.º 25
0
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)
Exemplo n.º 26
0
def search(request, schema_slug=''):
    "Performs a location search and redirects to the address/xy page."
    # Check whether a schema was provided.
    if schema_slug:
        try:
            schema = get_schema_manager(request).get(slug=schema_slug)
        except Schema.DoesNotExist:
            raise Http404('Schema does not exist')
        url_prefix = schema.url()[:-1]
    else:
        schema = None
        url_prefix = ''

    # Get the query.
    q = request.GET.get('q', '').strip()
    if not q:
        return HttpResponseRedirect(url_prefix + '/') # TODO: Do something better than redirecting.

    # For /search/?type=alert, we redirect results to the alert page, not the
    # place page.
    if request.GET.get('type', '') == 'alert':
        url_method = 'alert_url'
    else:
        url_method = 'url'

    # Try to geocode it using full_geocode().
    try:
        result = full_geocode(q, search_places=False)
    except: # TODO: Naked except clause.
        pass
    else:
        if result['ambiguous']:
            if result['type'] == 'block':
                return eb_render(request, 'db/search_invalid_block.html', {
                    'query': q,
                    'choices': result['result'],
                    'street_name': result['street_name'],
                    'block_number': result['block_number']
                })
            else:
                return eb_render(request, 'db/did_you_mean.html', {'query': q, 'choices': result['result']})
        elif result['type'] == 'location':
            return HttpResponseRedirect(url_prefix + getattr(result['result'], url_method)())
        elif result['type'] == 'address':
            # Block
            if result['result']['block']:
                return HttpResponseRedirect(url_prefix + getattr(result['result']['block'], url_method)())
            # Intersection
            try:
                intersection = Intersection.objects.get(id=result['result']['intersection_id'])
            except Intersection.DoesNotExist:
                pass
            else:
                return HttpResponseRedirect(url_prefix + getattr(intersection, url_method)())

    # Failing the geocoding, look in the special-case table.
    try:
        special_case = SearchSpecialCase.objects.get(query=normalize(q))
    except SearchSpecialCase.DoesNotExist:
        pass
    else:
        if special_case.redirect_to:
            return HttpResponseRedirect(special_case.redirect_to)
        else:
            return eb_render(request, 'db/search_special_case.html', {'query': q, 'special_case': special_case})

    # Failing that, display a list of ZIP codes if this looks like a ZIP.
    if re.search(r'^\s*\d{5}(?:-\d{4})?\s*$', q):
        z_list = Location.objects.filter(location_type__slug='zipcodes', is_public=True).select_related().order_by('name')
        if z_list:
            return eb_render(request, 'db/search_error_zip_list.html', {'query': q, 'zipcode_list': z_list})

    # Failing all of that, display the search error page.
    lt_list = LocationType.objects.filter(is_significant=True).order_by('name')
    return eb_render(request, 'db/search_error.html', {'query': q, 'locationtype_list': lt_list})
Exemplo n.º 27
0
def feed_signup(request, *args, **kwargs):
    context = get_place_info_for_request(request, *args, **kwargs)
    context['schema_list'] = get_schema_manager(request).filter(is_special_report=False).order_by('plural_name')
    return eb_render(request, 'db/feed_signup.html', context)
Exemplo n.º 28
0
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
Exemplo n.º 29
0
def _decode_map_permalink(request, show_default_layers=True, filters=None):
    """
    Permalinks for the big map, with more compact query parameters.

    Returns a map_config dictionary.

    Accepted parameters:

    c - map center, separated by underscore, eg. c=-92.28283_38.95658

    z - map zoom, eg. z=12

    l - layers to display on load, comma- or dash-separated,
        eg. l=p13,t32,p1 or eg. l=p12345-t7-t9,
        where p => place layer
        and t => schema ("type") layer

    i - items to load specificially by id, comma- or dash-separated,
        eg. i=t1234-t456

    p - popup center, with underscore, eg. p=-92.3438_38.9658
    f - popup feature, eg. f=t1234 or f=p1234
        where p = a place and t = a news item

    start_date - start date (inclusive) %m/%d/%Y
    end_date - end date (inclusive) %m/%d/%Y
    d - duration in days (overridden by end date), eg. d=7

    x - show as 'widget', just the map and nothign around it.
        Takes no value, eg. x
    w - width of map (widget only), in pixels
    h - height of map (widget only), in pixels
    v - limits what map controls are displayed (widget only).
        By default, widget-stype map shows none of these.
        Possible values, joined with no separator:
        l - layer switcher
        h - list of headlines next to map
        p - permalink
        eg. to turn them all on: v=lhp


    """
    params = request.GET
    schemas = set()
    place_types = set()
    lids = params.get("l", None)
    show_custom_layer = False
    if lids is not None:
        no_layers_specified = False
        try:
            pat = re.compile('(\w\d+)')
            for lid in pat.findall(lids):
                layer_type = lid[0]
                layer_id = int(lid[1:])
                if layer_type == 'p':
                    place_types.add(layer_id)
                elif layer_type == 't':
                    schemas.add(layer_id)
                elif layer_type == 'c':
                    show_custom_layer = True
        except:
            pass
    else:
        no_layers_specified = True

    # map center
    center = params.get("c", None)
    if center:
        try:
            center = [float(x) for x in center.split('_')][0:2]
        except:
            pass

    # map zoom level
    zoom = params.get("z", None)
    if zoom:
        try:
            zoom = float(zoom)
        except:
            pass

    # popup
    popup_info = None
    popup_center = params.get("p", None)
    popup_feature = params.get("f", None)
    if popup_center and popup_feature:
        try:
            popup_center = [float(x) for x in popup_center.split('_')][0:2]
            feature_type = popup_feature[0]
            feature_id = int(popup_feature[1:])
            if feature_type == 'p':
                openblock_type = 'place'
            elif feature_type == 't':
                openblock_type = 'newsitem'

            popup_info = {
                'id': feature_id,
                'openblock_type': openblock_type,
                'lonlat': [popup_center[0], popup_center[1]]
            }
        except:
            popup_center = None
            popup_feature = None

    # start and end date range
    default_interval = datetime.timedelta(days=7)
    duration = params.get('d')
    if duration is not None:
        try:
            duration = datetime.timedelta(days=int(duration))
        except (TypeError, ValueError):
            duration = default_interval
    else:
        duration = default_interval
    default_enddate = datetime.date.today()
    default_startdate = default_enddate - duration

    startdate = params.get('start_date')
    if startdate is not None:
        for format in ('%m/%d/%Y', '%Y-%m-%d'):
            try:
                startdate = datetime.datetime.strptime(startdate,
                                                       format).date()
                break
            except ValueError:
                pass
        if isinstance(startdate, basestring):
            startdate = None

    enddate = params.get('end_date')
    if enddate is not None:
        for format in ('%m/%d/%Y', '%Y-%m-%d'):
            try:
                enddate = datetime.datetime.strptime(enddate, format).date()
                break
            except ValueError:
                pass
        if isinstance(enddate, basestring):
            enddate = None

    # The filters argument can override startdate & enddate.
    if startdate is None and enddate is None and filters:
        date_filter = filters.get('date') or filters.get('pubdate')
        if date_filter:
            startdate = date_filter.start_date
            enddate = date_filter.end_date

    if startdate is None and enddate is None:
        enddate = datetime.date.today()
        startdate = enddate - duration
    elif startdate is None:
        startdate = enddate - duration
    elif enddate is None:
        enddate = startdate + duration

    if enddate < startdate:
        enddate = startdate + duration

    # inject date range into filters if none was specified:
    if filters and filters.get('date') is None:
        filters.add('date', startdate, enddate)

    api_startdate = startdate.strftime("%Y-%m-%d")
    api_enddate = (enddate + datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    layers = []

    if (startdate != default_startdate) or (enddate != default_enddate):
        show_custom_layer = True

    # All available place layers.
    for place_type in PlaceType.objects.filter(is_mappable=True).all():
        layers.append({
            'id':
            'p%d' % place_type.id,
            'title':
            place_type.plural_name,
            'url':
            reverse('place_detail_json', args=[place_type.slug]),
            'params': {
                'limit': 1000
            },
            'minZoom':
            15,
            'bbox':
            True,
            'visible':
            place_type.id in place_types  # off by default
        })

    # All available NewsItem layers.
    for schema in get_schema_manager(request).all():
        # if filters and 'schema' in filters and filters['schema'].schema == schema:
        #     visible = True
        if no_layers_specified and show_default_layers and not show_custom_layer:
            # default on if no 't' param given
            visible = True
        elif schemas and schema.id in schemas:
            visible = True
        else:
            visible = False
        layers.append({
            'id': 't%d' % schema.id,
            'title': schema.plural_name,
            'url': reverse('map_items_json'),
            'params': {
                'type': schema.slug,
                'limit': 1000,
                'startdate': api_startdate,
                'enddate': api_enddate
            },
            'bbox': False,
            'visible': visible
        })

    # Explicit filtering by ID.
    ids = params.get('i') or u''
    ids = [i.strip() for i in re.split(r'[^\d]+', ids) if i.strip()]
    if ids:
        show_custom_layer = True
        if filters is None:
            filters = FilterChain(request)
        filters.replace('id', *ids)

    # 'Custom' layer. This is a catch-all for all filtering
    # that isn't just enabling a default layer with the default
    # date range.
    # Not visible unless there is something like that to show.
    if filters and sorted(filters.keys()) not in ([], ['date'], [
            'date', 'schema'
    ], ['schema']):
        show_custom_layer = True

    if filters is not None:
        # Don't inspect filters['schema']; that's already covered by schemas above.
        base_url = reverse('map_items_json')
        layer_url = filters.make_url(base_url=base_url)
        # Quick ugly hacks to make the itemquery api happy.
        # Hooray proliferation of spellings.
        layer_url = layer_url.replace('locations=', 'locationid=')
        layer_url = layer_url.replace('start_date=', 'startdate=')
        layer_url = layer_url.replace('end_date=', 'enddate=')

        if 'schema' in filters:
            # Normally, filters.make_url() captures the schema in the
            # path part of the URL. But map_items_json doesn't,
            # so we add a query parameter.
            params = {'type': [s.slug for s in filters['schema'].schemas]}
        else:
            params = {}
        custom_layer = {
            'url': layer_url,
            'params': params,
            'title': u"Custom Filter",
            'visible': show_custom_layer,
            'id': 'c1',
        }
        layers.append(custom_layer)

    is_widget = params.get('x', None) is not None
    controls = {}
    control_list = params.get("v", None)
    if control_list is not None:
        if 'l' in control_list:
            controls['layers'] = True
        if 'h' in control_list:
            controls['headline_list'] = True
        if 'p' in control_list:
            controls['permalink'] = True

    width = params.get("w", None)
    if width:
        try:
            width = int(width)
        except:
            width = None

    height = params.get("h", None)
    if height:
        try:
            height = int(height)
        except:
            height = None

    config = {
        'center':
        center
        or [settings.DEFAULT_MAP_CENTER_LON, settings.DEFAULT_MAP_CENTER_LAT],
        'zoom':
        zoom or settings.DEFAULT_MAP_ZOOM,
        'layers':
        layers,
        'is_widget':
        is_widget,
        'permalink_params': {
            'start_date': startdate.strftime('%m/%d/%Y'),
            'end_date': enddate.strftime('%m/%d/%Y'),
        },
    }

    if 'id' in filters:
        # Put them in the params so the js code can construct, well,
        # permalinks with these ids, on the client side.
        ids = '-'.join(map(str, filters['id'].ids))
        config['permalink_params']['i'] = ids
    if popup_info:
        config['popup'] = popup_info

    if is_widget:
        config['controls'] = controls
        if width is not None:
            config['width'] = width
        if height is not None:
            config['height'] = height

    return config
Exemplo n.º 30
0
def _decode_map_permalink(request, show_default_layers=True, filters=None):
    """
    Permalinks for the big map, with more compact query parameters.

    Returns a map_config dictionary.

    Accepted parameters:

    c - map center, separated by underscore, eg. c=-92.28283_38.95658

    z - map zoom, eg. z=12

    l - layers to display on load, comma- or dash-separated,
        eg. l=p13,t32,p1 or eg. l=p12345-t7-t9,
        where p => place layer
        and t => schema ("type") layer

    i - items to load specificially by id, comma- or dash-separated,
        eg. i=t1234-t456

    p - popup center, with underscore, eg. p=-92.3438_38.9658
    f - popup feature, eg. f=t1234 or f=p1234
        where p = a place and t = a news item

    start_date - start date (inclusive) %m/%d/%Y
    end_date - end date (inclusive) %m/%d/%Y
    d - duration in days (overridden by end date), eg. d=7

    x - show as 'widget', just the map and nothign around it.
        Takes no value, eg. x
    w - width of map (widget only), in pixels
    h - height of map (widget only), in pixels
    v - limits what map controls are displayed (widget only).
        By default, widget-stype map shows none of these.
        Possible values, joined with no separator:
        l - layer switcher
        h - list of headlines next to map
        p - permalink
        eg. to turn them all on: v=lhp


    """
    params = request.GET
    schemas = set()
    place_types = set()
    lids = params.get("l", None)
    show_custom_layer = False
    if lids is not None: 
        no_layers_specified = False
        try:
            pat = re.compile('(\w\d+)')
            for lid in pat.findall(lids):
                layer_type = lid[0]
                layer_id = int(lid[1:])
                if layer_type == 'p': 
                    place_types.add(layer_id)
                elif layer_type == 't': 
                    schemas.add(layer_id)
                elif layer_type == 'c':
                    show_custom_layer = True
        except: 
            pass
    else:
        no_layers_specified = True

    # map center
    center = params.get("c", None)
    if center: 
        try:
            center = [float(x) for x in center.split('_')][0:2]
        except: 
            pass
    
    # map zoom level 
    zoom = params.get("z", None)
    if zoom:
        try:
            zoom = float(zoom)
        except: 
            pass
        
    # popup 
    popup_info = None
    popup_center = params.get("p", None)
    popup_feature = params.get("f", None)
    if popup_center and popup_feature: 
        try:
            popup_center = [float(x) for x in popup_center.split('_')][0:2]
            feature_type = popup_feature[0]
            feature_id = int(popup_feature[1:])
            if feature_type == 'p': 
                openblock_type = 'place'
            elif feature_type == 't': 
                openblock_type = 'newsitem'

            popup_info = {
                'id': feature_id,
                'openblock_type': openblock_type,
                'lonlat': [popup_center[0], popup_center[1]]
            }
        except: 
            popup_center = None
            popup_feature = None

    # start and end date range
    default_interval = datetime.timedelta(days=7)
    duration = params.get('d')
    if duration is not None:
        try:
            duration = datetime.timedelta(days=int(duration))
        except (TypeError, ValueError):
            duration = default_interval
    else:
        duration = default_interval
    default_enddate = datetime.date.today()
    default_startdate = default_enddate - duration

    startdate = params.get('start_date')
    if startdate is not None:
        for format in ('%m/%d/%Y', '%Y-%m-%d'):
            try:
                startdate = datetime.datetime.strptime(startdate, format).date()
                break
            except ValueError:
                pass
        if isinstance(startdate, basestring):
            startdate = None

    enddate = params.get('end_date')
    if enddate is not None:
        for format in ('%m/%d/%Y', '%Y-%m-%d'):
            try:
                enddate = datetime.datetime.strptime(enddate, format).date()
                break
            except ValueError:
                pass
        if isinstance(enddate, basestring):
            enddate = None

    # The filters argument can override startdate & enddate.
    if startdate is None and enddate is None and filters:
        date_filter = filters.get('date') or filters.get('pubdate')
        if date_filter:
            startdate = date_filter.start_date
            enddate = date_filter.end_date

    if startdate is None and enddate is None:
        enddate = datetime.date.today()
        startdate = enddate - duration
    elif startdate is None:
        startdate = enddate - duration
    elif enddate is None:
        enddate = startdate + duration

    if enddate < startdate:
        enddate = startdate + duration

    # inject date range into filters if none was specified:
    if filters and filters.get('date') is None: 
        filters.add('date', startdate, enddate)

    api_startdate = startdate.strftime("%Y-%m-%d")  
    api_enddate = (enddate + datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    layers = []

    if (startdate != default_startdate) or (enddate != default_enddate):
        show_custom_layer = True

    # All available place layers.
    for place_type in PlaceType.objects.filter(is_mappable=True).all():
        layers.append({
            'id': 'p%d' % place_type.id,
            'title': place_type.plural_name,
            'url': reverse('place_detail_json', args=[place_type.slug]),
            'params': {'limit': 1000},
            'minZoom': 15,
            'bbox': True,
            'visible': place_type.id in place_types # off by default
        })

    # All available NewsItem layers.
    for schema in get_schema_manager(request).all():
        # if filters and 'schema' in filters and filters['schema'].schema == schema:
        #     visible = True
        if no_layers_specified and show_default_layers and not show_custom_layer:
            # default on if no 't' param given
            visible = True
        elif schemas and schema.id in schemas:
            visible = True
        else:
            visible = False
        layers.append({
            'id': 't%d' % schema.id,
            'title':  schema.plural_name,
            'url':    reverse('map_items_json'),
            'params': {'type': schema.slug, 'limit': 1000,
                       'startdate': api_startdate,
                       'enddate': api_enddate},
            'bbox': False,
            'visible': visible
        })

    # Explicit filtering by ID.
    ids = params.get('i') or u''
    ids = [i.strip() for i in re.split(r'[^\d]+', ids)
           if i.strip()]
    if ids:
        show_custom_layer = True
        if filters is None:
            filters = FilterChain(request)
        filters.replace('id', *ids)


    # 'Custom' layer. This is a catch-all for all filtering
    # that isn't just enabling a default layer with the default
    # date range.
    # Not visible unless there is something like that to show.
    if filters and sorted(filters.keys()) not in ([],
                                                  ['date'],
                                                  ['date', 'schema'],
                                                  ['schema']):
        show_custom_layer = True

    if filters is not None:
        # Don't inspect filters['schema']; that's already covered by schemas above.
        base_url = reverse('map_items_json')
        layer_url = filters.make_url(base_url=base_url)
        # Quick ugly hacks to make the itemquery api happy.
        # Hooray proliferation of spellings.
        layer_url = layer_url.replace('locations=', 'locationid=')
        layer_url = layer_url.replace('start_date=', 'startdate=')
        layer_url = layer_url.replace('end_date=', 'enddate=')

        if 'schema' in filters:
            # Normally, filters.make_url() captures the schema in the
            # path part of the URL. But map_items_json doesn't,
            # so we add a query parameter.
            params = {'type': [s.slug for s in filters['schema'].schemas]}
        else:
            params = {}
        custom_layer = {
            'url': layer_url,
            'params': params,
            'title': u"Custom Filter",
            'visible': show_custom_layer,
            'id': 'c1',
            }
        layers.append(custom_layer)

    is_widget = params.get('x', None) is not None
    controls = {}
    control_list = params.get("v", None)
    if control_list is not None: 
        if 'l' in control_list: 
            controls['layers'] = True
        if 'h' in control_list: 
            controls['headline_list'] = True
        if 'p' in control_list: 
            controls['permalink'] = True

    width = params.get("w", None)
    if width:
        try:
            width = int(width)
        except: 
            width = None

    height = params.get("h", None)
    if height:
        try:
            height = int(height)
        except: 
            height = None

    config = {
      'center': center or [settings.DEFAULT_MAP_CENTER_LON,
                           settings.DEFAULT_MAP_CENTER_LAT],

      'zoom': zoom or settings.DEFAULT_MAP_ZOOM,
      
      'layers': layers, 
      
      'is_widget': is_widget,
      
      'permalink_params': {
        'start_date': startdate.strftime('%m/%d/%Y'),
        'end_date': enddate.strftime('%m/%d/%Y'),
      }, 
    }

    if 'id' in filters:
        # Put them in the params so the js code can construct, well,
        # permalinks with these ids, on the client side.
        ids = '-'.join(map(str, filters['id'].ids))
        config['permalink_params']['i'] = ids
    if popup_info:
        config['popup'] = popup_info

    if is_widget: 
        config['controls'] = controls
        if width is not None: 
            config['width'] = width
        if height is not None: 
            config['height'] = height
    
    return config
Exemplo n.º 31
0
def _decode_map_permalink(request, show_default_layers=True, filters=None):
    """
    request parameters: 
    c - map center 
    z - map zoom 
    l - layer info
    p - popup center
    f - popup feature
    start_date - start date (inclusive) %m/%d/%Y
    end_date - end date (inclusive) %m/%d/%Y
    d - duration in days (overridden by end date)

    x - show as 'widget' 
    v- limits what map controls are displayed (widget only)
    w - width of map (widget only)
    h - height of map (widget only)
    """

    params = request.GET

    #
    # enabled item, place layers "l" parameter
    #
    # l=p13,t32,p1 ...
    #
    # p => place layer
    # t => schema layer
    # remaining portion is dbid of place or schema
    #
    schemas = set()
    place_types = set()
    lids = params.get("l", None)
    if lids is not None:
        no_layers_specified = False
        try:
            pat = re.compile("(\w\d+)")
            for lid in pat.findall(lids):
                layer_type = lid[0]
                layer_id = int(lid[1:])
                if layer_type == "p":
                    place_types.add(layer_id)
                elif layer_type == "t":
                    schemas.add(layer_id)
        except:
            pass
    else:
        no_layers_specified = True

    # map center
    center = params.get("c", None)
    if center:
        try:
            center = [float(x) for x in center.split("_")][0:2]
        except:
            pass

    # map zoom level
    zoom = params.get("z", None)
    if zoom:
        try:
            zoom = float(zoom)
        except:
            pass

    # popup
    popup_info = None
    popup_center = params.get("p", None)
    popup_feature = params.get("f", None)
    if popup_center and popup_feature:
        try:
            popup_center = [float(x) for x in popup_center.split("_")][0:2]
            feature_type = popup_feature[0]
            feature_id = int(popup_feature[1:])
            if feature_type == "p":
                openblock_type = "place"
            elif feature_type == "t":
                openblock_type = "newsitem"

            popup_info = {
                "id": feature_id,
                "openblock_type": openblock_type,
                "lonlat": [popup_center[0], popup_center[1]],
            }
        except:
            popup_center = None
            popup_feature = None

    # start and end date range
    startdate = params.get("start_date")
    if startdate is not None:
        try:
            startdate = datetime.datetime.strptime(startdate, "%m/%d/%Y").date()
        except:
            startdate = None

    enddate = params.get("end_date")
    if enddate is not None:
        try:
            enddate = datetime.datetime.strptime(enddate, "%m/%d/%Y").date()
        except:
            enddate = None

    if startdate is None and enddate is None and filters:
        date_filter = filters.get("date") or filters.get("pubdate")
        if date_filter:
            startdate = date_filter.start_date
            enddate = date_filter.end_date

    default_interval = datetime.timedelta(days=7)
    duration = params.get("d")
    if duration is not None:
        try:
            duration = datetime.timedelta(days=int(duration))
        except:
            duration = default_interval
    else:
        duration = default_interval

    if startdate is None and enddate is None:
        enddate = datetime.date.today()
        startdate = enddate - duration
    elif startdate is None:
        startdate = enddate - duration
    elif enddate is None:
        enddate = startdate + duration

    if enddate < startdate:
        enddate = startdate + duration

    # inject date range into filters if none was specified:
    if filters and filters.get("date") is None:
        filters.add("date", startdate, enddate)

    layers = []
    for place_type in PlaceType.objects.filter(is_mappable=True).all():
        layers.append(
            {
                "id": "p%d" % place_type.id,
                "title": place_type.plural_name,
                "url": reverse("place_detail_json", args=[place_type.slug]),
                "params": {"limit": 1000},
                "minZoom": 15,
                "bbox": True,
                "visible": place_type.id in place_types,  # off by default
            }
        )

    api_startdate = startdate.strftime("%Y-%m-%d")
    api_enddate = (enddate + datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    for schema in get_schema_manager(request).all():
        layers.append(
            {
                "id": "t%d" % schema.id,
                "title": schema.plural_name,
                "url": reverse("map_items_json"),
                "params": {"type": schema.slug, "limit": 1000, "startdate": api_startdate, "enddate": api_enddate},
                "bbox": False,
                "visible": (no_layers_specified and show_default_layers)
                or schema.id in schemas,  # default on if no 't' param given
            }
        )

    is_widget = params.get("x", None) is not None

    controls = {}
    control_list = params.get("v", None)
    if control_list is not None:
        if "l" in control_list:
            controls["layers"] = True
        if "h" in control_list:
            controls["headline_list"] = True
        if "p" in control_list:
            controls["permalink"] = True

    width = params.get("w", None)
    if width:
        try:
            width = int(width)
        except:
            width = None

    height = params.get("h", None)
    if height:
        try:
            height = int(height)
        except:
            height = None

    config = {
        "center": center or [settings.DEFAULT_MAP_CENTER_LON, settings.DEFAULT_MAP_CENTER_LAT],
        "zoom": zoom or settings.DEFAULT_MAP_ZOOM,
        "layers": layers,
        "is_widget": is_widget,
        "permalink_params": {"start_date": startdate.strftime("%m/%d/%Y"), "end_date": enddate.strftime("%m/%d/%Y")},
    }

    if popup_info:
        config["popup"] = popup_info

    if is_widget:
        config["controls"] = controls
        if width is not None:
            config["width"] = width
        if height is not None:
            config["height"] = height

    return config