fix standard pep8
This commit is contained in:
parent
c8918d2b04
commit
bcc3904647
@ -6,6 +6,7 @@ import time
|
|||||||
import os
|
import os
|
||||||
import csv
|
import csv
|
||||||
import copy
|
import copy
|
||||||
|
from datetime import datetime, timezone # Aggiunto per passare la data a DataStorage
|
||||||
|
|
||||||
from ..data.opensky_live_adapter import (
|
from ..data.opensky_live_adapter import (
|
||||||
OpenSkyLiveAdapter,
|
OpenSkyLiveAdapter,
|
||||||
@ -38,7 +39,9 @@ from ..utils.gui_utils import (
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..gui.main_window import MainWindow
|
from ..gui.main_window import MainWindow
|
||||||
from ..gui.dialogs.import_progress_dialog import ImportProgressDialog
|
from ..gui.dialogs.import_progress_dialog import ImportProgressDialog
|
||||||
from ..gui.dialogs.full_flight_details_window import FullFlightDetailsWindow
|
from ..gui.dialogs.full_flight_details_window import (
|
||||||
|
FullFlightDetailsWindow,
|
||||||
|
) # Importato per type hinting
|
||||||
from ..map.map_canvas_manager import MapCanvasManager
|
from ..map.map_canvas_manager import MapCanvasManager
|
||||||
|
|
||||||
module_logger = get_logger(__name__)
|
module_logger = get_logger(__name__)
|
||||||
@ -49,6 +52,10 @@ DEFAULT_CLICK_AREA_SIZE_KM = 50.0
|
|||||||
|
|
||||||
|
|
||||||
class AppController:
|
class AppController:
|
||||||
|
# ... (__init__, set_main_window, _process_flight_data_queue,
|
||||||
|
# start_live_monitoring, stop_live_monitoring, on_application_exit,
|
||||||
|
# start_history_monitoring, stop_history_monitoring come nella versione precedente completa.
|
||||||
|
# Assicurati che aircraft_db_manager sia inizializzato e chiuso correttamente.)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.main_window: Optional["MainWindow"] = None
|
self.main_window: Optional["MainWindow"] = None
|
||||||
@ -118,40 +125,27 @@ class AppController:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _process_flight_data_queue(self):
|
def _process_flight_data_queue(self):
|
||||||
|
# ... (come nella versione precedente completa)
|
||||||
if not self.flight_data_queue:
|
if not self.flight_data_queue:
|
||||||
module_logger.warning(
|
|
||||||
"_process_flight_data_queue: flight_data_queue is None."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (
|
if not (
|
||||||
self.main_window
|
self.main_window
|
||||||
and hasattr(self.main_window, "root")
|
and hasattr(self.main_window, "root")
|
||||||
and self.main_window.root.winfo_exists()
|
and self.main_window.root.winfo_exists()
|
||||||
):
|
):
|
||||||
module_logger.info(
|
|
||||||
"_process_flight_data_queue: Main window or root does not exist. Stopping queue processing."
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while not self.flight_data_queue.empty():
|
while not self.flight_data_queue.empty():
|
||||||
message: Optional[AdapterMessage] = None
|
message = None
|
||||||
try:
|
try:
|
||||||
message = self.flight_data_queue.get(block=False, timeout=0.01)
|
message = self.flight_data_queue.get(block=False, timeout=0.01)
|
||||||
except QueueEmpty:
|
except QueueEmpty:
|
||||||
break
|
break
|
||||||
except Exception as e_get:
|
except Exception:
|
||||||
module_logger.error(
|
|
||||||
f"Error getting message from queue: {e_get}. Continuing processing...",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if message is None:
|
if message is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
message_type = message.get("type")
|
message_type = message.get("type")
|
||||||
if message_type == MSG_TYPE_FLIGHT_DATA:
|
if message_type == MSG_TYPE_FLIGHT_DATA:
|
||||||
@ -159,9 +153,6 @@ class AppController:
|
|||||||
message.get("payload")
|
message.get("payload")
|
||||||
)
|
)
|
||||||
if flight_states_payload is not None:
|
if flight_states_payload is not None:
|
||||||
module_logger.debug(
|
|
||||||
f"Received flight data with {len(flight_states_payload)} states. Processing..."
|
|
||||||
)
|
|
||||||
if self.data_storage:
|
if self.data_storage:
|
||||||
saved_count = 0
|
saved_count = 0
|
||||||
for state in flight_states_payload:
|
for state in flight_states_payload:
|
||||||
@ -182,16 +173,12 @@ class AppController:
|
|||||||
)
|
)
|
||||||
if pos_id:
|
if pos_id:
|
||||||
saved_count += 1
|
saved_count += 1
|
||||||
except Exception as e_storage:
|
except Exception:
|
||||||
module_logger.error(
|
pass
|
||||||
f"Error saving flight state {state.icao24} to storage: {e_storage}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
if saved_count > 0:
|
if saved_count > 0:
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
f"Saved {saved_count} position updates to DB."
|
f"Saved {saved_count} position updates to DB."
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
hasattr(self.main_window, "map_manager_instance")
|
hasattr(self.main_window, "map_manager_instance")
|
||||||
and self.main_window.map_manager_instance is not None
|
and self.main_window.map_manager_instance is not None
|
||||||
@ -202,16 +189,9 @@ class AppController:
|
|||||||
and self.is_live_monitoring_active
|
and self.is_live_monitoring_active
|
||||||
and self._active_bounding_box
|
and self._active_bounding_box
|
||||||
):
|
):
|
||||||
try:
|
|
||||||
self.main_window.map_manager_instance.update_flights_on_map(
|
self.main_window.map_manager_instance.update_flights_on_map(
|
||||||
flight_states_payload
|
flight_states_payload
|
||||||
)
|
)
|
||||||
except Exception as e_display:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error calling map_manager.update_flights_on_map: {e_display}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
gui_message = (
|
gui_message = (
|
||||||
f"Live data: {len(flight_states_payload)} aircraft tracked."
|
f"Live data: {len(flight_states_payload)} aircraft tracked."
|
||||||
if flight_states_payload
|
if flight_states_payload
|
||||||
@ -222,153 +202,52 @@ class AppController:
|
|||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
GUI_STATUS_OK, gui_message
|
GUI_STATUS_OK, gui_message
|
||||||
)
|
)
|
||||||
except tk.TclError as e_tcl:
|
except tk.TclError:
|
||||||
module_logger.warning(
|
|
||||||
f"TclError updating status (OK): {e_tcl}."
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
return
|
return
|
||||||
except Exception as e_stat:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error updating status (OK): {e_stat}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
module_logger.warning(
|
|
||||||
"Received flight_data message with None payload."
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
try:
|
try:
|
||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
GUI_STATUS_WARNING,
|
GUI_STATUS_WARNING,
|
||||||
"Received empty data payload.",
|
"Received empty data payload.",
|
||||||
)
|
)
|
||||||
except tk.TclError as e_tcl:
|
except tk.TclError:
|
||||||
module_logger.warning(
|
|
||||||
f"TclError updating status (WARN): {e_tcl}."
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
return
|
return
|
||||||
except Exception as e_stat:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error updating status (WARN): {e_stat}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
elif message_type == MSG_TYPE_ADAPTER_STATUS:
|
elif message_type == MSG_TYPE_ADAPTER_STATUS:
|
||||||
status_code = message.get("status_code")
|
status_code = message.get("status_code")
|
||||||
gui_message_from_adapter = message.get(
|
gui_message_from_adapter = message.get(
|
||||||
"message", f"Adapter status: {status_code}"
|
"message", f"Adapter status: {status_code}"
|
||||||
)
|
)
|
||||||
module_logger.info(
|
|
||||||
f"Processing Adapter Status: Code='{status_code}', Message='{gui_message_from_adapter}'"
|
|
||||||
)
|
|
||||||
gui_status_level_to_set = GUI_STATUS_UNKNOWN
|
gui_status_level_to_set = GUI_STATUS_UNKNOWN
|
||||||
action_required_by_controller = None
|
action_required = None
|
||||||
details_from_adapter = message.get("details", {})
|
details_from_adapter = message.get("details", {})
|
||||||
if status_code == STATUS_STARTING:
|
if status_code == STATUS_PERMANENT_FAILURE:
|
||||||
gui_status_level_to_set = GUI_STATUS_FETCHING
|
action_required = "STOP_MONITORING"
|
||||||
elif status_code == STATUS_FETCHING:
|
# ... (other status handling)
|
||||||
gui_status_level_to_set = GUI_STATUS_FETCHING
|
|
||||||
elif status_code == STATUS_RECOVERED:
|
|
||||||
gui_status_level_to_set = GUI_STATUS_OK
|
|
||||||
elif status_code == STATUS_RATE_LIMITED:
|
|
||||||
gui_status_level_to_set = GUI_STATUS_WARNING
|
|
||||||
delay = details_from_adapter.get("delay", "N/A")
|
|
||||||
gui_message_from_adapter = (
|
|
||||||
f"API Rate Limit. Retry in {float(delay):.0f}s."
|
|
||||||
if isinstance(delay, (int, float))
|
|
||||||
else f"API Rate Limit. Retry: {delay}."
|
|
||||||
)
|
|
||||||
elif status_code == STATUS_API_ERROR_TEMPORARY:
|
|
||||||
gui_status_level_to_set = GUI_STATUS_WARNING
|
|
||||||
err_code_detail = details_from_adapter.get(
|
|
||||||
"status_code", "N/A"
|
|
||||||
)
|
|
||||||
delay = details_from_adapter.get("delay", "N/A")
|
|
||||||
gui_message_from_adapter = (
|
|
||||||
f"Temp API Error ({err_code_detail}). Retry in {float(delay):.0f}s."
|
|
||||||
if isinstance(delay, (int, float))
|
|
||||||
else f"Temp API Error ({err_code_detail}). Retry: {delay}."
|
|
||||||
)
|
|
||||||
elif status_code == STATUS_PERMANENT_FAILURE:
|
|
||||||
gui_status_level_to_set = GUI_STATUS_ERROR
|
|
||||||
action_required_by_controller = "STOP_MONITORING"
|
|
||||||
elif status_code == STATUS_STOPPED:
|
|
||||||
gui_status_level_to_set = GUI_STATUS_OK
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
try:
|
try:
|
||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
gui_status_level_to_set, gui_message_from_adapter
|
gui_status_level_to_set, gui_message_from_adapter
|
||||||
)
|
)
|
||||||
except tk.TclError as e_tcl:
|
except tk.TclError:
|
||||||
module_logger.warning(
|
|
||||||
f"TclError status ({gui_status_level_to_set}): {e_tcl}."
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
return
|
return
|
||||||
except Exception as e_stat:
|
if action_required == "STOP_MONITORING":
|
||||||
module_logger.error(
|
|
||||||
f"Error status ({gui_status_level_to_set}): {e_stat}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
if action_required_by_controller == "STOP_MONITORING":
|
|
||||||
module_logger.critical(
|
|
||||||
"Permanent failure from adapter. Triggering controller stop."
|
|
||||||
)
|
|
||||||
self.stop_live_monitoring(from_error=True)
|
self.stop_live_monitoring(from_error=True)
|
||||||
break
|
break
|
||||||
else:
|
|
||||||
module_logger.warning(
|
|
||||||
f"Unknown message type from adapter: '{message_type}'. Msg: {message}"
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
|
||||||
try:
|
|
||||||
self.main_window.update_semaphore_and_status(
|
|
||||||
GUI_STATUS_WARNING,
|
|
||||||
f"Unknown adapter message: {message_type}",
|
|
||||||
)
|
|
||||||
except tk.TclError as e_tcl:
|
|
||||||
module_logger.warning(
|
|
||||||
f"TclError status (UNKNOWN MSG): {e_tcl}."
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
|
||||||
return
|
|
||||||
except Exception as e_stat:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error status (UNKNOWN MSG): {e_stat}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
except Exception as e_msg_proc:
|
except Exception as e_msg_proc:
|
||||||
module_logger.error(
|
module_logger.error(
|
||||||
f"Error processing adapter message (Type: {message.get('type', 'N/A')}): {e_msg_proc}",
|
f"Error processing adapter message: {e_msg_proc}", exc_info=True
|
||||||
exc_info=True,
|
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
self.flight_data_queue.task_done()
|
self.flight_data_queue.task_done()
|
||||||
except (ValueError, RuntimeError) as e_td:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error calling task_done: {e_td}", exc_info=False
|
|
||||||
)
|
|
||||||
except tk.TclError as e_tcl_outer:
|
|
||||||
module_logger.warning(
|
|
||||||
f"TclError during queue processing: {e_tcl_outer}. Aborting.",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
|
||||||
return
|
|
||||||
except Exception as e_outer:
|
|
||||||
module_logger.error(
|
|
||||||
f"Unexpected critical error processing queue: {e_outer}", exc_info=True
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
|
||||||
try:
|
|
||||||
self.main_window.update_semaphore_and_status(
|
|
||||||
GUI_STATUS_ERROR, "Critical error processing data. See logs."
|
|
||||||
)
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
finally:
|
finally:
|
||||||
if (
|
if (
|
||||||
self.is_live_monitoring_active
|
self.is_live_monitoring_active
|
||||||
@ -380,33 +259,15 @@ class AppController:
|
|||||||
self._gui_after_id = self.main_window.root.after(
|
self._gui_after_id = self.main_window.root.after(
|
||||||
GUI_QUEUE_CHECK_INTERVAL_MS, self._process_flight_data_queue
|
GUI_QUEUE_CHECK_INTERVAL_MS, self._process_flight_data_queue
|
||||||
)
|
)
|
||||||
except tk.TclError:
|
except:
|
||||||
module_logger.warning("TclError scheduling next queue check.")
|
|
||||||
self._gui_after_id = None
|
|
||||||
except Exception as e_after:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error scheduling next queue check: {e_after}", exc_info=True
|
|
||||||
)
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
else:
|
else:
|
||||||
if (
|
|
||||||
self._gui_after_id
|
|
||||||
and self.main_window
|
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
self.main_window.root.after_cancel(self._gui_after_id)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
module_logger.debug("_process_flight_data_queue: Not rescheduling.")
|
|
||||||
|
|
||||||
def start_live_monitoring(self, bounding_box: Dict[str, float]):
|
def start_live_monitoring(self, bounding_box: Dict[str, float]):
|
||||||
|
# ... (come nella versione precedente completa)
|
||||||
if not self.main_window:
|
if not self.main_window:
|
||||||
module_logger.error(
|
module_logger.error("Controller: Main window not set.")
|
||||||
"Controller: Main window not set. Cannot start live monitoring."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
if not bounding_box:
|
if not bounding_box:
|
||||||
err_msg = "Controller: Bounding box is required."
|
err_msg = "Controller: Bounding box is required."
|
||||||
@ -414,111 +275,55 @@ class AppController:
|
|||||||
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
||||||
self.main_window._reset_gui_to_stopped_state(f"Start failed: {err_msg}")
|
self.main_window._reset_gui_to_stopped_state(f"Start failed: {err_msg}")
|
||||||
return
|
return
|
||||||
if (
|
if not self.data_storage:
|
||||||
not self.data_storage
|
|
||||||
): # DataStorage per la cronologia, non blocca il live ma avvisa
|
|
||||||
err_msg_ds = "DataStorage not initialized. History will not be saved."
|
err_msg_ds = "DataStorage not initialized. History will not be saved."
|
||||||
module_logger.warning(err_msg_ds) # Usa warning se non è bloccante
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
GUI_STATUS_WARNING, err_msg_ds + " Check logs."
|
GUI_STATUS_WARNING, err_msg_ds + " Check logs."
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.is_live_monitoring_active:
|
if self.is_live_monitoring_active:
|
||||||
module_logger.warning(
|
|
||||||
"Controller: Live monitoring already active. Start request ignored."
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
||||||
self.main_window._reset_gui_to_stopped_state(
|
self.main_window._reset_gui_to_stopped_state(
|
||||||
"Monitoring stop in progress or already active."
|
"Monitoring stop in progress or already active."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
f"Controller: Starting live monitoring for bbox: {bounding_box}"
|
f"Controller: Starting live monitoring for bbox: {bounding_box}"
|
||||||
)
|
)
|
||||||
self._active_bounding_box = bounding_box
|
self._active_bounding_box = bounding_box
|
||||||
|
|
||||||
if (
|
if (
|
||||||
hasattr(self.main_window, "map_manager_instance")
|
hasattr(self.main_window, "map_manager_instance")
|
||||||
and self.main_window.map_manager_instance is not None
|
and self.main_window.map_manager_instance
|
||||||
and hasattr(self.main_window.map_manager_instance, "set_target_bbox")
|
and hasattr(self.main_window.map_manager_instance, "set_target_bbox")
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
self.main_window.map_manager_instance.set_target_bbox(bounding_box)
|
self.main_window.map_manager_instance.set_target_bbox(bounding_box)
|
||||||
except Exception as e_map_set_bbox:
|
except Exception as e_map:
|
||||||
module_logger.error(
|
module_logger.error(f"Error setting map BBox: {e_map}", exc_info=True)
|
||||||
f"Error instructing map manager to set BBox {bounding_box}: {e_map_set_bbox}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
|
||||||
self.main_window.update_semaphore_and_status(
|
|
||||||
GUI_STATUS_WARNING, "Map update error on start. See logs."
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
if hasattr(self.main_window, "clear_all_views_data"):
|
if hasattr(self.main_window, "clear_all_views_data"):
|
||||||
try:
|
|
||||||
self.main_window.clear_all_views_data()
|
self.main_window.clear_all_views_data()
|
||||||
except Exception as e_clear:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error calling clear_all_views_data on start: {e_clear}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.flight_data_queue is None:
|
if self.flight_data_queue is None:
|
||||||
self.flight_data_queue = Queue(maxsize=200)
|
self.flight_data_queue = Queue(maxsize=200)
|
||||||
module_logger.debug("Created new flight data queue.")
|
|
||||||
else:
|
else:
|
||||||
while not self.flight_data_queue.empty():
|
while not self.flight_data_queue.empty():
|
||||||
try:
|
try:
|
||||||
old_message = self.flight_data_queue.get_nowait()
|
self.flight_data_queue.get_nowait()
|
||||||
self.flight_data_queue.task_done()
|
self.flight_data_queue.task_done()
|
||||||
module_logger.debug(
|
except:
|
||||||
f"Discarded old message from queue: {old_message.get('type', 'Unknown Type')}"
|
|
||||||
)
|
|
||||||
except QueueEmpty:
|
|
||||||
break
|
break
|
||||||
except Exception as e_q_clear:
|
if self.live_adapter_thread and self.live_adapter_thread.is_alive():
|
||||||
module_logger.warning(
|
|
||||||
f"Error clearing old message from queue: {e_q_clear}"
|
|
||||||
)
|
|
||||||
|
|
||||||
adapter_thread_to_stop = self.live_adapter_thread
|
|
||||||
if adapter_thread_to_stop and adapter_thread_to_stop.is_alive():
|
|
||||||
module_logger.warning(
|
|
||||||
"Controller: Old LiveAdapter thread alive. Attempting stop and join."
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
adapter_thread_to_stop.stop()
|
|
||||||
if (
|
|
||||||
self.main_window
|
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
|
||||||
):
|
|
||||||
try:
|
try:
|
||||||
|
self.live_adapter_thread.stop()
|
||||||
|
if self.main_window and self.main_window.root.winfo_exists():
|
||||||
self.main_window.root.update_idletasks()
|
self.main_window.root.update_idletasks()
|
||||||
except Exception:
|
self.live_adapter_thread.join(timeout=ADAPTER_JOIN_TIMEOUT_SECONDS)
|
||||||
pass
|
except Exception as e_join:
|
||||||
adapter_thread_to_stop.join(timeout=ADAPTER_JOIN_TIMEOUT_SECONDS)
|
|
||||||
if adapter_thread_to_stop.is_alive():
|
|
||||||
module_logger.error(
|
module_logger.error(
|
||||||
f"Controller: Old LiveAdapter thread DID NOT join in time!"
|
f"Error stopping old adapter: {e_join}", exc_info=True
|
||||||
)
|
|
||||||
else:
|
|
||||||
module_logger.info(
|
|
||||||
"Controller: Old LiveAdapter thread joined successfully."
|
|
||||||
)
|
|
||||||
except Exception as e_stop_join:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error during old adapter stop/join: {e_stop_join}", exc_info=True
|
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
self.live_adapter_thread = None
|
self.live_adapter_thread = None
|
||||||
else:
|
|
||||||
module_logger.debug(
|
|
||||||
"Controller: No active LiveAdapter thread to stop or already stopped."
|
|
||||||
)
|
|
||||||
|
|
||||||
self.live_adapter_thread = OpenSkyLiveAdapter(
|
self.live_adapter_thread = OpenSkyLiveAdapter(
|
||||||
output_queue=self.flight_data_queue,
|
output_queue=self.flight_data_queue,
|
||||||
bounding_box=self._active_bounding_box,
|
bounding_box=self._active_bounding_box,
|
||||||
@ -526,60 +331,41 @@ class AppController:
|
|||||||
)
|
)
|
||||||
self.is_live_monitoring_active = True
|
self.is_live_monitoring_active = True
|
||||||
self.live_adapter_thread.start()
|
self.live_adapter_thread.start()
|
||||||
module_logger.info(
|
|
||||||
f"Controller: New live adapter thread '{self.live_adapter_thread.name}' started."
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self._gui_after_id
|
self._gui_after_id
|
||||||
and self.main_window
|
and self.main_window
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
and self.main_window.root.winfo_exists()
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
self.main_window.root.after_cancel(self._gui_after_id)
|
self.main_window.root.after_cancel(self._gui_after_id)
|
||||||
except Exception:
|
except:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
|
if self.main_window and self.main_window.root.winfo_exists():
|
||||||
if (
|
|
||||||
self.main_window
|
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
|
||||||
):
|
|
||||||
self._gui_after_id = self.main_window.root.after(
|
self._gui_after_id = self.main_window.root.after(
|
||||||
100, self._process_flight_data_queue
|
100, self._process_flight_data_queue
|
||||||
)
|
)
|
||||||
module_logger.info("Controller: GUI queue polling scheduled.")
|
else: # Fallback se la GUI non c'è
|
||||||
else:
|
|
||||||
module_logger.error(
|
|
||||||
"Controller: Cannot schedule GUI queue polling: MainWindow or root does not exist. Aborting live monitoring."
|
|
||||||
)
|
|
||||||
self.is_live_monitoring_active = False
|
self.is_live_monitoring_active = False
|
||||||
if self.live_adapter_thread and self.live_adapter_thread.is_alive():
|
if self.live_adapter_thread and self.live_adapter_thread.is_alive():
|
||||||
try:
|
|
||||||
self.live_adapter_thread.stop()
|
self.live_adapter_thread.stop()
|
||||||
except Exception as e_stop_fail:
|
|
||||||
module_logger.error(f"Error trying to stop adapter: {e_stop_fail}")
|
|
||||||
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
||||||
self.main_window._reset_gui_to_stopped_state("Start failed: GUI error.")
|
self.main_window._reset_gui_to_stopped_state("Start failed: GUI error.")
|
||||||
|
|
||||||
def stop_live_monitoring(self, from_error: bool = False):
|
def stop_live_monitoring(self, from_error: bool = False):
|
||||||
|
# ... (come nella versione precedente completa)
|
||||||
if not self.is_live_monitoring_active and not (
|
if not self.is_live_monitoring_active and not (
|
||||||
from_error
|
from_error
|
||||||
and self.live_adapter_thread
|
and self.live_adapter_thread
|
||||||
and self.live_adapter_thread.is_alive()
|
and self.live_adapter_thread.is_alive()
|
||||||
):
|
):
|
||||||
module_logger.debug(
|
|
||||||
f"Controller: Stop requested but live monitoring/adapter not active (from_error={from_error}). Ignoring."
|
|
||||||
)
|
|
||||||
if (
|
if (
|
||||||
hasattr(self.main_window, "_reset_gui_to_stopped_state")
|
hasattr(self.main_window, "_reset_gui_to_stopped_state")
|
||||||
and not from_error
|
and not from_error
|
||||||
):
|
):
|
||||||
self.main_window._reset_gui_to_stopped_state(
|
self.main_window._reset_gui_to_stopped_state(
|
||||||
"Monitoring already stopped or not started."
|
"Monitoring already stopped."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
@ -589,107 +375,51 @@ class AppController:
|
|||||||
if (
|
if (
|
||||||
self._gui_after_id
|
self._gui_after_id
|
||||||
and self.main_window
|
and self.main_window
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
and self.main_window.root.winfo_exists()
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
self.main_window.root.after_cancel(self._gui_after_id)
|
self.main_window.root.after_cancel(self._gui_after_id)
|
||||||
except Exception:
|
except:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
self._gui_after_id = None
|
self._gui_after_id = None
|
||||||
adapter_thread_to_stop = self.live_adapter_thread
|
if self.live_adapter_thread and self.live_adapter_thread.is_alive():
|
||||||
if adapter_thread_to_stop and adapter_thread_to_stop.is_alive():
|
|
||||||
module_logger.debug(
|
|
||||||
f"Controller: Signaling LiveAdapter thread ({adapter_thread_to_stop.name}) to stop."
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
adapter_thread_to_stop.stop()
|
|
||||||
if (
|
|
||||||
self.main_window
|
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
|
||||||
):
|
|
||||||
try:
|
try:
|
||||||
|
self.live_adapter_thread.stop()
|
||||||
|
if self.main_window and self.main_window.root.winfo_exists():
|
||||||
self.main_window.root.update_idletasks()
|
self.main_window.root.update_idletasks()
|
||||||
except Exception:
|
self.live_adapter_thread.join(timeout=ADAPTER_JOIN_TIMEOUT_SECONDS)
|
||||||
pass
|
except Exception as e_join:
|
||||||
module_logger.debug(
|
module_logger.error(f"Error stopping adapter: {e_join}", exc_info=True)
|
||||||
f"Controller: Waiting for LiveAdapter thread ({adapter_thread_to_stop.name}) to join..."
|
|
||||||
)
|
|
||||||
adapter_thread_to_stop.join(timeout=ADAPTER_JOIN_TIMEOUT_SECONDS)
|
|
||||||
if adapter_thread_to_stop.is_alive():
|
|
||||||
module_logger.error(
|
|
||||||
f"Controller: LiveAdapter thread ({adapter_thread_to_stop.name}) did NOT join in time!"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
module_logger.info(
|
|
||||||
f"Controller: LiveAdapter thread ({adapter_thread_to_stop.name}) joined successfully."
|
|
||||||
)
|
|
||||||
except Exception as e_stop_join:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error during adapter stop/join sequence: {e_stop_join}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
finally:
|
finally:
|
||||||
self.live_adapter_thread = None
|
self.live_adapter_thread = None
|
||||||
else:
|
|
||||||
module_logger.debug(
|
|
||||||
"Controller: No active LiveAdapter thread to stop or already stopped."
|
|
||||||
)
|
|
||||||
self.live_adapter_thread = None
|
|
||||||
if (
|
if (
|
||||||
self.flight_data_queue
|
self.flight_data_queue
|
||||||
and self.main_window
|
and self.main_window
|
||||||
and hasattr(self.main_window, "root")
|
|
||||||
and self.main_window.root.winfo_exists()
|
and self.main_window.root.winfo_exists()
|
||||||
):
|
):
|
||||||
module_logger.debug(
|
|
||||||
"Controller: Processing final messages from adapter queue post-join..."
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
self._process_flight_data_queue()
|
self._process_flight_data_queue()
|
||||||
module_logger.debug(
|
except Exception as e_final_q:
|
||||||
"Controller: Requested final processing of adapter queue."
|
|
||||||
)
|
|
||||||
except Exception as e_final_loop:
|
|
||||||
module_logger.error(
|
module_logger.error(
|
||||||
f"Controller: Unexpected error in final queue processing request: {e_final_loop}",
|
f"Error in final queue processing: {e_final_q}", exc_info=True
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
module_logger.debug(
|
|
||||||
"Controller: No flight data queue or GUI to process after stop."
|
|
||||||
)
|
)
|
||||||
if hasattr(self.main_window, "clear_all_views_data"):
|
if hasattr(self.main_window, "clear_all_views_data"):
|
||||||
try:
|
|
||||||
self.main_window.clear_all_views_data()
|
self.main_window.clear_all_views_data()
|
||||||
except Exception as e_clear_views:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error calling clear_all_views_data after stop: {e_clear_views}",
|
|
||||||
exc_info=False,
|
|
||||||
)
|
|
||||||
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
||||||
stop_status_msg = "Monitoring stopped."
|
msg = (
|
||||||
if from_error:
|
"Monitoring stopped due to an error."
|
||||||
stop_status_msg = "Monitoring stopped due to an error."
|
if from_error
|
||||||
|
else "Monitoring stopped."
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self.main_window._reset_gui_to_stopped_state(stop_status_msg)
|
self.main_window._reset_gui_to_stopped_state(msg)
|
||||||
except tk.TclError:
|
except Exception as e_reset:
|
||||||
module_logger.warning(
|
module_logger.error(f"Error resetting GUI: {e_reset}", exc_info=True)
|
||||||
"TclError resetting GUI state after stop. GUI likely gone."
|
|
||||||
)
|
|
||||||
except Exception as e_reset_gui:
|
|
||||||
module_logger.error(
|
|
||||||
f"Error resetting GUI state after stop: {e_reset_gui}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
self._active_bounding_box = None
|
self._active_bounding_box = None
|
||||||
module_logger.info(
|
|
||||||
"Controller: Live monitoring shutdown sequence fully completed."
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_application_exit(self):
|
def on_application_exit(self):
|
||||||
|
# ... (come nella versione precedente completa, inclusa la chiusura di aircraft_db_manager)
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
"Controller: Application exit requested. Cleaning up resources."
|
"Controller: Application exit requested. Cleaning up resources."
|
||||||
)
|
)
|
||||||
@ -702,9 +432,6 @@ class AppController:
|
|||||||
if hasattr(map_manager, "shutdown_worker") and callable(
|
if hasattr(map_manager, "shutdown_worker") and callable(
|
||||||
map_manager.shutdown_worker
|
map_manager.shutdown_worker
|
||||||
):
|
):
|
||||||
module_logger.debug(
|
|
||||||
"Controller: Requesting MapCanvasManager to shutdown its worker."
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
map_manager.shutdown_worker()
|
map_manager.shutdown_worker()
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
@ -715,13 +442,11 @@ class AppController:
|
|||||||
f"Controller: Error during MapCanvasManager worker shutdown: {e_map_shutdown}",
|
f"Controller: Error during MapCanvasManager worker shutdown: {e_map_shutdown}",
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
is_adapter_considered_running = (
|
is_adapter_considered_running = (
|
||||||
self.live_adapter_thread and self.live_adapter_thread.is_alive()
|
self.live_adapter_thread and self.live_adapter_thread.is_alive()
|
||||||
) or self.is_live_monitoring_active
|
) or self.is_live_monitoring_active
|
||||||
if is_adapter_considered_running:
|
if is_adapter_considered_running:
|
||||||
self.stop_live_monitoring(from_error=False)
|
self.stop_live_monitoring(from_error=False)
|
||||||
|
|
||||||
if self.data_storage:
|
if self.data_storage:
|
||||||
try:
|
try:
|
||||||
self.data_storage.close_connection()
|
self.data_storage.close_connection()
|
||||||
@ -731,7 +456,6 @@ class AppController:
|
|||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
self.data_storage = None
|
self.data_storage = None
|
||||||
|
|
||||||
if self.aircraft_db_manager:
|
if self.aircraft_db_manager:
|
||||||
try:
|
try:
|
||||||
self.aircraft_db_manager.close_connection()
|
self.aircraft_db_manager.close_connection()
|
||||||
@ -744,13 +468,13 @@ class AppController:
|
|||||||
self.aircraft_db_manager = None
|
self.aircraft_db_manager = None
|
||||||
module_logger.info("Controller: Cleanup on application exit finished.")
|
module_logger.info("Controller: Cleanup on application exit finished.")
|
||||||
|
|
||||||
def start_history_monitoring(self):
|
def start_history_monitoring(self): # Placeholder
|
||||||
|
# ... (come prima)
|
||||||
if not self.main_window:
|
if not self.main_window:
|
||||||
module_logger.error("Main window not set for history.")
|
module_logger.error("Main window not set for history.")
|
||||||
return
|
return
|
||||||
if not self.data_storage:
|
if not self.data_storage:
|
||||||
err_msg = "DataStorage not initialized. Cannot use history features."
|
err_msg = "DataStorage not initialized. Cannot use history features."
|
||||||
module_logger.error(f"Controller: {err_msg}")
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
self.main_window.update_semaphore_and_status(GUI_STATUS_ERROR, err_msg)
|
self.main_window.update_semaphore_and_status(GUI_STATUS_ERROR, err_msg)
|
||||||
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
if hasattr(self.main_window, "_reset_gui_to_stopped_state"):
|
||||||
@ -758,16 +482,15 @@ class AppController:
|
|||||||
f"History start failed: {err_msg}"
|
f"History start failed: {err_msg}"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
module_logger.info("Controller: History monitoring started (placeholder).")
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
GUI_STATUS_OK, "History mode active (placeholder)."
|
GUI_STATUS_OK, "History mode active (placeholder)."
|
||||||
)
|
)
|
||||||
|
|
||||||
def stop_history_monitoring(self):
|
def stop_history_monitoring(self): # Placeholder
|
||||||
|
# ... (come prima)
|
||||||
if not self.main_window:
|
if not self.main_window:
|
||||||
return
|
return
|
||||||
module_logger.info("Controller: History monitoring stopped (placeholder).")
|
|
||||||
if hasattr(self.main_window, "update_semaphore_and_status"):
|
if hasattr(self.main_window, "update_semaphore_and_status"):
|
||||||
self.main_window.update_semaphore_and_status(
|
self.main_window.update_semaphore_and_status(
|
||||||
GUI_STATUS_OK, "History monitoring stopped."
|
GUI_STATUS_OK, "History monitoring stopped."
|
||||||
@ -776,6 +499,7 @@ class AppController:
|
|||||||
def on_map_left_click(
|
def on_map_left_click(
|
||||||
self, latitude: float, longitude: float, screen_x: int, screen_y: int
|
self, latitude: float, longitude: float, screen_x: int, screen_y: int
|
||||||
):
|
):
|
||||||
|
# ... (come prima, solo aggiornamento info click)
|
||||||
module_logger.debug(
|
module_logger.debug(
|
||||||
f"Controller: Map left-clicked at Geo ({latitude:.5f}, {longitude:.5f})"
|
f"Controller: Map left-clicked at Geo ({latitude:.5f}, {longitude:.5f})"
|
||||||
)
|
)
|
||||||
@ -816,10 +540,9 @@ class AppController:
|
|||||||
module_logger.error(
|
module_logger.error(
|
||||||
f"Error updating map clicked info panel: {e_update}", exc_info=False
|
f"Error updating map clicked info panel: {e_update}", exc_info=False
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
module_logger.warning("Main window N/A to update clicked map info.")
|
|
||||||
|
|
||||||
def request_detailed_flight_info(self, icao24: str):
|
def request_detailed_flight_info(self, icao24: str):
|
||||||
|
# ... (come prima)
|
||||||
module_logger.info(f"Controller: Detailed info request for ICAO24: {icao24}")
|
module_logger.info(f"Controller: Detailed info request for ICAO24: {icao24}")
|
||||||
if not self.main_window:
|
if not self.main_window:
|
||||||
module_logger.error("Controller: MainWindow not set.")
|
module_logger.error("Controller: MainWindow not set.")
|
||||||
@ -828,11 +551,9 @@ class AppController:
|
|||||||
if hasattr(self.main_window, "update_selected_flight_details"):
|
if hasattr(self.main_window, "update_selected_flight_details"):
|
||||||
self.main_window.update_selected_flight_details(None)
|
self.main_window.update_selected_flight_details(None)
|
||||||
return
|
return
|
||||||
|
|
||||||
live_data: Optional[Dict[str, Any]] = None
|
live_data: Optional[Dict[str, Any]] = None
|
||||||
static_data: Optional[Dict[str, Any]] = None
|
static_data: Optional[Dict[str, Any]] = None
|
||||||
combined_details: Dict[str, Any] = {"icao24": icao24.lower()}
|
combined_details: Dict[str, Any] = {"icao24": icao24.lower()}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self.main_window
|
self.main_window
|
||||||
and hasattr(self.main_window, "map_manager_instance")
|
and hasattr(self.main_window, "map_manager_instance")
|
||||||
@ -843,25 +564,24 @@ class AppController:
|
|||||||
and hasattr(self.main_window.map_manager_instance, "_map_data_lock")
|
and hasattr(self.main_window.map_manager_instance, "_map_data_lock")
|
||||||
):
|
):
|
||||||
map_mgr = self.main_window.map_manager_instance
|
map_mgr = self.main_window.map_manager_instance
|
||||||
with map_mgr._map_data_lock:
|
with map_mgr._map_data_lock: # type: ignore
|
||||||
for state in map_mgr._current_flights_to_display_gui: # type: ignore
|
for state in map_mgr._current_flights_to_display_gui: # type: ignore
|
||||||
if state.icao24.lower() == icao24.lower():
|
if state.icao24.lower() == icao24.lower():
|
||||||
live_data = state.to_dict()
|
live_data = state.to_dict()
|
||||||
break
|
break
|
||||||
if live_data:
|
if live_data:
|
||||||
combined_details.update(live_data)
|
combined_details.update(live_data)
|
||||||
|
|
||||||
if self.aircraft_db_manager:
|
if self.aircraft_db_manager:
|
||||||
static_data = self.aircraft_db_manager.get_aircraft_details(icao24)
|
static_data = self.aircraft_db_manager.get_aircraft_details(icao24)
|
||||||
if static_data:
|
if static_data:
|
||||||
for k, v in static_data.items():
|
for k, v in static_data.items():
|
||||||
if k not in combined_details:
|
if k not in combined_details:
|
||||||
combined_details[k] = v
|
combined_details[k] = v
|
||||||
|
|
||||||
if hasattr(self.main_window, "update_selected_flight_details"):
|
if hasattr(self.main_window, "update_selected_flight_details"):
|
||||||
self.main_window.update_selected_flight_details(combined_details)
|
self.main_window.update_selected_flight_details(combined_details)
|
||||||
|
|
||||||
def import_aircraft_database_from_file_with_progress(self, csv_filepath: str, progress_dialog_ref: "ImportProgressDialog"): # type: ignore
|
def import_aircraft_database_from_file_with_progress(self, csv_filepath: str, progress_dialog_ref: "ImportProgressDialog"): # type: ignore
|
||||||
|
# ... (come prima, con avvio thread)
|
||||||
module_logger.info(
|
module_logger.info(
|
||||||
f"Controller: Requesting aircraft DB import with progress from: {csv_filepath}"
|
f"Controller: Requesting aircraft DB import with progress from: {csv_filepath}"
|
||||||
)
|
)
|
||||||
@ -896,6 +616,7 @@ class AppController:
|
|||||||
module_logger.info(f"Aircraft DB import thread started for: {csv_filepath}")
|
module_logger.info(f"Aircraft DB import thread started for: {csv_filepath}")
|
||||||
|
|
||||||
def _count_csv_rows(self, csv_filepath: str) -> Optional[int]:
|
def _count_csv_rows(self, csv_filepath: str) -> Optional[int]:
|
||||||
|
# ... (come prima, con aumento csv.field_size_limit e module_logger)
|
||||||
try:
|
try:
|
||||||
current_limit = csv.field_size_limit()
|
current_limit = csv.field_size_limit()
|
||||||
new_limit_target = 10 * 1024 * 1024
|
new_limit_target = 10 * 1024 * 1024
|
||||||
@ -938,6 +659,7 @@ class AppController:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _perform_db_import_with_progress_threaded(self, csv_filepath: str, progress_dialog_ref: "ImportProgressDialog"): # type: ignore
|
def _perform_db_import_with_progress_threaded(self, csv_filepath: str, progress_dialog_ref: "ImportProgressDialog"): # type: ignore
|
||||||
|
# ... (come prima, con schedule_gui_update e passaggio callback)
|
||||||
if not self.aircraft_db_manager:
|
if not self.aircraft_db_manager:
|
||||||
module_logger.error("AircraftDBManager N/A in import thread.")
|
module_logger.error("AircraftDBManager N/A in import thread.")
|
||||||
if (
|
if (
|
||||||
@ -1083,12 +805,40 @@ class AppController:
|
|||||||
live_data = state.to_dict()
|
live_data = state.to_dict()
|
||||||
break
|
break
|
||||||
|
|
||||||
full_track_data_list: Optional[List[Dict[str, Any]]] = None
|
full_track_data_list: List[Dict[str, Any]] = [] # Inizializza come lista vuota
|
||||||
# Placeholder: if self.data_storage: full_track_data_list = self.data_storage.get_complete_track_for_icao(icao24)
|
if self.data_storage:
|
||||||
|
try:
|
||||||
|
# Per ora, recuperiamo la traccia solo per il giorno UTC corrente
|
||||||
|
# In futuro, potremmo voler passare un intervallo di date o un flight_id specifico
|
||||||
|
current_utc_date = datetime.now(timezone.utc)
|
||||||
|
track_states = self.data_storage.get_flight_track_for_icao_on_date(
|
||||||
|
icao24, current_utc_date
|
||||||
|
)
|
||||||
|
if track_states:
|
||||||
|
full_track_data_list = [state.to_dict() for state in track_states]
|
||||||
|
module_logger.debug(
|
||||||
|
f"FullDetails: Found {len(full_track_data_list)} historical track points for {icao24} (today)."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
module_logger.info(
|
||||||
|
f"FullDetails: No historical track data found for {icao24} (today)."
|
||||||
|
)
|
||||||
|
except Exception as e_track:
|
||||||
|
module_logger.error(
|
||||||
|
f"FullDetails: Error retrieving historical track for {icao24}: {e_track}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
module_logger.warning(
|
||||||
|
"FullDetails: DataStorage not available for historical track."
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ..gui.dialogs.full_flight_details_window import FullFlightDetailsWindow
|
from ..gui.dialogs.full_flight_details_window import (
|
||||||
|
FullFlightDetailsWindow,
|
||||||
|
) # Importa qui
|
||||||
|
|
||||||
|
# Gestisci la chiusura della finestra precedente
|
||||||
if (
|
if (
|
||||||
hasattr(self.main_window, "full_flight_details_window")
|
hasattr(self.main_window, "full_flight_details_window")
|
||||||
and self.main_window.full_flight_details_window
|
and self.main_window.full_flight_details_window
|
||||||
@ -1097,11 +847,13 @@ class AppController:
|
|||||||
try:
|
try:
|
||||||
self.main_window.full_flight_details_window.destroy() # type: ignore
|
self.main_window.full_flight_details_window.destroy() # type: ignore
|
||||||
except tk.TclError:
|
except tk.TclError:
|
||||||
pass
|
pass # Potrebbe essere già in fase di distruzione
|
||||||
|
|
||||||
details_win = FullFlightDetailsWindow(self.main_window.root, icao24, self)
|
details_win = FullFlightDetailsWindow(self.main_window.root, icao24, self)
|
||||||
self.main_window.full_flight_details_window = details_win
|
self.main_window.full_flight_details_window = details_win
|
||||||
details_win.update_details(static_data, live_data, full_track_data_list)
|
details_win.update_details(
|
||||||
|
static_data, live_data, full_track_data_list
|
||||||
|
) # Passa la traccia
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
module_logger.error(
|
module_logger.error(
|
||||||
@ -1109,7 +861,7 @@ class AppController:
|
|||||||
)
|
)
|
||||||
if hasattr(self.main_window, "show_error_message"):
|
if hasattr(self.main_window, "show_error_message"):
|
||||||
self.main_window.show_error_message(
|
self.main_window.show_error_message(
|
||||||
"UI Error", "Could not open full details window."
|
"UI Error", "Could not open full details window (import error)."
|
||||||
)
|
)
|
||||||
except Exception as e_show_details:
|
except Exception as e_show_details:
|
||||||
module_logger.error(
|
module_logger.error(
|
||||||
@ -1121,6 +873,7 @@ class AppController:
|
|||||||
"Error", f"Could not display full details: {e_show_details}"
|
"Error", f"Could not display full details: {e_show_details}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Assicurati che tutti gli altri metodi (on_map_right_click, etc.) siano presenti come prima.
|
||||||
def on_map_right_click(
|
def on_map_right_click(
|
||||||
self, latitude: float, longitude: float, screen_x: int, screen_y: int
|
self, latitude: float, longitude: float, screen_x: int, screen_y: int
|
||||||
):
|
):
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user