mirror of
https://gitlab.com/pulsechaincom/staking-deposit-cli.git
synced 2024-12-23 03:51:39 +00:00
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
import inspect
|
|
import difflib
|
|
from functools import reduce
|
|
import json
|
|
from typing import (
|
|
Any,
|
|
Dict,
|
|
Iterable,
|
|
List,
|
|
Mapping,
|
|
Sequence,
|
|
)
|
|
import os
|
|
|
|
from staking_deposit.utils import config
|
|
from staking_deposit.utils.constants import (
|
|
INTL_CONTENT_PATH,
|
|
)
|
|
from staking_deposit.utils.file_handling import (
|
|
resource_path,
|
|
)
|
|
from staking_deposit.exceptions import ValidationError
|
|
|
|
|
|
def _get_from_dict(dataDict: Dict[str, Any], mapList: Iterable[str]) -> str:
|
|
'''
|
|
Iterate nested dictionaries
|
|
'''
|
|
try:
|
|
ans = reduce(dict.get, mapList, dataDict)
|
|
assert isinstance(ans, str)
|
|
return ans
|
|
except TypeError:
|
|
raise KeyError('%s not in internationalisation json file.' % mapList)
|
|
except AssertionError:
|
|
raise KeyError('The provided params (%s) were incomplete.' % mapList)
|
|
|
|
|
|
def load_text(params: List[str], file_path: str='', func: str='', lang: str='') -> str:
|
|
'''
|
|
Determine and return the appropriate internationalisation text for a given set of `params`.
|
|
'''
|
|
if file_path == '':
|
|
# Auto-detect file-path based on call stack
|
|
file_path = inspect.stack()[1].filename
|
|
file_path = file_path[:-3] + '.json' # replace .py with .json
|
|
|
|
if func == '':
|
|
# Auto-detect function based on call stack
|
|
func = inspect.stack()[1].function
|
|
|
|
if lang == '':
|
|
lang = config.language
|
|
|
|
# Determine path to json text
|
|
file_path_list = os.path.normpath(file_path).split(os.path.sep)
|
|
rel_path_list = file_path_list[file_path_list.index('staking_deposit') + 1:]
|
|
json_path = resource_path(os.path.join(INTL_CONTENT_PATH, lang, *rel_path_list))
|
|
|
|
try:
|
|
# browse json until text is found
|
|
with open(json_path) as f:
|
|
text_dict = json.load(f)
|
|
return _get_from_dict(text_dict, [func] + params)
|
|
except (KeyError, FileNotFoundError):
|
|
# If text not found in lang, try return English version
|
|
if lang == 'en':
|
|
raise KeyError('%s not in %s file' % ([func] + params, json_path))
|
|
return load_text(params, file_path, func, 'en')
|
|
|
|
|
|
def get_first_options(options: Mapping[str, Sequence[str]]) -> List[str]:
|
|
'''
|
|
Returns the first `option` in the values of the `options` dict.
|
|
'''
|
|
return list(map(lambda x: x[0], options.values()))
|
|
|
|
|
|
def closest_match(text: str, options: Iterable[str]) -> str:
|
|
'''
|
|
Finds the closest match to `text` in the `options_list`
|
|
'''
|
|
match = difflib.get_close_matches(text, options, n=1, cutoff=0.6)
|
|
if len(match) == 0:
|
|
raise ValidationError('%s is not a valid language option' % text)
|
|
return match[0]
|
|
|
|
|
|
def fuzzy_reverse_dict_lookup(text: str, options: Mapping[str, Sequence[str]]) -> str:
|
|
'''
|
|
Returns the closest match to `text` out of the `options`
|
|
:param text: The test string that needs to be found
|
|
:param options: A dict with keys (the value that will be returned)
|
|
and values a list of the options to be matched against
|
|
'''
|
|
reverse_lookup_dict = {value: key for key, values in options.items() for value in values}
|
|
match = closest_match(text, reverse_lookup_dict.keys())
|
|
return reverse_lookup_dict[match]
|