linastk/utils/formatting.py
2024-01-28 20:10:23 +06:00

76 lines
2.1 KiB
Python

import datetime
from typing import Optional, SupportsInt
def flagconverter(code: str):
"""Converts the specified country code to a flag."""
if code is None:
return ''
if len(code) == 1 or len(code) > 2:
raise ValueError("CC too short or long")
res = f"{''.join(chr(127397 + ord(str.upper(k))) for k in code)}"
return res
def bigip(x: int):
"""Converts a BIG formatted IP address to a human-readable format"""
return '.'.join([str(y) for y in int.to_bytes(int(x), 4, 'big')])
def humanize_timedelta(
*, timedelta: Optional[datetime.timedelta] = None, seconds: Optional[SupportsInt] = None
) -> str:
"""
Get a locale aware human timedelta representation.
This works with either a timedelta object or a number of seconds.
Fractional values will be omitted, and values less than 1 second
an empty string.
Parameters
----------
timedelta: Optional[datetime.timedelta]
A timedelta object
seconds: Optional[SupportsInt]
A number of seconds
Returns
-------
str
A locale aware representation of the timedelta or seconds.
Raises
------
ValueError
The function was called with neither a number of seconds nor a timedelta object
"""
try:
obj = seconds if seconds is not None else timedelta.total_seconds()
except AttributeError:
raise ValueError("You must provide either a timedelta or a number of seconds")
seconds = int(obj)
periods = [
("year", "years", 60 * 60 * 24 * 365),
("month", "months", 60 * 60 * 24 * 30),
("day", "days", 60 * 60 * 24),
("hour", "hours", 60 * 60),
("minute", "minutes", 60),
("second", "seconds", 1),
]
strings = []
for period_name, plural_period_name, period_seconds in periods:
if seconds >= period_seconds:
period_value, seconds = divmod(seconds, period_seconds)
if period_value == 0:
continue
unit = plural_period_name if period_value > 1 else period_name
strings.append(f"{period_value} {unit}")
return ", ".join(strings)