from functools import partial from typing import Any, Callable, Iterable, Optional, Tuple, Union from server.utils.glom import delete from server.utils.mappers.core.getters import DEFAULT_NONE_VALUES, getter from server.utils.mappers.core.mappers import mapper from server.utils.mappers.core.setters import setter def format_id( _id: Optional[str], remove_prefix: bool = False, to_int: bool = False, all_except_prefix: bool = False ) -> Optional[Union[str, int]]: if not _id: return _id if remove_prefix: id_parts = _id.split("_") if len(id_parts) > 1: _id = id_parts[1] if not all_except_prefix else "_".join(id_parts[1:]) if to_int: _id = int(_id) return _id def map_id( item: dict, key, key_to: str = None, remove_prefix: bool = False, to_int: bool = False, remove_key: bool = False ): """ Map 'id' field for various item. @param item: item to work with (get from, set to) @param key: key to get original value from @param key_to: key to save new value to, if None 'key' is used @param remove_prefix: should prefix (before '_' delimiter) be removed or not @param to_int: should value be converted to int (after prefix removal) or not @param remove_key: should original 'key' be removed from item or not """ return mapper( item, key, key_to=key_to, f=partial(format_id, remove_prefix=remove_prefix, to_int=to_int), remove_key=remove_key, ) def get_not_none( item: dict, keys: Iterable[Any], to_int: bool = False, remove_key: bool = False, remove_prefix: bool = False, none_result: Any = None, none_values: Tuple[Any] = DEFAULT_NONE_VALUES, getter: Callable = getter, ) -> Any: """It returns first not-nullable value got by key from 'keys' @param item: item to work with (get from, set to) @param keys: iterable of keys to get possible values from @param to_int: should value be converted to int (after prefix removal) or not @param remove_key: should 'key' be removed from item or not @param remove_prefix: should prefix be removed from value or not @param none_result: result to be returned if there is not non-nullable values for passed keys @param none_values: values considered as None @param getter: function to get value from item """ value = none_result for k in keys: value = getter( item, key=k, none_values=none_values, none_result=none_result, f=partial(format_id, remove_prefix=remove_prefix, to_int=to_int), ) if remove_key: delete(item, k, ignore_missing=True) if value != none_result: break return value def map_id_not_none( item: dict, keys: Iterable[Any], key_to: Any, to_int: bool = False, remove_key: bool = False, none_result: Any = None, none_values: Tuple[Any] = DEFAULT_NONE_VALUES, getter: Callable = getter, setter: Callable = setter, ): """ Map 'id' field for various item. It sets first not-nullable value got by key from 'keys' to 'key_to'. @param item: item to work with (get from, set to) @param keys: iterable of keys to get possible 'id' values from @param key_to: new key to set value to @param to_int: should value be converted to int (after prefix removal) or not @param remove_key: should original 'key' be removed from item or not @param none_result: result to be returned if there is not non-nullable values for passed keys @param none_values: values considered as None @param getter: function to get value from item @param setter: function to set value to item """ value = get_not_none( item, keys=keys, to_int=to_int, remove_key=remove_key, remove_prefix=True, none_result=none_result, none_values=none_values, getter=getter, ) setter(item, key_to, value=value)