Source code for pyra

"""
..
   __init__.py

Responsible for initialization of RetroArcher.
"""
# future imports
from __future__ import annotations

# standard imports
import os
import subprocess
import sys
import threading
from typing import Union

# local imports
from pyra import config
from pyra import definitions
from pyra import helpers
from pyra import logger

# get logger
log = logger.get_logger(name=__name__)

_INITIALIZED = False
CONFIG = None
CONFIG_FILE = None
DEBUG = False
DEV = False
SIGNAL = None  # Signal to watch for
INIT_LOCK = threading.Lock()
QUIET = False


[docs] def initialize(config_file: str) -> bool: """ Initialize RetroArcher. Sets up config, loggers, and http port. Parameters ---------- config_file : str The path to the config file. Returns ------- bool True if initialize succeeds, otherwise False. Raises ------ SystemExit If unable to correct possible issues with config file. Examples -------- >>> initialize(config_file='config.ini') True """ with INIT_LOCK: global CONFIG global CONFIG_FILE global DEBUG global _INITIALIZED try: CONFIG = config.create_config(config_file=config_file) except Exception: raise SystemExit("Unable to initialize due to a corrupted config file. Exiting...") CONFIG_FILE = config_file assert CONFIG is not None logger.blacklist_config(config=CONFIG) # setup log blacklist if _INITIALIZED: return False # create logs folder definitions.Paths.LOG_DIR, log_writable = helpers.check_folder_writable( folder=definitions.Paths.LOG_DIR, fallback=os.path.join(definitions.Paths.DATA_DIR, 'logs'), name='logs' ) if not log_writable and not QUIET: sys.stderr.write("Unable to create the log directory. Logging to screen only.\n") # setup loggers... cannot use logging until this is finished logger.setup_loggers() if CONFIG['Network']['HTTP_PORT'] < 21 or CONFIG['Network']['HTTP_PORT'] > 65535: log.warning(msg=f"HTTP_PORT out of bounds: 21 < {CONFIG['Network']['HTTP_PORT']} < 65535") CONFIG['Network']['HTTP_PORT'] = 9696 DEBUG = DEBUG or bool(CONFIG['Logging']['DEBUG_LOGGING']) _INITIALIZED = True return True
[docs] def stop(exit_code: Union[int, str] = 0, restart: bool = False): """ Stop RetroArcher. This function ends the tray icon if it's running. Then restarts or shutdowns RetroArcher depending on the value of the `restart` parameter. Parameters ---------- exit_code : Union[int, str], default = 0 The exit code to send. Does not apply if `restart = True`. restart : bool, default = False Set to True to restart RetroArcher. Examples -------- >>> stop(exit_code=0, restart=False) """ # stop the tray icon from pyra.tray_icon import tray_end try: tray_end() except AttributeError: pass if restart: if definitions.Modes.FROZEN: args = [definitions.Paths.BINARY_PATH] else: args = [sys.executable, definitions.Paths.BINARY_PATH] args += sys.argv[1:] if '--nolaunch' not in args: # don't launch the browser again args += ['--nolaunch'] # also os.execv requires at least one argument # os.execv(sys.executable, args) # `os.execv` is more desirable, but is not working correctly # flask app does not respond to requests after restarting # alternative to os.execv() subprocess.Popen(args=args, cwd=os.getcwd()) sys.exit(exit_code)