]> 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 import re
11 import logging
12 from nominatim.tools.special_phrases.special_phrase import SpecialPhrase
13 from nominatim.tools.exec_utils import get_url
14
15 LOG = logging.getLogger()
16
17 def _get_wiki_content(lang):
18     """
19         Request and return the wiki page's content
20         corresponding to special phrases for a given lang.
21         Requested URL Example :
22             https://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/EN
23     """
24     url = 'https://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/' \
25           + lang.upper()
26     return get_url(url)
27
28
29 class SPWikiLoader:
30     """
31         Handles loading of special phrases from the wiki.
32     """
33     def __init__(self, config):
34         super().__init__()
35         self.config = config
36         # Compile the regex here to increase performances.
37         self.occurence_pattern = re.compile(
38             r'\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([\-YN])'
39         )
40         # Hack around a bug where building=yes was imported with quotes into the wiki
41         self.type_fix_pattern = re.compile(r'\"|"')
42         self._load_languages()
43
44
45     def generate_phrases(self):
46         """ Download the wiki pages for the configured languages
47             and extract the phrases from the page.
48         """
49         for lang in self.languages:
50             LOG.warning('Importing phrases for lang: %s...', lang)
51             loaded_xml = _get_wiki_content(lang)
52
53             # One match will be of format [label, class, type, operator, plural]
54             matches = self.occurence_pattern.findall(loaded_xml)
55
56             for match in matches:
57                 yield SpecialPhrase(match[0],
58                                     match[1],
59                                     self.type_fix_pattern.sub('', match[2]),
60                                     match[3])
61
62
63     def _load_languages(self):
64         """
65             Get list of all languages from env config file
66             or default if there is no languages configured.
67             The system will extract special phrases only from all specified languages.
68         """
69         if self.config.LANGUAGES:
70             self.languages = self.config.get_str_list('LANGUAGES')
71         else:
72             self.languages = [
73             'af', 'ar', 'br', 'ca', 'cs', 'de', 'en', 'es',
74             'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
75             'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
76             'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi']