Source code for gnomish_army_knife.runtime

"""
A module implementing this package's runtime environment.
"""

# built-in
from argparse import ArgumentParser as _ArgumentParser
from argparse import Namespace as _Namespace
from contextlib import ExitStack, contextmanager
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Iterator, Optional

# third-party
from rcmpy.xdg import user_state
from runtimepy.mixins.environment import ChannelEnvironmentMixin
from vcorelib.logging import LoggerMixin

# internal
from gnomish_army_knife import DEFAULT_CONFIG, PKG_ABBREV
from gnomish_army_knife.config import Config
from gnomish_army_knife.database import ArenaMatchDb
from gnomish_army_knife.paths import (
    combat_log_datetime,
    path_is_combat_log,
    wow_dir,
)


[docs] class GakRuntime(ChannelEnvironmentMixin, LoggerMixin): """A class implementing a runtime environment interface.""" def __init__(self, stack: ExitStack, args: _Namespace) -> None: """Initialize this instance.""" ChannelEnvironmentMixin.__init__(self) LoggerMixin.__init__(self) self.config = Config.decode(args.config, require_success=False) self.wow_dir = wow_dir(args, self.config) self.logger.info( "Using '%s' as installation directory.", self.wow_dir.resolve() ) state = ( args.state if not args.ephemeral # pylint: disable=consider-using-with else Path(stack.enter_context(TemporaryDirectory())) # pylint: enable=consider-using-with ) self.database = ArenaMatchDb(stack, state) @property def retail(self) -> Path: """Get the root path to the retail WoW installation.""" return self.wow_dir.joinpath("_retail_") @property def combat_logs(self) -> Iterator[Path]: """Iterate over combat logs found.""" base = self.retail.joinpath("Logs") for item in base.iterdir(): if path_is_combat_log(item): yield item
[docs] def latest_combat_log(self) -> Optional[Path]: """Attempt to get the most recent combat-log file.""" latest = None logs = list(self.combat_logs) if logs: latest = logs[0] latest_time = combat_log_datetime(latest) for log in logs[1:]: curr_time = combat_log_datetime(log) if curr_time > latest_time: latest = log latest_time = curr_time return latest
[docs] @staticmethod def cli_args(parser: _ArgumentParser) -> None: """Add command-line argumments related to the runtime environment.""" parser.add_argument( "-c", "--config", default=DEFAULT_CONFIG, type=Path, help=( "path to an optional configuration file " "(default: '%(default)s')" ), ) parser.add_argument( "-s", "--state", default=user_state(PKG_ABBREV), type=Path, help=( "path to the program's state directory " "(default: '%(default)s')" ), ) parser.add_argument( "-e", "--ephemeral", action="store_true", help="set to use new, temporary directories when applicable", )
[docs] @staticmethod @contextmanager def create(args: _Namespace) -> Iterator["GakRuntime"]: """Create a runtime instance as a context.""" with ExitStack() as stack: yield GakRuntime(stack, args)