mirror of
https://github.com/aclist/dztui.git
synced 2026-10-28 13:42:42 +01:00
feat: validate atomic mods
This commit is contained in:
1 parent
46117ecdda
commit
a4ac357c8f
9 files changed
+68
-8
No files matched your search
+10
-3
@@ -12,6 +12,7 @@ from typing import Any, Generator, Union
|
||||
from warnings import deprecated
|
||||
|
||||
from dzgui.api.acf import ACF
|
||||
from dzgui.const.endpoints import VALIDATE
|
||||
from dzgui.init.prereqs import has_any_client
|
||||
from dzgui.init.prereqs import has_flatpak_client, has_steam_client
|
||||
from dzgui.const.constants import (
|
||||
@@ -316,10 +317,9 @@ def unsubscribe(key: str, mod: int) -> None:
|
||||
update_workshop(key, mod, UNSUB_ENDPOINT)
|
||||
|
||||
|
||||
@deprecated("Use subscribe()")
|
||||
def enqueue_mod(client: str, mod: str, appid: int) -> None:
|
||||
def validate_mod(client: str, mod: str) -> None:
|
||||
client_args = concat_bash_args(client)
|
||||
subprocess.Popen([*client_args, "+workshop_download_item", str(appid), mod])
|
||||
subprocess.Popen([*client_args, "+workshop_download_item", str(APPID_DAYZ), mod])
|
||||
|
||||
|
||||
@deprecated("Cf. https://github.com/ValveSoftware/steam-for-linux/issues/9672")
|
||||
@@ -500,3 +500,10 @@ def get_app_name(appid: int) -> str | None:
|
||||
except Exception as e:
|
||||
logger.debug(e)
|
||||
return None
|
||||
|
||||
|
||||
@deprecated("Currently unused")
|
||||
def validate_dayz(client: str) -> None:
|
||||
client_args = concat_bash_args(client)
|
||||
uri = VALIDATE + str(APPID_DAYZ)
|
||||
subprocess.Popen([*client_args, uri])
|
||||
@@ -18,6 +18,7 @@ COORDS_API = "http://ip-api.com/json"
|
||||
# steam URIs
|
||||
WORKSHOP = "steam://url/CommunityFilePage/"
|
||||
OPEN_URL = "steam://openurl/"
|
||||
VALIDATE = "steam://validate/"
|
||||
|
||||
# user facing
|
||||
GITHUB_PAGES = "https://aclist.github.io/dzgui/index"
|
||||
|
||||
+6
-1
@@ -157,6 +157,7 @@ class ContextMenu(EnumWithAttrs):
|
||||
COPY_SERVER_IP = {"label": strings.copy_ip}
|
||||
COPY_SERVER_NAME = {"label": strings.copy_name}
|
||||
UNSUB_MOD = {"label": strings.unsub_mod}
|
||||
VALIDATE_MOD = {"label": strings.validate_mod}
|
||||
OPEN_WORKSHOP = {"label": strings.open_workshop}
|
||||
REFRESH_PLAYERS = {"label": strings.refresh_players}
|
||||
REMOVE_HISTORY = {"label": strings.remove_history}
|
||||
@@ -172,7 +173,7 @@ class ContextMenuGroup(Enum):
|
||||
"""
|
||||
|
||||
SERVER_MOD = (ContextMenu.OPEN_WORKSHOP,)
|
||||
MOD = (ContextMenu.OPEN_WORKSHOP, ContextMenu.UNSUB_MOD)
|
||||
MOD = (ContextMenu.OPEN_WORKSHOP, ContextMenu.UNSUB_MOD, ContextMenu.VALIDATE_MOD)
|
||||
MOD_OFFLINE = (None,)
|
||||
LOG = (ContextMenu.COPY_LOG_CLIPBOARD,)
|
||||
SERVER_BROWSER = (
|
||||
@@ -246,6 +247,10 @@ class ModButton(EnumWithAttrs):
|
||||
"label": strings.mod_panel.select_stale,
|
||||
"tooltip": strings.mod_panel.select_stale_tooltip,
|
||||
}
|
||||
VALIDATE = {
|
||||
"label": strings.mod_panel.validate,
|
||||
"tooltip": strings.mod_panel.validate_tooltip,
|
||||
}
|
||||
|
||||
|
||||
class ButtonType(EnumWithAttrs):
|
||||
|
||||
@@ -102,6 +102,16 @@ class Controller(GObject.GObject):
|
||||
except AttributeError:
|
||||
logger.critical(f"{attr} is not a valid AppNavigation attribute.")
|
||||
|
||||
def validate_mods(
|
||||
self, treeview: Union["ModTreeView", "OfflineModTreeView", None] = None
|
||||
) -> None:
|
||||
if treeview is None:
|
||||
view = self.mediator.modtreeview
|
||||
else:
|
||||
view = treeview
|
||||
mod_man = view.get_mod_man()
|
||||
mod_man.validate_mods()
|
||||
|
||||
def get_prefs(self) -> UserPrefs:
|
||||
return self.prefs
|
||||
|
||||
|
||||
@@ -75,10 +75,14 @@ class ContextMenuManager:
|
||||
|
||||
if isinstance(self.treeview, (ModTreeView, OfflineModTreeView)):
|
||||
match action:
|
||||
case ContextMenu.UNSUB_MOD:
|
||||
self.controller.unsub_mods(self.treeview)
|
||||
case ContextMenu.OPEN_WORKSHOP:
|
||||
self.open_mod_page()
|
||||
case ContextMenu.UNSUB_MOD:
|
||||
self.controller.unsub_mods(self.treeview)
|
||||
case ContextMenu.VALIDATE_MOD:
|
||||
self.controller.validate_mods(self.treeview)
|
||||
case _:
|
||||
pass
|
||||
|
||||
if isinstance(self.treeview, LogTreeView):
|
||||
match action:
|
||||
|
||||
+26
-2
@@ -4,7 +4,7 @@ import time
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.api.steam import unsubscribe
|
||||
from dzgui.api.steam import unsubscribe, validate_mod
|
||||
from dzgui.api.mods import (
|
||||
get_delimited_mods,
|
||||
find_stale_mods,
|
||||
@@ -85,7 +85,7 @@ class ModManager:
|
||||
total_mods = len(self.store)
|
||||
self.emitter.emit("mods_updated", msg, total_mods)
|
||||
|
||||
def unsub_mods(self) -> None:
|
||||
def get_selected_mods(self) -> list[tuple[str, Gtk.TreeIter]]:
|
||||
sel = self.treeview.get_selection()
|
||||
model, pathlist = sel.get_selected_rows()
|
||||
# NOTE: reverse when multiple selection
|
||||
@@ -96,6 +96,15 @@ class ModManager:
|
||||
continue
|
||||
mod, _iter = res
|
||||
mods.append((mod, _iter))
|
||||
return mods
|
||||
|
||||
def validate_mods(self) -> None:
|
||||
mods = self.get_selected_mods()
|
||||
self.thread_man.set_job_count(len(mods))
|
||||
self.validate_all_mods(mods)
|
||||
|
||||
def unsub_mods(self) -> None:
|
||||
mods = self.get_selected_mods()
|
||||
self.thread_man.set_job_count(len(mods))
|
||||
self.unsub_all_mods(mods)
|
||||
|
||||
@@ -109,6 +118,21 @@ class ModManager:
|
||||
mod = model.get_value(tree_iter, 2)
|
||||
return mod, tree_iter
|
||||
|
||||
def validate_atomic_mod(self, mod: str) -> None:
|
||||
# NOTE: propagation to dayz exp will happen during
|
||||
# subsequent symlink phase on connect
|
||||
client = self.controller.query_config(Preferences.CLIENT)
|
||||
validate_mod(client, mod)
|
||||
|
||||
@call_on_thread(dialogs.validating_mods)
|
||||
def validate_all_mods(self, mods: list[tuple[str, Gtk.TreeIter]]) -> None:
|
||||
for mod, _iter in mods:
|
||||
self.validate_atomic_mod(mod)
|
||||
self.thread_man.increment_dialog()
|
||||
time.sleep(API_RATE_LIMIT)
|
||||
func = StoredFunc(lambda: None)
|
||||
self.thread_man.set_cleanup_func(func)
|
||||
|
||||
@call_on_thread(dialogs.deleting_mods)
|
||||
def unsub_all_mods(self, mods: list[tuple[str, Gtk.TreeIter]]) -> None:
|
||||
for mod, _iter in mods:
|
||||
|
||||
@@ -9,6 +9,7 @@ update_success = "Updated successfully. Please exit and relaunch."
|
||||
load_error_lan = "Failed to find any servers on your network.\nCheck the server query port or your firewall settings."
|
||||
fetching_mods = "Fetching mod metadata"
|
||||
deleting_mods = "Unsubscribing mods"
|
||||
validating_mods = "Validating mods"
|
||||
scanning_mods = "Scanning mods"
|
||||
parsing_mods = "Parsing mods"
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ show_details = "Show server details"
|
||||
refresh_players = "Refresh player count"
|
||||
open_workshop = "Open in Steam Workshop"
|
||||
unsub_mod = "Unsubscribe mod"
|
||||
validate_mod = "Validate mod"
|
||||
copy_name = "Copy name to clipboard"
|
||||
copy_ip = "Copy IP to clipboard"
|
||||
copy_log = "Copy record(s) to clipboard"
|
||||
@@ -200,6 +201,8 @@ class ModPanelStrings:
|
||||
clear_highlights: str
|
||||
select_stale: str
|
||||
select_stale_tooltip: str
|
||||
validate: str
|
||||
validate_tooltip: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
@@ -319,6 +322,8 @@ mod_panel = ModPanelStrings(
|
||||
clear_highlights="Clears highlights and reverts the table to a default state",
|
||||
select_stale="Select stale",
|
||||
select_stale_tooltip="Only selects highlighted stale mods",
|
||||
validate="Validate selected",
|
||||
validate_tooltip="Validates selected mods and updates them if necessary",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class ModSelectionPanel(Gtk.Box):
|
||||
ModButton.SELECT_ALL,
|
||||
ModButton.UNSELECT_ALL,
|
||||
ModButton.UNSUB_SELECTED,
|
||||
ModButton.VALIDATE,
|
||||
)
|
||||
for button in buttons:
|
||||
b = EnumeratedModButton(button)
|
||||
@@ -114,3 +115,5 @@ class ModSelectionPanel(Gtk.Box):
|
||||
self.swap_sensitive(False)
|
||||
case ModButton.SELECT_STALE:
|
||||
self.controller.select_colorized()
|
||||
case ModButton.VALIDATE:
|
||||
self.controller.validate_mods()
|
||||
Reference in new issue
Block a user