diff --git a/backend/services/navi_places/place_detail.py b/backend/services/navi_places/place_detail.py index dcf05ac..94b2ab7 100644 --- a/backend/services/navi_places/place_detail.py +++ b/backend/services/navi_places/place_detail.py @@ -291,6 +291,7 @@ def _parse_nominatim(data): 'email': raw_extra.get('email') or raw_extra.get('contact:email'), 'wikipedia': raw_extra.get('wikipedia'), 'wikidata': raw_extra.get('wikidata'), + 'wikivoyage': raw_extra.get('wikivoyage'), 'cuisine': raw_extra.get('cuisine'), 'operator': raw_extra.get('operator'), 'wheelchair': raw_extra.get('wheelchair'), @@ -376,6 +377,7 @@ def _parse_overpass(data, osm_type, osm_id): 'email': tags.get('email') or tags.get('contact:email'), 'wikipedia': tags.get('wikipedia'), 'wikidata': tags.get('wikidata'), + 'wikivoyage': tags.get('wikivoyage'), 'cuisine': tags.get('cuisine'), 'operator': tags.get('operator'), 'wheelchair': tags.get('wheelchair'), diff --git a/backend/services/navi_places/tests/test_place.py b/backend/services/navi_places/tests/test_place.py index a219eff..d99ab3c 100644 --- a/backend/services/navi_places/tests/test_place.py +++ b/backend/services/navi_places/tests/test_place.py @@ -181,6 +181,40 @@ def test_wiki_rewrite_original_passes_through(tmp_path, monkeypatch): assert 'wikipedia' not in d.get('sources', {}).get('wiki_rewrites', {}) +def test_catalog_url_requests_full_library(): + # Fix 1: the OPDS fetch must pull the whole library (kiwix-serve defaults to the + # first 10 entries, which hid wikivoyage and other page-2 ZIMs from discovery). + from services.navi_places import wiki_rewrite + assert 'count=-1' in wiki_rewrite.KIWIX_CATALOG_URL + + +def test_wikivoyage_tag_rewrites_to_local(tmp_path, monkeypatch): + # Fix 2: a wikivoyage OSM tag for a mirrored article rewrites to a local Kiwix + # URL via the same source_type-generic path as wikipedia. Kiwix is mocked: the + # ZIM map is seeded with the wikivoyage book and the HEAD probe returns 200. + monkeypatch.setenv('NAVI_PLACE_CACHE_DB', str(tmp_path / 'pc.db')) + monkeypatch.setenv('NAVI_WIKI_CACHE_DB', str(tmp_path / 'wiki_cache.db')) + _flags(monkeypatch, enabled=('has_wiki_rewriting',)) + + wr = pd.wiki_rewrite + wr.reset() + monkeypatch.setattr(wr, '_ensure_zim_map', lambda: None) + monkeypatch.setattr(wr, '_zim_map', {'wikivoyage': 'wikivoyage_en_all_maxi_2026-03'}) + + class FakeKiwixHTTP: + def head(self, url, **kw): + return FakeResp(200) + monkeypatch.setattr(wr, 'http_requests', FakeKiwixHTTP()) + + nom = {**NOMINATIM_CAFE, 'extratags': {'wikivoyage': 'en:Twin Falls'}} + monkeypatch.setattr(pd, 'http_requests', FakeHTTP(get=lambda url, **kw: FakeResp(200, nom))) + + d = create_app().test_client().get('/api/place/W/123').get_json() + assert d['extratags']['wikivoyage'] == \ + 'https://wiki.echo6.co/content/wikivoyage_en_all_maxi_2026-03/Twin_Falls' + assert d['sources']['wiki_rewrites']['wikivoyage'] == 'local' + + # ── wiki index summary via local wiki_index.db ── def test_wiki_enrich_via_local_db_merges_fields(tmp_path, monkeypatch): diff --git a/backend/services/navi_places/wiki_rewrite.py b/backend/services/navi_places/wiki_rewrite.py index d2afbe2..16bde27 100644 --- a/backend/services/navi_places/wiki_rewrite.py +++ b/backend/services/navi_places/wiki_rewrite.py @@ -33,7 +33,10 @@ logger = logging.getLogger('navi_places.wiki_rewrite') KIWIX_BASE = os.environ.get('NAVI_KIWIX_BASE_URL', 'http://localhost:8430') KIWIX_PUBLIC_BASE = os.environ.get('NAVI_KIWIX_PUBLIC_BASE', 'https://wiki.echo6.co') -KIWIX_CATALOG_URL = f"{KIWIX_BASE}/catalog/v2/entries" +# count=-1 returns the full library; kiwix-serve OPDS defaults to only the first +# 10 entries, which silently hid ZIMs past page 1 (e.g. wikivoyage) from +# _discover_zims so their tags never rewrote to local. +KIWIX_CATALOG_URL = f"{KIWIX_BASE}/catalog/v2/entries?count=-1" HEAD_TIMEOUT = 1.5 # seconds CATALOG_REFRESH_INTERVAL = 3600 # 1 hour