[docs]defprogress_bar(progress:float,total:float)->None:"""Prints a progress bar. Args: progress: current progress to total. x/total. total: the total. """percent=int(progress/(int(total)/100))bar_length=50bar_progress=int(progress/(int(total)/bar_length))bar_texture="■"*bar_progresswhitespace_texture=" "*(bar_length-bar_progress)ifprogress==total:full_bar="■"*bar_lengthprint(f"\r[ PROGRESS ] ❙{full_bar}❙ 100%",end="\n")# noqa: T201else:print(# noqa: T201f"\r[ PROGRESS ] ❙{bar_texture}{whitespace_texture}❙ {percent}%",end="\r",)
[docs]defpop_dict(input_dict:dict[str,Any],keys:list[str])->dict[str,Any]:"""Remove keys (and value for key) from `dict`. does not modify the input dict. does nothing if the keys don't exist in the dict. Args: input_dict: dict to remove keys from. keys: list of keys to remove. Returns: The new dict without the specified keys. """log.debug(f"cleaning dict keys={keys}")output_dict=input_dict.copy()forkeyinkeys:output_dict.pop(key,None)returnoutput_dict
[docs]defchunks(input_list:list[Any],output_length:int)->Generator[list[Any],None,None]:"""Get chunks of list -> list of lists. Args: input_list: the list to split into chunks. output_length: length of the chunks. Yields: the chunked list of lists. """foriinrange(0,len(input_list),output_length):yieldinput_list[i:i+output_length]
[docs]defget_random_letters(count:int)->str:"""Get a string of random letters. Args: count: count of random characters in the returned string. Raises: ValueError: if count is smaller than 1. Returns: The string of random letters. """ifcount<=1:log.error(f"'{count}' is not a valid integer")raiseValueErrorrandom_letters=random.choices(string.ascii_letters,k=count)# noqa: S311return"".join(random_letters)
[docs]defwait_random(max_seconds:int)->None:"""Wait random amount of seconds. Args: max_seconds: max seconds to wait. """ifmax_seconds<=1:log.debug("skipping wait")returnwait_time=random.randrange(1,max_seconds+1)# noqa: S311log.debug(f"waiting {wait_time} seconds")sleep(wait_time)
[docs]deffix_punycode(zone_name:str)->str:"""Fix punycode characters in domain name. Args: zone_name: domain/zone name. Returns: The fixed domain/zone name. """returnzone_name.encode("idna").decode("utf8")
[docs]defcheck_null(item:str|bool|float)->bool:"""Check if an item is null/0/none. Args: item: the item. Raises: ValueError: if the item is not a `str`, `bool`, `int` or `float`. Returns: If the value is considered null/0/none. """ifisinstance(item,bool):returnitemifisinstance(item,int|float):returnbool(item)ifisinstance(item,str):ifitem.lower()in{"null","nil","none","false","0"}:returnFalsereturnbool(item)log.error(f"invalid null item {item=}")raiseValueError