Source code for circleguard.utils

from logging import Formatter
from copy import copy

from circleguard.mod import Mod


########### LOGGING ##############

TRACE = 5

[docs]class ColoredFormatter(Formatter): """ A subclass of :class:`logging.Formatter` that uses ANSI escape codes to color different parts of the :class:`logging.LogRecord` when printed to the console. Notes ----- Adapted from https://stackoverflow.com/a/46482050. """ COLOR_PREFIX = '\033[' COLOR_SUFFIX = '\033[0m' COLOR_MAPPING = { "TRACE" : 90, # bright black "DEBUG" : 94, # bright blue "INFO" : 95, # bright magenta "WARNING" : 31, # red "ERROR" : 91, # bright red "CRITICAL" : 41, # white on red bg "NAME" : 32, # green "MESSAGE" : 93, # bright yellow "FILENAME" : 92, # bright green "LINENO" : 91 # bright red } def __init__(self, patern): Formatter.__init__(self, patern) self.colored_log = "{prefix}{{color}}m{{msg}}{suffix}".format( prefix=self.COLOR_PREFIX, suffix=self.COLOR_SUFFIX)
[docs] def format(self, record): # c as in colored, not as in copy c_record = copy(record) # logging's choice of camelCase, not mine threadName = c_record.threadName color = self.COLOR_MAPPING["NAME"] c_threadName = self.colored_log.format(color=color, msg=threadName) levelname = c_record.levelname color = self.COLOR_MAPPING.get(levelname, 37) # default to white c_levelname = self.colored_log.format(color=color, msg=levelname) name = c_record.name color = self.COLOR_MAPPING["NAME"] c_name = self.colored_log.format(color=color, msg=name) message = c_record.msg # why is this msg, but we format it as %(message)s in the formatter? blame logging color = self.COLOR_MAPPING["MESSAGE"] c_msg = self.colored_log.format(color=color, msg=message) filename = c_record.filename color = self.COLOR_MAPPING["FILENAME"] c_filename = self.colored_log.format(color=color, msg=filename) lineno = c_record.lineno color = self.COLOR_MAPPING["LINENO"] c_lineno = self.colored_log.format(color=color, msg=lineno) c_record.threadName = c_threadName c_record.levelname = c_levelname c_record.name = c_name c_record.msg = c_msg c_record.filename = c_filename c_record.lineno = c_lineno return Formatter.format(self, c_record)
######### UTILS ###########
[docs]def convert_ur(ur, mods, *, to): """ Converts an unstable rate to a converted unstable rate, depending on the mods the replay was played with. Parameters ---------- ur: float The unconverted ur of the replay. mods: Mod The mods the replay was played with. Only ``Mod.DT`` and ``Mod.HT`` will affect the unstable rate conversion. to: string What to convert the ur to. One of ``cv`` (converted) or ``ucv`` (unconverted). """ if to not in ["cv", "ucv"]: raise ValueError(f"Expected one of cv, ucv. Got {to}") conversion_factor = 1 if Mod.DT in mods: conversion_factor = (1 / 1.5) elif Mod.HT in mods: conversion_factor = (1 / 0.75) if to == "cv": return ur * conversion_factor elif to == "ucv": return ur / conversion_factor