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
示例#2
0
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
    }
示例#3
0
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)
示例#4
0
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
示例#5
0
 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
示例#6
0
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))
示例#7
0
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))