mirror of
https://github.com/aclist/dztui.git
synced 2026-10-29 14:12:45 +01:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4eec00e8e7 | ||
|
|
09ef3e446a | ||
|
|
ebffbe39f2 | ||
|
|
191776ce74 | ||
|
|
7ae34747e9 | ||
|
|
1555ba2d64 | ||
|
|
4bac804fd7 | ||
|
|
748e1870da | ||
|
|
cd4c6fdfb2 | ||
|
|
b3b05918b7 | ||
|
|
e6e0a3036d | ||
|
|
8c44a6e255 | ||
|
|
7fc1264b65 | ||
|
|
f748b09ba7 |
No files matched your search
+4
-4
@@ -11,7 +11,7 @@ from typing import Any, Union
|
|||||||
from warnings import deprecated
|
from warnings import deprecated
|
||||||
|
|
||||||
from dzgui.api.acf import ACF
|
from dzgui.api.acf import ACF
|
||||||
from dzgui.init.prereqs import has_steam_client
|
from dzgui.init.prereqs import has_any_client
|
||||||
from dzgui.const.constants import (
|
from dzgui.const.constants import (
|
||||||
APPID_DAYZ,
|
APPID_DAYZ,
|
||||||
APPID_DAYZ_EXP,
|
APPID_DAYZ_EXP,
|
||||||
@@ -59,7 +59,7 @@ class VDFLoadError(Exception):
|
|||||||
|
|
||||||
def get_steam_paths() -> list[tuple[Path, str]]:
|
def get_steam_paths() -> list[tuple[Path, str]]:
|
||||||
paths = []
|
paths = []
|
||||||
if has_steam_client():
|
if has_any_client():
|
||||||
HOME = Path.home()
|
HOME = Path.home()
|
||||||
env = os.environ.get("XDG_DATA_HOME")
|
env = os.environ.get("XDG_DATA_HOME")
|
||||||
if env is not None:
|
if env is not None:
|
||||||
@@ -265,12 +265,12 @@ def find_user_id_32(path: Path) -> int:
|
|||||||
|
|
||||||
|
|
||||||
class SteamAPIKeyError(Exception):
|
class SteamAPIKeyError(Exception):
|
||||||
def __init__(self, msg=None):
|
def __init__(self, msg: str | None = None) -> None:
|
||||||
super().__init__(msg or api_validation_error)
|
super().__init__(msg or api_validation_error)
|
||||||
|
|
||||||
|
|
||||||
class SteamWorkshopEndpointError(Exception):
|
class SteamWorkshopEndpointError(Exception):
|
||||||
def __init__(self, msg=None):
|
def __init__(self, msg: str | None = None) -> None:
|
||||||
super().__init__(msg or workshop_endpoint_error)
|
super().__init__(msg or workshop_endpoint_error)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ from dzgui.init.migrate import (
|
|||||||
migrate_cols_file,
|
migrate_cols_file,
|
||||||
)
|
)
|
||||||
from dzgui.init.flock import lock_acquire
|
from dzgui.init.flock import lock_acquire
|
||||||
from dzgui.init.prereqs import has_steam_client
|
from dzgui.init.prereqs import has_any_client
|
||||||
from dzgui.strings import boot
|
from dzgui.strings import boot
|
||||||
|
|
||||||
from dzgui.util.deck import is_steam_deck, is_game_mode
|
from dzgui.util.deck import is_steam_deck, is_game_mode
|
||||||
@@ -136,7 +136,7 @@ def load_gui(version: str, is_debug: bool) -> None:
|
|||||||
# TODO: sudo escalation dialog
|
# TODO: sudo escalation dialog
|
||||||
# count = get_map_count()
|
# count = get_map_count()
|
||||||
# TODO: move into module
|
# TODO: move into module
|
||||||
if has_steam_client() is False:
|
if has_any_client() is False:
|
||||||
EarlyAlertDialog(init.requires_steam)
|
EarlyAlertDialog(init.requires_steam)
|
||||||
|
|
||||||
bootwin = BootWindow(XDG, version)
|
bootwin = BootWindow(XDG, version)
|
||||||
|
|||||||
@@ -541,8 +541,8 @@ class Controller(GObject.GObject):
|
|||||||
def update_status(self) -> None:
|
def update_status(self) -> None:
|
||||||
self.mediator.preconnect.mark_finished()
|
self.mediator.preconnect.mark_finished()
|
||||||
|
|
||||||
def get_steam_client_name(self) -> str:
|
def get_steam_client_name(self, cmd: str) -> str:
|
||||||
return self.mediator.options.get_client_name()
|
return self.mediator.options.get_client_name(cmd)
|
||||||
|
|
||||||
def present_window(self) -> None:
|
def present_window(self) -> None:
|
||||||
self.mediator.window.present_with_time(Gdk.CURRENT_TIME)
|
self.mediator.window.present_with_time(Gdk.CURRENT_TIME)
|
||||||
|
|||||||
+20
-7
@@ -7,19 +7,32 @@ from dzgui.const.constants import APP_NAME, FLATPAK_APPID, FLATPAK_CMD, STEAM_CM
|
|||||||
logger = logging.getLogger(APP_NAME)
|
logger = logging.getLogger(APP_NAME)
|
||||||
|
|
||||||
|
|
||||||
def has_steam_client() -> bool:
|
def has_flatpak_client() -> bool:
|
||||||
if shutil.which(STEAM_CMD):
|
|
||||||
return True
|
|
||||||
if not shutil.which(FLATPAK_CMD):
|
|
||||||
return False
|
|
||||||
try:
|
try:
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
[FLATPAK_CMD, "list"], capture_output=True, text=True, check=True
|
[FLATPAK_CMD, "list", "--columns=application"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
)
|
)
|
||||||
if FLATPAK_APPID in res.stdout:
|
if FLATPAK_APPID in res.stdout:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
except subprocess.CalledProcessError as e:
|
except Exception as e:
|
||||||
logger.critical(e)
|
logger.critical(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def has_steam_client() -> bool:
|
||||||
|
if shutil.which(STEAM_CMD):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def has_any_client() -> bool:
|
||||||
|
if shutil.which(STEAM_CMD):
|
||||||
|
return True
|
||||||
|
if not shutil.which(FLATPAK_CMD):
|
||||||
|
return False
|
||||||
|
return has_flatpak_client()
|
||||||
+9
-4
@@ -16,12 +16,15 @@ logger = logging.getLogger(APP_NAME)
|
|||||||
|
|
||||||
|
|
||||||
def is_steam_running(cmd: str) -> bool:
|
def is_steam_running(cmd: str) -> bool:
|
||||||
if cmd == STEAM_CMD:
|
is_flatpak_running = is_flatpak_steam_running()
|
||||||
|
if cmd in (FLATPAK_RUN_CMD, FLATPAK_SANDBOX):
|
||||||
|
return is_flatpak_running
|
||||||
|
elif cmd == STEAM_CMD:
|
||||||
|
if is_flatpak_running:
|
||||||
|
return False
|
||||||
if has_cmd(STEAM_CMD) is False:
|
if has_cmd(STEAM_CMD) is False:
|
||||||
return False
|
return False
|
||||||
return is_running(STEAM_CMD)
|
return is_running(STEAM_CMD)
|
||||||
elif cmd == FLATPAK_RUN_CMD or FLATPAK_SANDBOX:
|
|
||||||
return is_flatpak_steam_running()
|
|
||||||
else:
|
else:
|
||||||
raise TypeError("Not a valid Steam client selection")
|
raise TypeError("Not a valid Steam client selection")
|
||||||
|
|
||||||
@@ -31,7 +34,9 @@ def is_steam_running(cmd: str) -> bool:
|
|||||||
def is_flatpak_steam_running() -> bool:
|
def is_flatpak_steam_running() -> bool:
|
||||||
if has_cmd(FLATPAK_CMD) is False:
|
if has_cmd(FLATPAK_CMD) is False:
|
||||||
return False
|
return False
|
||||||
proc = subprocess.check_output([FLATPAK_CMD, "ps"], text=True)
|
proc = subprocess.check_output(
|
||||||
|
[FLATPAK_CMD, "ps", "--columns=application"], text=True
|
||||||
|
)
|
||||||
lines = proc.splitlines()
|
lines = proc.splitlines()
|
||||||
if FLATPAK_APPID in lines:
|
if FLATPAK_APPID in lines:
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ class ConnectionManager:
|
|||||||
else:
|
else:
|
||||||
allows_downloads = (True, "")
|
allows_downloads = (True, "")
|
||||||
|
|
||||||
client_name = self.controller.get_steam_client_name()
|
|
||||||
client = self.controller.query_config(Preferences.CLIENT)
|
client = self.controller.query_config(Preferences.CLIENT)
|
||||||
|
client_name = self.controller.get_steam_client_name(client)
|
||||||
running = is_steam_running(client)
|
running = is_steam_running(client)
|
||||||
steam_proc = SteamProcess(client_name, running)
|
steam_proc = SteamProcess(client_name, running)
|
||||||
self.client = client
|
self.client = client
|
||||||
|
|||||||
+1
-8
@@ -1,6 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
import signal
|
import signal
|
||||||
import warnings
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Literal, Self
|
from typing import TYPE_CHECKING, Literal, Self
|
||||||
|
|
||||||
@@ -47,10 +46,6 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
logger = logging.getLogger(APP_NAME)
|
logger = logging.getLogger(APP_NAME)
|
||||||
|
|
||||||
# TODO: drop
|
|
||||||
# https://bugzilla.gnome.org/show_bug.cgi?id=708676
|
|
||||||
warnings.filterwarnings("ignore", ".*g_value_get_int", Warning)
|
|
||||||
|
|
||||||
|
|
||||||
class OuterWindow(Gtk.ApplicationWindow):
|
class OuterWindow(Gtk.ApplicationWindow):
|
||||||
def __init__(self, app: Gtk.Application) -> None:
|
def __init__(self, app: Gtk.Application) -> None:
|
||||||
@@ -344,8 +339,6 @@ try:
|
|||||||
theme = Gtk.IconTheme.get_default()
|
theme = Gtk.IconTheme.get_default()
|
||||||
icons = theme.list_icons(None)
|
icons = theme.list_icons(None)
|
||||||
if STEAM_ICON not in icons:
|
if STEAM_ICON not in icons:
|
||||||
logger.warn(strings.steam_icon_missing)
|
logger.warning(strings.steam_icon_missing)
|
||||||
warnings.warn(strings.steam_icon_missing, stacklevel=2)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(e)
|
logger.warning(e)
|
||||||
warnings.warn(strings.gtk_theme_missing, stacklevel=2)
|
|
||||||
@@ -3,6 +3,8 @@ from dzgui.strings import options
|
|||||||
from dzgui.views.components.box import HBox
|
from dzgui.views.components.box import HBox
|
||||||
from dzgui.views.components.buttons import Icon
|
from dzgui.views.components.buttons import Icon
|
||||||
|
|
||||||
|
from typing import Self
|
||||||
|
from dzgui.init.prereqs import has_steam_client, has_flatpak_client
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
@@ -14,29 +16,55 @@ class ClientCombo(Gtk.ComboBox):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.client_store = Gtk.ListStore(str, str)
|
has_steam = has_steam_client()
|
||||||
clients = (
|
has_flatpak = has_flatpak_client()
|
||||||
|
self.client_store = Gtk.ListStore(str, str, bool)
|
||||||
|
self.clients = (
|
||||||
(
|
(
|
||||||
options.steam_combo,
|
options.steam_combo,
|
||||||
STEAM_CMD,
|
STEAM_CMD,
|
||||||
|
has_steam,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
options.flatpak_combo,
|
options.flatpak_combo,
|
||||||
FLATPAK_RUN_CMD,
|
FLATPAK_RUN_CMD,
|
||||||
|
has_flatpak,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
options.flatpak_container_combo,
|
options.flatpak_container_combo,
|
||||||
FLATPAK_SANDBOX,
|
FLATPAK_SANDBOX,
|
||||||
|
has_flatpak,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
for client in clients:
|
for client in self.clients:
|
||||||
self.client_store.append(client)
|
self.client_store.append(client)
|
||||||
|
|
||||||
self.set_model(self.client_store)
|
self.set_model(self.client_store)
|
||||||
renderer_text = Gtk.CellRendererText()
|
renderer_text = Gtk.CellRendererText()
|
||||||
self.pack_start(renderer_text, True)
|
self.pack_start(renderer_text, True)
|
||||||
self.add_attribute(renderer_text, "text", 0)
|
self.add_attribute(renderer_text, "text", 0)
|
||||||
self.set_active(0)
|
self.set_active(0)
|
||||||
|
|
||||||
|
self.set_cell_data_func(self.get_cells()[0], self.data_func)
|
||||||
|
|
||||||
|
def data_func(
|
||||||
|
self,
|
||||||
|
combo: Self,
|
||||||
|
cell: Gtk.CellRendererText,
|
||||||
|
model: Gtk.ListStore,
|
||||||
|
_iter: Gtk.TreeIter,
|
||||||
|
) -> None:
|
||||||
|
sens = model[_iter][2]
|
||||||
|
cell.set_property("sensitive", sens)
|
||||||
|
|
||||||
|
def get_client_human_readable(self, cmd: str) -> str:
|
||||||
|
for client in self.clients:
|
||||||
|
human, command, sens = client
|
||||||
|
if command == cmd:
|
||||||
|
return human
|
||||||
|
raise TypeError("Not a valid Steam client selection")
|
||||||
|
|
||||||
|
|
||||||
class ErrorPopover(Gtk.Popover):
|
class ErrorPopover(Gtk.Popover):
|
||||||
def __init__(self, relative_to: Gtk.Widget, position: Gtk.PositionType) -> None:
|
def __init__(self, relative_to: Gtk.Widget, position: Gtk.PositionType) -> None:
|
||||||
super().__init__(relative_to=relative_to, position=position)
|
super().__init__(relative_to=relative_to, position=position)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class SubmitField(Gtk.Box):
|
|||||||
self.button = Gtk.Button(label=options.save_button)
|
self.button = Gtk.Button(label=options.save_button)
|
||||||
|
|
||||||
self.button.connect("clicked", self._on_save_clicked)
|
self.button.connect("clicked", self._on_save_clicked)
|
||||||
self.entry.connect("insert-text", self._on_text_typed)
|
self.entry.connect("changed", self._on_text_typed)
|
||||||
self.entry.connect("activate", self._on_field_activated)
|
self.entry.connect("activate", self._on_field_activated)
|
||||||
self.entry.get_property("buffer").connect("deleted-text", self._on_text_deleted)
|
self.entry.get_property("buffer").connect("deleted-text", self._on_text_deleted)
|
||||||
|
|
||||||
@@ -113,13 +113,9 @@ class SubmitField(Gtk.Box):
|
|||||||
def _on_text_typed(
|
def _on_text_typed(
|
||||||
self,
|
self,
|
||||||
entry: Gtk.Entry,
|
entry: Gtk.Entry,
|
||||||
text: str,
|
|
||||||
length: int,
|
|
||||||
pos: int,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
buffer = entry.get_property("buffer")
|
text = entry.get_text()
|
||||||
text = buffer.get_text() + text
|
|
||||||
state = self._is_valid_text(text)
|
state = self._is_valid_text(text)
|
||||||
self.button.set_sensitive(state)
|
self.button.set_sensitive(state)
|
||||||
|
|
||||||
@@ -371,10 +367,8 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
|||||||
|
|
||||||
self.connect("key-press-event", self._on_keypress)
|
self.connect("key-press-event", self._on_keypress)
|
||||||
|
|
||||||
def get_client_name(self) -> str:
|
def get_client_name(self, cmd: str) -> str:
|
||||||
model = self.client_combo.get_model()
|
return self.client_combo.get_client_human_readable(cmd)
|
||||||
ind = self.client_combo.get_active()
|
|
||||||
return str(model[ind][0])
|
|
||||||
|
|
||||||
def block_text_entry(self) -> None:
|
def block_text_entry(self) -> None:
|
||||||
self.steam_box.block_text_entry()
|
self.steam_box.block_text_entry()
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
|
|||||||
authors = [
|
authors = [
|
||||||
{name = "aclist"}
|
{name = "aclist"}
|
||||||
]
|
]
|
||||||
version = "7.0.0b25"
|
version = "7.0.0b26"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
license-files = ["LICENSE"]
|
license-files = ["LICENSE"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from dzgui.const.constants import (
|
||||||
|
FLATPAK_APPID,
|
||||||
|
FLATPAK_RUN_CMD,
|
||||||
|
FLATPAK_SANDBOX,
|
||||||
|
STEAM_CMD,
|
||||||
|
)
|
||||||
|
from dzgui.init import proc
|
||||||
|
|
||||||
|
|
||||||
|
class TestSteamDetection(unittest.TestCase):
|
||||||
|
def test_flatpak_detection_with_multiple_running_apps(self):
|
||||||
|
def flatpak_output(args, *, text):
|
||||||
|
# Default `flatpak ps` includes instance, PID, app and runtime columns.
|
||||||
|
if args == ["flatpak", "ps", "--columns=application"]:
|
||||||
|
return f"com.spotify.Client\n{FLATPAK_APPID}\n{FLATPAK_APPID}\n"
|
||||||
|
return f"3904921611\t1257689\t{FLATPAK_APPID}\torg.freedesktop.Platform\n"
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch.object(proc, "has_cmd", return_value=True),
|
||||||
|
patch.object(proc.subprocess, "check_output", side_effect=flatpak_output),
|
||||||
|
):
|
||||||
|
for client in (FLATPAK_RUN_CMD, FLATPAK_SANDBOX):
|
||||||
|
with self.subTest(client=client):
|
||||||
|
self.assertTrue(proc.is_steam_running(client))
|
||||||
|
|
||||||
|
def test_flatpak_not_running(self):
|
||||||
|
with patch.object(proc, "has_cmd", return_value=True):
|
||||||
|
for output in ("", "com.spotify.Client\n", f"{FLATPAK_APPID}Helper\n"):
|
||||||
|
with (
|
||||||
|
self.subTest(output=output),
|
||||||
|
patch.object(proc.subprocess, "check_output", return_value=output),
|
||||||
|
):
|
||||||
|
self.assertFalse(proc.is_flatpak_steam_running())
|
||||||
|
|
||||||
|
def test_flatpak_not_installed(self):
|
||||||
|
with (
|
||||||
|
patch.object(proc, "has_cmd", return_value=False),
|
||||||
|
patch.object(proc.subprocess, "check_output") as check_output,
|
||||||
|
):
|
||||||
|
self.assertFalse(proc.is_flatpak_steam_running())
|
||||||
|
check_output.assert_not_called()
|
||||||
|
|
||||||
|
def test_native_steam(self):
|
||||||
|
with patch.object(proc, "has_cmd", return_value=True):
|
||||||
|
for running in (True, False):
|
||||||
|
with (
|
||||||
|
self.subTest(running=running),
|
||||||
|
patch.object(proc, "is_running", return_value=running),
|
||||||
|
):
|
||||||
|
self.assertEqual(proc.is_steam_running(STEAM_CMD), running)
|
||||||
|
|
||||||
|
def test_native_steam_while_flatpak_is_running(self):
|
||||||
|
with patch.object(proc, "is_flatpak_steam_running", return_value=True):
|
||||||
|
self.assertEqual(proc.is_steam_running(STEAM_CMD), False)
|
||||||
|
|
||||||
|
def test_invalid_client(self):
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
proc.is_steam_running("invalid-client")
|
||||||
@@ -14,7 +14,11 @@ from dzgui.views.dialogs.calc import (
|
|||||||
|
|
||||||
|
|
||||||
class DummyEmitter:
|
class DummyEmitter:
|
||||||
pass
|
def __init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def connect(self, _, __) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)])
|
@pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)])
|
||||||
|
|||||||
Reference in new issue
Block a user