Example #1
0
    def build_filters(self, filters=None, request=None):
        basedn = None
        filter = None

        parts = []
        for arg_name, arg_value in filters.items():
            if arg_name in ['limit', 'offset']:  # XXX permit limit arg
                continue

            if arg_name not in self.fields or arg_name in ['limit']:
                raise InvalidFilterError(
                    "Not a valid filter: {0}".format(arg_name))

            if getattr(self.fields[arg_name], 'is_related', False):
                method = getattr(self, 'filter_on_{0}'.format(arg_name), None)
                if method:
                    basedn = method(arg_value)
                    continue
                else:
                    raise InvalidFilterError(
                        "Cannot filter on a relation field: {0}".format(
                            arg_name))

            model_field_name = self.get_model_field_name(arg_name)
            part = eq(model_field_name, arg_value)
            parts.append(part)

        if parts:
            filter = opand(*parts)
        search_params = SearchParams(basedn=basedn, filter=filter)

        return search_params
Example #2
0
def poly_from_bbox(bbox_val):
    points = bbox_val.split(',')
    if len(points) != 4:
        raise InvalidFilterError("bbox must be in format 'left,bottom,right,top'")
    try:
        return Polygon.from_bbox( [float(p) for p in points])
    except ValueError:
        raise InvalidFilterError("bbox values must be floating point")
Example #3
0
    def check_filtering(self,
                        field_name,
                        filter_type='exact',
                        filter_bits=None):
        """
        Given a field name, a optional filter type and an optional list of
        additional relations, determine if a field can be filtered on.

        If a filter does not meet the needed conditions, it should raise an
        ``InvalidFilterError``.

        If the filter meets the conditions, a list of attribute names (not
        field names) will be returned.
        """
        if filter_bits is None:
            filter_bits = []

        if not field_name in self._meta.filtering:
            raise InvalidFilterError(
                "The '%s' field does not allow filtering." % field_name)

        # Check to see if it's an allowed lookup type.
        if not self._meta.filtering[field_name] in (ALL, ALL_WITH_RELATIONS):
            # Must be an explicit whitelist.
            if not filter_type in self._meta.filtering[field_name]:
                raise InvalidFilterError(
                    "'%s' is not an allowed filter on the '%s' field." %
                    (filter_type, field_name))

        if self.fields[field_name].attribute is None:
            raise InvalidFilterError(
                "The '%s' field has no 'attribute' for searching with." %
                field_name)

        # Check to see if it's a relational lookup and if that's allowed.
        if len(filter_bits):
            if not getattr(self.fields[field_name], 'is_related', False):
                raise InvalidFilterError(
                    "The '%s' field does not support relations." % field_name)

            if not self._meta.filtering[field_name] == ALL_WITH_RELATIONS:
                raise InvalidFilterError(
                    "Lookups are not allowed more than one level deep on the '%s' field."
                    % field_name)

            # Recursively descend through the remaining lookups in the filter,
            # if any. We should ensure that all along the way, we're allowed
            # to filter on that field by the related resource.
            related_resource = self.fields[field_name].get_related_resource(
                None)
            return [self.fields[field_name].attribute
                    ] + related_resource.check_filtering(
                        filter_bits[0], filter_type, filter_bits[1:])

        return [self.fields[field_name].attribute]
Example #4
0
    def check_filtering(self, field_name, filter_type='contains'):
        if not field_name in self._meta.filtering:
            raise InvalidFilterError(
                "The '%s' field does not allow filtering." % field_name)

        if not filter_type in self._meta.filtering[field_name]:
            raise InvalidFilterError(
                "'%s' is not an allowed filter on the '%s' field." %
                (filter_type, field_name))

        return True
Example #5
0
def srid_to_srs(srid):
    if not srid:
        srid = DEFAULT_SRID
    try:
        srid = int(srid)
    except ValueError:
        raise InvalidFilterError("'srid' must be an integer")
    try:
        srs = SpatialReference(srid)
    except SRSException:
        raise InvalidFilterError("SRID %d not found (try 4326 for GPS coordinate system)" % srid)
    return srs
