mirror of
https://github.com/aclist/dztui.git
synced 2026-10-31 15:12:48 +01:00
feat: add ConnectionManager
This commit is contained in:
1 parent
e56b89fd64
commit
6bbe0d6882
9 files changed
+159
-101
No files matched your search
+10
-5
@@ -1,14 +1,18 @@
|
|||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from dzgui.api.servers import Record
|
|
||||||
from dzgui.config.query import lookup
|
from dzgui.config.query import lookup
|
||||||
from dzgui.const.endpoints import BM_SERVERS
|
from dzgui.const.endpoints import BM_SERVERS
|
||||||
from dzgui.const.enum import Preferences
|
from dzgui.const.enum import Preferences
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from dzgui.api.servers import Record
|
||||||
|
|
||||||
|
|
||||||
def get_attributes(config: Path, uid: int) -> str:
|
def get_attributes(config: Path, uid: int) -> str:
|
||||||
# TODO: handle if key is not set
|
# TODO: handle if key is not set
|
||||||
# TODO: tests for malformed IDs/values
|
# TODO: tests for malformed IDs/values
|
||||||
@@ -18,7 +22,7 @@ def get_attributes(config: Path, uid: int) -> str:
|
|||||||
payload: dict[str, str] = {
|
payload: dict[str, str] = {
|
||||||
"filter[game]": "dayz",
|
"filter[game]": "dayz",
|
||||||
"sort": "-players",
|
"sort": "-players",
|
||||||
"filter[ids][whitelist]": str(uid)
|
"filter[ids][whitelist]": str(uid),
|
||||||
}
|
}
|
||||||
res = requests.get(BM_SERVERS, params=payload, headers=hdr)
|
res = requests.get(BM_SERVERS, params=payload, headers=hdr)
|
||||||
res.raise_for_status()
|
res.raise_for_status()
|
||||||
@@ -26,13 +30,14 @@ def get_attributes(config: Path, uid: int) -> str:
|
|||||||
return j
|
return j
|
||||||
|
|
||||||
|
|
||||||
def map_id_to_record(config: Path, uid: int) -> Record | None:
|
def map_id_to_record(config: Path, uid: int) -> Optional["Record"]:
|
||||||
|
from dzgui.api.servers import Record
|
||||||
|
|
||||||
try:
|
try:
|
||||||
record = get_attributes(config, uid)
|
record = get_attributes(config, uid)
|
||||||
ip = record["ip"]
|
ip = record["ip"]
|
||||||
port = record["port"]
|
port = record["port"]
|
||||||
qport = record["portQuery"]
|
qport = record["portQuery"]
|
||||||
return Record(ip, port, qport)
|
return Record(ip, port, qport)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.warn(e)
|
|
||||||
return None
|
return None
|
||||||
@@ -12,6 +12,7 @@ import typing # noqa
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
from dzgui.api.bm import map_id_to_record
|
||||||
from dzgui.const.constants import REQUEST_TIMEOUT
|
from dzgui.const.constants import REQUEST_TIMEOUT
|
||||||
from dzgui.const.endpoints import STEAM_SERVERS
|
from dzgui.const.endpoints import STEAM_SERVERS
|
||||||
from dzgui.util import strings
|
from dzgui.util import strings
|
||||||
@@ -451,3 +452,27 @@ def get_rules(ip: str, qport: int) -> list[int]:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical(e)
|
logger.critical(e)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def response_to_fq_ip(res: dict) -> str:
|
||||||
|
ip = res["addr"].split(":")[0]
|
||||||
|
gameport = res["gameport"]
|
||||||
|
qport = res["addr"].split(":")[1]
|
||||||
|
return f"{ip}:{gameport}:{qport}"
|
||||||
|
|
||||||
|
|
||||||
|
def query_id_or_ip(addr: str) -> None:
|
||||||
|
# NOTE: Battlemetrics
|
||||||
|
if addr.isdigit():
|
||||||
|
try:
|
||||||
|
config = self.controller.get_prefs().paths.config
|
||||||
|
resolved = map_id_to_record(config, addr)
|
||||||
|
res = query_direct(resolved.ip, resolved.qport)
|
||||||
|
except Exception as e:
|
||||||
|
logger.critical(e)
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
record = addr.split(":")
|
||||||
|
ip, qport = record[0], record[1]
|
||||||
|
res = query_direct(ip, int(qport))
|
||||||
|
return res
|
||||||
+17
-10
@@ -113,8 +113,8 @@ class Controller(GObject.GObject):
|
|||||||
self.emitter = Emitter()
|
self.emitter = Emitter()
|
||||||
self.emitter.connect("map_selection_changed", self._on_map_selection_changed)
|
self.emitter.connect("map_selection_changed", self._on_map_selection_changed)
|
||||||
self.emitter.connect("check_toggled", self._on_check_toggled)
|
self.emitter.connect("check_toggled", self._on_check_toggled)
|
||||||
self.emitter.connect("servers_loaded", self._on_servers_loaded)
|
|
||||||
self.emitter.connect("servers_loaded_init", self._on_servers_loaded_init)
|
self.emitter.connect("servers_loaded_init", self._on_servers_loaded_init)
|
||||||
|
#self.emitter.connect("servers_loaded", self._on_servers_loaded)
|
||||||
|
|
||||||
# NOTE: suppress requests until entire UI is loaded
|
# NOTE: suppress requests until entire UI is loaded
|
||||||
self.loaded = False
|
self.loaded = False
|
||||||
@@ -861,7 +861,11 @@ class Controller(GObject.GObject):
|
|||||||
self.filter_man = filter_man
|
self.filter_man = filter_man
|
||||||
|
|
||||||
def populate_model(self, tv: Gtk.TreeView) -> None:
|
def populate_model(self, tv: Gtk.TreeView) -> None:
|
||||||
ServerModelManager(self, tv, first_iteration=True)
|
# NOTE: skip on previously loaded tabs
|
||||||
|
if tv.is_loaded():
|
||||||
|
self.emitter.emit("servers_loaded", tv.get_enum())
|
||||||
|
return
|
||||||
|
ServerModelManager(self, tv, first_iteration=True).load()
|
||||||
|
|
||||||
def get_favorite(self) -> tuple[str, str] | tuple[None, None]:
|
def get_favorite(self) -> tuple[str, str] | tuple[None, None]:
|
||||||
fav = str(self.query_config(Preferences.FAV_LBL))
|
fav = str(self.query_config(Preferences.FAV_LBL))
|
||||||
@@ -913,14 +917,14 @@ class Controller(GObject.GObject):
|
|||||||
store = self.get_map_store()
|
store = self.get_map_store()
|
||||||
self.emitter.emit("load_maps", store)
|
self.emitter.emit("load_maps", store)
|
||||||
|
|
||||||
def _on_servers_loaded(self, emitter: "Emitter", tab: "ServerTab") -> None:
|
#def _on_servers_loaded(self, emitter: "Emitter", tab: "ServerTab") -> None:
|
||||||
return
|
# return
|
||||||
# NOTE: workaround for GTK bug where fullscreen causes headers to vanish when model is None
|
# # NOTE: workaround for GTK bug where fullscreen causes headers to vanish when model is None
|
||||||
# TODO: this should be internal to servers page
|
# # TODO: this should be internal to servers page
|
||||||
state = self.has_server_model()
|
# state = self.has_server_model()
|
||||||
tv = self.get_active_treeview()
|
# tv = self.get_active_treeview()
|
||||||
tv.set_headers_visible(state)
|
# tv.set_headers_visible(state)
|
||||||
tv.set_headers_clickable(state)
|
# tv.set_headers_clickable(state)
|
||||||
|
|
||||||
def has_server_model(self) -> bool:
|
def has_server_model(self) -> bool:
|
||||||
treeview = self.get_active_treeview()
|
treeview = self.get_active_treeview()
|
||||||
@@ -946,6 +950,9 @@ class Controller(GObject.GObject):
|
|||||||
return self.mediator.notebook
|
return self.mediator.notebook
|
||||||
|
|
||||||
def get_servers(self) -> "Notebook":
|
def get_servers(self) -> "Notebook":
|
||||||
|
return self.mediator.servers
|
||||||
|
|
||||||
|
def get_server_notebook(self) -> "Notebook":
|
||||||
return self.mediator.servers.notebook
|
return self.mediator.servers.notebook
|
||||||
|
|
||||||
def get_window(self) -> "OuterWindow":
|
def get_window(self) -> "OuterWindow":
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import dzgui.api.servers as Servers
|
||||||
|
from dzgui.managers.thread_man import call_on_thread, StoredFunc, ThreadingManager
|
||||||
|
from dzgui.util.strings import api_warn_msg, dialog
|
||||||
|
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||||
|
|
||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
from gi.repository import Gtk # noqa E402
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from dzgui.controllers.mc import Controller
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionManager:
|
||||||
|
def __init__(self, controller: "Controller") -> None:
|
||||||
|
|
||||||
|
self.controller = controller
|
||||||
|
self.thread_man = ThreadingManager(parent=controller)
|
||||||
|
|
||||||
|
@call_on_thread(dialog.querying)
|
||||||
|
def _connect_by_id_or_ip(self, addr: str) -> None:
|
||||||
|
res = Servers.query_id_or_ip(addr)
|
||||||
|
if res is None:
|
||||||
|
self.thread_man.set_cleanup_func(StoredFunc(self._connection_failure))
|
||||||
|
# TODO: add to history if successful
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
def _connection_failure(self) -> None:
|
||||||
|
# TODO: more explicit warning message, not necessarily API failure?
|
||||||
|
dialog = ExceptionDialog(self.controller, api_warn_msg)
|
||||||
|
dialog.run()
|
||||||
@@ -21,7 +21,6 @@ def call_on_thread(dialog_str: str) -> Callable:
|
|||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
self = args[0]
|
self = args[0]
|
||||||
stored = StoredFunc(func, *args, **kwargs)
|
stored = StoredFunc(func, *args, **kwargs)
|
||||||
print("SELF", self)
|
|
||||||
if not hasattr(self, "thread_man"):
|
if not hasattr(self, "thread_man"):
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
if type(self.thread_man) is not ThreadingManager:
|
if type(self.thread_man) is not ThreadingManager:
|
||||||
|
|||||||
+62
-80
@@ -1,40 +1,36 @@
|
|||||||
from datetime import datetime
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
from concurrent.futures import as_completed
|
||||||
from concurrent.futures import wait, as_completed
|
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
import dzgui.api.servers as Servers
|
import dzgui.api.servers as Servers
|
||||||
|
from dzgui.const.enum import FilterMode, Preferences, ServerTab
|
||||||
from dzgui.const.constants import (
|
from dzgui.const.constants import (
|
||||||
APPID_DAYZ,
|
APPID_DAYZ,
|
||||||
APPID_DAYZ_EXP,
|
APPID_DAYZ_EXP,
|
||||||
)
|
)
|
||||||
from dzgui.const.enum import FilterMode, Preferences, ServerTab
|
|
||||||
from dzgui.managers.thread_man import call_on_thread, StoredFunc, ThreadingManager
|
from dzgui.managers.thread_man import call_on_thread, StoredFunc, ThreadingManager
|
||||||
from dzgui.util.strings import api_warn_msg, dialog
|
from dzgui.util.strings import api_warn_msg, dialog
|
||||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||||
|
|
||||||
from typing import Optional, TYPE_CHECKING
|
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "3.0")
|
||||||
from gi.repository import Gtk, GLib # noqa E402
|
from gi.repository import Gtk # noqa E402
|
||||||
|
|
||||||
LAN_TIMEOUT = 0.5
|
LAN_TIMEOUT = 0.5
|
||||||
API_TIMEOUT = 3
|
API_TIMEOUT = 3
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from dzgui.controllers.mc import Controller
|
from dzgui.controllers.mc import Controller
|
||||||
from dzgui.controllers.emitter import Emitter
|
|
||||||
from dzgui.model.filtered_model import FilteredModelManager
|
from dzgui.model.filtered_model import FilteredModelManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# TODO: failure: spawns error dialog
|
# TODO: failure: spawns error dialog
|
||||||
# TODO: non failure with empty model: updates statusbar
|
# TODO: non failure with empty model: updates statusbar with help text
|
||||||
|
|
||||||
|
|
||||||
class ServerModelManager:
|
class ServerModelManager:
|
||||||
@@ -42,28 +38,32 @@ class ServerModelManager:
|
|||||||
self, controller: "Controller", tv: Gtk.TreeView, first_iteration=False
|
self, controller: "Controller", tv: Gtk.TreeView, first_iteration=False
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
enum = tv.get_enum()
|
self.tv = tv
|
||||||
|
self.enum = tv.get_enum()
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.emitter = controller.get_emitter()
|
self.emitter = controller.get_emitter()
|
||||||
if tv.is_loaded():
|
|
||||||
self.emitter.emit("servers_loaded", enum)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.tv = tv
|
|
||||||
self.jobs = 1
|
self.jobs = 1
|
||||||
|
|
||||||
|
# NOTE: store filter man for access inside thread
|
||||||
self.filter_man = tv.get_filter_man()
|
self.filter_man = tv.get_filter_man()
|
||||||
|
|
||||||
|
# FIXME: change WaitDialog to use parent window only
|
||||||
self.thread_man = ThreadingManager(parent=controller)
|
self.thread_man = ThreadingManager(parent=controller)
|
||||||
|
|
||||||
# TODO: if first iteration, clear filter man control model
|
# TODO: if first iteration, clear filter man control model
|
||||||
# literal first load: iteration 1
|
# literal first load: iteration 1
|
||||||
# refresh: iteration 1 (wipe model)
|
# refresh: iteration 1 (wipe model)
|
||||||
# filter: iteration N+1
|
# filter: iteration N+1
|
||||||
|
# TODO: can drop first iteration arg and process in methods
|
||||||
self.first_iteration = first_iteration
|
self.first_iteration = first_iteration
|
||||||
|
|
||||||
# TODO: pass servers.saved treeview when using conpan regardless of current context
|
def load(self) -> None:
|
||||||
|
"""
|
||||||
match enum:
|
There may be cases where you want to instantiate this class without dumping servers,
|
||||||
|
e.g., adding saved servers from another tab
|
||||||
|
"""
|
||||||
|
match self.enum:
|
||||||
case ServerTab.BROWSER:
|
case ServerTab.BROWSER:
|
||||||
# NOTE: extra DAYZ_EXP param
|
# NOTE: extra DAYZ_EXP param
|
||||||
self.thread_man.set_job_count(len(Servers.params) + 1)
|
self.thread_man.set_job_count(len(Servers.params) + 1)
|
||||||
@@ -71,14 +71,12 @@ class ServerModelManager:
|
|||||||
case ServerTab.SAVED:
|
case ServerTab.SAVED:
|
||||||
self._dump_favorites()
|
self._dump_favorites()
|
||||||
case ServerTab.RECENT:
|
case ServerTab.RECENT:
|
||||||
# TODO: get row count
|
|
||||||
self._dump_history()
|
self._dump_history()
|
||||||
case ServerTab.LAN:
|
case ServerTab.LAN:
|
||||||
# NOTE: LAN tab is only loaded on demand
|
# NOTE: LAN tab is only loaded on demand
|
||||||
pass
|
pass
|
||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
# self._dump_lan()
|
|
||||||
|
|
||||||
@call_on_thread(dialog.fetching)
|
@call_on_thread(dialog.fetching)
|
||||||
def _dump_api(self) -> None:
|
def _dump_api(self) -> None:
|
||||||
@@ -113,7 +111,6 @@ class ServerModelManager:
|
|||||||
j = res.json
|
j = res.json
|
||||||
servers += j["response"]["servers"]
|
servers += j["response"]["servers"]
|
||||||
|
|
||||||
# TODO: try/except when parsing
|
|
||||||
parsed = Servers.parse_json(servers)
|
parsed = Servers.parse_json(servers)
|
||||||
self._push_data(parsed, FilterMode.INITIAL)
|
self._push_data(parsed, FilterMode.INITIAL)
|
||||||
|
|
||||||
@@ -150,11 +147,10 @@ class ServerModelManager:
|
|||||||
parsed = Servers.parse_json(servers)
|
parsed = Servers.parse_json(servers)
|
||||||
self._push_data(parsed, FilterMode.INITIAL)
|
self._push_data(parsed, FilterMode.INITIAL)
|
||||||
|
|
||||||
# TODO: strings
|
@call_on_thread(dialog.fetching)
|
||||||
@call_on_thread("dumping ips")
|
|
||||||
def _dump_ips(self, ips: list[str]) -> None:
|
def _dump_ips(self, ips: list[str]) -> None:
|
||||||
# NOTE: block malformed records (TODO: add github issue no.)
|
# NOTE: block malformed records (TODO: add github issue no.)
|
||||||
# TODO: sanitize ip list at config time, drop this
|
# TODO: sanitize ip list at config time and drop this
|
||||||
ips = [ip for ip in ips if len(ip.split(":")) == 3 and ip.split(":")[2] != ""]
|
ips = [ip for ip in ips if len(ip.split(":")) == 3 and ip.split(":")[2] != ""]
|
||||||
job = Servers.query_direct
|
job = Servers.query_direct
|
||||||
with ThreadPoolExecutor() as executor:
|
with ThreadPoolExecutor() as executor:
|
||||||
@@ -183,42 +179,32 @@ class ServerModelManager:
|
|||||||
parsed = Servers.parse_json(servers)
|
parsed = Servers.parse_json(servers)
|
||||||
self._push_data(parsed, FilterMode.INITIAL)
|
self._push_data(parsed, FilterMode.INITIAL)
|
||||||
|
|
||||||
def _query_ip_id(self, addr: str) -> None:
|
@call_on_thread(dialog.querying)
|
||||||
# NOTE: Battlemetrics
|
|
||||||
if addr.isdigit():
|
|
||||||
# FIXME:
|
|
||||||
config = self.controller.get_prefs().paths.config
|
|
||||||
resolved = map_id_to_record(config, addr)
|
|
||||||
res = Servers.query_direct(resolved.ip, resolved.qport)
|
|
||||||
else:
|
|
||||||
record = addr.split(":")
|
|
||||||
ip, qport = record[0], record[1]
|
|
||||||
res = Servers.query_direct(ip, int(qport))
|
|
||||||
return res
|
|
||||||
|
|
||||||
# TODO: strings
|
|
||||||
@call_on_thread("querying address")
|
|
||||||
def _connect_by_id_or_ip(self, addr: str) -> None:
|
|
||||||
res = self._query_ip_id(addr)
|
|
||||||
# TODO: unimplemented
|
|
||||||
|
|
||||||
@call_on_thread("querying address")
|
|
||||||
def _add_by_id_or_ip(self, addr: str) -> None:
|
def _add_by_id_or_ip(self, addr: str) -> None:
|
||||||
res = self.query_ip_id(addr)
|
res = Servers.query_id_or_ip(addr)
|
||||||
# TODO: investigate this
|
|
||||||
if res is None:
|
if res is None:
|
||||||
self.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||||
return
|
return
|
||||||
# NOTE: single record insertion
|
|
||||||
self.insert_record = Servers.parse_json([res])
|
record = Servers.parse_json([res])
|
||||||
# TODO: add into saved servers file
|
|
||||||
# TODO: update saved servers model
|
filter_man = self._get_filter_man()
|
||||||
# NOTE: this can be called from other tabs--if current focus is not ServerTab.SAVED, update label only
|
model = filter_man.get_control()
|
||||||
# TODO: saved servers might not be loaded yet, in which case should just update local file only
|
|
||||||
# TODO: perform simple equality comparison of self.tv.get_enum() == ServerTab.SAVED
|
# TODO: make this a method of ConfigManager
|
||||||
# FIXME: filter man is saved on a per tab basis, so this will mismatch
|
fqip = Servers.response_to_fq_ip(res)
|
||||||
# check if servers.get_active_treeview() is same as self.tv
|
ips = self.controller.query_config(Preferences.IP_LIST)
|
||||||
self.set_cleanup_func(StoredFunc(self._cleanup_on_insert))
|
ips.append(fqip)
|
||||||
|
self.controller.update_config(Preferences.IP_LIST, ips)
|
||||||
|
|
||||||
|
if model is not None:
|
||||||
|
# NOTE: single record insertion
|
||||||
|
model.append(record[0])
|
||||||
|
# TODO: if all filters are already applied, strange behavior may occur
|
||||||
|
# -> need to insert and update per current filters
|
||||||
|
filter_man.filter(FilterMode.INITIAL)
|
||||||
|
|
||||||
|
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_single_ip))
|
||||||
|
|
||||||
def _dump_history(self) -> None:
|
def _dump_history(self) -> None:
|
||||||
history = self.controller.get_prefs().paths.history
|
history = self.controller.get_prefs().paths.history
|
||||||
@@ -242,6 +228,7 @@ class ServerModelManager:
|
|||||||
def _dump_favorites(self) -> None:
|
def _dump_favorites(self) -> None:
|
||||||
ips = self.controller.query_config(Preferences.IP_LIST)
|
ips = self.controller.query_config(Preferences.IP_LIST)
|
||||||
self.thread_man.set_job_count(len(ips))
|
self.thread_man.set_job_count(len(ips))
|
||||||
|
|
||||||
# TODO: customize statusbar to mention how records can be added via contextmenu
|
# TODO: customize statusbar to mention how records can be added via contextmenu
|
||||||
if len(ips) == 0:
|
if len(ips) == 0:
|
||||||
# FIXME: this is not a failure, just a quiet exit with custom statusbar
|
# FIXME: this is not a failure, just a quiet exit with custom statusbar
|
||||||
@@ -252,25 +239,20 @@ class ServerModelManager:
|
|||||||
return
|
return
|
||||||
self._dump_ips(ips)
|
self._dump_ips(ips)
|
||||||
|
|
||||||
def _cleanup_on_insert(self) -> None:
|
def _cleanup_single_ip(self) -> None:
|
||||||
filter_man = self.get_filter_man()
|
proxy = self._get_filter_man().get_proxy_model()
|
||||||
model = filter_man.get_control()
|
|
||||||
|
|
||||||
# FIXME: this is a single row insertion,
|
|
||||||
# but refiltration should occur in thread for consistency/scalability
|
|
||||||
model.append(self.insert_record[0])
|
|
||||||
proxy = filter_man.filter(FilterMode.INITIAL)
|
|
||||||
|
|
||||||
# TODO: get proxy model out of thread
|
|
||||||
proxy = self.get_filter_man().get_proxy_model()
|
|
||||||
self.tv.set_model(proxy)
|
self.tv.set_model(proxy)
|
||||||
|
|
||||||
# TODO: update statusbar
|
# TODO: if current tab != self.saved, add label
|
||||||
context = self.tv.get_enum()
|
|
||||||
# TODO: adding a row may update available maps
|
# TODO: adding a row may update available maps
|
||||||
# TODO: if all filters are already applied, strange behavior may occur
|
self.emitter.emit("servers_loaded", self.enum)
|
||||||
# -> need to insert and update per current filters
|
self._update_maps()
|
||||||
self.emitter.emit("servers_loaded", context)
|
|
||||||
|
def _update_maps(self) -> None:
|
||||||
|
map_man = self.tv.get_map_man()
|
||||||
|
map_man.set_unique_maps(self._get_new_maps())
|
||||||
|
self.emitter.emit("servers_loaded_init")
|
||||||
|
self.first_iteration = False
|
||||||
|
|
||||||
def _cleanup_on_success(self) -> None:
|
def _cleanup_on_success(self) -> None:
|
||||||
self.tv.set_model(self.to_insert)
|
self.tv.set_model(self.to_insert)
|
||||||
@@ -285,14 +267,8 @@ class ServerModelManager:
|
|||||||
context = self.tv.get_enum()
|
context = self.tv.get_enum()
|
||||||
self.emitter.emit("servers_loaded", context)
|
self.emitter.emit("servers_loaded", context)
|
||||||
|
|
||||||
# CHORE: this is placeholder logic,
|
|
||||||
# refills map combo with new maps
|
|
||||||
if self.first_iteration:
|
if self.first_iteration:
|
||||||
map_man = self.tv.get_map_man()
|
self._update_maps()
|
||||||
map_man.set_unique_maps(self.new_maps)
|
|
||||||
self.emitter.emit("servers_loaded_init")
|
|
||||||
self.first_iteration = False
|
|
||||||
self.new_maps = None
|
|
||||||
|
|
||||||
def _cleanup_on_failure(self, show_dialog=True) -> None:
|
def _cleanup_on_failure(self, show_dialog=True) -> None:
|
||||||
map_man = self.tv.get_map_man()
|
map_man = self.tv.get_map_man()
|
||||||
@@ -334,10 +310,16 @@ class ServerModelManager:
|
|||||||
self.to_insert = manager.get_proxy_model()
|
self.to_insert = manager.get_proxy_model()
|
||||||
|
|
||||||
u_maps = set([row[1] for row in data])
|
u_maps = set([row[1] for row in data])
|
||||||
self.new_maps = sorted(u_maps)
|
self._set_new_maps(sorted(u_maps))
|
||||||
|
|
||||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))
|
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))
|
||||||
|
|
||||||
|
def _set_new_maps(self, maps: list[str]) -> None:
|
||||||
|
self.new_maps = maps
|
||||||
|
|
||||||
|
def _get_new_maps(self) -> list[str]:
|
||||||
|
return self.new_maps
|
||||||
|
|
||||||
def _get_filter_man(self) -> "FilteredModelManager":
|
def _get_filter_man(self) -> "FilteredModelManager":
|
||||||
return self.filter_man
|
return self.filter_man
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from dzgui.managers.connection import ConnectionManager
|
||||||
from dzgui.model.servers import ServerModelManager
|
from dzgui.model.servers import ServerModelManager
|
||||||
from dzgui.util.strings import connect_panel, fav_panel, lan_panel
|
from dzgui.util.strings import connect_panel, fav_panel, lan_panel
|
||||||
from dzgui.views.components.buttons import (
|
from dzgui.views.components.buttons import (
|
||||||
@@ -178,6 +179,7 @@ class AddPanel(Gtk.Frame):
|
|||||||
self.add_server.connect("clicked", self._on_add_clicked)
|
self.add_server.connect("clicked", self._on_add_clicked)
|
||||||
|
|
||||||
self.conn_server = SteamConnectButton()
|
self.conn_server = SteamConnectButton()
|
||||||
|
self.conn_server.connect("clicked", self._on_connect_clicked)
|
||||||
self.conn_server.set_sensitive(False)
|
self.conn_server.set_sensitive(False)
|
||||||
self.add_server.set_sensitive(False)
|
self.add_server.set_sensitive(False)
|
||||||
|
|
||||||
@@ -199,11 +201,14 @@ class AddPanel(Gtk.Frame):
|
|||||||
|
|
||||||
self.add(self.grid)
|
self.add(self.grid)
|
||||||
|
|
||||||
|
def _on_connect_clicked(self, button: Gtk.Button) -> None:
|
||||||
|
text = self.entry.get_text()
|
||||||
|
ConnectionManager(self.controller)._connect_by_id_or_ip(text)
|
||||||
|
|
||||||
def _submit_query(self) -> None:
|
def _submit_query(self) -> None:
|
||||||
text = self.entry.get_text()
|
text = self.entry.get_text()
|
||||||
# TODO: call servermodelmanager
|
saved = self.controller.get_servers().get_saved()
|
||||||
ServerModelManager().add_by_id_or_ip(text)
|
ServerModelManager(self.controller, saved)._add_by_id_or_ip(text)
|
||||||
# self.controller.add_by_id_or_ip(text)
|
|
||||||
|
|
||||||
def _on_activate(self, entry: Gtk.Entry) -> None:
|
def _on_activate(self, entry: Gtk.Entry) -> None:
|
||||||
if not self.add_server.is_sensitive():
|
if not self.add_server.is_sensitive():
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class Breadcrumbs(Gtk.Label):
|
|||||||
self.set_markup(crumbs)
|
self.set_markup(crumbs)
|
||||||
|
|
||||||
notebook = controller.get_notebook()
|
notebook = controller.get_notebook()
|
||||||
servers = controller.get_servers()
|
servers = controller.get_server_notebook()
|
||||||
notebook.connect_after("switch-page", self._on_notebook_page_changed)
|
notebook.connect_after("switch-page", self._on_notebook_page_changed)
|
||||||
servers.connect_after("switch-page", self._on_server_tab_changed)
|
servers.connect_after("switch-page", self._on_server_tab_changed)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import logging
|
|||||||
|
|
||||||
from typing import Optional, Self, TYPE_CHECKING
|
from typing import Optional, Self, TYPE_CHECKING
|
||||||
|
|
||||||
from dzgui.controllers.mc import StoredFunc
|
|
||||||
from dzgui.const.enum import ContextMenuGroup, ServerTab
|
from dzgui.const.enum import ContextMenuGroup, ServerTab
|
||||||
from dzgui.views.trees.tree_servers import ServerTreeView
|
from dzgui.views.trees.tree_servers import ServerTreeView
|
||||||
from dzgui.util.strings import server_labels
|
from dzgui.util.strings import server_labels
|
||||||
@@ -16,6 +15,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from dzgui.controllers.mc import Controller
|
from dzgui.controllers.mc import Controller
|
||||||
|
from dzgui.controllers.mc import Emitter
|
||||||
|
|
||||||
|
|
||||||
class ServerNotebook(Gtk.ScrolledWindow):
|
class ServerNotebook(Gtk.ScrolledWindow):
|
||||||
|
|||||||
Reference in new issue
Block a user