Example #1
0
 def get(self, id, region=None, lon=None, lat=None):
     self.region = i_manager.get_region(region, lon, lat)
     args = self.parsers["get"].parse_args()
     args.update({
         "uri": transform_id(id),
         "_current_datetime": datetime.datetime.utcnow()
     })
     response = i_manager.dispatch(args,
                                   "place_uri",
                                   instance_name=self.region)
     return response, 200
Example #2
0
    def get(self, id, region=None, lon=None, lat=None):
        args = self.parsers["get"].parse_args()
        args.update({"uri": transform_id(id), "_current_datetime": datetime.utcnow()})
        if any([region, lon, lat]):
            self.region = i_manager.get_region(region, lon, lat)
            timezone.set_request_timezone(self.region)
            response = i_manager.dispatch(args, "place_uri", instance_name=self.region)
        else:
            user = authentication.get_user(token=authentication.get_token(), abort_if_no_token=False)
            available_instances = get_all_available_instances(user)
            autocomplete = global_autocomplete.get('bragi')
            if not autocomplete:
                raise TechnicalError('world wide autocompletion service not available')
            response = autocomplete.get_by_uri(args["uri"], instances=available_instances)

        return response, 200
Example #3
0
    def get(self, id, region=None, lon=None, lat=None):
        args = self.parsers["get"].parse_args()
        args.update({
            "uri": transform_id(id),
            "_current_datetime": datetime.utcnow()
        })
        request_id = "places_{}".format(flask.request.id)
        args["request_id"] = request_id

        if any([region, lon, lat]):
            self.region = i_manager.get_region(region, lon, lat)
            timezone.set_request_timezone(self.region)
            response = i_manager.dispatch(args,
                                          "place_uri",
                                          instance_name=self.region)
        else:
            user = authentication.get_user(token=authentication.get_token(),
                                           abort_if_no_token=False)
            available_instances = get_all_available_instances(
                user, exclude_backend='kraken')

            # If no instance available most probably due to database error
            if (not user) and (not available_instances):
                raise TechnicalError(
                    'world wide autocompletion service not available temporarily'
                )

            # If parameter '_autocomplete' is absent use 'bragi' as default value
            if args["_autocomplete"] is None:
                args["_autocomplete"] = app.config.get(
                    'DEFAULT_AUTOCOMPLETE_BACKEND', 'bragi')
            autocomplete = global_autocomplete.get(args["_autocomplete"])
            if not autocomplete:
                raise TechnicalError(
                    'world wide autocompletion service not available')
            response = autocomplete.get_by_uri(args["uri"],
                                               request_id=request_id,
                                               instances=available_instances)

        return response, 200
Example #4
0
 def get(self, region=None, lon=None, lat=None, uri=None):
     self.region = i_manager.get_region(region, lon, lat)
     timezone.set_request_timezone(self.region)
     args = self.parsers["get"].parse_args()
     if uri:
         if uri[-1] == '/':
             uri = uri[:-1]
         uris = uri.split("/")
         if len(uris) >= 2:
             args["uri"] = transform_id(uris[-1])
             # for coherence we check the type of the object
             obj_type = uris[-2]
             if obj_type not in places_types:
                 abort(404,
                       message='places_nearby api not available for {}'.
                       format(obj_type))
         else:
             abort(404)
     elif lon and lat:
         # check if lon and lat can be converted to float
         float(lon)
         float(lat)
         args["uri"] = "coord:{}:{}".format(lon, lat)
     else:
         abort(404)
     args["filter"] = args["filter"].replace(".id", ".uri")
     self._register_interpreted_parameters(args)
     response = i_manager.dispatch(args,
                                   "places_nearby",
                                   instance_name=self.region)
     response = marshal(response, places_nearby)
     if i_manager.instances[
             self.region].bss_provider and args["bss_stands"]:
         response["places_nearby"] = bss_provider_manager.handle_places(
             response["places_nearby"])
     return response, 200
