def get_search_url(commune_id, distance, rome_id): """ Build search URL for given commune_id, distance and rome_id """ if mapping_util.rome_is_valid(rome_id): rome_description = settings.ROME_DESCRIPTIONS[rome_id.upper()] slugified_rome_description = slugify(rome_description) city = geocoding.get_city_by_commune_id(commune_id) if city: # Here we hardcode the URL since this script typically runs in staging # for data confidentiality reasons and not in production. # However we need the resulting URLs to be pointing to production, # this is why we do not use `url_for`. search_url = 'https://labonneboite.pole-emploi.fr/entreprises/%s-%s/%s?d=%s&%s' % ( city['slug'], city['zipcode'], slugified_rome_description, distance, GA_TRACKING_SEARCH, ) return search_url else: logging.info("WARNING city not found : %s", commune_id) else: logging.info("WARNING invalid rome_code : %s", rome_id) return None
def get_results(commune_id, rome_1_id, rome_2_id): """ Try to find enough offices matching this commune_id, for either of the two provided rome_ids, and within as small of a distance as possible. The result is a dictionary: - offices found - distance which was eventually used for the result - rome_id which was eventually used for the result """ if ENABLE_FAKE_METZ_INSEE_CODE_FOR_ALL: commune_id = METZ_INSEE_CODE city = geocoding.get_city_by_commune_id(commune_id) if city is None: return { 'offices': [], 'distance': settings.DISTANCE_FILTER_DEFAULT, 'rome_id': rome_1_id } latitude = city['coords']['lat'] longitude = city['coords']['lon'] offices = [] # the only case where those two stay None is if there is no result at all used_distance = None used_rome_id = None # itertools.product iterates over all combinations of values in multiple lists, see: # https://stackoverflow.com/questions/16384109/iterate-over-all-combinations-of-values-in-multiple-lists-in-python for distance, rome_id in itertools.product(DISTANCE_ATTEMPTS, [rome_1_id, rome_2_id]): if mapping_util.rome_is_valid(rome_id): naf_code_list = mapping_util.map_romes_to_nafs([rome_id]) # FIXME randomize per user to avoid spamming companies offices, _, _ = fetch_offices( naf_codes=naf_code_list, rome_codes=[rome_id], latitude=latitude, longitude=longitude, distance=distance, from_number=1, to_number=OFFICES_PER_USER, hiring_type=hiring_type_util.DPAE, ) if len(offices) >= 1: used_rome_id = rome_id used_distance = distance if len(offices) >= OFFICES_PER_USER: break return { 'offices': offices, 'distance': used_distance, 'rome_id': used_rome_id }
def results_by_commune_and_rome(commune_id, rome_id): """ Convenience function to be used by Pôle Emploi, Bob Emploi and other partners Redirects internally to our real user-facing url displaying results for his search. For more information about the differences between commune_id and zipcode, please consult README file """ fix_csrf_session() try: rome_description = settings.ROME_DESCRIPTIONS[rome_id.upper()] slugified_rome_description = slugify(rome_description) except KeyError: rome_description = None city = geocoding.get_city_by_commune_id(commune_id) if not city or not rome_description: abort(404) params = request.args.copy() params['city'] = city['slug'] params['zipcode'] = city['zipcode'] params['occupation'] = slugified_rome_description url = url_for('search.entreprises', **params) # Pass all GET params to the redirect URL: this will allow users of the API to build web links # roughly equivalent to the result of an API call - see Trello #971. return redirect(url)
def get_location(request_args): """ Parse request arguments to compute location objects. Args: request_args (dict) Return: location (Location) zipcode (str) commune_id (str) departements (str) """ location = None zipcode = None commune_id = None departements = None # Commune_id or longitude/latitude if 'commune_id' in request_args: commune_id = request_args['commune_id'] city = geocoding.get_city_by_commune_id(commune_id) if not city: raise InvalidFetcherArgument( 'could not resolve latitude and longitude from given commune_id' ) latitude = city['coords']['lat'] longitude = city['coords']['lon'] location = Location(latitude, longitude) zipcode = city['zipcode'] elif 'latitude' in request_args and 'longitude' in request_args: if not request_args.get('latitude') or not request_args.get( 'longitude'): raise InvalidFetcherArgument( 'latitude or longitude (or both) have no value') try: latitude = float(request_args['latitude']) longitude = float(request_args['longitude']) location = Location(latitude, longitude) except ValueError: raise InvalidFetcherArgument( 'latitude and longitude must be float') elif 'departments' not in request_args: raise InvalidFetcherArgument( 'missing arguments: either commune_id or departments or both latitude and longitude' ) if 'departments' in request_args: departements = request_args.get('departments') return location, zipcode, commune_id, departements
def codes_as_geolocations(codes): """ Converts the given string of codes to an array of `lat/lon tuples`. E.g.: [ (48.68, 6.17), (49.15, 6.22), ] """ geolocations = [] codes_list = OfficeAdminExtraGeoLocation.codes_as_list(codes) for code in codes_list: if geocoding.is_departement(code): for city in geocoding.get_all_cities_from_departement(code): geolocations.append( (city['coords']['lat'], city['coords']['lon'])) elif geocoding.is_commune_id(code): city = geocoding.get_city_by_commune_id(code) geolocations.append( (city['coords']['lat'], city['coords']['lon'])) return geolocations
def city_code_details(): """ Endpoint used by La Bonne Alternance only. Required parameter: city-code (str) """ result = {} city_code = request.args.get('city-code', '') if not city_code: return 'no city-code given', 400 city = geocoding.get_city_by_commune_id(city_code) if not city: return 'no city found associated to the code {}'.format(city_code), 400 result['city'] = { 'name': city['name'], 'slug': '{}-{}'.format(city['slug'], city['zipcode']), 'longitude': city['coords']['lon'], 'latitude': city['coords']['lat'], } return make_response(json.dumps(result))
def sanity_check_rome_codes(): ogr_rome_mapping = OGR_ROME_CODES rome_labels = settings.ROME_DESCRIPTIONS rome_naf_mapping = mapping_util.MANUAL_ROME_NAF_MAPPING romes_from_ogr_rome_mapping = set(ogr_rome_mapping.values()) romes_from_rome_labels = set(rome_labels.keys()) romes_from_rome_naf_mapping = set(rome_naf_mapping.keys()) subset1 = romes_from_ogr_rome_mapping - romes_from_rome_labels subset2 = romes_from_rome_labels - romes_from_ogr_rome_mapping subset3 = romes_from_rome_naf_mapping - romes_from_rome_labels subset4 = romes_from_rome_labels - romes_from_rome_naf_mapping msg = """ -------------- SANITY CHECK ON ROME CODES -------------- found %s distinct rome_codes in romes_from_ogr_rome_mapping found %s distinct rome_codes in romes_from_rome_labels found %s distinct rome_codes in romes_from_rome_naf_mapping found %s rome_codes present in romes_from_ogr_rome_mapping but not in romes_from_rome_labels: %s found %s rome_codes present in romes_from_rome_labels but not in romes_from_ogr_rome_mapping: %s found %s rome_codes present in romes_from_rome_naf_mapping but not in romes_from_rome_labels: %s found %s rome_codes present in romes_from_rome_labels but not in romes_from_rome_naf_mapping: %s """ % ( len(romes_from_ogr_rome_mapping), len(romes_from_rome_labels), len(romes_from_rome_naf_mapping), len(subset1), subset1, len(subset2), subset2, len(subset3), subset3, len(subset4), # CSV style output for easier manipulation afterwards "".join(["\n%s|%s" % (r, rome_labels[r]) for r in subset4]), ) logger.info(msg) city = geocoding.get_city_by_commune_id('75056') latitude = city['coords']['lat'] longitude = city['coords']['lon'] distance = 1000 # CSV style output for easier manipulation afterwards logger.info("rome_id|rome_label|offices_in_france") for rome_id in romes_from_rome_naf_mapping: naf_code_list = mapping_util.map_romes_to_nafs([rome_id]) disable_verbose_loggers() offices, _, _ = fetch_offices( naf_codes=naf_code_list, rome_codes=[rome_id], latitude=latitude, longitude=longitude, distance=distance, from_number=1, to_number=10, hiring_type=hiring_type_util.DPAE, ) enable_verbose_loggers() if len(offices) < 5: logger.info("%s|%s|%s", rome_id, rome_labels[rome_id], len(offices))