Example #6
0
    def build_filters(self, filters=None):
        if filters is None:
            raise InvalidFilterError("Filter fields  are necessaries.")

        if 'session' not in filters:
            raise InvalidFilterError("Session field is necessary.")

        if 'number' not in filters:
            raise InvalidFilterError("Number field is necessary.")

        orm_filters = super(VoteResource, self).build_filters(filters)
        return orm_filters
Example #7
0
    def get_query_terms(self, field_name):
        """ Helper to determine supported filter operations for a field """

        if field_name not in self.fields:
            raise InvalidFilterError("The '%s' field is not a valid field" % field_name)

        try:
            django_field_name = self.fields[field_name].attribute
            django_field = self._meta.object_class._meta.get_field(django_field_name)
            if hasattr(django_field, "field"):
                django_field = django_field.field  # related field
        except FieldDoesNotExist:
            raise InvalidFilterError("The '%s' field is not a valid field name" % field_name)

        return django_field.get_lookups().keys()
Example #8
0
    def check_filtering(self, field_name, filter_type="exact", filter_bits=None):
        """ Overrides BaseModelResource.check_filtering to work with self.build_filters above """

        if filter_bits is None:
            filter_bits = []

        if field_name not in self._meta.filtering:
            raise InvalidFilterError("The '%s' field does not allow filtering." % field_name)

        # Check to see if it's an allowed lookup type.
        if filter_type != "exact" and self._meta.filtering[field_name] not in (ALL, ALL_WITH_RELATIONS):
            # Must be an explicit whitelist.
            if filter_type not in self._meta.filtering[field_name]:
                raise InvalidFilterError("'%s' is not an allowed filter on the '%s' field." % (filter_type, field_name))

        if self.fields[field_name].attribute is None:
            raise InvalidFilterError("The '%s' field has no 'attribute' for searching with." % field_name)

        if len(filter_bits) == 0:
            # Only a field provided, match with provided filter type
            return [self.fields[field_name].attribute] + [filter_type]

        elif len(filter_bits) == 1 and filter_bits[0] in self.get_query_terms(field_name):
            # Match with valid filter type (i.e. contains, startswith, Etc.)
            return [self.fields[field_name].attribute] + filter_bits

        else:
            # Check to see if it's a relational lookup and if that's allowed.
            if not getattr(self.fields[field_name], "is_related", False):
                raise InvalidFilterError("The '%s' field does not support relations." % field_name)

            if not self._meta.filtering[field_name] == ALL_WITH_RELATIONS:
                raise InvalidFilterError(
                    "Lookups are not allowed more than one level deep on the '%s' field." % field_name
                )

            # Recursively descend through the remaining lookups in the filter,
            # if any. We should ensure that all along the way, we're allowed
            # to filter on that field by the related resource.
            related_resource = self.fields[field_name].get_related_resource(None)

            next_field_name = filter_bits[0]
            next_filter_bits = filter_bits[1:]
            next_filter_type = related_resource.resolve_filter_type(next_field_name, next_filter_bits, filter_type)

            return [self.fields[field_name].attribute] + related_resource.check_filtering(
                next_field_name, next_filter_type, next_filter_bits
            )
