From df0b97ccc5f16bdd9ee5cf9dfcce6b2bc4cbcc48 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Fri, 30 May 2025 15:03:41 +0000 Subject: [PATCH] loguru again - Source Commit: c7661f2aebcd79873248d90992dc3e7a48901f11 - Date: 2025-05-30 15:03:41 - Job ID: 117494 - Pipeline ID: 29056 - [skip ci] --- noctua/config/constants.py | 2 +- noctua/sequencer.py | 31 ++++++++++++++++++------------ noctua/templates/testlamp.py | 4 +--- noctua/templates/testoutput.py | 2 +- noctua/utils/logger.py | 19 +++++++++++------- noctua/utils/structure.py | 35 +++++++++++++++++----------------- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/noctua/config/constants.py b/noctua/config/constants.py index c05fb8b..16654c8 100644 --- a/noctua/config/constants.py +++ b/noctua/config/constants.py @@ -141,6 +141,6 @@ dateobs = "DATE-OBS" # '2021-12-18T05:09:56.163' ############ FILE_PREFIX = "OARPAF" -FITS_EXT = "fits" # File extension +FITS_EXT = "fits" # File extension FOCUS_EXT = "foc" LOG_EXT = "log" diff --git a/noctua/sequencer.py b/noctua/sequencer.py index 6a68fbc..7728c98 100755 --- a/noctua/sequencer.py +++ b/noctua/sequencer.py @@ -195,30 +195,35 @@ class Sequencer(): sys.stderr.write("\n--- INTERRUPT ---\n") sys.stderr.write("(P)ause, (R)esume, (N)ext template, (Q)uit:\n") sys.stderr.flush() - + raw_line = sys.stdin.readline() try: # answer = input( # "(P)ause, (R)esume, (N)ext template, (Q)uit:\n") - if not raw_line: # THIS IS THE CHECK FOR EOF (Ctrl+D) + if not raw_line: # THIS IS THE CHECK FOR EOF (Ctrl+D) msg = "SEQUENCER: CTRL-D (EOF) detected with readline!" log.critical(msg) if not self.embedded: log.info("SEQUENCER: EOF in non-embedded mode. Forcing exit.") - if hasattr(self, 'tpl') and self.tpl and hasattr(self.tpl, 'abort'): + if hasattr( + self, + 'tpl') and self.tpl and hasattr( + self.tpl, + 'abort'): try: self.tpl.abort() - except Exception: pass # Best effort + except Exception: + pass # Best effort os._exit(1) else: log.info("SEQUENCER: EOF in embedded mode. Signaling quit.") self.quit() - return # Exit the interrupt handler - + return # Exit the interrupt handler + answer = raw_line.strip().lower() - + if answer.startswith('p'): self.pause() elif answer.startswith('r'): @@ -237,19 +242,21 @@ class Sequencer(): # os._exit(1) # Force exit if not embedded # else: # self.quit() # Attempt graceful quit if embedded - + except (KeyboardInterrupt, RuntimeError): # If Ctrl+C is hit again during input log.warning( "SEQUENCER: Interrupted during interrupt handling. Quitting.") self.quit() - except Exception as e: # Add a broad catch here for debugging - sys.stderr.write(f"ERROR IN INTERRUPT HANDLER: {type(e).__name__}: {e}\n") + except Exception as e: # Add a broad catch here for debugging + sys.stderr.write( + f"ERROR IN INTERRUPT HANDLER: { + type(e).__name__}: {e}\n") log.error("Error in interrupt handler", exc_info=True) # Fallback to quitting if the handler itself fails self.quit() finally: - signal.signal(signal.SIGINT, self.interrupt) # Re-hook - + signal.signal(signal.SIGINT, self.interrupt) # Re-hook + def pause(self): ''' Put the pause attribute in the running template to True. diff --git a/noctua/templates/testlamp.py b/noctua/templates/testlamp.py index 8087902..cbd5881 100644 --- a/noctua/templates/testlamp.py +++ b/noctua/templates/testlamp.py @@ -4,13 +4,11 @@ # System modules from time import sleep -# Third-party modules -from .basetemplate import BaseTemplate - # Other templates from ..config.constants import on_off from ..devices import light from ..utils.logger import log +from .basetemplate import BaseTemplate class Template(BaseTemplate): diff --git a/noctua/templates/testoutput.py b/noctua/templates/testoutput.py index 15f29ec..a86c266 100644 --- a/noctua/templates/testoutput.py +++ b/noctua/templates/testoutput.py @@ -7,9 +7,9 @@ from astropy.time import Time # Other templates from ..config.constants import on_off -from ..utils.structure import foc_path # from devices import lamp, light from ..utils.logger import log +from ..utils.structure import foc_path from .basetemplate import BaseTemplate diff --git a/noctua/utils/logger.py b/noctua/utils/logger.py index 832f9c9..1eb54dd 100644 --- a/noctua/utils/logger.py +++ b/noctua/utils/logger.py @@ -3,18 +3,21 @@ """Custom format log""" # System modules +import datetime +import os # Will be used if log_path only returns a directory import sys -import os # Will be used if log_path only returns a directory # Third-party modules from loguru import logger -import datetime + +# Other templates from .structure import log_path - + + def mylog(): "logger function" - logger.remove() # Remove default handler to prevent duplicate console logs + logger.remove() # Remove default handler to prevent duplicate console logs time_fmt = "{time:YYYY-MM-DD HH:mm:ss.SSSSSS!UTC} " level_fmt = "{level: <8} " @@ -30,14 +33,14 @@ def mylog(): ) full_log_file_path = log_path() - + logger.add( full_log_file_path, format=fmt, colorize=True, # For file logs - rotation="16:19", # Local time + rotation="16:19", # Local time # retention="7 days", # Old logs - level="DEBUG" + level="DEBUG" ) # Custom levels @@ -46,9 +49,11 @@ def mylog(): return logger + # This ensures mylog() is called only once. log = mylog() + def main(): """Main function""" diff --git a/noctua/utils/structure.py b/noctua/utils/structure.py index 3b895e6..1c47bb2 100644 --- a/noctua/utils/structure.py +++ b/noctua/utils/structure.py @@ -13,14 +13,15 @@ from pathlib import Path from astropy.io import fits from astropy.time import Time -# Custom modules -from ..config.constants import ( DATA_FOLDER, LOG_FOLDER, FITS_FOLDER, - FOCUS_FOLDER, FILE_PREFIX, dateobs, - dir_type, frame_number, imagetyp, - FITS_EXT, FOCUS_EXT, LOG_EXT ) +# Other templates +from ..config.constants import (DATA_FOLDER, FILE_PREFIX, FITS_EXT, + FITS_FOLDER, FOCUS_EXT, FOCUS_FOLDER, LOG_EXT, + LOG_FOLDER, dateobs, dir_type, frame_number, + imagetyp) PROJECT_ROOT = Path(__file__).parent.parent.parent + def date_folder(): """Create a date folder string based on astronomical convention (changes at midday UTC). @@ -28,7 +29,7 @@ def date_folder(): now = Time.now() # If current UTC hour is before midday UTC, the "observing night" # belongs to the previous calendar date. - if now.datetime.hour < 12: + if now.datetime.hour < 12: folder_date_obj = now.datetime.date() - timedelta(days=1) else: folder_date_obj = now.datetime.date() @@ -55,10 +56,10 @@ def fits_path(header, dry=False): """ Create a fits file path where the file will be stored """ - + root = PROJECT_ROOT / DATA_FOLDER / FITS_FOLDER - date_str = date_folder() + date_str = date_folder() date_path_part = Path(date_str) frame_path_part = Path(frame_folder(header)) @@ -74,9 +75,9 @@ def log_path(dry=False): Returns the Path object for the log directory. Creates it if it doesn't exist (unless dry=True). """ - + path = PROJECT_ROOT / DATA_FOLDER / LOG_FOLDER - + if not dry: path.mkdir(parents=True, exist_ok=True) @@ -84,7 +85,7 @@ def log_path(dry=False): outfile = f"{FILE_PREFIX}.{LOG_EXT}" outpath = path / outfile return outpath - + return outpath @@ -92,7 +93,7 @@ def foc_path(timestamp, dry=False): """ Create the focus output text file name and its path """ - + path = PROJECT_ROOT / DATA_FOLDER / FOCUS_FOLDER if not dry: @@ -108,19 +109,19 @@ def save_filename(infile_path_str): """ Save a fits file in its path with an ESO-style filename. """ - + inpath = Path(infile_path_str) header = fits.getheader(inpath) # '2021-12-28T20:09:56.163' - date_obs_str = header[dateobs] # DATE-OBS from FITS header + date_obs_str = header[dateobs] # DATE-OBS from FITS header name_for_file = Time(date_obs_str).isot - + outfile_name = f"{FILE_PREFIX}.{name_for_file}.{FITS_EXT}" outfile = Path(outfile_name) - outdir = fits_path(header) # This already creates the directory + outdir = fits_path(header) # This already creates the directory outpath = outdir / outfile shutil.copy2(inpath, outpath) - return str(outpath) + return str(outpath) -- GitLab