212 lines
5.7 KiB
Python
212 lines
5.7 KiB
Python
from __future__ import annotations
|
|
|
|
import random
|
|
import colorsys
|
|
import time
|
|
from datetime import datetime
|
|
from typing import ClassVar
|
|
|
|
from wonderwords import RandomWord, RandomSentence # type: ignore
|
|
from fontTools.ttLib import TTFont # type: ignore
|
|
|
|
from .config import Config
|
|
|
|
|
|
class Utils:
|
|
names: ClassVar[list[str]] = []
|
|
countries: ClassVar[list[str]] = []
|
|
rand_word: RandomWord
|
|
rand_sentence: RandomSentence
|
|
vowels = "aeiou"
|
|
consonants = "bcdfghjklmnpqrstvwxyz"
|
|
|
|
@staticmethod
|
|
def prepare() -> None:
|
|
from .storage import Storage
|
|
|
|
Utils.names = Storage.get_names()
|
|
Utils.countries = Storage.get_countries()
|
|
Utils.rand_word = RandomWord()
|
|
Utils.rand_sentence = RandomSentence()
|
|
|
|
@staticmethod
|
|
def now() -> int:
|
|
return int(time.time())
|
|
|
|
@staticmethod
|
|
def singular_or_plural(num: float, singular: str, plural: str) -> str:
|
|
if num == 1:
|
|
return singular
|
|
|
|
return plural
|
|
|
|
@staticmethod
|
|
def time_ago(start_time: float, end_time: float) -> str:
|
|
diff = end_time - start_time
|
|
seconds = int(diff)
|
|
|
|
if seconds < 60:
|
|
word = Utils.singular_or_plural(seconds, "second", "seconds")
|
|
return f"{seconds} {word} ago"
|
|
|
|
minutes = seconds // 60
|
|
|
|
if minutes < 60:
|
|
word = Utils.singular_or_plural(minutes, "minute", "minutes")
|
|
return f"{minutes} {word} ago"
|
|
|
|
hours = minutes / 60
|
|
|
|
if hours < 24:
|
|
word = Utils.singular_or_plural(hours, "hour", "hours")
|
|
return f"{hours:.1f} {word} ago"
|
|
|
|
days = hours / 24
|
|
|
|
if days < 30:
|
|
word = Utils.singular_or_plural(days, "day", "days")
|
|
return f"{days:.1f} {word} ago"
|
|
|
|
months = days / 30
|
|
|
|
if months < 12:
|
|
word = Utils.singular_or_plural(months, "month", "months")
|
|
return f"{months:.1f} {word} ago"
|
|
|
|
years = months / 12
|
|
word = Utils.singular_or_plural(years, "year", "years")
|
|
return f"{years:.1f} {word} ago"
|
|
|
|
@staticmethod
|
|
def print(text: str) -> None:
|
|
print(text) # noqa: T201
|
|
|
|
@staticmethod
|
|
def random_color(seed: str) -> tuple[int, int, int]:
|
|
seed_int = hash(seed)
|
|
random.seed(seed_int)
|
|
|
|
h, s, l = (
|
|
random.random(),
|
|
0.5 + random.random() / 2.0,
|
|
0.4 + random.random() / 5.0,
|
|
)
|
|
|
|
r, g, b = (int(256 * i) for i in colorsys.hls_to_rgb(h, l, s))
|
|
return r, g, b
|
|
|
|
@staticmethod
|
|
def random_name(ignore: list[str], include: list[str] | None = None) -> str:
|
|
names = Utils.names
|
|
|
|
if include:
|
|
for name in include:
|
|
if name not in names:
|
|
names.append(name)
|
|
|
|
filtered = [name for name in Utils.names if name not in ignore]
|
|
|
|
if not filtered:
|
|
return Utils.make_name()
|
|
|
|
return random.choice(filtered)
|
|
|
|
@staticmethod
|
|
def get_rgb(color: tuple[int, int, int]) -> str:
|
|
return f"rgb{color}"
|
|
|
|
@staticmethod
|
|
def random_character(font_path: str, num: int) -> str:
|
|
font = TTFont(font_path)
|
|
cmap = font["cmap"]
|
|
unicode_map = cmap.getBestCmap()
|
|
characters = [chr(code_point) for code_point in unicode_map]
|
|
|
|
for _ in range(10): # Try up to 10 times
|
|
selected = random.sample(characters, num)
|
|
|
|
if all((char.isprintable() and not char.isspace()) for char in selected):
|
|
return " ".join(selected)
|
|
|
|
return ""
|
|
|
|
@staticmethod
|
|
def random_emoji(num: int) -> str:
|
|
return Utils.random_character(str(Config.emoji_font_path), num)
|
|
|
|
@staticmethod
|
|
def to_date(timestamp: float) -> str:
|
|
dt_object = datetime.fromtimestamp(timestamp)
|
|
hour = dt_object.strftime("%I").lstrip("0")
|
|
return dt_object.strftime(f"%b %d %Y - {hour}:%M %p")
|
|
|
|
@staticmethod
|
|
def get_seconds(msecs: int) -> str:
|
|
seconds = msecs // 1000
|
|
|
|
if seconds < 60:
|
|
return f"{seconds} seconds"
|
|
|
|
minutes = seconds // 60
|
|
|
|
if minutes == 1:
|
|
return "1 minute"
|
|
|
|
return f"{minutes} minutes"
|
|
|
|
@staticmethod
|
|
def random_country(ignore: list[str]) -> str:
|
|
filtered = [country for country in Utils.countries if country not in ignore]
|
|
return random.choice(filtered)
|
|
|
|
@staticmethod
|
|
def random_word() -> str:
|
|
word = Utils.rand_word.word(
|
|
include_parts_of_speech=["nouns", "adjectives"], word_max_length=8
|
|
)
|
|
|
|
return str(word)
|
|
|
|
@staticmethod
|
|
def random_words(num: int = 1) -> list[str]:
|
|
return [Utils.random_word() for _ in range(num)]
|
|
|
|
@staticmethod
|
|
def capitalize(word: str) -> str:
|
|
return word[0].upper() + word[1:]
|
|
|
|
@staticmethod
|
|
def words_1() -> str:
|
|
return str(Utils.rand_sentence.simple_sentence())
|
|
|
|
@staticmethod
|
|
def words_2() -> str:
|
|
return str(Utils.rand_sentence.bare_bone_sentence())
|
|
|
|
@staticmethod
|
|
def words_3() -> str:
|
|
return str(Utils.rand_sentence.bare_bone_with_adjective())
|
|
|
|
@staticmethod
|
|
def words_4() -> str:
|
|
return str(Utils.rand_sentence.sentence())
|
|
|
|
@staticmethod
|
|
def make_word() -> str:
|
|
name = ""
|
|
name += random.choice(Utils.consonants)
|
|
name += random.choice(Utils.vowels)
|
|
name += random.choice(Utils.consonants)
|
|
name += random.choice(Utils.vowels)
|
|
return name
|
|
|
|
@staticmethod
|
|
def make_words(num: int = 1) -> list[str]:
|
|
return [Utils.make_word() for _ in range(num)]
|
|
|
|
@staticmethod
|
|
def make_name() -> str:
|
|
words = Utils.make_words(2)
|
|
words = [word.capitalize() for word in words]
|
|
return " ".join(words)
|