Example #5
0
    def parse_args(self, region=None, uri=None):
        args = self.parsers['get'].parse_args()

        if args.get('max_duration_to_pt') is not None:
            # retrocompatibility: max_duration_to_pt override all individual value by mode
            args['max_walking_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bike_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bss_duration_to_pt'] = args['max_duration_to_pt']
            args['max_car_duration_to_pt'] = args['max_duration_to_pt']
            args['max_car_no_park_duration_to_pt'] = args['max_duration_to_pt']

        if args['data_freshness'] is None:
            # retrocompatibilty handling
            args['data_freshness'] = 'adapted_schedule' if args[
                'disruption_active'] is True else 'base_schedule'

        # TODO : Changer le protobuff pour que ce soit propre
        if args['destination_mode'] == 'vls':
            args['destination_mode'] = 'bss'
        if args['origin_mode'] == 'vls':
            args['origin_mode'] = 'bss'

        # for last and first section mode retrocompatibility
        if 'first_section_mode' in args and args['first_section_mode']:
            args['origin_mode'] = args['first_section_mode']
        if 'last_section_mode' in args and args['last_section_mode']:
            args['destination_mode'] = args['last_section_mode']

        if region:
            if uri:
                objects = uri.split('/')
                if objects and len(objects) % 2 == 0:
                    args['origin'] = objects[-1]
                else:
                    abort(503,
                          message="Unable to compute journeys "
                          "from this object")

        # we transform the origin/destination url to add information
        if args['origin']:
            args['origin'] = transform_id(args['origin'])
        if args['destination']:
            args['destination'] = transform_id(args['destination'])

        if args['datetime']:
            args['original_datetime'] = args['datetime']
        else:
            args['original_datetime'] = pytz.UTC.localize(
                args['_current_datetime'])

        if args.get('traveler_type'):
            traveler_profile = TravelerProfile.make_traveler_profile(
                region, args['traveler_type'])
            traveler_profile.override_params(args)

        # We set default modes for fallback modes.
        # The reason why we cannot put default values in parser_get.add_argument() is that, if we do so,
        # fallback modes will always have a value, and traveler_type will never override fallback modes.
        if args.get('origin_mode') is None:
            args['origin_mode'] = ['walking']
        if args.get('destination_mode') is None:
            args['destination_mode'] = ['walking']

        return args