Example #9
0
    def dispatch(self, request_type, request, **kwargs):
        """
        Override of the default dispatch method for a resource.  This
        provides front end level caching for TastyPie APIs.  This requires
        fairly high level tinkering with some API basics but provides
        very effective caching.
        """
        # Since we are hitting this before other validation
        # Ensure that a format has been passed in.

        if getattr(settings, 'API_CACHE_ENABLE', False):

            response_format = request.GET.get('format', None)
            if response_format is None:
                if settings.TASTYPIE_DEFAULT_FORMATS:
                    response_format = settings.TASTYPIE_DEFAULT_FORMATS[0]
                else:
                    raise InvalidFilterError(u'Format is required.')
            data = self.get_cache(request, force_jsonp=self.is_jsonp(request))
            if data:
                if self.is_jsonp(request):
                    data = self.wrap_json_response(request, data)
                # If the request is a valid cache format, return it.
                return_string = data
                content_type = self._get_valid_content_type(response_format)
                return HttpResponse(return_string,
                                    content_type=content_type,
                                    status=200)
            else:
                # If no cache is found go 'Move Along'...
                return super(CachedResource,
                             self).dispatch(request_type, request, **kwargs)
        else:
            return super(CachedResource,
                         self).dispatch(request_type, request, **kwargs)
Example #10
0
    def apply_filters(self, request, filters):
        """
        An ORM-specific implementation of ``apply_filters``.
        
        Emulates native tastypie django-specific filters.
        """

        qs_filters = []

        qs_set_filters = {}

        for filter_expr, value in filters.items():
            filter_bits = filter_expr.split(LOOKUP_SEP)
            field_name = filter_bits.pop(0)
            filter_type = 'exact'

            if not field_name in self.fields:
                # It's not a field we know about. Move along citizen.
                continue

            # resolve filter type
            if len(filter_bits) and filter_bits[-1] in QUERY_TERMS:
                filter_type = filter_bits.pop()

            lookup_bits = self.check_filtering(field_name, filter_type, filter_bits)

            # check, whether the specified atribute is a single value or set;
            # also get final attribute type
            # (Pony ORM-specific)
            is_set = False
            t = self._meta.object_class
            for bit in lookup_bits:
                a = getattr(t,bit,None)
                if not a:
                    raise InvalidFilterError("The attribute %s not found for %s" % (bit,t))
                t = a.py_type
                if issubclass(t,orm.core.Entity) and isinstance(a,orm.Set):
                    is_set = True

            # split single and set-oriented filters to emulate django filters
            if not is_set:
                flt = self.combine_lookup_and_value(t,filter_type,lookup_bits,value,'o.')
                if flt:
                    qs_filters.append(flt)
            else:
                set_object = tuple(lookup_bits[:-1])
                flt = self.combine_lookup_and_value(t,filter_type,lookup_bits[-1:],value,'p.')
                if flt:
                    if not set_object in qs_set_filters:
                        qs_set_filters[set_object] = []
                    qs_set_filters[set_object].append(flt)
        q = self.get_object_list(request)
        for f in qs_filters:
            q.filter(f)
        for set_object in qs_set_filters:
            q.filter("orm.exists(p for p in %s if %s)" % (
                'o.'+'.'.join(set_object),
                ' and '.join([('(%s)' % flt) for flt in qs_set_filters[set_object]])
            ))
        return q
Example #11
0
    def build_filters(self, filters={}):
        orm_filters = super(ModelResource, self).build_filters(filters)

        if ('Q' in filters):
            if (not 'Q' in self._meta.filtering
                    or self._meta.filtering['Q'] is not ALL):
                raise InvalidFilterError(
                    'Q filtering is not allowed for this resource.')

            q = re.sub('from|import|del|sleep|while|for', '', filters['Q'])
            try:
                orm_filters.update({'Q': (eval(q))})
            except:
                raise InvalidFilterError('Q has wrong syntax')

        return orm_filters
Example #12
0
    def _date_consumer(key, value):
        if '.' in key and key.split(".")[0] == field:
            prefix, qualifier = key.split(".", maxsplit=1)
            try:
                return date_filter(qualifier, value)
            except ValueError as e:
                raise InvalidFilterError(str(e))

        return {}
Example #13
0
    def build_filters(self, filters=None):
        res = super(AlbumResource, self).build_filters(filters)

        if 'year' in filters:
            try:
                res.update({'year': int(filters['year'])})
            except:
                raise InvalidFilterError('year must be an integer!')
        return res
