ripple-python-common/generalUtils.py

181 lines
3.8 KiB
Python

import string
import random
import hashlib
from functools import partial
from common.log import logUtils as log
import dill
from common.constants import mods
from time import localtime, strftime
def randomString(length = 8):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))
def stringToBool(s):
"""
Convert a string (True/true/1) to bool
:param s: string/int value
:return: True/False
"""
return s == "True" or s == "true" or s == "1" or s == 1
def fileMd5(filename):
"""
Return filename's md5
:param filename: name of the file
:return: file md5
"""
with open(filename, mode='rb') as f:
d = hashlib.md5()
for buf in iter(partial(f.read, 128), b''):
d.update(buf)
return d.hexdigest()
def stringMd5(s):
"""
Return string's md5
:param s: input string
:return: `string`'s md5
"""
d = hashlib.md5()
d.update(s.encode("utf-8"))
return d.hexdigest()
def getRank(gameMode=None, __mods=None, acc=None, c300=None, c100=None, c50=None, cmiss=None, *, score_=None):
"""
Return a string with rank/grade for a given score.
Used mainly for tillerino
:param gameMode: game mode number
:param __mods: mods value
:param acc: accuracy
:param c300: 300 hit count
:param c100: 100 hit count
:param c50: 50 hit count
:param cmiss: misses count
:param score_: score object. Optional.
:return: rank/grade string
"""
if score_ is not None:
return getRank(score_.gameMode, score_.mods, score_.accuracy, score_.c300, score_.c100, score_.c50, score_.cMiss)
total = c300 + c100 + c50 + cmiss
hdfl = (__mods & mods.HIDDEN > 0) or (__mods & mods.FLASHLIGHT > 0)
def ss():
return "XH" if hdfl else "X"
def s():
return "SH" if hdfl else "S"
if gameMode == 0:
# osu!std
if acc == 100:
return ss()
if c300 / total > 0.90 and c50 / total < 0.1 and cmiss == 0:
return s()
if (c300 / total > 0.80 and cmiss == 0) or (c300 / total > 0.90):
return "A"
if (c300 / total > 0.70 and cmiss == 0) or (c300 / total > 0.80):
return "B"
if c300 / total > 0.60:
return "C"
return "D"
elif gameMode == 1:
# TODO: taiko rank
return "A"
elif gameMode == 2:
# CtB
if acc == 100:
return ss()
if 98.01 <= acc <= 99.99:
return s()
if 94.01 <= acc <= 98.00:
return "A"
if 90.01 <= acc <= 94.00:
return "B"
if 98.01 <= acc <= 90.00:
return "C"
return "D"
elif gameMode == 3:
# osu!mania
if acc == 100:
return ss()
if acc > 95:
return s()
if acc > 90:
return "A"
if acc > 80:
return "B"
if acc > 70:
return "C"
return "D"
return "A"
def getTimestamp():
"""
Return current time in YYYY-MM-DD HH:MM:SS format.
Used in logs.
:return: readable timestamp
"""
return strftime("%Y-%m-%d %H:%M:%S", localtime())
def hexString(s):
"""
Output `s`'s bytes in DEX
:param s: string
:return: string with HEX values
"""
return ":".join("{:02x}".format(ord(str(c))) for c in s)
def readableMods(__mods):
# TODO: same as common.scoreUtils.readableMods. Remove this or the other one.
r = ""
if __mods == 0:
return r
if __mods & mods.NOFAIL > 0:
r += "NF"
if __mods & mods.EASY > 0:
r += "EZ"
if __mods & mods.HIDDEN > 0:
r += "HD"
if __mods & mods.HARDROCK > 0:
r += "HR"
if __mods & mods.DOUBLETIME > 0:
r += "DT"
if __mods & mods.HALFTIME > 0:
r += "HT"
if __mods & mods.FLASHLIGHT > 0:
r += "FL"
if __mods & mods.SPUNOUT > 0:
r += "SO"
return r
def strContains(s, w):
"""
Check if `w` is in `s`
:param s: haystack
:param w: needle
:return: True if `w` is in `s`, otherwise False
"""
return (' ' + w + ' ') in (' ' + s + ' ')
def getTotalSize(o):
"""
Get approximate object size using dill
:param o: object
:return: approximate bytes size
"""
try:
return len(dill.dumps(o, recurse=True))
except:
log.error("Error while getting total object size!")
return 0