Exemplo n.º 1
0
    def filter_queryset(self, queryset):
        """
        TODO: convert to use proper filter framework
        """

        queryset = super(EventViewSet, self).filter_queryset(queryset)

        if 'show_all' not in self.request.QUERY_PARAMS:
            queryset = queryset.filter(Q(event_status=Event.SCHEDULED))

        val = self.request.QUERY_PARAMS.get('start', None)
        if val:
            dt = parse_time(val, is_start=True)
            queryset = queryset.filter(Q(end_time__gte=dt) | Q(start_time__gte=dt))
        val = self.request.QUERY_PARAMS.get('end', None)
        if val:
            dt = parse_time(val, is_start=False)
            queryset = queryset.filter(Q(end_time__lte=dt) | Q(start_time__lte=dt))

        val = self.request.QUERY_PARAMS.get('bbox', None)
        if val:
            bbox_filter = build_bbox_filter(self.srs, val, 'location')
            places = Place.geo_objects.filter(**bbox_filter)
            queryset = queryset.filter(location__in=places)

        return queryset
Exemplo n.º 2
0
 def filter_queryset(self, request, queryset, view):
     srs = srid_to_srs(request.query_params.get('srid', None))
     bbox = request.query_params.get('bbox', None)
     if bbox:
         bbox_filter = build_bbox_filter(srs, bbox, 'geometry')
         queryset = queryset.filter(**bbox_filter)
     return queryset
Exemplo n.º 3
0
    def get_queryset(self):
        queryset = super(UnitViewSet, self).get_queryset()
        filters = self.request.QUERY_PARAMS
        if 'id' in filters:
            id_list = filters['id'].split(',')
            queryset = queryset.filter(id__in=id_list)

        if 'municipality' in filters:
            val = filters['municipality'].lower().strip()
            if len(val) > 0:
                municipalities = val.split(',')
                muni_sq = Q()
                for municipality_raw in municipalities:
                    municipality = municipality_raw.strip()
                    if municipality.startswith('ocd-division'):
                        ocd_id = municipality
                    else:
                        ocd_id = make_muni_ocd_id(municipality)
                    try:
                        muni = Municipality.objects.get(division__ocd_id=ocd_id)
                        muni_sq |= Q(municipality=muni)
                    except Municipality.DoesNotExist:
                        raise ParseError("municipality with ID '%s' not found" % ocd_id)

                queryset = queryset.filter(muni_sq)

        if 'provider_type' in filters:
            val = filters.get('provider_type')
            pr_ids = val.split(',')
            queryset = queryset.filter(provider_type__in=pr_ids)

        level = filters.get('level', None)
        level_specs = None
        if level:
            if level != 'all':
                level_specs = settings.LEVELS.get(level)

        def services_by_ancestors(service_ids):
            srv_list = set()
            for srv_id in service_ids:
                srv_list |= set(Service.objects.all().by_ancestor(srv_id).values_list('id', flat=True))
                srv_list.add(int(srv_id))
            return list(srv_list)

        services = filters.get('service', None)
        service_ids = None
        if services:
            services = services.lower()
            service_ids = services.split(',')
        elif level_specs:
            if level_specs['type'] == 'include':
                service_ids = level_specs['services']
        if service_ids:
            queryset = queryset.filter(services__in=services_by_ancestors(service_ids)).distinct()

        service_ids = None
        val = filters.get('exclude_services', None)
        if val:
            val = val.lower()
            service_ids = val.split(',')
        elif level_specs:
            if level_specs['type'] == 'exclude':
                service_ids = level_specs['services']
        if service_ids:
            queryset = queryset.exclude(services__in=services_by_ancestors(service_ids)).distinct()

        if 'division' in filters:
            # Divisions can be specified with form:
            # division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5
            d_list = filters['division'].lower().split(',')
            div_list = []
            for division_path in d_list:
                if division_path.startswith('ocd-division'):
                    muni_ocd_id = division_path
                else:
                    ocd_id_base = r'[\w0-9~_.-]+'
                    match_re = r'(%s)/([\w_-]+):(%s)' % (ocd_id_base, ocd_id_base)
                    m = re.match(match_re, division_path, re.U)
                    if not m:
                        raise ParseError("'division' must be of form 'muni/type:id'")

                    arr = division_path.split('/')
                    muni_ocd_id = make_muni_ocd_id(arr.pop(0), '/'.join(arr))
                try:
                    div = AdministrativeDivision.objects.select_related('geometry').get(ocd_id=muni_ocd_id)
                except AdministrativeDivision.DoesNotExist:
                    raise ParseError("administrative division with OCD ID '%s' not found" % muni_ocd_id)
                div_list.append(div)

            div_geom = [div.geometry.boundary for div in div_list]
            if div_list:
                mp = div_list.pop(0).geometry.boundary
                for div in div_list:
                    mp += div.geometry.boundary

            queryset = queryset.filter(location__within=mp)

        if 'lat' in filters and 'lon' in filters:
            try:
                lat = float(filters['lat'])
                lon = float(filters['lon'])
            except ValueError:
                raise ParseError("'lat' and 'lon' need to be floating point numbers")
            point = Point(lon, lat, srid=4326)

            if 'distance' in filters:
                try:
                    distance = float(filters['distance'])
                    if not distance > 0:
                        raise ValueError()
                except ValueError:
                    raise ParseError("'distance' needs to be a floating point number")
                queryset = queryset.filter(location__distance_lte=(point, distance))
            queryset = queryset.distance(point, field_name='geometry').order_by('distance')

        if 'bbox' in filters:
            val = self.request.QUERY_PARAMS.get('bbox', None)
            if 'bbox_srid' in filters:
                ref = SpatialReference(filters.get('bbox_srid', None))
            else:
                ref = self.srs
            if val:
                bbox_filter = munigeo_api.build_bbox_filter(ref, val, 'location')
                queryset = queryset.filter(**bbox_filter)

        maintenance_organization = self.request.QUERY_PARAMS.get('maintenance_organization')
        if maintenance_organization:
            queryset = queryset.filter(
                Q(extensions__maintenance_organization=maintenance_organization) |
                Q(extensions__additional_maintenance_organization=maintenance_organization))

        if 'observations' in self.include_fields:
            queryset = queryset.prefetch_related('observation_set__property__allowed_values').prefetch_related('observation_set__value')
        if 'connections' in self.include_fields:
            queryset = queryset.prefetch_related('connections')
        return queryset