Example #6
0
    def get(self, region=None, lon=None, lat=None, uri=None):
        args = self.parsers['get'].parse_args()

        if args.get('traveler_type') is not None:
            traveler_profile = TravelerProfile.make_traveler_profile(
                region, args['traveler_type'])
            traveler_profile.override_params(args)

        # We set default modes for fallback modes.
        # The reason why we cannot put default values in parser_get.add_argument() is that, if we do so,
        # fallback modes will always have a value, and traveler_type will never override fallback modes.
        if args.get('origin_mode') is None:
            args['origin_mode'] = ['walking']
        if args.get('destination_mode') is None:
            args['destination_mode'] = ['walking']

        if args['max_duration_to_pt'] is not None:
            #retrocompatibility: max_duration_to_pt override all individual value by mode
            args['max_walking_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bike_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bss_duration_to_pt'] = args['max_duration_to_pt']
            args['max_car_duration_to_pt'] = args['max_duration_to_pt']

        if args['data_freshness'] is None:
            # retrocompatibilty handling
            args['data_freshness'] = \
                'adapted_schedule' if args['disruption_active'] is True else 'base_schedule'

        # TODO : Changer le protobuff pour que ce soit propre
        if args['destination_mode'] == 'vls':
            args['destination_mode'] = 'bss'
        if args['origin_mode'] == 'vls':
            args['origin_mode'] = 'bss'

        #count override min_nb_journey or max_nb_journey
        if 'count' in args and args['count']:
            args['min_nb_journeys'] = args['count']
            args['max_nb_journeys'] = args['count']

        # for last and first section mode retrocompatibility
        if 'first_section_mode' in args and args['first_section_mode']:
            args['origin_mode'] = args['first_section_mode']
        if 'last_section_mode' in args and args['last_section_mode']:
            args['destination_mode'] = args['last_section_mode']

        if region:
            self.region = i_manager.get_region(region)
            if uri:
                objects = uri.split('/')
                if objects and len(objects) % 2 == 0:
                    args['origin'] = objects[-1]
                else:
                    abort(503,
                          message="Unable to compute journeys "
                          "from this object")

        def _set_specific_params(mod):
            if args.get('max_duration') is None:
                args['max_duration'] = mod.max_duration
            if args.get('_walking_transfer_penalty') is None:
                args[
                    '_walking_transfer_penalty'] = mod.walking_transfer_penalty
            if args.get('_night_bus_filter_base_factor') is None:
                args[
                    '_night_bus_filter_base_factor'] = mod.night_bus_filter_base_factor
            if args.get('_night_bus_filter_max_factor') is None:
                args[
                    '_night_bus_filter_max_factor'] = mod.night_bus_filter_max_factor

        if region:
            _set_specific_params(i_manager.instances[region])
        else:
            _set_specific_params(default_values)

        if not (args['destination'] or args['origin']):
            abort(
                400,
                message=
                "you should at least provide either a 'from' or a 'to' argument"
            )

        if args['debug']:
            g.debug = True

        #we transform the origin/destination url to add information
        if args['origin']:
            args['origin'] = transform_id(args['origin'])
        if args['destination']:
            args['destination'] = transform_id(args['destination'])

        if not args['datetime']:
            args['datetime'] = datetime.now()
            args['datetime'] = args['datetime'].replace(hour=13, minute=37)

        if not region:
            #TODO how to handle lon/lat ? don't we have to override args['origin'] ?
            possible_regions = compute_regions(args)
        else:
            possible_regions = [region]

        if args['destination'] and args['origin']:
            api = 'journeys'
        else:
            api = 'isochrone'

        # we save the original datetime for debuging purpose
        args['original_datetime'] = args['datetime']
        #we add the interpreted parameters to the stats
        self._register_interpreted_parameters(args)

        logging.getLogger(__name__).debug(
            "We are about to ask journeys on regions : {}".format(
                possible_regions))
        #we want to store the different errors
        responses = {}
        for r in possible_regions:
            self.region = r

            #we store the region in the 'g' object, which is local to a request
            set_request_timezone(self.region)

            if args['debug']:
                # In debug we store all queried region
                if not hasattr(g, 'regions_called'):
                    g.regions_called = []
                g.regions_called.append(r)

            original_datetime = args['original_datetime']
            new_datetime = self.convert_to_utc(original_datetime)
            args['datetime'] = date_to_timestamp(new_datetime)

            response = i_manager.dispatch(args, api, instance_name=self.region)

            if response.HasField(b'error') \
                    and len(possible_regions) != 1:
                logging.getLogger(__name__).debug(
                    "impossible to find journeys for the region {},"
                    " we'll try the next possible region ".format(r))

                if args['debug']:
                    # In debug we store all errors
                    if not hasattr(g, 'errors_by_region'):
                        g.errors_by_region = {}
                    g.errors_by_region[r] = response.error

                responses[r] = response
                continue

            if all(
                    map(
                        lambda j: j.type in
                        ("non_pt_walk", "non_pt_bike", "non_pt_bss", "car"),
                        response.journeys)):
                responses[r] = response
                continue

            return response

        for response in responses.values():
            if not response.HasField(b"error"):
                return response

        # if no response have been found for all the possible regions, we have a problem
        # if all response had the same error we give it, else we give a generic 'no solution' error
        first_response = responses.values()[0]
        if all(r.error.id == first_response.error.id
               for r in responses.values()):
            return first_response

        resp = response_pb2.Response()
        er = resp.error
        er.id = response_pb2.Error.no_solution
        er.message = "No journey found"

        return resp
