From e794aa82dc12fa57f729d74b333d1ea535a100a9 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Sat, 24 Jan 2026 08:51:22 +0900 Subject: [PATCH] chore: dynamic statusbar WIP --- dzgui/controllers/mc.py | 25 +------------------- dzgui/util/dist.py | 3 ++- dzgui/util/ip.py | 38 +++++++++++++++---------------- dzgui/views/base.py | 44 +++++++++++++++++++----------------- dzgui/views/pages/servers.py | 25 ++++---------------- pyproject.toml | 1 + 6 files changed, 49 insertions(+), 87 deletions(-) diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index b66bbd7..d668b2d 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -81,11 +81,9 @@ class AppNavigation: filters: "FilterPanel" -class Controller: +class Controller(GObject.GObject): def __init__(self) -> None: self.dist_cache: dict[str, "Haversine", "ServerTab"] = {} - # TODO: store in crumbs class - self.crumbs_cache = "" self.mediator = AppNavigation() self.prefs: UserPrefs @@ -100,13 +98,6 @@ class Controller: except AttributeError: logger.critical(f"{attr} is not a valid AppNavigation attribute.") - # TODO: relegate to crumbs class - def set_crumbs(self, text: str) -> None: - self.mediator.grid.set_breadcrumbs(text) - - def get_crumbs(self) -> str: - return self.mediator.grid.get_breadcrumbs() - def get_help_store(self) -> Gtk.ListStore: return self.model_man.get_help_store() @@ -363,16 +354,8 @@ class Controller: case ButtonType.MODS: # TODO: reload using refresh button, rather than on demand self.load_mods() - case ButtonType.HELP: - pass - case ButtonType.SERVERS: - # TODO: drop after fixing crumbs signal - self.mediator.notebook.set_page_by_enum(button.opens) - return self.mediator.notebook.set_page_by_enum(button.opens) - # TODO: set crumbs by signal - self.set_crumbs(button.get_label()) def get_help_row(self) -> str: tv = self.mediator.menu @@ -697,12 +680,6 @@ class Controller: def propagate_column_width(self, col: Gtk.TreeViewColumn) -> None: GLib.idle_add(self.mediator.servers.update_tab_widths, col) - def set_crumbs_cache(self, text: str) -> None: - self.crumbs_cache = text - - def get_crumbs_cache(self) -> str: - return self.crumbs_cache - def refresh_tree(self) -> None: treeview = self.get_active_treeview() treeview.set_loaded(False) diff --git a/dzgui/util/dist.py b/dzgui/util/dist.py index 2eb6be3..34472ba 100644 --- a/dzgui/util/dist.py +++ b/dzgui/util/dist.py @@ -67,13 +67,14 @@ class CalcDist(multiprocessing.Process): self.result_queue.put([self.addr, dist, self.enum]) def compare(self, remote: str) -> int | None: + # TODO: cache this prefs = self.controller.get_prefs() local = prefs.coords if local is None: return None try: remote = get_coords(prefs.paths.ips, remote) - except GeolocationError: + except Exception: return None # TODO: handle failed remote dist diff --git a/dzgui/util/ip.py b/dzgui/util/ip.py index f4dceb5..a9deccd 100644 --- a/dzgui/util/ip.py +++ b/dzgui/util/ip.py @@ -2,6 +2,7 @@ import a2s import requests import shutil import subprocess +from warnings import deprecated from dataclasses import dataclass from typing import TYPE_CHECKING @@ -14,6 +15,7 @@ from dzgui.const.endpoints import COORDS_API, IP_ECHO if TYPE_CHECKING: from pathlib import Path + @dataclass class Coords: lat: float @@ -51,11 +53,11 @@ def get_coords(ips: "Path", ip: str) -> Coords: prefix = f"^{split[0]}.{split[1]}." - proc = subprocess.run( - ["/usr/bin/grep", "-E", prefix, ips], - capture_output=True, - text=True - ) + if shutil.which("rg") is not None: + args = ["/usr/bin/rg", prefix, ips] + else: + args = ["/usr/bin/grep", "-E", prefix, ips] + proc = subprocess.run(args, capture_output=True, text=True) if proc.returncode != 0: raise GeolocationError("Failed to split records") @@ -80,9 +82,9 @@ def get_coords(ips: "Path", ip: str) -> Coords: return Coords(float(fields[-2]), float(fields[-1])) raise GeolocationError("No matching records found") + def get_local_ip() -> str: ip = "" - # TODO: use shlex if shutil.which("dig") is not None: proc = subprocess.run( [ @@ -90,10 +92,10 @@ def get_local_ip() -> str: "-4", "+short", "myip.opendns.com", - "@resolver1.opendns.com" + "@resolver1.opendns.com", ], capture_output=True, - text=True + text=True, ) if proc.returncode == 0: @@ -110,7 +112,7 @@ def resolve_ip(address: Record) -> Record: """ Multiple game modes may be hosted on the same IP and query port, but resolve to different game ports. The canonical record must - contain the real game port. This is merely used when saving a + contain the real game port. This is merely used when saving a record as a UUID. """ res = a2s.info((address.ip, address.qport)) @@ -121,17 +123,13 @@ def resolve_ip(address: Record) -> Record: def is_valid_port(port: str) -> bool: if len(port) < 1: return True - if ( - not port.isdigit() - or int(port) == 0 - or int(port[0]) == 0 - or int(port) > 65535 - ): + if not port.isdigit() or int(port) == 0 or int(port[0]) == 0 or int(port) > 65535: return True return False -# TODO: deprecated -#def get_local_coords(ip: str): -# url = COORDS_API + "/" + ip -# #local res=$(curl -Ls "$url" | jq -r '"\(.lat)\n\(.lon)"') -# return url + +@deprecated("use ips.csv") +def get_local_coords(ip: str): + url = COORDS_API + "/" + ip + # local res=$(curl -Ls "$url" | jq -r '"\(.lat)\n\(.lon)"') + return url diff --git a/dzgui/views/base.py b/dzgui/views/base.py index 156be48..631fda0 100644 --- a/dzgui/views/base.py +++ b/dzgui/views/base.py @@ -300,22 +300,20 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore def _on_page_changed( self, notebook: "Notebook", page: Gtk.Widget, page_num: int ) -> None: - enum = self.get_page_by_enum() + return + # enum = self.get_page_by_enum() # TODO: crumbs signal - if enum is not None: - crumbs = enum.dict["crumbs"] - MainController.set_crumbs(crumbs) + # if enum is not None: + # crumbs = enum.dict["crumbs"] + # MainController.set_crumbs(crumbs) - if self.is_return is True: - MainController.mediator.statusbar.emit( - "notebook_page_returned", self.prior_page - ) - else: - MainController.mediator.statusbar.emit("notebook_page_changed", enum) - - self.is_return = False - #if enum is NotebookPage.SERVERS: - # MainController.present_servers() + # if self.is_return is True: + # MainController.mediator.statusbar.emit( + # "notebook_page_returned", self.prior_page + # ) + # else: + # MainController.mediator.statusbar.emit("notebook_page_changed", enum) + # self.is_return = False class Grid(Gtk.Grid): @@ -331,17 +329,21 @@ class Grid(Gtk.Grid): self.statusbar = Statusbar(MainController) self.right_panel = RightPanel(MainController) - self.breadcrumbs = Gtk.Label(halign=Gtk.Align.START) - self.set_breadcrumbs(strings.label_main_menu) + # self.breadcrumbs = Gtk.Label(halign=Gtk.Align.START) + # self.set_breadcrumbs(strings.label_main_menu) - self.bu = Gtk.Button(label="Shrink to fit", halign=Gtk.Align.END) - self.crumb_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) - self.crumb_box.add(self.breadcrumbs) - self.crumb_box.add(self.bu) - self.bu.connect("clicked", self._shrink) + # self.bu = Gtk.Button(label="Shrink to fit", halign=Gtk.Align.END) + # self.bu.connect("clicked", self._shrink) + + # self.crumb_box.add(self.bu) self.notebook = Notebook() self.conpan = ConnectPanel(MainController) + from dzgui.views.components.crumbs import Breadcrumbs + + self.breadcrumbs = Breadcrumbs(MainController) + self.crumb_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + self.crumb_box.add(self.breadcrumbs) self.attach(self.notebook, 0, 0, MAX_COLS, SINGLE_ROW) diff --git a/dzgui/views/pages/servers.py b/dzgui/views/pages/servers.py index 781ddaa..81ad88c 100644 --- a/dzgui/views/pages/servers.py +++ b/dzgui/views/pages/servers.py @@ -21,7 +21,6 @@ class ServerNotebook(Gtk.ScrolledWindow): def __init__(self, controller: "Controller"): super().__init__() - self.tab_cache = "" self.controller = controller self.controller.register_widget("servers", self) self.notebook = Gtk.Notebook(show_tabs=True) @@ -56,9 +55,6 @@ class ServerNotebook(Gtk.ScrolledWindow): self.connect("map", self._on_map) self.connect("unmap", self._on_unmap) - # TODO: strings - self.set_crumbs("Server browser") - def _on_map(self, widget: Self) -> None: self.controller.toggle_server_panels(True) @@ -77,10 +73,10 @@ class ServerNotebook(Gtk.ScrolledWindow): return self.get_active_treeview().grab_focus() - def set_crumbs(self, text: str) -> None: - string = f"Servers > {text}" - self.controller.set_crumbs(string) - self.set_cached_label(string) + def get_current_tab_text(self) -> None: + ind = self.notebook.get_current_page() + child = self.notebook.get_nth_page(ind) + return self.notebook.get_tab_label_text(child) def _on_page_changed( self, notebook: Gtk.Notebook, child: Gtk.Widget, index: int @@ -88,10 +84,6 @@ class ServerNotebook(Gtk.ScrolledWindow): if self.controller.loaded is False: return - # TODO :signals - # emit signal to crumbs - # emit signal to statusbar - # TODO: abstract label = self.notebook.get_tab_label_text(child) if label is None: return @@ -99,17 +91,8 @@ class ServerNotebook(Gtk.ScrolledWindow): # TODO: strings text = label.strip("*") self.notebook.set_tab_label_text(child, text) - self.set_crumbs(text) - - #self.controller.present_servers() self.controller.populate_model() - def set_cached_label(self, label: str) -> None: - self.tab_cache = label - - def get_cached_label(self) -> str: - return self.tab_cache - def get_active_treeview(self) -> ServerTreeView: index = self.notebook.get_current_page() scrollable = self.notebook.get_nth_page(index) diff --git a/pyproject.toml b/pyproject.toml index 9864d41..17dfca4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ build-backend = "setuptools.build_meta" line-length = 88 indent-width = 4 extend-exclude = ["tree_servers.py", "tree_server_mods.py", "dialogs", "right_panel.py", "filter_panel.py", "base.py", "*lib/a2s", "dist.py"] +lint.unfixable = ["F401"] [tool.ruff.format] quote-style = "double"