Example #14
0
    def build_filters(self, filters=None):
        res = super(ReviewResource, self).build_filters(filters)

        if 'tid' in filters:
            try:
                res.update({'tid': str(filters['tid'])})
            except:
                raise InvalidFilterError('tid must be an integer!')
        return res
Example #15
0
 def apply_filters(self, request, applicable_filters):
     semi_filtered = self.get_object_list(request)
     if applicable_filters:
         try:
             if hasattr(applicable_filters, 'keys'):
                 semi_filtered = semi_filtered.filter(**applicable_filters)
             else:
                 semi_filtered = semi_filtered.filter(applicable_filters)
         except Exception, ex:
             raise InvalidFilterError('%s' % ex)
Example #16
0
 def apply_sorting(self, objects, options=None):
     if options and 'lon' in options and 'lat' in options:
         try:
             lat = float(options['lat'])
             lon = float(options['lon'])
         except ValueError:
             raise InvalidFilterError("'lon' and 'lat' need to be floats")
         pnt = Point(lon, lat, srid=4326)
         pnt.transform(PROJECTION_SRID)
         objects = objects.distance(pnt).order_by('distance')
     return super(POIResource, self).apply_sorting(objects, options)
Example #17
0
    def check_filtering(self, field_name, filter_type='exact', filter_bits=None):
        if filter_bits is None:
            filter_bits = []
        if field_name not in self._meta.filtering:
            raise InvalidFilterError("The '%s' field does not allow filtering." % field_name)

        # Check to see if it's an allowed lookup type.
        if self._meta.filtering[field_name] not in QUERY_TERMS:
            # Must be an explicit whitelist.
            if filter_type not in self._meta.filtering[field_name]:
                raise InvalidFilterError(
                    "'%s' is not an allowed filter on the '%s' field." % (
                        filter_type, field_name
                        ))

        if self.fields[field_name].attribute is None:
            raise InvalidFilterError(
                "The '%s' field has no 'attribute' for searching with." % field_name
                )
        return [self.fields[field_name].attribute]
Example #18
0
 def build_filters(self, filters=None, **kwargs):
     orm_filters = super(TemplateSchemeResource, self).build_filters(filters, **kwargs)
     if "project__id" in filters and "template_id" in filters:
         template_id = filters.pop("template_id")[0]
         project_id = filters.pop("project__id")[0]
         try:
             template = TaskTemplate.objects.get(pk=template_id, project_id=project_id)
         except TaskTemplate.DoesNotExist:
             message = "flow template[id={template_id}] in project[id={project_id}] does not exist".format(
                 template_id=template_id, project_id=project_id
             )
             logger.error(message)
             raise InvalidFilterError(message)
         except Exception as e:
             message = "Error on getting template[id={template_id}] in project[id={project_id}]: {error}".format(
                 template_id=template_id, project_id=project_id, error=e
             )
             logger.error(message)
             raise InvalidFilterError(message)
         orm_filters.update({"template__template_id": template.pipeline_template.template_id})
     elif "pk" not in filters:
         # 不允许请求全部执行方案
         orm_filters.update({"unique_id": ""})
     return orm_filters
Example #19
0
 def combine_lookup_and_value(self,final_type,filter_type,lookup_bits,value,prefix):
     attribute = prefix + '.'.join(lookup_bits)
     value_convertor = QUERY_TERM_CONVERT_VALUE[final_type]
     if filter_type == 'isnull':
         value_convertor = QUERY_TERM_CONVERT_VALUE[bool]
     elif filter_type in ('day','month','year'):
         value_convertor = QUERY_TERM_CONVERT_VALUE[int]
     try:
         if filter_type in ('in','range'):
             value = [repr(value_convertor(v)) for v in value.split(',')]
         else:
             value = repr(value_convertor(value))
     except:
         raise InvalidFilterError("Value %s is not allowed for '%s' filter with attribute '%s'" % (repr(value),filter_type,'.'.join(lookup_bits)))
     expr = QUERY_TERMS[filter_type]
     return expr(attribute,value)
Example #20
0
    def build_filters(self, filters=None):
        if filters is None:
            filters = {}

        orm_filters = super(PostResource, self).build_filters(filters)

        if "member_id" in filters:
            try:
                member = Member.objects.get(pk=filters['member_id'])
            except Member.DoesNotExist:
                raise InvalidFilterError("Could not find member id %s" % filters['member_id'])
            links = Link.objects.for_model(member)
            feeds = Feed.objects.filter(url__in=map(lambda x: x.url, links), is_active=True)

            orm_filters["feed__in"] = feeds

        return orm_filters
Example #21
0
    def build_filters(self, filters=None):
        # Override the filters so we can stop Tastypie silently ignoring
        # invalid filters. That will cause an invalid filtering just to return
        # lots of results.
        if filters is None:
            filters = {}
        qs_filters = {}

        for filter_expr, value in filters.items():
            filter_bits = filter_expr.split(LOOKUP_SEP)
            field_name = filter_bits.pop(0)
            filter_type = 'exact'

            if not field_name in self.fields:
                # Don't just ignore this. Tell the world. Shame I have to
                # override all this, just to do this.
                raise InvalidFilterError('Not a valid filtering field: %s' %
                                         field_name)

            if len(filter_bits) and filter_bits[-1] in QUERY_TERMS:
                filter_type = filter_bits.pop()

            lookup_bits = self.check_filtering(field_name, filter_type,
                                               filter_bits)

            if value in ['true', 'True', True]:
                value = True
            elif value in ['false', 'False', False]:
                value = False
            elif value in ('nil', 'none', 'None', None):
                value = None

            # Split on ',' if not empty string and either an in or range
            # filter.
            if filter_type in ('in', 'range') and len(value):
                if hasattr(filters, 'getlist'):
                    value = filters.getlist(filter_expr)
                else:
                    value = value.split(',')

            db_field_name = LOOKUP_SEP.join(lookup_bits)
            qs_filter = '%s%s%s' % (db_field_name, LOOKUP_SEP, filter_type)
            qs_filters[qs_filter] = value

        return dict_strip_unicode_keys(qs_filters)
Example #22
0
    def build_filters(self, filters=None, ignore_bad_filters=True):
        """
        Example:
          {"or":[{"and":[{"not":{"status":"S"}},{"performer":null}]},{"status":"P"}]}
        Result:
          (OR: (AND: (NOT (AND: (u'status', u'S'))), (u'performer__isnull', True)), (u'status', u'P'))
        """

        if filters is None:
            filters = {}
        orm_filters = {}
        qset = {}
        if ('filter' in filters):
            query = filters['filter']
            try:
                qset = self.parse_filter_condition(json.loads(query))
            except Exception, ex:
                raise InvalidFilterError("%s" % ex)
Example #23
0
    def obj_get_list(self, bundle, **kwargs):
        result = super(PersonResource, self).obj_get_list(bundle, **kwargs)

        filters = bundle.request.GET.copy()
        if 'has_contacts' in filters:
            # Count the number of contacts the person has
            filters['has_contacts'] = filters['has_contacts'].lower()
            if filters['has_contacts'] == 'true':
                result = result.has_contacts()
            elif filters['has_contacts'] == 'false':
                result = result.doesnt_have_contacts()
            else:
                raise InvalidFilterError(
                    "'has_contacts' field must either be 'true' or 'false'.")

        if 'instance_id' in filters:
            result = result.filter(
                writeit_instances__id=filters['instance_id'])

        return result
