AnPv2/Python/Utils/Utils.py

140 lines
3.9 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Any, Self, Sequence, Optional
from re import Match as REMatch
from Utils.Check import Check
from Utils.Options import Options
from Utils.Patterns import RE
class Utils:
GET_DICTIONARY_OPTIONS:Options = Options(Options.NO_OVERWRITE)
GET_VALUE_OPTIONS:Options = Options(Options.ALLOW_NULLS)
@classmethod
def get_keys(cls:type[Self], *items:Any|None) -> list[str]:
keys:list[str] = []
item:Any|None
for item in items:
if Check.is_key(item):
item in keys or keys.append(item)
elif Check.is_array(item):
key:str
for key in cls.get_keys(*item):
key in keys or keys.append(key)
return keys
@classmethod
def get_dictionaries(cls:type[Self], *items:Any|None) -> list[dict[str, Any|None]]:
dictionaries:list[dict[str, Any|None]] = []
item:Any|None
for item in items:
if Check.is_dictionary(item):
item in dictionaries or dictionaries.append(item)
elif Check.is_array(item):
dictionary:dict
for dictionary in cls.get_dictionaries(*item):
dictionary in dictionaries or dictionaries.append(dictionary)
return dictionaries
@classmethod
def get_dictionary(cls:type[Self], items:Any|None, custom_options:int = 0) -> dict[str, Any|None]:
dictionary:dict[str, Any|None] = {}
options:Options = Options(custom_options, cls.GET_DICTIONARY_OPTIONS)
if Check.is_dictionary(items):
dictionary = items
elif Check.is_array(items):
item:Any|None
for item in items:
key:str
value:Any|None
for key, value in cls.get_dictionary(item, options).items():
if options.overwrite or key not in dictionary:
dictionary[key] = value
return dictionary
@classmethod
def get_value(cls:type[Self],
keys:str|Sequence[str],
inputs:dict[str, Any|None]|Sequence[Any|None],
default:Optional[Any] = None,
custom_options:int = 0
) -> Any|None:
options:Options = Options(custom_options, cls.GET_VALUE_OPTIONS)
if len(keys := cls.get_keys(keys)):
subinputs:dict[str, Any|None]
for subinputs in cls.get_dictionaries(inputs):
key:str
for key in keys:
if key in subinputs and (
options.allow_null or
subinputs[key] is not None
):
return subinputs[key]
return default
@staticmethod
def get_array(value:Any|None) -> list[Any]:
return (
value if isinstance(value, list) else
list(value) if isinstance(value, (set, tuple)) else
[value])
@staticmethod
def get_strings(value:Any|None) -> list[str]:
strings:list[str] = []
item:Any|None
for item in Utils.get_array(value):
if Check.is_string(item):
item in strings or strings.append(item)
elif Check.is_array(item):
strings.extend(Utils.get_strings(item))
return strings
@classmethod
def string_variables(cls:type[Self],
string:str,
variables:dict[str, Any|None],
default:Optional[str] = None
) -> str:
variables = Utils.get_dictionary(variables)
def callback(matches:REMatch) -> str:
key:str = matches.group(1)
return (
str(variables[key]) if key in variables else
default if default is not None else
matches.group(0))
return RE.STRING_VARIABLES.sub(callback, string)