ai-content-maker/.venv/Lib/site-packages/dateparser/languages/loader.py

184 lines
6.7 KiB
Python

from collections import OrderedDict
from importlib import import_module
from itertools import zip_longest
import regex as re
from copy import deepcopy
from ..data import language_order, language_locale_dict
from .locale import Locale
LOCALE_SPLIT_PATTERN = re.compile(r'-(?=[A-Z0-9]+$)')
def _isvalidlocale(locale):
language = LOCALE_SPLIT_PATTERN.split(locale)[0]
if language not in language_order:
return False
else:
locales_list = language_locale_dict[language]
if locale == language or locale in locales_list:
return True
else:
return False
def _filter_valid_locales(locales):
return [locale for locale in locales if _isvalidlocale(locale)]
def _construct_locales(languages, region):
if region:
possible_locales = [language + '-' + region for language in languages]
locales = _filter_valid_locales(possible_locales)
else:
locales = languages
return locales
class LocaleDataLoader:
"""Class that handles loading of locale instances."""
_loaded_languages = {}
_loaded_locales = {}
def get_locale_map(self, languages=None, locales=None, region=None,
use_given_order=False, allow_conflicting_locales=False):
"""
Get an ordered mapping with locale codes as keys
and corresponding locale instances as values.
:param languages:
A list of language codes, e.g. ['en', 'es', 'zh-Hant'].
If locales are not given, languages and region are
used to construct locales to load.
:type languages: list
:param locales:
A list of codes of locales which are to be loaded,
e.g. ['fr-PF', 'qu-EC', 'af-NA']
:type locales: list
:param region:
A region code, e.g. 'IN', '001', 'NE'.
If locales are not given, languages and region are
used to construct locales to load.
:type region: str
:param use_given_order:
If True, the returned mapping is ordered in the order locales are given.
:type use_given_order: bool
:param allow_conflicting_locales:
if True, locales with same language and different region can be loaded.
:type allow_conflicting_locales: bool
:return: ordered locale code to locale instance mapping
"""
return OrderedDict(self._load_data(
languages=languages, locales=locales, region=region, use_given_order=use_given_order,
allow_conflicting_locales=allow_conflicting_locales))
def get_locales(self, languages=None, locales=None, region=None,
use_given_order=False, allow_conflicting_locales=False):
"""
Yield locale instances.
:param languages:
A list of language codes, e.g. ['en', 'es', 'zh-Hant'].
If locales are not given, languages and region are
used to construct locales to load.
:type languages: list
:param locales:
A list of codes of locales which are to be loaded,
e.g. ['fr-PF', 'qu-EC', 'af-NA']
:type locales: list
:param region:
A region code, e.g. 'IN', '001', 'NE'.
If locales are not given, languages and region are
used to construct locales to load.
:type region: str
:param use_given_order:
If True, the returned mapping is ordered in the order locales are given.
:type use_given_order: bool
:param allow_conflicting_locales:
if True, locales with same language and different region can be loaded.
:type allow_conflicting_locales: bool
:yield: locale instances
"""
for _, locale in self._load_data(
languages=languages, locales=locales, region=region,
use_given_order=use_given_order,
allow_conflicting_locales=allow_conflicting_locales):
yield locale
def get_locale(self, shortname):
"""
Get a locale instance.
:param shortname:
A locale code, e.g. 'fr-PF', 'qu-EC', 'af-NA'.
:type shortname: str
:return: locale instance
"""
return list(self.get_locales(locales=[shortname]))[0]
def _load_data(self, languages=None, locales=None, region=None,
use_given_order=False, allow_conflicting_locales=False):
locale_dict = OrderedDict()
if locales:
invalid_locales = []
for locale in locales:
lang_reg = LOCALE_SPLIT_PATTERN.split(locale)
if len(lang_reg) == 1:
lang_reg.append('')
locale_dict[locale] = tuple(lang_reg)
if not _isvalidlocale(locale):
invalid_locales.append(locale)
if invalid_locales:
raise ValueError("Unknown locale(s): %s"
% ', '.join(map(repr, invalid_locales)))
if not allow_conflicting_locales:
if len(set(locales)) > len({t[0] for t in locale_dict.values()}):
raise ValueError("Locales should not have same language and different region")
else:
if languages is None:
languages = language_order
unsupported_languages = set(languages) - set(language_order)
if unsupported_languages:
raise ValueError("Unknown language(s): %s"
% ', '.join(map(repr, unsupported_languages)))
if region is None:
region = ''
locales = _construct_locales(languages, region)
locale_dict.update(zip_longest(locales,
tuple(zip_longest(languages, [], fillvalue=region))))
if not use_given_order:
locale_dict = OrderedDict(sorted(locale_dict.items(),
key=lambda x: language_order.index(x[1][0])))
for shortname, lang_reg in locale_dict.items():
if shortname not in self._loaded_locales:
lang, reg = lang_reg
if lang in self._loaded_languages:
locale = Locale(shortname, language_info=deepcopy(self._loaded_languages[lang]))
self._loaded_locales[shortname] = locale
else:
language_info = getattr(
import_module('dateparser.data.date_translation_data.' + lang), 'info')
locale = Locale(shortname, language_info=deepcopy(language_info))
self._loaded_languages[lang] = language_info
self._loaded_locales[shortname] = locale
yield shortname, self._loaded_locales[shortname]
default_loader = LocaleDataLoader()