Example #24
0
    def check_filtering(self, field_name, filter_type='exact', filter_bits=None):
        """Verify that filter_bits does not begin with a related field lookup.

        This allows the user to make filters that begin with a related lookup,
        but not filters that involve multiple related lookups ("second-order"
        lookups).
        """
        # We want to call the super method right before we return, so wrap it
        # in a lambda expression -- that way we know it's always called right
        result = lambda: (super(FirstOrderResource, self).
                          check_filtering(field_name, filter_type, filter_bits))
        if filter_bits and field_name in self.fields:
            # NB: filter_bits must be non-empty in addition to not being None
            # get the field object
            target_field = self.fields[field_name]
            # Figure out if it's a relationship field
            try:
                is_related = target_field.is_related
            except AttributeError:
                is_related = False
            if not is_related:
                # It isn't, so we don't have to do anything
                return result()
            # get the resource at the "other end" of this relationship
            target_resource = target_field.get_related_resource(None)
            # get the next part of the filter
            next_filter = filter_bits[0]
            if next_filter not in target_resource.fields:
                # the filter doesn't refer to a field on the resource
                return result()
            next_field = target_resource.fields[next_filter]
            try:
                is_second_order = next_field.is_related
            except AttributeError:
                is_second_order = False
            if is_second_order:
                # The filter refers to a relationship field on the resource,
                # so we need to abort since we can't handle those correctly
                raise InvalidFilterError("Second-order relationship traversal"+
                                         " is not allowed.")
        return result()
Example #25
0
 def build_filters(self, filters=None, **kwargs):
     orm_filters = super(TemplateSchemeResource,
                         self).build_filters(filters, **kwargs)
     if 'project__id' in filters and 'template_id' in filters:
         template_id = filters.pop('template_id')[0]
         project_id = filters.pop('project__id')[0]
         try:
             template = TaskTemplate.objects.get(pk=template_id,
                                                 project_id=project_id)
         except TaskTemplate.DoesNotExist:
             message = 'flow template[id={template_id}] in project[id={project_id}] does not exist'.format(
                 template_id=template_id, project_id=project_id)
             logger.error(message)
             raise InvalidFilterError(message)
         orm_filters.update({
             'template__template_id':
             template.pipeline_template.template_id
         })
     elif 'pk' not in filters:
         # 不允许请求全部执行方案
         orm_filters.update({'unique_id': ''})
     return orm_filters
Example #26
0
    def build_filters(self, filters=None, ignore_bad_filters=False):
        subjects = None
        ids = None
        user = None

        if filters is None:
            filters = {}

        if 'subjects' in filters:
            subjects = filters['subjects']
            del filters['subjects']

        if 'ids' in filters:
            ids = filters['ids']
            del filters['ids']

        if 'user' in filters:
            user = filters['user']
            del filters['user']

        orm_filters = super(ImageResource,
                            self).build_filters(filters, ignore_bad_filters)

        if subjects:
            from astrobin_apps_platesolving.models import Solution

            def fix_catalog(name):
                capitalize = (
                    'ngc',
                    'm',
                    'b',
                    'ic',
                    'ugc',
                    'pgc',
                )
                if name.lower() in [x.lower() for x in capitalize]:
                    return name.upper() + ' '
                remove = ('name', )
                if name.lower() in [x.lower() for x in remove]:
                    return ''
                return name + ' '

            def fix_name(name):
                import re
                fix = re.compile('^(?P<catalog>M|NGC)(?P<name>\d+)',
                                 re.IGNORECASE)
                m = fix.match(name)
                if m:
                    return '%s%s' % (fix_catalog(
                        m.group('catalog')), m.group('name'))
                return name

            qs = Solution.objects.filter(
                objects_in_field__icontains=fix_name(subjects))[:100]
            orm_filters['pk__in'] = [i.object_id for i in qs]

        if ids:
            max = 100
            if len(ids) > max:
                raise InvalidFilterError(
                    f'Please do not request over {max} image IDs')
            orm_filters['pk__in'] = ids.split(',')

        if user:
            orm_filters['user__username'] = user

        return orm_filters