From 1e7ad1ea344fbdd6610162f1bb78b809d95976e2 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sat, 22 Oct 2022 23:26:13 -0500 Subject: [PATCH] added dirty start check --- src/__main__.py | 7 ++++++ src/app.py | 24 ++++++++------------- src/core/window.py | 1 + src/utils/ipc_server.py | 17 +++++++++------ src/utils/settings.py | 47 +++++++++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index 56e28ef..cd4ddb1 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -36,6 +36,13 @@ if __name__ == "__main__": # Read arguments (If any...) args, unknownargs = parser.parse_known_args() + if args.debug == "true": + settings.set_debug(True) + + if args.trace_debug == "true": + settings.set_trace_debug(True) + + settings.do_dirty_start_check() Application(args, unknownargs) Gtk.main() except Exception as e: diff --git a/src/app.py b/src/app.py index 2470aaf..c15a781 100644 --- a/src/app.py +++ b/src/app.py @@ -6,7 +6,6 @@ import time # Application imports from utils.ipc_server import IPCServer -from utils.settings import Settings from core.window import Window @@ -23,23 +22,18 @@ class Application(IPCServer): def __init__(self, args, unknownargs): super(Application, self).__init__() - if args.debug == "true": - settings.set_debug(True) - - if args.trace_debug == "true": - settings.set_trace_debug(True) - if not settings.is_trace_debug(): - self.create_ipc_listener() - time.sleep(0.05) + try: + self.create_ipc_listener() + except Exception: + ... if not self.is_ipc_alive: - if unknownargs: - for arg in unknownargs: - if os.path.isdir(arg): - message = f"FILE|{arg}" - self.send_ipc_message(message) + for arg in unknownargs + [args.new_tab,]: + if os.path.isdir(arg): + message = f"FILE|{arg}" + self.send_ipc_message(message) - raise AppLaunchException(f"IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/{app_name}-ipc.sock") + raise AppLaunchException(f"{app_name} IPC Server Exists: Will send path(s) to it and close...") Window(args, unknownargs) diff --git a/src/core/window.py b/src/core/window.py index 572841c..2394050 100644 --- a/src/core/window.py +++ b/src/core/window.py @@ -72,5 +72,6 @@ class Window(Gtk.ApplicationWindow): def _tear_down(self, widget=None, eve=None): + settings.clear_pid() time.sleep(event_sleep_time) Gtk.main_quit() diff --git a/src/utils/ipc_server.py b/src/utils/ipc_server.py index f71691b..92b94fe 100644 --- a/src/utils/ipc_server.py +++ b/src/utils/ipc_server.py @@ -10,7 +10,7 @@ from multiprocessing.connection import Listener, Client class IPCServer: - """ Create a listener so that other SolarFM instances send requests back to existing instance. """ + """ Create a listener so that other {app_name} instances send requests back to existing instance. """ def __init__(self, ipc_address: str = '127.0.0.1', conn_type: str = "socket"): self.is_ipc_alive = False self._ipc_port = 4848 @@ -35,11 +35,10 @@ class IPCServer: event_system.subscribe("post_file_to_ipc", self.send_ipc_message) - @daemon_threaded def create_ipc_listener(self) -> None: if self._conn_type == "socket": - if os.path.exists(self._ipc_address): - return + if os.path.exists(self._ipc_address) and settings.is_dirty_start(): + os.unlink(self._ipc_address) listener = Listener(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) elif "unsecured" not in self._conn_type: @@ -49,17 +48,21 @@ class IPCServer: self.is_ipc_alive = True + self._run_ipc_loop(listener) + + @daemon_threaded + def _run_ipc_loop(self, listener) -> None: while True: conn = listener.accept() start_time = time.perf_counter() - self.handle_message(conn, start_time) + self.handle_ipc_message(conn, start_time) listener.close() - def handle_message(self, conn, start_time) -> None: + def handle_ipc_message(self, conn, start_time) -> None: while True: msg = conn.recv() - if debug: + if settings.is_debug(): print(msg) if "FILE|" in msg: diff --git a/src/utils/settings.py b/src/utils/settings.py index ba65b42..81e017e 100644 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -21,6 +21,7 @@ class Settings: self._KEY_BINDINGS_FILE = f"{self._CONFIG_PATH}/key-bindings.json" self._CSS_FILE = f"{self._CONFIG_PATH}/stylesheet.css" self._DEFAULT_ICONS = f"{self._CONFIG_PATH}/icons" + self._PID_FILE = f"{self._CONFIG_PATH}/{app_name.lower()}.pid" self._WINDOW_ICON = f"{self._DEFAULT_ICONS}/{app_name.lower()}.png" self._USR_PATH = f"/usr/share/{app_name.lower()}" @@ -61,11 +62,43 @@ class Settings: self._trace_debug = False self._debug = False + self._dirty_start = False - def get_builder(self) -> any: return self._builder - def set_builder(self, builder) -> any: self._builder = builder - def get_glade_file(self) -> str: return self._GLADE_FILE + def do_dirty_start_check(self): + if not os.path.exists(self._PID_FILE): + self._write_new_pid() + else: + with open(self._PID_FILE, "r") as _pid: + pid = _pid.readline().strip() + if pid not in ("", None): + self._check_alive_status(int(pid)) + else: + self._write_new_pid() + + """ Check For the existence of a unix pid. """ + def _check_alive_status(self, pid): + print(f"PID Found: {pid}") + try: + os.kill(pid, 0) + except OSError: + print(f"{app_name} is starting dirty...") + self._dirty_start = True + self._write_new_pid() + return + + print("PID is alive... Let downstream errors (sans debug args) handle app closure propigation.") + + def _write_new_pid(self): + pid = os.getpid() + self._write_pid(pid) + + def _clean_pid(self): + os.unlink(self._PID_FILE) + + def _write_pid(self, pid): + with open(self._PID_FILE, "w") as _pid: + _pid.write(f"{pid}") def register_signals_to_builder(self, classes=None): handlers = {} @@ -80,6 +113,11 @@ class Settings: self._builder.connect_signals(handlers) + + def get_builder(self) -> any: return self._builder + def set_builder(self, builder) -> any: self._builder = builder + def get_glade_file(self) -> str: return self._GLADE_FILE + def get_logger(self) -> Logger: return self._logger def get_plugins_path(self) -> str: return self._PLUGINS_PATH def get_icon_theme(self) -> str: return self._ICON_THEME @@ -101,7 +139,8 @@ class Settings: def is_trace_debug(self) -> str: return self._trace_debug def is_debug(self) -> str: return self._debug - + def is_dirty_start(self) -> bool: return self._dirty_start + def clear_pid(self): self._clean_pid() def set_trace_debug(self, trace_debug): self._trace_debug = trace_debug