Example #7
0
    def post(self, region=None, lon=None, lat=None, uri=None):
        args = self.parsers['post'].parse_args()
        if args['traveler_type']:
            profile = travelers_profile[args['traveler_type']]
            profile.override_params(args)

        #check that we have at least one departure and one arrival
        if len(args['from']) == 0:
            abort(400, message="from argument must contain at least one item")
        if len(args['to']) == 0:
            abort(400, message="to argument must contain at least one item")

        # TODO : Changer le protobuff pour que ce soit propre
        if args['destination_mode'] == 'vls':
            args['destination_mode'] = 'bss'
        if args['origin_mode'] == 'vls':
            args['origin_mode'] = 'bss'

        if args['max_duration_to_pt']:
            #retrocompatibility: max_duration_to_pt override all individual value by mode
            args['max_walking_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bike_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bss_duration_to_pt'] = args['max_duration_to_pt']
            args['max_car_duration_to_pt'] = args['max_duration_to_pt']

        #count override min_nb_journey or max_nb_journey
        if 'count' in args and args['count']:
            args['min_nb_journeys'] = args['count']
            args['max_nb_journeys'] = args['count']

        if region:
            self.region = i_manager.get_region(region)
            set_request_timezone(self.region)

        if not region:
            #TODO how to handle lon/lat ? don't we have to override args['origin'] ?
            self.region = compute_regions(args)

        #store json data into 4 arrays
        args['origin'] = []
        args['origin_access_duration'] = []
        args['destination'] = []
        args['destination_access_duration'] = []
        for loop in [('from', 'origin', True), ('to', 'destination', False)]:
            for location in args[loop[0]]:
                if "access_duration" in location:
                    args[loop[1]+'_access_duration'].append(location["access_duration"])
                else:
                    args[loop[1]+'_access_duration'].append(0)
                stop_uri = location["uri"]
                stop_uri = transform_id(stop_uri)
                args[loop[1]].append(stop_uri)

        #default Date
        if not "datetime" in args or not args['datetime']:
            args['datetime'] = datetime.now()
            args['datetime'] = args['datetime'].replace(hour=13, minute=37)

        # we save the original datetime for debuging purpose
        args['original_datetime'] = args['datetime']
        original_datetime = args['original_datetime']

        #we add the interpreted parameters to the stats
        self._register_interpreted_parameters(args)

        new_datetime = self.convert_to_utc(original_datetime)
        args['datetime'] = date_to_timestamp(new_datetime)

        api = 'nm_journeys'

        response = i_manager.dispatch(args, api, instance_name=self.region)
        return response
