Modules
TMan.
api
¶
Defines the public API.
TManAPI
¶
Main API handle.
__eq__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __eq__(self, other):
if other.__class__ is not self.__class__:
return NotImplemented
return (
self.data_dir,
self.config_file,
) == (
other.data_dir,
other.config_file,
)
__ge__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __ge__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) >= attrs_to_tuple(other)
return NotImplemented
__gt__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __gt__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) > attrs_to_tuple(other)
return NotImplemented
__init__(self, data_dir, config_file)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __init__(self, data_dir, config_file):
self.data_dir = __attr_converter_data_dir(data_dir)
self.config_file = __attr_converter_config_file(config_file)
self.__attrs_post_init__()
__le__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __le__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) <= attrs_to_tuple(other)
return NotImplemented
__lt__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __lt__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) < attrs_to_tuple(other)
return NotImplemented
__ne__(self, other)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __ne__(self, other):
"""
Check equality and either forward a NotImplemented or
return the result negated.
"""
result = self.__eq__(other)
if result is NotImplemented:
return NotImplemented
return not result
__repr__(self)
special
¶
Method generated by attrs for class TManAPI.
Source code in tman/api.py
def __repr__(self):
"""
Automatically created by attrs.
"""
try:
working_set = _already_repring.working_set
except AttributeError:
working_set = set()
_already_repring.working_set = working_set
if id(self) in working_set:
return "..."
real_cls = self.__class__
if ns is None:
qualname = getattr(real_cls, "__qualname__", None)
if qualname is not None:
class_name = qualname.rsplit(">.", 1)[-1]
else:
class_name = real_cls.__name__
else:
class_name = ns + "." + real_cls.__name__
# Since 'self' remains on the stack (i.e.: strongly referenced) for the
# duration of this call, it's safe to depend on id(...) stability, and
# not need to track the instance and therefore worry about properties
# like weakref- or hash-ability.
working_set.add(id(self))
try:
result = [class_name, "("]
first = True
for name, attr_repr in attr_names_with_reprs:
if first:
first = False
else:
result.append(", ")
result.extend(
(name, "=", attr_repr(getattr(self, name, NOTHING)))
)
return "".join(result) + ")"
finally:
working_set.remove(id(self))
backend
special
¶
TMan backend.
gui
special
¶
TMan GUI.
main
¶
Main GUI entry point.
main()
¶
Start GUI.
Source code in tman/gui/main.py
def main() -> None:
"""Start GUI."""
app_name = "TMan"
init_logging(verbosity="DEBUG", logdir=user_log_dir(app_name))
logger.debug("Initializing backend")
api = TManAPI( # noqa: F841
data_dir=user_data_dir(app_name), config_file=user_config_dir(app_name) + "/config.json"
)
logger.debug("Starting UI")
sg.theme("DarkBlue")
layout = [
[sg.Text("Some text on Row 1")],
[sg.Text("Enter something on Row 2"), sg.InputText()],
[sg.Button("Ok"), sg.Button("Cancel")],
]
window = sg.Window("Window Title", layout)
while True:
event, values = window.read()
if event in (None, "Cancel"):
break
logger.info(f"You entered {values[0]}")
window.close()
logger.info("Finished successfully.")
util
special
¶
Collection of utility functions for TMan.
logging
¶
Various logging functionality.
InterceptHandler (Handler)
¶
Handler to force stdlib logging to go through loguru.
Based on https://github.com/Delgan/loguru/issues/78
emit(self, record)
¶
Process log record and log with loguru.
Source code in tman/util/logging.py
def emit(self, record: logging.LogRecord) -> None:
"""Process log record and log with loguru."""
depth = self._get_depth()
logger_opt = logger.opt(depth=depth, exception=record.exc_info)
for line in record.getMessage().split("\n"):
level = record.levelname
level_: Union[str, int] = int(level[6:]) if level.startswith("Level ") else level
logger_opt.log(level_, line.rstrip())
init_logging(verbosity, logdir)
¶
Configure loggers according to specified verbosity level and log directory.
Should be called at the program's main entrypoint.
Source code in tman/util/logging.py
def init_logging(verbosity: str, logdir: Union[str, Path]) -> None:
"""
Configure loggers according to specified verbosity level and log directory.
Should be called at the program's main entrypoint.
"""
# Remove default loguru logger
logger.remove()
# Intercept all third-party logging
logging.basicConfig(handlers=[InterceptHandler()], level=0)
# Log to stdout and logfiles
trace_logfile = Path(logdir) / "trace.log"
info_logfile = Path(logdir) / "info.log"
kwargs: Dict[str, Any] = dict(backtrace=True, diagnose=True, enqueue=True)
logger.add(trace_logfile, level="TRACE", **kwargs)
kwargs["format"] = "<level>[{level.name[0]}] {time:HH:mm:ss}</level> {message}"
logger.add(info_logfile, level="INFO", **kwargs)
logger.add(sys.stdout, level=verbosity, **kwargs)
logger.debug("Logging initialized.")
logger.debug(f"Logging to {info_logfile} and {trace_logfile}.")