Source code for univention.info_tools

#
# Univention Configuration Registry
#  dictionary class for localized keys
#
# SPDX-FileCopyrightText: 2007-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

import configparser
import re
from typing import TypeVar, overload


_VT = TypeVar('_VT')

# default locale
_locale = 'de'
MYPY = False


if MYPY:  # pragma: no cover
    __LVD = dict[str, str]
else:
    __LVD = dict


[docs] class LocalizedValue(__LVD): """Localized description entry.""" def __init__(self, *args, **kwargs): tmp = dict(*args, **kwargs) self.__default = tmp.pop('__default', '') dict.__init__(self, tmp) def __repr__(self): return '%s(%s, __default=%r)' % ( self.__class__.__name__, dict.__repr__(self), self.__default, )
[docs] def get(self, locale: str | None = None) -> str: # type: ignore if not locale: locale = _locale if locale in self: return self[locale] return self.__default
[docs] def set(self, value: str, locale: str | None = None) -> None: self[locale or _locale] = value
[docs] def set_default(self, default: str) -> None: self.__default = default
[docs] def get_default(self) -> str: return self.__default
if MYPY: # pragma: no cover __LD = dict[str, str] else: __LD = dict
[docs] class LocalizedDictionary(__LD): # noqa: PLW1641 """Localized descriptions.""" _LOCALE_REGEX = re.compile(r'(?P<key>[a-zA-Z]*)\[(?P<lang>[a-z]*)\]$') def __init__(self) -> None: dict.__init__(self) def __setitem__(self, key: str, value: str) -> None: key = key.lower() matches = LocalizedDictionary._LOCALE_REGEX.match(key) # localized value? if matches: key, lang = matches.groups() val = self.setdefault(key, LocalizedValue()) # type: ignore if matches: val.set(value, lang) # type: ignore else: val.set_default(value) # type: ignore def __getitem__(self, key: str) -> str: key = key.lower() lang: str | None = None matches = LocalizedDictionary._LOCALE_REGEX.match(key) # localized value? if matches: key, lang = matches.groups() return dict.__getitem__(self, key).get(lang) # type: ignore @overload def get(self, key: str) -> str | None: # pragma: no cover pass @overload def get(self, key: str, default: _VT) -> str | _VT: # pragma: no cover pass
[docs] def get(self, key: str, default: _VT | None = None) -> str | _VT: try: value = self.__getitem__(key) or default return value # type: ignore except KeyError: return default # type: ignore
def __contains__(self, key: str) -> bool: # type: ignore key = key.lower() matches = LocalizedDictionary._LOCALE_REGEX.match(key) if matches: key = matches.group(1) return dict.__contains__(self, key) # type: ignore[operator] has_key = __contains__ # type: ignore def __normalize_key(self, key: str) -> dict[str, str]: if key not in self: return {} temp = {} variable: LocalizedValue = dict.__getitem__(self, key) # type: ignore for locale, value in variable.items(): temp['%s[%s]' % (key, locale)] = value if variable.get_default(): # type: ignore temp[key] = variable.get_default() return temp
[docs] def normalize(self, key: str | None = None) -> dict[str, str]: if key: return self.__normalize_key(key) temp: dict[str, str] = {} for key2 in self.keys(): temp.update(self.__normalize_key(key2)) return temp
[docs] def get_dict(self, key: str) -> dict[str, str]: if key not in self: return {} return dict.__getitem__(self, key) # type: ignore
def __eq__(self, other): if not isinstance(other, dict): return False me = self.normalize() you = other.normalize() return dict.__eq__(me, you) def __ne__(self, other): return not self.__eq__(other)
# my config parser
[docs] class UnicodeConfig(configparser.ConfigParser): def __init__(self): configparser.ConfigParser.__init__(self, strict=False, interpolation=None)
[docs] def read(self, filename, encoding='UTF-8'): return configparser.ConfigParser.read(self, filename, encoding=encoding)
[docs] def write(self, fp): """Write an .ini-format representation of the configuration state.""" if self._defaults: fp.write("[%s]\n" % configparser.DEFAULTSECT) for (key, value) in self._defaults.items(): fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") for section in self._sections: fp.write("[%s]\n" % section) for (key, value) in self._sections[section].items(): if key != "__name__": fp.write("%s = %s\n" % (key, value.replace('\n', '\n\t'))) fp.write("\n")
[docs] def set_language(lang): global _locale _locale = lang