Exemplo n.º 4
0
    def get_queryset(self):
        queryset = super(UnitViewSet, self).get_queryset()
        filters = self.request.QUERY_PARAMS
        if 'id' in filters:
            id_list = filters['id'].split(',')
            queryset = queryset.filter(id__in=id_list)

        if 'municipality' in filters:
            val = filters['municipality'].lower().strip()
            if len(val) > 0:
                municipalities = val.split(',')
                muni_sq = Q()
                for municipality_raw in municipalities:
                    municipality = municipality_raw.strip()
                    if municipality.startswith('ocd-division'):
                        ocd_id = municipality
                    else:
                        ocd_id = make_muni_ocd_id(municipality)
                    try:
                        muni = Municipality.objects.get(division__ocd_id=ocd_id)
                        muni_sq |= Q(municipality=muni)
                    except Municipality.DoesNotExist:
                        raise ParseError("municipality with ID '%s' not found" % ocd_id)

                queryset = queryset.filter(muni_sq)

        if 'provider_type' in filters:
            val = filters.get('provider_type')
            pr_ids = val.split(',')
            queryset = queryset.filter(provider_type__in=pr_ids)

        level = filters.get('level', None)
        level_specs = None
        if level:
            if level != 'all':
                level_specs = settings.LEVELS.get(level)

        def services_by_ancestors(service_ids):
            srv_list = set()
            for srv_id in service_ids:
                srv_list |= set(Service.objects.all().by_ancestor(srv_id).values_list('id', flat=True))
                srv_list.add(int(srv_id))
            return list(srv_list)

        services = filters.get('service', None)
        service_ids = None
        if services:
            services = services.lower()
            service_ids = services.split(',')
        elif level_specs:
            if level_specs['type'] == 'include':
                service_ids = level_specs['services']
        if service_ids:
            queryset = queryset.filter(services__in=services_by_ancestors(service_ids)).distinct()

        service_ids = None
        val = filters.get('exclude_services', None)
        if val:
            val = val.lower()
            service_ids = val.split(',')
        elif level_specs:
            if level_specs['type'] == 'exclude':
                service_ids = level_specs['services']
        if service_ids:
            queryset = queryset.exclude(services__in=services_by_ancestors(service_ids)).distinct()

        if 'division' in filters:
            # Divisions can be specified with form:
            # division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5
            d_list = filters['division'].lower().split(',')
            div_list = []
            for division_path in d_list:
                if division_path.startswith('ocd-division'):
                    muni_ocd_id = division_path
                else:
                    ocd_id_base = r'[\w0-9~_.-]+'
                    match_re = r'(%s)/([\w_-]+):(%s)' % (ocd_id_base, ocd_id_base)
                    m = re.match(match_re, division_path, re.U)
                    if not m:
                        raise ParseError("'division' must be of form 'muni/type:id'")

                    arr = division_path.split('/')
                    muni_ocd_id = make_muni_ocd_id(arr.pop(0), '/'.join(arr))
                try:
                    div = AdministrativeDivision.objects.select_related('geometry').get(ocd_id=muni_ocd_id)
                except AdministrativeDivision.DoesNotExist:
                    raise ParseError("administrative division with OCD ID '%s' not found" % muni_ocd_id)
                div_list.append(div)

            div_geom = [div.geometry.boundary for div in div_list]
            if div_list:
                mp = div_list.pop(0).geometry.boundary
                for div in div_list:
                    mp += div.geometry.boundary

            queryset = queryset.filter(location__within=mp)

        if 'lat' in filters and 'lon' in filters:
            try:
                lat = float(filters['lat'])
                lon = float(filters['lon'])
            except ValueError:
                raise ParseError("'lat' and 'lon' need to be floating point numbers")
            point = Point(lon, lat, srid=4326)

            if 'distance' in filters:
                try:
                    distance = float(filters['distance'])
                    if not distance > 0:
                        raise ValueError()
                except ValueError:
                    raise ParseError("'distance' needs to be a floating point number")
                queryset = queryset.filter(location__distance_lte=(point, distance))
            queryset = queryset.distance(point, field_name='geometry').order_by('distance')

        if 'bbox' in filters:
            val = self.request.QUERY_PARAMS.get('bbox', None)
            if 'bbox_srid' in filters:
                ref = SpatialReference(filters.get('bbox_srid', None))
            else:
                ref = self.srs
            if val:
                bbox_filter = munigeo_api.build_bbox_filter(ref, val, 'location')
                queryset = queryset.filter(**bbox_filter)

        maintenance_organization = self.request.QUERY_PARAMS.get('maintenance_organization')
        if maintenance_organization:
            queryset = queryset.filter(
                Q(extensions__maintenance_organization=maintenance_organization) |
                Q(extensions__additional_maintenance_organization=maintenance_organization))

        if 'observations' in self.include_fields:
            queryset = queryset.prefetch_related('observation_set__property__allowed_values').prefetch_related('observation_set__value')
        if 'connections' in self.include_fields:
            queryset = queryset.prefetch_related('connections')
        return queryset
Exemplo n.º 5
0
    def get_queryset(self):
        queryset = super(UnitViewSet, self).get_queryset()

        queryset = queryset.prefetch_related('accessibility_shortcomings')
        if self._service_details_requested():
            queryset = queryset.prefetch_related('service_details')
            queryset = queryset.prefetch_related('service_details__service')

        filters = self.request.query_params
        if 'id' in filters:
            id_list = filters['id'].split(',')
            queryset = queryset.filter(id__in=id_list)

        if 'municipality' in filters:
            val = filters['municipality'].lower().strip()
            if len(val) > 0:
                municipalities = val.split(',')
                muni_sq = Q()

                for municipality_raw in municipalities:
                    municipality = municipality_raw.strip()
                    if municipality.startswith('ocd-division'):
                        ocd_id = municipality
                    else:
                        ocd_id = make_muni_ocd_id(municipality)
                    try:
                        muni = Municipality.objects.get(
                            division__ocd_id=ocd_id)
                        muni_sq |= Q(municipality=muni)
                    except Municipality.DoesNotExist:
                        raise ParseError(
                            "municipality with ID '%s' not found" % ocd_id)

                queryset = queryset.filter(muni_sq)

        if 'city_as_department' in filters:
            val = filters['city_as_department'].lower().strip()

            if len(val) > 0:
                deps_uuid = val.split(',')

                deps = Department.objects.filter(
                    uuid__in=deps_uuid).select_related('municipality')
                munis = [d.municipality for d in deps]

                queryset = queryset.filter(
                    root_department__in=deps) | queryset.filter(
                        municipality__in=munis)

        if 'provider_type' in filters:
            val = filters.get('provider_type')
            pr_ids = val.split(',')
            queryset = queryset.filter(provider_type__in=pr_ids)

        if 'provider_type__not' in filters:
            val = filters.get('provider_type__not')
            pr_ids = val.split(',')
            queryset = queryset.exclude(provider_type__in=pr_ids)

        level = filters.get('level', None)
        level_specs = None
        if level:
            if level != 'all':
                level_specs = settings.LEVELS.get(level)

        def service_nodes_by_ancestors(service_node_ids):
            srv_list = set()
            for srv_id in service_node_ids:
                srv_list |= set(
                    ServiceNode.objects.all().by_ancestor(srv_id).values_list(
                        'id', flat=True))
                srv_list.add(int(srv_id))
            return list(srv_list)

        service_nodes = filters.get('service_node', None)

        service_node_ids = None
        if service_nodes:
            service_nodes = service_nodes.lower()
            service_node_ids = service_nodes.split(',')
        elif level_specs:
            if level_specs['type'] == 'include':
                service_node_ids = level_specs['service_nodes']
        if service_node_ids:
            queryset = queryset.filter(
                service_nodes__in=service_nodes_by_ancestors(
                    service_node_ids)).distinct()

        service_node_ids = None
        val = filters.get('exclude_service_nodes', None)
        if val:
            val = val.lower()
            service_node_ids = val.split(',')
        elif level_specs:
            if level_specs['type'] == 'exclude':
                service_node_ids = level_specs['service_nodes']
        if service_node_ids:
            queryset = queryset.exclude(
                service_nodes__in=service_nodes_by_ancestors(
                    service_node_ids)).distinct()

        services = filters.get('service')
        if services is not None:
            queryset = queryset.filter(
                services__in=services.split(',')).distinct()

        if 'division' in filters:
            # Divisions can be specified with form:
            # division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5
            d_list = filters['division'].lower().split(',')
            div_list = []
            for division_path in d_list:
                if division_path.startswith('ocd-division'):
                    muni_ocd_id = division_path
                else:
                    ocd_id_base = r'[\w0-9~_.-]+'
                    match_re = r'(%s)/([\w_-]+):(%s)' % (ocd_id_base,
                                                         ocd_id_base)
                    m = re.match(match_re, division_path, re.U)
                    if not m:
                        raise ParseError(
                            "'division' must be of form 'muni/type:id'")

                    arr = division_path.split('/')
                    muni_ocd_id = make_muni_ocd_id(arr.pop(0), '/'.join(arr))
                try:
                    div = AdministrativeDivision.objects.select_related(
                        'geometry').get(ocd_id=muni_ocd_id)
                except AdministrativeDivision.DoesNotExist:
                    raise ParseError(
                        "administrative division with OCD ID '%s' not found" %
                        muni_ocd_id)
                div_list.append(div)

            if div_list:
                mp = div_list.pop(0).geometry.boundary
                for div in div_list:
                    mp += div.geometry.boundary

            queryset = queryset.filter(location__within=mp)

        if 'lat' in filters and 'lon' in filters:
            try:
                lat = float(filters['lat'])
                lon = float(filters['lon'])
            except ValueError:
                raise ParseError(
                    "'lat' and 'lon' need to be floating point numbers")
            point = Point(lon, lat, srid=4326)

            if 'distance' in filters:
                try:
                    distance = float(filters['distance'])
                    if not distance > 0:
                        raise ValueError()
                except ValueError:
                    raise ParseError(
                        "'distance' needs to be a floating point number")
                queryset = queryset.filter(
                    location__distance_lte=(point, D(m=distance)))
            queryset = queryset.annotate(
                distance=Distance("location", point)).order_by("distance")

        if 'bbox' in filters:
            val = self.request.query_params.get('bbox', None)
            if 'bbox_srid' in filters:
                ref = SpatialReference(filters.get('bbox_srid', None))
            else:
                ref = self.srs
            if val:
                bbox_filter = munigeo_api.build_bbox_filter(
                    ref, val, 'location')
                bbox_geometry_filter = munigeo_api.build_bbox_filter(
                    ref, val, 'geometry')
                queryset = queryset.filter(
                    Q(**bbox_filter) | Q(**bbox_geometry_filter))

        if 'category' in filters:
            services_and_service_nodes = filters.get('category',
                                                     None).split(',')
            service_ids = []
            servicenode_ids = []
            for category in services_and_service_nodes:
                key = category.split(':')[0]
                value = category.split(':')[1]
                if key == 'service':
                    service_ids.append(value)
                elif key == 'service_node':
                    servicenode_ids.append(value)
            queryset = queryset.filter(
                Q(services__in=service_ids)
                | Q(service_nodes__in=service_nodes_by_ancestors(
                    servicenode_ids))).distinct()

        maintenance_organization = self.request.query_params.get(
            'maintenance_organization')
        if maintenance_organization:
            queryset = queryset.filter(
                Q(extensions__maintenance_organization=maintenance_organization
                  )
                | Q(extensions__additional_maintenance_organization=
                    maintenance_organization))

        if 'observations' in self.include_fields:
            queryset = queryset.prefetch_related(
                Prefetch(
                    "observation_set",
                    queryset=Observation.objects.filter(
                        Q(property__expiration=None)
                        | Q(time__gt=timezone.now() -
                            F("property__expiration"))),
                )).prefetch_related("observation_set__property__allowed_values"
                                    ).prefetch_related(
                                        "observation_set__value")

        if 'service_nodes' in self.include_fields:
            queryset = queryset.prefetch_related('service_nodes')

        for field in ['connections', 'accessibility_properties', 'keywords']:
            if self._should_prefetch_field(field):
                queryset = queryset.prefetch_related(field)

        return queryset