Example #8
0
    def get(self, region=None, lon=None, lat=None, uri=None):
        args = self.parsers['get'].parse_args()

        if args['traveler_type']:
            profile = travelers_profile[args['traveler_type']]
            profile.override_params(args)

        if args['max_duration_to_pt']:
            #retrocompatibility: max_duration_to_pt override all individual value by mode
            args['max_walking_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bike_duration_to_pt'] = args['max_duration_to_pt']
            args['max_bss_duration_to_pt'] = args['max_duration_to_pt']
            args['max_car_duration_to_pt'] = args['max_duration_to_pt']

        # TODO : Changer le protobuff pour que ce soit propre
        if args['destination_mode'] == 'vls':
            args['destination_mode'] = 'bss'
        if args['origin_mode'] == 'vls':
            args['origin_mode'] = 'bss'

        #count override min_nb_journey or max_nb_journey
        if 'count' in args and args['count']:
            args['min_nb_journeys'] = args['count']
            args['max_nb_journeys'] = args['count']

        # for last and first section mode retrocompatibility
        if 'first_section_mode' in args and args['first_section_mode']:
            args['origin_mode'] = args['first_section_mode']
        if 'last_section_mode' in args and args['last_section_mode']:
            args['destination_mode'] = args['last_section_mode']

        # Technically, bss mode enable walking (if it is better than bss)
        # so if the user ask for walking and bss, we only keep bss
        if 'walking' in args['origin_mode'] and 'bss' in args['origin_mode']:
            args['origin_mode'].remove('walking')
        if 'walking' in args['destination_mode'] and 'bss' in args['destination_mode']:
            args['destination_mode'].remove('walking')

        if region:
            self.region = i_manager.get_region(region)
            if uri:
                objects = uri.split('/')
                if objects and len(objects) % 2 == 0:
                    args['origin'] = objects[-1]
                else:
                    abort(503, message="Unable to compute journeys "
                                       "from this object")

        if not args["origin"]:  #@vlara really ? I though we could do reverse isochrone ?
            #shoudl be in my opinion if not args["origin"] and not args["destination"]:
            abort(400, message="from argument is required")

        #we transform the origin/destination url to add information
        if args['origin']:
            args['origin'] = transform_id(args['origin'])
        if args['destination']:
            args['destination'] = transform_id(args['destination'])

        if not args['datetime']:
            args['datetime'] = datetime.now()
            args['datetime'] = args['datetime'].replace(hour=13, minute=37)

        if not region:
            #TODO how to handle lon/lat ? don't we have to override args['origin'] ?
            possible_regions = compute_regions(args)
        else:
            possible_regions = [region]

        api = None
        if args['destination']:
            api = 'journeys'
        else:
            api = 'isochrone'

        # we save the original datetime for debuging purpose
        args['original_datetime'] = args['datetime']
        #we add the interpreted parameters to the stats
        self._register_interpreted_parameters(args)

        logging.getLogger(__name__).debug("We are about to ask journeys on regions : {}" .format(possible_regions))
        #we want to store the different errors
        responses = {}
        for r in possible_regions:
            self.region = r

            #we store the region in the 'g' object, which is local to a request
            set_request_timezone(self.region)

            if args['debug']:
                # In debug we store all queried region
                if not hasattr(g, 'regions_called'):
                    g.regions_called = []
                g.regions_called.append(r)

            original_datetime = args['original_datetime']
            new_datetime = self.convert_to_utc(original_datetime)
            args['datetime'] = date_to_timestamp(new_datetime)

            response = i_manager.dispatch(args, api, instance_name=self.region)

            if response.HasField('error') \
                    and len(possible_regions) != 1:
                logging.getLogger(__name__).debug("impossible to find journeys for the region {},"
                                                 " we'll try the next possible region ".format(r))

                if args['debug']:
                    # In debug we store all errors
                    if not hasattr(g, 'errors_by_region'):
                        g.errors_by_region = {}
                    g.errors_by_region[r] = response.error

                responses[r] = response
                continue

            if all(map(lambda j: j.type in ("non_pt_walk", "non_pt_bike", "non_pt_bss", "car"), response.journeys)):
                responses[r] = response
                continue

            return response

        for response in responses.itervalues():
            if not response.HasField("error"):
                return response


        # if no response have been found for all the possible regions, we have a problem
        # if all response had the same error we give it, else we give a generic 'no solution' error
        first_response = responses.itervalues().next()
        if all(r.error.id == first_response.error.id for r in responses.values()):
            return first_response

        resp = response_pb2.Response()
        er = resp.error
        er.id = response_pb2.Error.no_solution
        er.message = "No journey found"

        return resp
Example #9
0
 def test_transform_id_something(self):
     id = "something"
     uri = id
     assert transform_id(id) == uri
Example #10
0
 def test_transform_id_address(self):
     id = "address:toto:12345"
     uri = id
     assert transform_id(id) == uri
Example #11
0
 def test_transform_id_admin(self):
     id = "admin:fr:12345"
     uri = id
     assert transform_id(id) == uri
Example #12
0
 def test_transform_id_almost_coord(self):
     id = "1.23456789012345;2.23456789012345toto"
     uri = id
     assert transform_id(id) == uri
Example #13
0
 def test_transform_id_coord(self):
     id = "1.23456789012345;2.23456789012345"
     uri = "coord:1.23456789012345:2.23456789012345"
     assert transform_id(id) == uri
Example #14
0
 def test_transform_id_address(self):
     id = "address:1:12345"
     uri = "address:12345"
     assert transform_id(id) == uri