Ruby-Cogs/casino/utils.py

128 lines
3.6 KiB
Python

import re
import math
from typing import Union, Dict, List, Sequence
utf8_re = re.compile(r"^[\U00000000-\U0010FFFF]*$")
min_int, max_int = 1 - (2 ** 64), (2 ** 64) - 1
def is_input_unsupported(data: Union[Dict, List, str, int, float]):
if type(data) is dict:
for k, v in data.items():
if is_input_unsupported(k) or is_input_unsupported(v):
return True
if type(data) is list:
for i in data:
if is_input_unsupported(i):
return True
if type(data) is str and not utf8_re.match(data):
return True
if type(data) is int:
if not (min_int <= data <= max_int):
return True
if type(data) is float:
if math.isnan(data) or math.isinf(data):
return True
if not (min_int <= data <= max_int):
return True
class PluralDict(dict):
"""This class is used to plural strings
You can plural strings based on the value input when using this class as a dictionary.
"""
def __missing__(self, key):
if "(" in key and key.endswith(")"):
key, rest = key.split("(", 1)
value = super().__getitem__(key)
suffix = rest.rstrip(")").split(",")
if len(suffix) == 1:
suffix.insert(0, "")
return suffix[0] if value <= 1 else suffix[1]
raise KeyError(key)
def time_converter(units):
return sum(int(x) * 60 ** i for i, x in enumerate(reversed(units.split(":"))))
def color_lookup(color="grey"):
colors = {
"blue": 0x3366FF,
"red": 0xFF0000,
"green": 0x00CC33,
"orange": 0xFF6600,
"purple": 0xA220BD,
"yellow": 0xFFFF00,
"teal": 0x009999,
"magenta": 0xBA2586,
"turquoise": 0x00FFFF,
"grey": 0x666666,
"pink": 0xFE01D1,
"white": 0xFFFFFF,
}
color = colors[color]
return color
def fmt_join(words: Sequence, ending: str = "or"):
if not words:
return ""
elif len(words) == 1:
return words[0]
else:
return "{} {} {}".format(", ".join(map(str, words[:-1])), ending, words[-1])
def cooldown_formatter(seconds, custom_msg="0"):
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
if h > 0:
msg = "{0}h"
if m > 0 and s > 0:
msg += ", {1}m, and {2}s"
elif s > 0 and m == 0:
msg += " and {2}s"
elif s == 0 and m == 0:
pass
else:
msg += " and {1}m"
elif h == 0 and m > 0:
msg = "{1}m" if s == 0 else "{1}m and {2}s"
elif m == 0 and h == 0 and s > 0:
msg = "{2}s"
else:
msg = custom_msg
return msg.format(h, m, s)
def time_formatter(seconds):
# Calculate the time and input into a dict to plural the strings later.
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
data = PluralDict({"hour": h, "minute": m, "second": s})
# Determine the remaining time.
if h > 0:
fmt = "{hour} hour{hour(s)}"
if data["minute"] > 0 and data["second"] > 0:
fmt += ", {minute} minute{minute(s)}, and {second} second{second(s)}"
if data["second"] > 0 == data["minute"]:
fmt += ", and {second} second{second(s)}"
msg = fmt.format_map(data)
elif h == 0 and m > 0:
if data["second"] == 0:
fmt = "{minute} minute{minute(s)}"
else:
fmt = "{minute} minute{minute(s)}, and {second} second{second(s)}"
msg = fmt.format_map(data)
elif m == 0 and h == 0 and s > 0:
fmt = "{second} second{second(s)}"
msg = fmt.format_map(data)
else:
msg = "None"
return msg