Exemplo n.º 6
0
def _filter_event_queryset(queryset, params, srs=None):
    """
    Filter events queryset by params
    (e.g. self.request.QUERY_PARAMS in EventViewSet)
    """
    # Filter by string (case insensitive). This searches from all fields
    # which are marked translatable in translation.py
    val = params.get('text', None)
    if val:
        val = val.lower()
        # Free string search from all translated fields
        fields = EventTranslationOptions.fields
        # and these languages
        languages = [x[0] for x in settings.LANGUAGES]
        qset = Q()
        for field in fields:
            for lang in languages:
                kwarg = {field + '_' + lang + '__icontains': val}
                qset |= Q(**kwarg)
        queryset = queryset.filter(qset)

    val = params.get('last_modified_since', None)
    # This should be in format which dateutil.parser recognizes, e.g.
    # 2014-10-29T12:00:00Z == 2014-10-29T12:00:00+0000 (UTC time)
    # or 2014-10-29T12:00:00+0200 (local time)
    if val:
        dt = parse_time(val, is_start=False)
        queryset = queryset.filter(Q(last_modified_time__gte=dt))

    val = params.get('start', None)
    if val:
        dt = parse_time(val, is_start=True)
        queryset = queryset.filter(Q(end_time__gt=dt) | Q(start_time__gte=dt))

    val = params.get('end', None)
    if val:
        dt = parse_time(val, is_start=False)
        queryset = queryset.filter(Q(end_time__lt=dt) | Q(start_time__lte=dt))

    val = params.get('bbox', None)
    if val:
        bbox_filter = build_bbox_filter(srs, val, 'position')
        places = Place.geo_objects.filter(**bbox_filter)
        queryset = queryset.filter(location__in=places)

    val = params.get('data_source', None)
    if val:
        queryset = queryset.filter(data_source=val)

    # Filter by location id, multiple ids separated by comma
    val = params.get('location', None)
    if val:
        val = val.split(',')
        queryset = queryset.filter(location_id__in=val)

    # Filter by keyword id, multiple ids separated by comma
    val = params.get('keyword', None)
    if val:
        val = val.split(',')
        queryset = queryset.filter(keywords__pk__in=val)

    # Filter only super or sub events if recurring has value
    val = params.get('recurring', None)
    if val:
        val = val.lower()
        if val == 'super':
            queryset = queryset.filter(is_recurring_super=True)
        elif val == 'sub':
            queryset = queryset.filter(is_recurring_super=False)

    val = params.get('max_duration', None)
    if val:
        dur = parse_duration(val)
        cond = 'end_time - start_time <= %s :: interval'
        queryset = queryset.extra(where=[cond], params=[str(dur)])

    val = params.get('min_duration', None)
    if val:
        dur = parse_duration(val)
        cond = 'end_time - start_time >= %s :: interval'
        queryset = queryset.extra(where=[cond], params=[str(dur)])

    return queryset