Skip to content

Commit

Permalink
feature(install): add handler for installation logs
Browse files Browse the repository at this point in the history
  • Loading branch information
maugde committed Jul 23, 2024
1 parent 3ab6751 commit 8a3d100
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 24 deletions.
37 changes: 35 additions & 2 deletions src/antares_web_installer/gui/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import typing
from pathlib import Path

import psutil
from platformdirs import user_log_dir

from .mvc import Controller, Model, View
from .model import WizardModel
from .view import WizardView
Expand All @@ -25,10 +28,35 @@ class WizardController(Controller):
launch: typing.Optional[bool] = True

server_path: typing.Optional[Path] = None
log_path: typing.Optional[Path] = dataclasses.field(init=False)
log_file: typing.Optional[Path] = dataclasses.field(init=False)
app: App = dataclasses.field(init=False)

def __post_init__(self):
super().__init__()
self.initialize_log_path()

def initialize_log_path(self):
self.log_path = Path(user_log_dir("AntaresWebInstaller", "RTE"))
if not self.log_path.exists():
msg = "No log directory found with path '{}'.".format(self.log_path)
logger.warning(msg)
try:
self.log_path.mkdir(parents=True)
except FileExistsError:
logger.warning("Path '{}' already exists.".format(self.log_path))
else:
logger.info("Path '{}' successfully created.".format(self.log_path))
tmp_file_name = "web-installer.log"

self.log_file = self.log_path.joinpath(tmp_file_name)

# check if file exists
if self.log_file not in list(self.log_path.iterdir()):
# if not, create it first
with open(self.log_file, "w") as f:
pass
f.close()

def init_model(self, **kwargs) -> Model:
model = WizardModel(self)
Expand All @@ -51,11 +79,16 @@ def install(self):
self.app.run()
except InstallError as e:
logger.error(e)
self.view.raise_error("The installation encountered an error. The target directory may have be corrupted. "
"Please check its integrity and try again.")
self.view.raise_error("The installation encountered an error. The target directory may have been "
"corrupted. Please check its integrity and try again.")
except psutil.NoSuchProcess as e:
logger.error(e)
self.view.raise_error("The installation encountered an error. The installation encountered an error while "
"scanning processes. Please retry later.")
else:
logger.debug("Launch installer worker")
logger.debug("Installation complete")

self.view.frames[self.view.current_index].event_generate("<<InstallationComplete>>")

def save_target_dir(self, path: str):
Expand Down
6 changes: 6 additions & 0 deletions src/antares_web_installer/gui/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ def current_index(self, new_index: int):
self._current_index = new_index
self.change_frame()

def get_log_file(self):
try:
return self.controller.log_file
except AttributeError as e:
self.raise_error("The installer encountered an error while initializing the logger. Please retry later.")

def set_geometry(self, width, height):
"""
@param width:
Expand Down
65 changes: 43 additions & 22 deletions src/antares_web_installer/gui/widgets/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class LogManager(logging.Handler):
def __init__(self, progress_frame: "ProgressFrame"):
logging.Handler.__init__(self)
self.setLevel(logging.INFO)
formatter = logging.Formatter(FORMAT)
formatter = logging.Formatter("[%(asctime)-15s] %(message)s")
self.setFormatter(formatter)
self.progress_frame = progress_frame

Expand Down Expand Up @@ -258,46 +258,67 @@ def __init__(self, master: tk.Misc, window: "WizardView", index: int, *args, **k
def progress_update(self, value: float):
self.progress_bar["value"] = value

def initialize_user_log_manager(self, logger):
# One log after another is displayed in the main window
log_manager = LogManager(self)
logger.addHandler(log_manager)

def initialize_file_log_manager(self, logger):
from antares_web_installer.gui.controller import WizardController

if isinstance(self.window.controller, WizardController):
# create new tmp directory if it does not exist yet
tmp_dir_path = self.window.controller.log_path
tmp_file_name = "web-installer.log"

tmp_file = tmp_dir_path.joinpath(tmp_file_name)

# check if file exists
if tmp_file not in list(tmp_dir_path.iterdir()):
logger.info("No temporary file was found. Create a new one.")
# if not, create it first

if tmp_file.exists():
logger.info("Creation successful")
else:
self.window.raise_error("No temporary file was created or found.")

def on_active_frame(self, event):
# Lazy import for typing and testing purposes
from antares_web_installer.gui.controller import WizardController

# retrieve app logger
main_logger = logging.getLogger("antares_web_installer.app")

if isinstance(self.window.controller, WizardController):
# create new tmp directory if it does not exist yet
tmp_dir_path = self.window.controller.target_dir.joinpath("tmp/")

try:
os.mkdir(tmp_dir_path)
except FileExistsError:
main_logger.warning("Directory already exists. Skip directory creation step.")
except FileNotFoundError as e:
msg = "An error occured while saving logs."
main_logger.error(f"'tmp' directory was not found in {tmp_dir_path}: {e}")
main_logger.info(msg)
self.window.raise_error(msg)
# Initialize log manager
log_manager = LogManager(self)
main_logger.addHandler(log_manager)

if isinstance(self.window.controller, WizardController):
# redirect logs in the target `tmp` directory
file_logger = logging.FileHandler(tmp_dir_path.joinpath("web-installer.log"))
file_logger.setFormatter(logging.Formatter(FORMAT))
file_logger.setLevel(logging.ERROR)
file_logger = logging.FileHandler(self.window.get_log_file())
file_logger.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s: %(message)s"))
file_logger.setLevel(logging.INFO)
main_logger.addHandler(file_logger)

# One log after another is displayed in the main window
log_manager = LogManager(self)
main_logger.addHandler(log_manager)

# Launching installation in concurrency with the current process
self.thread = Thread(target=self.window.controller.install, args=())
self.thread.start()
else:
msg = "The installer encounters an issue while instantiating controller (code 'NotImplementedError')."
msg = "The installer encounters an issue while instantiating controller ('NotImplementedError')."
main_logger.error(f"Not implemented {type(self.window.controller)}.")
self.window.raise_error(msg)

def on_installation_complete(self, event):
# Lazy import for typing and testing purposes
from antares_web_installer.gui.controller import WizardController

if isinstance(self.window.controller, WizardController):
# move log file in application log directory
file_name = self.window.controller.log_file.name
log_directory = self.window.controller.target_dir.joinpath('logs')
self.window.get_log_file().rename(self.window.controller.target_dir.joinpath(log_directory, file_name))

self.control_btn.btns["next"].toggle_btn(True)


Expand Down

0 comments on commit 8a3d100

Please sign in to comment.