Ejemplo n.º 1
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(title='Invalid Value',
                                 description='Invalid arguments in URL query:\n{}'.format(e.message))
        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name', 'description']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        try:
            if 'geolocation' in query_params:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                updated_params['__raw__'] = {
                    'geolocation': {
                        '$near': {
                            '$geometry': {
                                'type': 'Point',
                                'coordinates': geolocation_val
                            },
                            '$maxDistance': max_distance
                        },
                    }
                }

        except Exception:
            raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val))

        query_params.update(updated_params)  # update modified params for filtering

        restaurants = Restaurant.objects(**query_params)[start:end]
        for r in restaurants:
            reformat_geolocations_point_field_to_map(r, 'geolocation')

        res.body = {'items': restaurants, 'count': len(restaurants)}
Ejemplo n.º 2
0
 def test_remove(self):
     Restaurant.objects(name__in=['a', 'b']).delete()
     self.assertEquals(len(Restaurant.objects), 0)
Ejemplo n.º 3
0
 def tearDown(self):
     Restaurant.objects(id__in=[r.id for r in self.restaurants]).delete()
Ejemplo n.º 4
0
 def tearDown(self):
     Restaurant.objects(id__in=[r.id for r in self.restaurants]).delete()
Ejemplo n.º 5
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(
                title='Invalid Value',
                description='Invalid arguments in URL query:\n{}'.format(
                    e.message))

        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        # skip updating query_params for filters on list fields like tags,
        # since mongoengine filters directly by finding any Menu that has tags of that value
        # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag

        for item in ['price', 'rating']:
            if item in query_params:
                range = query_params.pop(item)
                r_min, r_max = min_max(range, type='float')
                updated_params['{}__gte'.format(item)] = r_min
                updated_params['{}__lte'.format(item)] = r_max

        # for convenience, we allow users to search for menus by their restaurant's geolocation too
        if 'geolocation' in query_params:
            try:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(
                    query_params.pop('maxDistance',
                                     constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                restaurant_query_params = {
                    '__raw__': {
                        'geolocation': {
                            '$near': {
                                '$geometry': {
                                    'type': 'Point',
                                    'coordinates': geolocation_val
                                },
                                '$maxDistance': max_distance
                            },
                        }
                    }
                }
                # return list of restaurants satisfying geolocation requirements
                restaurants = Restaurant.objects(**restaurant_query_params)

                # we found nearby restaurants, filter menus further to menus from these restaurants only
                updated_params['__raw__'] = {
                    "restaurant.$id": {
                        "$in": [r.id for r in restaurants]
                    }
                }

            except Exception:
                raise HTTPBadRequest(
                    'Invalid Value',
                    'geolocation supplied is invalid: {}'.format(
                        geolocation_val))

        query_params.update(
            updated_params)  # update modified params for filtering
        menus = Menu.objects(**query_params)[start:end]

        res.body = {'items': menus, 'count': len(menus)}
Ejemplo n.º 6
0
 def tearDown(self):
     Restaurant.objects(id__in=[self.restaurant.id]).delete()
     Menu.objects().delete()
Ejemplo n.º 7
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(title='Invalid Value',
                                 description='Invalid arguments in URL query:\n{}'.format(e.message))

        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        # skip updating query_params for filters on list fields like tags,
        # since mongoengine filters directly by finding any Menu that has tags of that value
        # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag

        for item in ['price', 'rating']:
            if item in query_params:
                range = query_params.pop(item)
                r_min, r_max = min_max(range, type='float')
                updated_params['{}__gte'.format(item)] = r_min
                updated_params['{}__lte'.format(item)] = r_max

        # for convenience, we allow users to search for menus by their restaurant's geolocation too
        if 'geolocation' in query_params:
            try:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                restaurant_query_params = {
                    '__raw__': {
                        'geolocation': {
                            '$near': {
                                '$geometry': {
                                    'type': 'Point',
                                    'coordinates': geolocation_val
                                },
                                '$maxDistance': max_distance
                            },
                        }
                    }
                }
                # return list of restaurants satisfying geolocation requirements
                restaurants = Restaurant.objects(**restaurant_query_params)

                # we found nearby restaurants, filter menus further to menus from these restaurants only
                updated_params['__raw__'] = {
                    "restaurant.$id": {
                        "$in": [r.id for r in restaurants]
                    }
                }

            except Exception:
                raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val))

        query_params.update(updated_params)  # update modified params for filtering
        menus = Menu.objects(**query_params)[start:end]

        res.body = {'items': menus, 'count': len(menus)}