diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..fb57207b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "python.analysis.diagnosticSeverityOverrides": { + "reportUndefinedVariable": "none" + }, + "files.associations": { + "*logconf*.json": "jsonc" + } +} + diff --git a/python/PiFinder/comets.py b/python/PiFinder/comets.py index 9430094f..e8734fc3 100644 --- a/python/PiFinder/comets.py +++ b/python/PiFinder/comets.py @@ -4,6 +4,7 @@ from skyfield.constants import GM_SUN_Pitjeva_2005_km3_s2 as GM_SUN from PiFinder.utils import Timer, comet_file from PiFinder.calc_utils import sf_utils +import pandas as pd import requests import os import logging @@ -198,6 +199,14 @@ def calc_comets( .set_index("designation", drop=False) ) + # groupby/last can coerce numeric columns to strings when NaN values + # are present; ensure perihelion date fields are numeric before use + for col in ("perihelion_year", "perihelion_month", "perihelion_day"): + comets_df[col] = pd.to_numeric(comets_df[col], errors="coerce") + comets_df = comets_df.dropna( + subset=["perihelion_year", "perihelion_month", "perihelion_day"] + ) + # Report progress after pandas processing (roughly 66% of setup time) if progress_callback: progress_callback(2) diff --git a/python/PiFinder/main.py b/python/PiFinder/main.py index d447bf66..83577e52 100644 --- a/python/PiFinder/main.py +++ b/python/PiFinder/main.py @@ -51,6 +51,8 @@ from PiFinder.displays import DisplayBase, get_display +import PiFinder.manager_patch as patch + from typing import Any, TYPE_CHECKING # Mypy i8n fix @@ -124,6 +126,9 @@ def setup_dirs(): os.chmod(Path(utils.data_dir), 0o777) +patch.apply() + + class StateManager(BaseManager): pass @@ -348,10 +353,6 @@ def main( ) langXX.install() - import PiFinder.manager_patch as patch - - patch.apply() - with StateManager() as manager: shared_state = manager.SharedState() # type: ignore[attr-defined] location = shared_state.location() diff --git a/python/PiFinder/multiproclogging.py b/python/PiFinder/multiproclogging.py index 92d36dcc..83b7f437 100644 --- a/python/PiFinder/multiproclogging.py +++ b/python/PiFinder/multiproclogging.py @@ -87,6 +87,10 @@ def start(self, initial_queue: Optional[Queue] = None): len(self._queues) >= 1 ), "No queues in use. You should have requested at least one queue." + # Create the main-process queue BEFORE starting the sink so the sink + # receives it in its queue list and monitors it. + queue = initial_queue if initial_queue is not None else self.get_queue() + self._proc = Process( target=self._run_sink, args=( @@ -97,7 +101,6 @@ def start(self, initial_queue: Optional[Queue] = None): # Start separate process that consumes from the queues. self._proc.start() # Now in this process we can divert logging to the newly created class - queue = self.get_queue() MultiprocLogging.configurer(queue) def join(self): diff --git a/python/PiFinder/server.py b/python/PiFinder/server.py index ff9db6d1..8fd622bb 100644 --- a/python/PiFinder/server.py +++ b/python/PiFinder/server.py @@ -781,7 +781,7 @@ def logs_page(): def stream_logs(): try: position = int(request.query.get("position", 0)) - log_file = "/home/pifinder/PiFinder_data/pifinder.log" + log_file = str(utils.data_dir / "pifinder.log") try: file_size = os.path.getsize(log_file) diff --git a/python/pyproject.toml b/python/pyproject.toml index 05a2b26e..b61f2782 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -42,6 +42,9 @@ indent-width = 4 # Assume Python 3.9 target-version = "py39" +# _ is the i18n/gettext builtin injected at runtime +builtins = ["_"] + [tool.ruff.lint] # Enable preview mode, allow os.env changes before imports preview = true