mirror of
https://github.com/aclist/dztui.git
synced 2026-10-31 07:02:50 +01:00
feat: preconnection assistant (WIP)
This commit is contained in:
1 parent
139b226959
commit
33fbf765ed
8 files changed
+78
-23
No files matched your search
+6
-1
@@ -154,7 +154,12 @@ def remove_stale_signatures(config: Path, versions: Path) -> None:
|
|||||||
def find_stale_mods(config: Path) -> list[int]:
|
def find_stale_mods(config: Path) -> list[int]:
|
||||||
def push_record(rec: str) -> list:
|
def push_record(rec: str) -> list:
|
||||||
record = fqip_to_record(rec)
|
record = fqip_to_record(rec)
|
||||||
return [mod.workshop_id for mod in get_rules(record)]
|
try:
|
||||||
|
mods = get_rules(record)
|
||||||
|
print(mods)
|
||||||
|
except Exception:
|
||||||
|
return []
|
||||||
|
return [mod.workshop_id for mod in mods]
|
||||||
|
|
||||||
steam = lookup(config, Preferences.DEFAULT)
|
steam = lookup(config, Preferences.DEFAULT)
|
||||||
steam_path = Path(steam)
|
steam_path = Path(steam)
|
||||||
|
|||||||
@@ -438,6 +438,7 @@ def get_rules(record: Record) -> list["DayzMod"]:
|
|||||||
return [mod for mod in mods]
|
return [mod for mod in mods]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical(e)
|
logger.critical(e)
|
||||||
|
# TODO: supposed to skip failing servers for highlight action
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class NotebookPage(EnumWithAttrs):
|
|||||||
OPTIONS = {"crumbs": strings.crumbs.options, "statusbar": False}
|
OPTIONS = {"crumbs": strings.crumbs.options, "statusbar": False}
|
||||||
SERVERS = {"crumbs": strings.crumbs.servers, "statusbar": True}
|
SERVERS = {"crumbs": strings.crumbs.servers, "statusbar": True}
|
||||||
THANKS = {"crumbs": strings.crumbs.thanks, "statusbar": True}
|
THANKS = {"crumbs": strings.crumbs.thanks, "statusbar": True}
|
||||||
|
CONNECTION = {"crumbs": "Connect", "statusbar": False}
|
||||||
|
|
||||||
|
|
||||||
class RowType(EnumWithAttrs):
|
class RowType(EnumWithAttrs):
|
||||||
|
|||||||
+14
-4
@@ -27,6 +27,7 @@ from dzgui.util.format import format_player_count
|
|||||||
from dzgui.util.open_links import open_user_workshop, open_workshop_page
|
from dzgui.util.open_links import open_user_workshop, open_workshop_page
|
||||||
from dzgui.views.dialogs.filepicker import FilePicker
|
from dzgui.views.dialogs.filepicker import FilePicker
|
||||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||||
|
from dzgui.views.dialogs.servers import ServerModDialog
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ logger = logging.getLogger(APP_NAME)
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from dzgui.api.servers import Record
|
from dzgui.api.servers import Record
|
||||||
from dzgui.const.enum import ServerTab
|
from dzgui.const.enum import ServerTab
|
||||||
|
from dzgui.lib.dayzquery import DayzMod
|
||||||
from dzgui.managers.filter import FilterManager
|
from dzgui.managers.filter import FilterManager
|
||||||
from dzgui.util.dist import Haversine
|
from dzgui.util.dist import Haversine
|
||||||
from dzgui.views.base import Notebook, Grid, OuterWindow
|
from dzgui.views.base import Notebook, Grid, OuterWindow
|
||||||
@@ -139,7 +141,9 @@ class Controller(GObject.GObject):
|
|||||||
def remove_statusbar(self, context: "NotebookPage | ServerTab") -> None:
|
def remove_statusbar(self, context: "NotebookPage | ServerTab") -> None:
|
||||||
self.mediator.statusbar.pop(context)
|
self.mediator.statusbar.pop(context)
|
||||||
|
|
||||||
def set_statusbar_dist(self, haversine: Union["Haversine", None], enum: "ServerTab") -> None:
|
def set_statusbar_dist(
|
||||||
|
self, haversine: Union["Haversine", None], enum: "ServerTab"
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
NOTE: prevents race condition when server tab changed,
|
NOTE: prevents race condition when server tab changed,
|
||||||
but allows caching the distance in the background
|
but allows caching the distance in the background
|
||||||
@@ -400,7 +404,7 @@ class Controller(GObject.GObject):
|
|||||||
ConnectionManager(self).query_details(record)
|
ConnectionManager(self).query_details(record)
|
||||||
|
|
||||||
def get_modlist(self, record: "Record") -> None:
|
def get_modlist(self, record: "Record") -> None:
|
||||||
ConnectionManager(self).query_modlist(record)
|
ConnectionManager(self).query_modlist_and_present(record)
|
||||||
|
|
||||||
def get_server_name(self) -> str:
|
def get_server_name(self) -> str:
|
||||||
tv = self.get_active_treeview()
|
tv = self.get_active_treeview()
|
||||||
@@ -448,8 +452,14 @@ class Controller(GObject.GObject):
|
|||||||
def get_modtreeview(self) -> "ModTreeView":
|
def get_modtreeview(self) -> "ModTreeView":
|
||||||
return self.mediator.modtreeview
|
return self.mediator.modtreeview
|
||||||
|
|
||||||
|
def get_exit_event(self) -> None:
|
||||||
|
return self.exit_event
|
||||||
|
|
||||||
def set_exit_event(self) -> None:
|
def set_exit_event(self) -> None:
|
||||||
self.exit_event.set()
|
self.exit_event.set()
|
||||||
|
|
||||||
def get_exit_event(self) -> threading.Event:
|
def open_connection_assistant(self, res: dict[Any], mods: list["DayzMod"]) -> None:
|
||||||
return self.exit_event
|
self.open_page(NotebookPage.CONNECTION)
|
||||||
|
# TODO: populate assistant
|
||||||
|
# TODO: embed dialogs
|
||||||
|
# dialog = ServerModDialog(self, mods)
|
||||||
@@ -55,11 +55,18 @@ class ConnectionManager:
|
|||||||
self.thread_man.set_cleanup_func(
|
self.thread_man.set_cleanup_func(
|
||||||
StoredFunc(self._server_timeout), destroy_first=True
|
StoredFunc(self._server_timeout), destroy_first=True
|
||||||
)
|
)
|
||||||
rules = Servers.get_rules(record)
|
|
||||||
|
|
||||||
|
# TODO: proper error handling (currently returns empty list)
|
||||||
|
try:
|
||||||
|
mods = self.query_modlist(record)
|
||||||
|
except Exception:
|
||||||
|
self.thread_man.set_cleanup_func(
|
||||||
|
StoredFunc(self._server_timeout), destroy_first=True
|
||||||
|
)
|
||||||
|
self.controller.open_connection_assistant(res, mods)
|
||||||
# TODO: add to history if successful
|
# TODO: add to history if successful
|
||||||
print(res)
|
# print(res)
|
||||||
print(rules)
|
# print(rules)
|
||||||
|
|
||||||
@call_on_thread(dialog.querying)
|
@call_on_thread(dialog.querying)
|
||||||
def query_details(self, record: Servers.Record) -> None:
|
def query_details(self, record: Servers.Record) -> None:
|
||||||
@@ -73,18 +80,17 @@ class ConnectionManager:
|
|||||||
StoredFunc(self._present_details_dialog, details), destroy_first=True
|
StoredFunc(self._present_details_dialog, details), destroy_first=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@call_on_thread(dialog.querying)
|
|
||||||
def query_modlist(self, record: Servers.Record) -> None:
|
def query_modlist(self, record: Servers.Record) -> None:
|
||||||
mods = Servers.get_rules(record)
|
mods = Servers.get_rules(record)
|
||||||
steam_path = self.controller.query_config(Preferences.DEFAULT)
|
steam_path = self.controller.query_config(Preferences.DEFAULT)
|
||||||
local = get_local_mod_ids(steam_path)
|
local = get_local_mod_ids(steam_path)
|
||||||
if len(mods) == 0:
|
# if len(mods) == 0:
|
||||||
# TODO: separate message for no mods
|
# # TODO: separate message for no mods
|
||||||
# TODO: separate message for actual timeout
|
# # TODO: separate message for actual timeout
|
||||||
self.thread_man.set_cleanup_func(
|
# self.thread_man.set_cleanup_func(
|
||||||
StoredFunc(self._server_timeout), destroy_first=True
|
# StoredFunc(self._server_timeout), destroy_first=True
|
||||||
)
|
# )
|
||||||
return
|
# return
|
||||||
alpha_mods = [
|
alpha_mods = [
|
||||||
[
|
[
|
||||||
mod.name,
|
mod.name,
|
||||||
@@ -94,9 +100,19 @@ class ConnectionManager:
|
|||||||
for mod in mods
|
for mod in mods
|
||||||
]
|
]
|
||||||
alpha_mods.sort(key=lambda x: x[0])
|
alpha_mods.sort(key=lambda x: x[0])
|
||||||
|
return alpha_mods
|
||||||
|
|
||||||
|
@call_on_thread(dialog.querying)
|
||||||
|
def query_modlist_and_present(self, record: Servers.Record) -> None:
|
||||||
|
try:
|
||||||
|
mods = self.query_modlist(record)
|
||||||
|
except Exception:
|
||||||
|
self.thread_man.set_cleanup_func(
|
||||||
|
StoredFunc(self._server_timeout), destroy_first=True
|
||||||
|
)
|
||||||
|
return
|
||||||
self.thread_man.set_cleanup_func(
|
self.thread_man.set_cleanup_func(
|
||||||
StoredFunc(self._present_modlist_dialog, alpha_mods),
|
StoredFunc(self._present_modlist_dialog, mods),
|
||||||
destroy_first=True,
|
destroy_first=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+18
-4
@@ -16,6 +16,9 @@ from dzgui.const.enum import Preferences
|
|||||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||||
from dzgui.model.model_factory import FastInsertListStore, ModelFactory
|
from dzgui.model.model_factory import FastInsertListStore, ModelFactory
|
||||||
from dzgui.util.format import format_mods
|
from dzgui.util.format import format_mods
|
||||||
|
from dzgui.util.strings import server_timeout
|
||||||
|
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||||
|
|
||||||
|
|
||||||
import dzgui.api.pefile as PeFile
|
import dzgui.api.pefile as PeFile
|
||||||
|
|
||||||
@@ -34,11 +37,9 @@ class ModManager:
|
|||||||
"""
|
"""
|
||||||
Because mods may be dynamically updated on the system,
|
Because mods may be dynamically updated on the system,
|
||||||
this manager is instantiated each time the Mods page is opened
|
this manager is instantiated each time the Mods page is opened
|
||||||
and persists until the next time the page is opened
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, controller: "Controller") -> None:
|
def __init__(self, controller: "Controller") -> None:
|
||||||
|
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.emitter = controller.get_emitter()
|
self.emitter = controller.get_emitter()
|
||||||
self.prefs = controller.get_prefs()
|
self.prefs = controller.get_prefs()
|
||||||
@@ -50,6 +51,7 @@ class ModManager:
|
|||||||
self.thread_man = ThreadingManager(controller)
|
self.thread_man = ThreadingManager(controller)
|
||||||
self._get_mods()
|
self._get_mods()
|
||||||
|
|
||||||
|
# TODO: strings
|
||||||
@call_on_thread("getting mods")
|
@call_on_thread("getting mods")
|
||||||
def _get_mods(self) -> None:
|
def _get_mods(self) -> None:
|
||||||
mods = get_delimited_mods(self.path)
|
mods = get_delimited_mods(self.path)
|
||||||
@@ -69,11 +71,12 @@ class ModManager:
|
|||||||
total_mods = len(self.store)
|
total_mods = len(self.store)
|
||||||
self.emitter.emit("mods_updated", msg, total_mods)
|
self.emitter.emit("mods_updated", msg, total_mods)
|
||||||
|
|
||||||
|
# TODO: strings
|
||||||
@call_on_thread("deleting mods")
|
@call_on_thread("deleting mods")
|
||||||
def delete_mods(self) -> None:
|
def delete_mods(self) -> None:
|
||||||
sel = self.treeview.get_selection()
|
sel = self.treeview.get_selection()
|
||||||
model, pathlist = sel.get_selected_rows()
|
model, pathlist = sel.get_selected_rows()
|
||||||
# NOTE reverse when multiple selection
|
# NOTE: reverse when multiple selection
|
||||||
iters = []
|
iters = []
|
||||||
for path in reversed(pathlist):
|
for path in reversed(pathlist):
|
||||||
_iter = self.delete_single_mod(path)
|
_iter = self.delete_single_mod(path)
|
||||||
@@ -174,13 +177,24 @@ class ModManager:
|
|||||||
model[path][4] = True
|
model[path][4] = True
|
||||||
self.emitter.emit("mods_highlighted")
|
self.emitter.emit("mods_highlighted")
|
||||||
|
|
||||||
|
# TODO: strings
|
||||||
@call_on_thread("working")
|
@call_on_thread("working")
|
||||||
def highlight_stale(self) -> None:
|
def highlight_stale(self) -> None:
|
||||||
# TODO: set progress bar for number of mods
|
# try:
|
||||||
stale = find_stale_mods(self.prefs.paths.config)
|
stale = find_stale_mods(self.prefs.paths.config)
|
||||||
|
# except Exception:
|
||||||
|
# # TODO: clearer error message
|
||||||
|
# func = StoredFunc(self._server_timeout)
|
||||||
|
# self.thread_man.set_cleanup_func(func)
|
||||||
|
# return
|
||||||
|
|
||||||
func = StoredFunc(self._on_stale_mods_found, stale)
|
func = StoredFunc(self._on_stale_mods_found, stale)
|
||||||
self.thread_man.set_cleanup_func(func)
|
self.thread_man.set_cleanup_func(func)
|
||||||
|
|
||||||
|
def _server_timeout(self) -> None:
|
||||||
|
dialog = ExceptionDialog(self.controller, server_timeout)
|
||||||
|
dialog.run()
|
||||||
|
|
||||||
def select_colorized(self) -> None:
|
def select_colorized(self) -> None:
|
||||||
model = self.treeview.get_model()
|
model = self.treeview.get_model()
|
||||||
if model is None:
|
if model is None:
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class ThreadingManager:
|
|||||||
def __init__(self, controller: "Controller") -> None:
|
def __init__(self, controller: "Controller") -> None:
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.jobs = 1
|
self.jobs = 1
|
||||||
self.cleanup_func: StoredFunc | None
|
self.cleanup_func: StoredFunc | None = None
|
||||||
self.destroy_first = False
|
self.destroy_first = False
|
||||||
|
|
||||||
def call_on_thread(self, dialog_str: str, func: StoredFunc) -> None:
|
def call_on_thread(self, dialog_str: str, func: StoredFunc) -> None:
|
||||||
@@ -75,7 +75,9 @@ class ThreadingManager:
|
|||||||
def increment_dialog_with_str(self, text: str) -> None:
|
def increment_dialog_with_str(self, text: str) -> None:
|
||||||
GLib.idle_add(lambda: self.wait_dialog.increment(text))
|
GLib.idle_add(lambda: self.wait_dialog.increment(text))
|
||||||
|
|
||||||
def set_cleanup_func(self, func: StoredFunc | None, destroy_first: bool = False) -> None:
|
def set_cleanup_func(
|
||||||
|
self, func: StoredFunc | None, destroy_first: bool = False
|
||||||
|
) -> None:
|
||||||
if type(func) not in (StoredFunc, type(None)):
|
if type(func) not in (StoredFunc, type(None)):
|
||||||
msg = f"Callback function '{func}' is not of type StoredFunc or None"
|
msg = f"Callback function '{func}' is not of type StoredFunc or None"
|
||||||
logger.critical(msg)
|
logger.critical(msg)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from dzgui.views.pages.keys import Keybindings
|
|||||||
from dzgui.views.pages.log import Log
|
from dzgui.views.pages.log import Log
|
||||||
from dzgui.views.pages.mods import Mods
|
from dzgui.views.pages.mods import Mods
|
||||||
from dzgui.views.pages.options import Options
|
from dzgui.views.pages.options import Options
|
||||||
|
from dzgui.views.pages.preconnect import PreConnectionAssistant
|
||||||
from dzgui.views.pages.servers import ServerNotebook
|
from dzgui.views.pages.servers import ServerNotebook
|
||||||
from dzgui.views.pages.thanks import Thanks
|
from dzgui.views.pages.thanks import Thanks
|
||||||
|
|
||||||
@@ -62,6 +63,8 @@ warnings.filterwarnings("ignore", ".*g_value_get_int", Warning)
|
|||||||
# return f"{record.ip}:{record.gameport}:{record.qport}"
|
# return f"{record.ip}:{record.gameport}:{record.qport}"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class OuterWindow(Gtk.Window):
|
class OuterWindow(Gtk.Window):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(title=APP_NAME, border_width=10, icon_name=APP_NAME_LOWER)
|
super().__init__(title=APP_NAME, border_width=10, icon_name=APP_NAME_LOWER)
|
||||||
@@ -125,6 +128,8 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore
|
|||||||
self.log = Log(MainController)
|
self.log = Log(MainController)
|
||||||
self.developers = Developers(MainController)
|
self.developers = Developers(MainController)
|
||||||
|
|
||||||
|
self.connection = PreConnectionAssistant(MainController)
|
||||||
|
|
||||||
self.pages = {
|
self.pages = {
|
||||||
self.help: NotebookPage.HELP,
|
self.help: NotebookPage.HELP,
|
||||||
self.clog: NotebookPage.CHANGELOG,
|
self.clog: NotebookPage.CHANGELOG,
|
||||||
@@ -135,6 +140,7 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore
|
|||||||
self.log: NotebookPage.LOG,
|
self.log: NotebookPage.LOG,
|
||||||
self.thanks: NotebookPage.THANKS,
|
self.thanks: NotebookPage.THANKS,
|
||||||
self.developers: NotebookPage.DEVELOPERS,
|
self.developers: NotebookPage.DEVELOPERS,
|
||||||
|
self.connection: NotebookPage.CONNECTION,
|
||||||
}
|
}
|
||||||
self.indexes = {}
|
self.indexes = {}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user