mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20dab38fff | ||
|
|
1ddc4a5ff1 | ||
|
|
d605447fca | ||
|
|
94fe3f9dff | ||
|
|
a966993999 | ||
|
|
8ee3b36816 | ||
|
|
3af53775cd | ||
|
|
e2d6a462db | ||
|
|
c4cc9f04c4 | ||
|
|
bcd59162b1 | ||
|
|
2f0bac75ac | ||
|
|
9191f43c8e | ||
|
|
2419fedd19 | ||
|
|
83a7996189 | ||
|
|
9d3aa8d9f5 | ||
|
|
0de0dd4a03 | ||
|
|
aeefc830cd | ||
|
|
647f75cde3 | ||
|
|
7e8b8eb7f7 | ||
|
|
79af78a7e0 |
No files matched your search
@@ -14,6 +14,7 @@ from typing import Any, Optional, TYPE_CHECKING, Union
|
||||
from dzgui.api.bm import map_id_to_record
|
||||
from dzgui.const.constants import APP_NAME, REQUEST_TIMEOUT
|
||||
from dzgui.const.endpoints import STEAM_SERVERS
|
||||
from dzgui.util.format import format_exception
|
||||
from dzgui.util import strings
|
||||
|
||||
import a2s
|
||||
@@ -272,8 +273,9 @@ def source_info_to_dict(ip: str, qport: int, info: "SourceInfo") -> dict[str, An
|
||||
res["ping"] = ping
|
||||
return res
|
||||
except Exception as e:
|
||||
# TODO: generalized function
|
||||
logger.critical(f"{type(e).__name__}: {e} ({ip}:{qport})")
|
||||
msg = format_exception(e)
|
||||
msg += f" ({ip}:{qport})"
|
||||
logger.critical(msg)
|
||||
raise e
|
||||
|
||||
|
||||
|
||||
+4
-9
@@ -73,14 +73,9 @@ def get_local_signatures(version_file: Path) -> dict[str, int]:
|
||||
return hashes
|
||||
|
||||
|
||||
def enqueue_mod(mod: str, appid: int) -> None:
|
||||
args = [
|
||||
"steam",
|
||||
f"steam://url/CommunityFilePage/{mod}+workshop_download_item",
|
||||
str(appid),
|
||||
mod,
|
||||
]
|
||||
subprocess.Popen(["/usr/bin/env", "bash", *args])
|
||||
def enqueue_mod(client: str, mod: str, appid: int) -> None:
|
||||
client_args = concat_bash_args(client)
|
||||
subprocess.Popen([*client_args, "+workshop_download_item", str(appid), mod])
|
||||
|
||||
|
||||
def get_needs_update(
|
||||
@@ -146,7 +141,7 @@ def connect(client: str, addr: str, appid: int, name: str, mods: list[str]) -> i
|
||||
return proc.returncode
|
||||
|
||||
|
||||
def load_to_menu(client: str, addr: str, appid: int, name: str, mods: list[str]) -> int:
|
||||
def load_to_menu(client: str, appid: int, name: str, mods: list[str]) -> int:
|
||||
"""Loads to the menu screen with the selected mods; used for AFK/pre-joining"""
|
||||
concat = concat_mods(mods)
|
||||
client_args = concat_bash_args(client)
|
||||
|
||||
@@ -79,4 +79,4 @@ LOG_FILTERS = ("CRITICAL", "WARNING", "INFO", "DEBUG")
|
||||
|
||||
TMP_PATH = "/tmp"
|
||||
TMP_TARBALL = "/tmp/dzgui.tar.gz"
|
||||
TMP_EXE = "/tmp/dzgui"
|
||||
TMP_EXE = "/tmp/dzgui/dzgui"
|
||||
@@ -88,6 +88,7 @@ class ConnectionManager:
|
||||
self.record: Record
|
||||
self.workshop: Path
|
||||
|
||||
self.client: str
|
||||
self.remote_mod_ids: list[str] = []
|
||||
self.missing_mods: list[tuple[str, str, int, int]] = []
|
||||
|
||||
@@ -171,6 +172,7 @@ class ConnectionManager:
|
||||
client = self.controller.query_config(Preferences.CLIENT)
|
||||
running = is_steam_running(client)
|
||||
steam_proc = SteamProcess(client_name, running)
|
||||
self.client = client
|
||||
|
||||
game_mode = prefs.is_game_mode
|
||||
|
||||
@@ -238,8 +240,7 @@ class ConnectionManager:
|
||||
def query_modlist_and_present(self, record: Servers.Record) -> None:
|
||||
try:
|
||||
mods = self._query_modlist(record)
|
||||
except Exception as e:
|
||||
print(f"{type(e).__name__}: {e}")
|
||||
except Exception:
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._server_timeout), destroy_first=True
|
||||
)
|
||||
@@ -264,11 +265,10 @@ class ConnectionManager:
|
||||
def _connect_steam(self, menu_only: bool) -> None:
|
||||
addr = f"{self.record.ip}:{self.record.gameport}"
|
||||
playername = self.controller.query_config(Preferences.NAME)
|
||||
client = self.controller.query_config(Preferences.CLIENT)
|
||||
if menu_only:
|
||||
rc = load_to_menu(client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
rc = load_to_menu(self.client, self.appid, playername, self.remote_mod_ids)
|
||||
else:
|
||||
rc = connect(client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
rc = connect(self.client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
if rc != 0:
|
||||
# TODO: log/pop the error
|
||||
func = StoredFunc(self.controller.update_status)
|
||||
@@ -299,7 +299,8 @@ class ConnectionManager:
|
||||
for title, mod, stamp, size in self.missing_mods:
|
||||
if self.controller.is_cancel_pending():
|
||||
return
|
||||
enqueue_mod(mod, self.appid)
|
||||
enqueue_mod(self.client, mod, self.appid)
|
||||
# NOTE: prevents rate limiting
|
||||
time.sleep(3)
|
||||
|
||||
if raise_window is True:
|
||||
|
||||
@@ -42,7 +42,7 @@ class UpdateManager:
|
||||
with tarfile.open(TMP_TARBALL) as tar:
|
||||
tar.extractall(TMP_PATH)
|
||||
|
||||
shutil.move(TMP_EXE, exe_path)
|
||||
shutil.copy(TMP_EXE, exe_path)
|
||||
|
||||
proc = subprocess.run([exe_path, "self", "restore"])
|
||||
if proc.returncode == 0:
|
||||
@@ -53,7 +53,7 @@ class UpdateManager:
|
||||
func = StoredFunc(self._on_update_failure, msg)
|
||||
self.thread_man.set_cleanup_func(func, destroy_first=True)
|
||||
except Exception as e:
|
||||
func = StoredFunc(self._on_update_failure, e)
|
||||
func = StoredFunc(self._on_update_failure, str(e))
|
||||
self.thread_man.set_cleanup_func(func, destroy_first=True)
|
||||
logger.warning(e)
|
||||
|
||||
|
||||
@@ -83,3 +83,7 @@ def format_player_count(model: Gtk.TreeModel | None, control: list) -> str:
|
||||
|
||||
def embolden(text: str) -> str:
|
||||
return f"<b>{text}</b>"
|
||||
|
||||
|
||||
def format_exception(e: Exception) -> str:
|
||||
return f"{type(e).__name__}: {e}"
|
||||
@@ -181,7 +181,7 @@ filter_lowpop = "Low pop"
|
||||
filter_nonascii = "Non-ASCII"
|
||||
filter_duplicate = "Duplicate"
|
||||
filter_official = "Official"
|
||||
filter_unofficial = "Unoffic."
|
||||
filter_unofficial = "Unofficial"
|
||||
filter_modded = "Modded"
|
||||
|
||||
# maps
|
||||
|
||||
@@ -11,6 +11,7 @@ from dzgui.const.constants import (
|
||||
)
|
||||
from dzgui.const.enum import FilterMode
|
||||
from dzgui.model.servers import ServerModelManager
|
||||
from dzgui.util.format import format_exception
|
||||
from dzgui.util.strings import all_maps
|
||||
from dzgui.views.components.maps_combo import MapsCombo
|
||||
from dzgui.views.components.labels import BoldLabel
|
||||
@@ -333,6 +334,10 @@ class FilterPanel(Gtk.Box):
|
||||
self.emitter.emit("map_selection_changed", name)
|
||||
|
||||
def set_filters(self, filters: dict[str, bool]) -> None:
|
||||
for check in self.button_grid.checks:
|
||||
label = check.get_label()
|
||||
check.set_active(filters[label])
|
||||
try:
|
||||
for check in self.button_grid.checks:
|
||||
label = check.get_label()
|
||||
check.set_active(filters[label])
|
||||
except Exception as e:
|
||||
msg = format_exception(e)
|
||||
logger.warning(msg)
|
||||
@@ -1,5 +1,4 @@
|
||||
from typing import Self, Union, TYPE_CHECKING
|
||||
from warnings import deprecated
|
||||
|
||||
from dzgui.const.enum import NotebookPage, ServerTab
|
||||
from dzgui.util.strings import esc_to_return, question_to_return
|
||||
@@ -8,7 +7,7 @@ from dzgui.views.components.buttons import LoggerAlertsButton
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GObject # noqa E402
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.const.enum import ServerTab
|
||||
@@ -26,6 +25,8 @@ class Statusbar(Gtk.Grid):
|
||||
self.controller.register_widget("statusbar", self)
|
||||
self.emitter = controller.get_emitter()
|
||||
|
||||
self.prior_enum: NotebookPage
|
||||
self.prior_status: str
|
||||
self.playercount = ""
|
||||
self.statusbar = Gtk.Statusbar()
|
||||
|
||||
@@ -34,14 +35,6 @@ class Statusbar(Gtk.Grid):
|
||||
self.attach(self.statusbar, 0, 0, 3, 1)
|
||||
self.attach_next_to(self.spinner, self.statusbar, Gtk.PositionType.RIGHT, 3, 1)
|
||||
|
||||
# TODO: pack version event box in right panel into hbox with update button
|
||||
# TODO: spawns a modal or just jumps right to install page
|
||||
# from dzgui.views.components.buttons import IconTextButton
|
||||
# b = IconTextButton("dialog-information-symbolic", label="Updates available")
|
||||
# b.set_halign(Gtk.Align.END)
|
||||
# b.set_hexpand(True)
|
||||
# self.attach_next_to(b, self.spinner, Gtk.PositionType.RIGHT, 3, 1)
|
||||
|
||||
self.players = ""
|
||||
|
||||
controller.get_menu().connect("generic_treesel_changed", self._help_row_changed)
|
||||
@@ -79,6 +72,7 @@ class Statusbar(Gtk.Grid):
|
||||
NotebookPage.LOG,
|
||||
NotebookPage.CONNECTION,
|
||||
):
|
||||
self.prior_enum = enum
|
||||
self.set_by_context(enum, esc_to_return)
|
||||
return
|
||||
|
||||
@@ -88,16 +82,11 @@ class Statusbar(Gtk.Grid):
|
||||
case NotebookPage.KEYS:
|
||||
bar = question_to_return
|
||||
case _:
|
||||
return
|
||||
bar = self.prior_status
|
||||
|
||||
self.prior_enum = enum
|
||||
self.set_by_context(enum, bar)
|
||||
|
||||
# TODO: unused
|
||||
def _on_notebook_page_returned(
|
||||
self, statusbar: Self, prior_context: NotebookPage
|
||||
) -> None:
|
||||
self.pop(prior_context)
|
||||
|
||||
def _on_server_row_changed(self, statusbar: Self) -> None:
|
||||
self.spinner.start()
|
||||
|
||||
@@ -111,6 +100,10 @@ class Statusbar(Gtk.Grid):
|
||||
context: Union["ServerTab", NotebookPage],
|
||||
) -> None:
|
||||
self.spinner.stop()
|
||||
|
||||
if type(context) is NotebookPage:
|
||||
self.prior_enum = context
|
||||
self.prior_status = ""
|
||||
# FIXME: CalcDist is being called when table is not loaded
|
||||
if dist is None:
|
||||
return
|
||||
@@ -132,15 +125,11 @@ class Statusbar(Gtk.Grid):
|
||||
cid = self.statusbar.get_context_id(str(context))
|
||||
self.statusbar.pop(cid)
|
||||
|
||||
@deprecated("currently unused")
|
||||
# def get_text(self) -> str:
|
||||
# area = self.statusbar.get_message_area()
|
||||
# label = area.get_children()[0]
|
||||
# return str(label.get_text())
|
||||
|
||||
def set_by_context(
|
||||
self, context: Union[NotebookPage, "ServerTab"], string: str
|
||||
) -> None:
|
||||
if context != NotebookPage.KEYS:
|
||||
self.prior_status = string
|
||||
meta = self.statusbar.get_context_id(str(context))
|
||||
self.statusbar.push(meta, string)
|
||||
self.set_cache(string)
|
||||
|
||||
@@ -14,6 +14,7 @@ from dzgui.init.update import check_updates
|
||||
from dzgui.const.constants import EXPAND, FILL
|
||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||
from dzgui.strings import preboot
|
||||
from dzgui.util.format import format_exception
|
||||
from dzgui.util.strings import dialog_header
|
||||
from dzgui.util.symlink import rebuild_symlinks
|
||||
from dzgui.views.components.buttons import ClipboardButton
|
||||
@@ -175,8 +176,7 @@ class BootDialog(Gtk.Dialog):
|
||||
self.thread_man.set_cleanup_func(callback)
|
||||
except Exception as e:
|
||||
self.failed = True
|
||||
# TODO: generic exception wrapper
|
||||
self.exception = f"{type(e).__name__}: {e}"
|
||||
self.exception = format_exception(e)
|
||||
callback = StoredFunc(self.update_status, Success.FAIL)
|
||||
self.thread_man.set_cleanup_func(callback)
|
||||
|
||||
|
||||
@@ -327,10 +327,7 @@ class PreConnectionAssistant(Gtk.Box):
|
||||
self.connect_last.hide()
|
||||
|
||||
self._process_warnings(prereqs)
|
||||
if self.tree.is_visible():
|
||||
self.tree.grab_focus()
|
||||
else:
|
||||
self.grab_focus()
|
||||
self.tree.grab_focus()
|
||||
|
||||
def mark_finished(self) -> None:
|
||||
self.mod_count.set_label(preconnect.all_updated)
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Any, Optional, TYPE_CHECKING
|
||||
from warnings import deprecated
|
||||
|
||||
from dzgui.const.constants import APP_NAME, SEPARATOR
|
||||
from dzgui.util.keys import is_navkey
|
||||
from dzgui.util.keys import is_ctrl_mask, is_navkey
|
||||
from dzgui.views.mixins.cursor_mixin import CursorMixin
|
||||
|
||||
import gi
|
||||
@@ -85,10 +85,17 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
|
||||
model, rows = sel.get_selected_rows()
|
||||
return [model[row] for row in rows]
|
||||
|
||||
def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> None:
|
||||
def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> bool:
|
||||
from dzgui.views.trees.tree_servers import ServerTreeView
|
||||
|
||||
# NOTE: suppress popup search and delegate binding to server view (cf. request_keyword_focus)
|
||||
if not isinstance(treeview, ServerTreeView):
|
||||
if is_ctrl_mask(event) and event.keyval == Gdk.KEY_f:
|
||||
return True
|
||||
|
||||
if is_navkey(event.keyval):
|
||||
if self.get_model() is None:
|
||||
return
|
||||
return True
|
||||
if self.sel_blocked is False:
|
||||
self.sel_blocked = True
|
||||
self.controller.suppress_signal(
|
||||
@@ -98,7 +105,7 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
|
||||
True,
|
||||
)
|
||||
self._vim_nav(event)
|
||||
return
|
||||
return False
|
||||
|
||||
def _on_key_release(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> None:
|
||||
"""
|
||||
|
||||
@@ -30,8 +30,6 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView): # type: ignore
|
||||
emitter.connect("mods_highlighted", self._on_mods_highlighted)
|
||||
|
||||
self.set_fixed_height_mode(True)
|
||||
self.set_headers_visible(True)
|
||||
|
||||
self.set_model(None)
|
||||
|
||||
for i, column_title in enumerate(strings.mod_cols):
|
||||
@@ -64,6 +62,7 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView): # type: ignore
|
||||
def _on_mods_updated(self, emitter: "Emitter", msg: str, mods: int) -> None:
|
||||
if mods < 1:
|
||||
return
|
||||
self.set_headers_visible(True)
|
||||
path = Gtk.TreePath.new_from_indices([0])
|
||||
self.set_cursor(path)
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
|
||||
authors = [
|
||||
{name = "aclist"}
|
||||
]
|
||||
version = "7.0.0b9"
|
||||
version = "7.0.0b11"
|
||||
license = "GPL-3.0-or-later"
|
||||
license-files = ["LICENSE"]
|
||||
readme = "README.md"
|
||||
|
||||
Reference in new issue
Block a user