]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/tools/special_phrases/sp_wiki_loader.py
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / nominatim / tools / special_phrases / sp_wiki_loader.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2022 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8     Module containing the SPWikiLoader class.
9 """
10 from typing import Iterable
11 import re
12 import logging
13
14 from nominatim.config import Configuration
15 from nominatim.tools.special_phrases.special_phrase import SpecialPhrase
16 from nominatim.tools.exec_utils import get_url
17
18 LOG = logging.getLogger()
19
20 def _get_wiki_content(lang: str) -> str:
21     """
22         Request and return the wiki page's content
23         corresponding to special phrases for a given lang.
24         Requested URL Example :
25             https://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/EN
26     """
27     url = 'https://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/' \
28           + lang.upper()
29     return get_url(url)
30
31
32 class SPWikiLoader:
33     """
34         Handles loading of special phrases from the wiki.
35     """
36     def __init__(self, config: Configuration) -> None:
37         self.config = config
38         # Compile the regex here to increase performances.
39         self.occurence_pattern = re.compile(
40             r'\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([\-YN])'
41         )
42         # Hack around a bug where building=yes was imported with quotes into the wiki
43         self.type_fix_pattern = re.compile(r'\"|"')
44
45         self.languages = self.config.get_str_list('LANGUAGES') or \
46                          ['af', 'ar', 'br', 'ca', 'cs', 'de', 'en', 'es',
47                           'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
48                           'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
49                           'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi']
50
51
52     def generate_phrases(self) -> Iterable[SpecialPhrase]:
53         """ Download the wiki pages for the configured languages
54             and extract the phrases from the page.
55         """
56         for lang in self.languages:
57             LOG.warning('Importing phrases for lang: %s...', lang)
58             loaded_xml = _get_wiki_content(lang)
59
60             # One match will be of format [label, class, type, operator, plural]
61             matches = self.occurence_pattern.findall(loaded_xml)
62
63             for match in matches:
64                 yield SpecialPhrase(match[0],
65                                     match[1],
66                                     self.type_fix_pattern.sub('', match[2]),
67                                     match[3])