]> git.openstreetmap.org Git - nominatim.git/commitdiff
move localization into add_result_details
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 19 Sep 2023 09:17:04 +0000 (11:17 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Wed, 4 Oct 2023 12:58:05 +0000 (14:58 +0200)
This means that the locale now needs to be handed in into the search
functions already. At least search needs them for reranking.

nominatim/api/results.py
nominatim/api/types.py
nominatim/api/v1/server_glue.py
nominatim/clicmd/api.py
test/python/api/test_api_details.py
test/python/cli/test_cmd_api.py

index 0183f5b9f35e1cf201773104aee7821653f78402..1b2534e24bc8299d844ed7a34136a7359c6f4c11 100644 (file)
@@ -292,12 +292,6 @@ class SearchResults(List[SearchResult]):
         May be empty when no result was found.
     """
 
-    def localize(self, locales: Locales) -> None:
-        """ Apply the given locales to all results.
-        """
-        for result in self:
-            result.localize(locales)
-
 
 def _filter_geometries(row: SaRow) -> Dict[str, str]:
     return {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212
@@ -459,6 +453,8 @@ async def add_result_details(conn: SearchConnection, results: List[BaseResultT],
             log().comment('Query keywords')
             for result in results:
                 await complete_keywords(conn, result)
+        for result in results:
+            result.localize(details.locales)
 
 
 def _result_row_to_address_row(row: SaRow) -> AddressLine:
index c96b3f59c04241d228b7ca594d04c9ce115d7065..3ca023e7bbe1c7dce2a82a8b510c248a029d8721 100644 (file)
@@ -17,6 +17,7 @@ from struct import unpack
 from binascii import unhexlify
 
 from nominatim.errors import UsageError
+from nominatim.api.localization import Locales
 
 # pylint: disable=no-member,too-many-boolean-expressions,too-many-instance-attributes
 
@@ -386,7 +387,7 @@ TParam = TypeVar('TParam', bound='LookupDetails') # pylint: disable=invalid-name
 
 @dataclasses.dataclass
 class LookupDetails:
-    """ Collection of parameters that define the amount of details
+    """ Collection of parameters that define which kind of details are
         returned with a lookup or details result.
     """
     geometry_output: GeometryFormat = GeometryFormat.NONE
@@ -413,6 +414,9 @@ class LookupDetails:
         0.0 means the original geometry is kept. The higher the value, the
         more the geometry gets simplified.
     """
+    locales: Locales = Locales()
+    """ Prefered languages for localization of results.
+    """
 
     @classmethod
     def from_kwargs(cls: Type[TParam], kwargs: Dict[str, Any]) -> TParam:
index 5e8dbf4f4ba4b783b2c3ff99e3127b95a934b063..70f7dc40611f9ba552d8e8397922b1c0fc78e61a 100644 (file)
@@ -308,7 +308,8 @@ async def details_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
                                keywords=params.get_bool('keywords', False),
                                geometry_output = napi.GeometryFormat.GEOJSON
                                                  if params.get_bool('polygon_geojson', False)
-                                                 else napi.GeometryFormat.NONE
+                                                 else napi.GeometryFormat.NONE,
+                               locales=locales
                               )
 
     if debug:
@@ -317,8 +318,6 @@ async def details_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
     if result is None:
         params.raise_error('No place with that OSM ID found.', status=404)
 
-    result.localize(locales)
-
     output = formatting.format_result(result, fmt,
                  {'locales': locales,
                   'group_hierarchy': params.get_bool('group_hierarchy', False),
@@ -337,6 +336,7 @@ async def reverse_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
     details = params.parse_geometry_details(fmt)
     details['max_rank'] = helpers.zoom_to_rank(params.get_int('zoom', 18))
     details['layers'] = params.get_layers()
+    details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
 
     result = await api.reverse(coord, **details)
 
@@ -357,9 +357,6 @@ async def reverse_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
                    'namedetails': params.get_bool('namedetails', False),
                    'addressdetails': params.get_bool('addressdetails', True)}
 
-    if result:
-        result.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
-
     output = formatting.format_result(napi.ReverseResults([result] if result else []),
                                       fmt, fmt_options)
 
@@ -372,6 +369,7 @@ async def lookup_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
     fmt = params.parse_format(napi.SearchResults, 'xml')
     debug = params.setup_debugging()
     details = params.parse_geometry_details(fmt)
+    details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
 
     places = []
     for oid in (params.get('osm_ids') or '').split(','):
@@ -394,8 +392,6 @@ async def lookup_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
                    'namedetails': params.get_bool('namedetails', False),
                    'addressdetails': params.get_bool('addressdetails', True)}
 
-    results.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
-
     output = formatting.format_result(results, fmt, fmt_options)
 
     return params.build_response(output, num_results=len(results))
@@ -456,6 +452,8 @@ async def search_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
     else:
         details['layers'] = params.get_layers()
 
+    details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
+
     # unstructured query parameters
     query = params.get('q', None)
     # structured query parameters
@@ -480,8 +478,6 @@ async def search_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
     except UsageError as err:
         params.raise_error(str(err))
 
-    results.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
-
     if details['dedupe'] and len(results) > 1:
         results = helpers.deduplicate_results(results, max_results)
 
index e8f1d233db8c4a3b1d372940ffc626281dae1bff..e8450e6ba9890aef096f5911e606277038eab02a 100644 (file)
@@ -109,7 +109,8 @@ class APISearch:
                                   'countries': args.countrycodes,
                                   'excluded': args.exclude_place_ids,
                                   'viewbox': args.viewbox,
-                                  'bounded_viewbox': args.bounded
+                                  'bounded_viewbox': args.bounded,
+                                  'locales': args.get_locales(api.config.DEFAULT_LANGUAGE)
                                  }
 
         if args.query:
@@ -124,9 +125,6 @@ class APISearch:
                                          country=args.country,
                                          **params)
 
-        for result in results:
-            result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
-
         if args.dedupe and len(results) > 1:
             results = deduplicate_results(results, args.limit)
 
@@ -187,14 +185,14 @@ class APIReverse:
                              layers=args.get_layers(napi.DataLayer.ADDRESS | napi.DataLayer.POI),
                              address_details=True, # needed for display name
                              geometry_output=args.get_geometry_output(),
-                             geometry_simplification=args.polygon_threshold)
+                             geometry_simplification=args.polygon_threshold,
+                             locales=args.get_locales(api.config.DEFAULT_LANGUAGE))
 
         if args.format == 'debug':
             print(loglib.get_and_disable())
             return 0
 
         if result:
-            result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
             output = api_output.format_result(
                         napi.ReverseResults([result]),
                         args.format,
@@ -249,10 +247,8 @@ class APILookup:
         results = api.lookup(places,
                              address_details=True, # needed for display name
                              geometry_output=args.get_geometry_output(),
-                             geometry_simplification=args.polygon_threshold or 0.0)
-
-        for result in results:
-            result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
+                             geometry_simplification=args.polygon_threshold or 0.0,
+                             locales=args.get_locales(api.config.DEFAULT_LANGUAGE))
 
         output = api_output.format_result(
                     results,
@@ -326,6 +322,7 @@ class APIDetails:
 
         api = napi.NominatimAPI(args.project_dir)
 
+        locales = args.get_locales(api.config.DEFAULT_LANGUAGE)
         result = api.details(place,
                              address_details=args.addressdetails,
                              linked_places=args.linkedplaces,
@@ -333,13 +330,11 @@ class APIDetails:
                              keywords=args.keywords,
                              geometry_output=napi.GeometryFormat.GEOJSON
                                              if args.polygon_geojson
-                                             else napi.GeometryFormat.NONE)
+                                             else napi.GeometryFormat.NONE,
+                            locales=locales)
 
 
         if result:
-            locales = args.get_locales(api.config.DEFAULT_LANGUAGE)
-            result.localize(locales)
-
             output = api_output.format_result(
                         result,
                         'json',
index 101dfd13429439e87212013a15e6308a595477c4..05a7aa7f29f030202523c7941fed66636e1ec1a3 100644 (file)
@@ -150,17 +150,20 @@ def test_lookup_placex_with_address_details(apiobj):
                                 category=('highway', 'residential'),
                                 names={'name': 'Street'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=26, distance=0.0),
+                                rank_address=26, distance=0.0,
+                                local_name='Street'),
                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
                                 category=('place', 'suburb'),
                                 names={'name': 'Smallplace'}, extratags={},
                                 admin_level=13, fromarea=False, isaddress=True,
-                                rank_address=23, distance=0.0034),
+                                rank_address=23, distance=0.0034,
+                                local_name='Smallplace'),
                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
                                 category=('place', 'city'),
                                 names={'name': 'Bigplace'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=16, distance=0.0),
+                                rank_address=16, distance=0.0,
+                                local_name='Bigplace'),
                napi.AddressLine(place_id=None, osm_object=None,
                                 category=('place', 'country_code'),
                                 names={'ref': 'pl'}, extratags={},
@@ -341,22 +344,26 @@ def test_lookup_osmline_with_address_details(apiobj):
                                 category=('place', 'house_number'),
                                 names={'ref': '2'}, extratags={},
                                 admin_level=None, fromarea=True, isaddress=True,
-                                rank_address=28, distance=0.0),
+                                rank_address=28, distance=0.0,
+                                local_name='2'),
                napi.AddressLine(place_id=332, osm_object=('W', 4),
                                 category=('highway', 'residential'),
                                 names={'name': 'Street'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=26, distance=0.0),
+                                rank_address=26, distance=0.0,
+                                local_name='Street'),
                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
                                 category=('place', 'suburb'),
                                 names={'name': 'Smallplace'}, extratags={},
                                 admin_level=13, fromarea=False, isaddress=True,
-                                rank_address=23, distance=0.0034),
+                                rank_address=23, distance=0.0034,
+                                local_name='Smallplace'),
                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
                                 category=('place', 'city'),
                                 names={'name': 'Bigplace'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=16, distance=0.0),
+                                rank_address=16, distance=0.0,
+                                local_name='Bigplace'),
                napi.AddressLine(place_id=None, osm_object=None,
                                 category=('place', 'country_code'),
                                 names={'ref': 'pl'}, extratags={},
@@ -441,22 +448,26 @@ def test_lookup_tiger_with_address_details(apiobj):
                                 category=('place', 'house_number'),
                                 names={'ref': '2'}, extratags={},
                                 admin_level=None, fromarea=True, isaddress=True,
-                                rank_address=28, distance=0.0),
+                                rank_address=28, distance=0.0,
+                                local_name='2'),
                napi.AddressLine(place_id=332, osm_object=('W', 4),
                                 category=('highway', 'residential'),
                                 names={'name': 'Street'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=26, distance=0.0),
+                                rank_address=26, distance=0.0,
+                                local_name='Street'),
                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
                                 category=('place', 'suburb'),
                                 names={'name': 'Smallplace'}, extratags={},
                                 admin_level=13, fromarea=False, isaddress=True,
-                                rank_address=23, distance=0.0034),
+                                rank_address=23, distance=0.0034,
+                                local_name='Smallplace'),
                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
                                 category=('place', 'city'),
                                 names={'name': 'Bigplace'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=16, distance=0.0),
+                                rank_address=16, distance=0.0,
+                                local_name='Bigplace'),
                napi.AddressLine(place_id=None, osm_object=None,
                                 category=('place', 'country_code'),
                                 names={'ref': 'us'}, extratags={},
@@ -536,17 +547,20 @@ def test_lookup_postcode_with_address_details(apiobj):
                                 category=('place', 'suburb'),
                                 names={'name': 'Smallplace'}, extratags={},
                                 admin_level=13, fromarea=True, isaddress=True,
-                                rank_address=23, distance=0.0),
+                                rank_address=23, distance=0.0,
+                                local_name='Smallplace'),
                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
                                 category=('place', 'city'),
                                 names={'name': 'Bigplace'}, extratags={},
                                 admin_level=15, fromarea=True, isaddress=True,
-                                rank_address=16, distance=0.0),
+                                rank_address=16, distance=0.0,
+                                local_name='Bigplace'),
                napi.AddressLine(place_id=None, osm_object=None,
                                 category=('place', 'postcode'),
                                 names={'ref': '34 425'}, extratags={},
                                 admin_level=None, fromarea=False, isaddress=True,
-                                rank_address=5, distance=0.0),
+                                rank_address=5, distance=0.0,
+                                local_name='34 425'),
                napi.AddressLine(place_id=None, osm_object=None,
                                 category=('place', 'country_code'),
                                 names={'ref': 'gb'}, extratags={},
index 05e3c4f09f7171d20209833a9832445a022bdb9d..ca160a359e5cb97b7f1de5d8ec96afea676f98e4 100644 (file)
@@ -67,7 +67,9 @@ class TestCliReverseCall:
         result = napi.ReverseResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                     napi.Point(1.0, -3.0),
                                     names={'name':'Name', 'name:fr': 'Nom'},
-                                    extratags={'extra':'Extra'})
+                                    extratags={'extra':'Extra'},
+                                    locale_name='Name',
+                                    display_name='Name')
 
         monkeypatch.setattr(napi.NominatimAPI, 'reverse',
                             lambda *args, **kwargs: result)
@@ -109,16 +111,6 @@ class TestCliReverseCall:
         assert out['type'] == 'FeatureCollection'
 
 
-    def test_reverse_language(self, cli_call, tmp_path, capsys):
-        result = cli_call('reverse', '--project-dir', str(tmp_path),
-                          '--lat', '34', '--lon', '34', '--lang', 'fr')
-
-        assert result == 0
-
-        out = json.loads(capsys.readouterr().out)
-        assert out['name'] == 'Nom'
-
-
 class TestCliLookupCall:
 
     @pytest.fixture(autouse=True)
@@ -126,7 +118,9 @@ class TestCliLookupCall:
         result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                     napi.Point(1.0, -3.0),
                                     names={'name':'Name', 'name:fr': 'Nom'},
-                                    extratags={'extra':'Extra'})
+                                    extratags={'extra':'Extra'},
+                                    locale_name='Name',
+                                    display_name='Name')
 
         monkeypatch.setattr(napi.NominatimAPI, 'lookup',
                             lambda *args, **kwargs: napi.SearchResults([result]))
@@ -150,9 +144,11 @@ class TestCliLookupCall:
                                              ])
 def test_search(cli_call, tmp_path, capsys, monkeypatch, endpoint, params):
     result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
-                                napi.Point(1.0, -3.0),
-                                names={'name':'Name', 'name:fr': 'Nom'},
-                                extratags={'extra':'Extra'})
+                               napi.Point(1.0, -3.0),
+                               names={'name':'Name', 'name:fr': 'Nom'},
+                               extratags={'extra':'Extra'},
+                               locale_name='Name',
+                               display_name='Name')
 
     monkeypatch.setattr(napi.NominatimAPI, endpoint,
                         lambda *args, **kwargs: napi.SearchResults([result]))