From e3c1ef59ee2d1dcdf180ed8d456c7f660c49ed21 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Sun, 1 Nov 2026 23:42:06 +0900 Subject: [PATCH] feat: get last updated timestamp --- dzgui/api/acf.py | 23 +++++++++++++++++++++++ dzgui/api/steam.py | 11 +++++++++++ dzgui/lib/dayzquery | 2 +- dzgui/views/pages/options.py | 15 +++++++++++++-- tests/test_app_download_settings.py | 10 +++++++++- 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/dzgui/api/acf.py b/dzgui/api/acf.py index 9d34909..284f710 100644 --- a/dzgui/api/acf.py +++ b/dzgui/api/acf.py @@ -2,6 +2,7 @@ import logging import re from collections.abc import Iterator +from datetime import date, datetime from pathlib import Path from typing import Any from warnings import deprecated @@ -69,6 +70,28 @@ class ACF: except StopIteration: return acf + def search_key(self, key: str) -> str: + return self.dict["AppState"][key] + + def date_to_str(self, epoch: int) -> str | None: + if epoch == 0: + return None + return datetime.fromtimestamp(epoch).isoformat(" ") + + def get_date_by_key(self, key: str) -> str | None: + try: + stamp = int(self.search_key(key)) + return self.date_to_str(stamp) + except Exception as e: + logger.critical(e) + return None + + def get_last_updated(self) -> str | None: + return self.get_date_by_key("LastUpdated") + + def get_last_played(self) -> str: + return self.get_date_by_key("LastPlayed") + def get_allows_downloads(self) -> int | None: try: # TODO: consider coercing strs to ints on initial import diff --git a/dzgui/api/steam.py b/dzgui/api/steam.py index be691b4..a7f8732 100644 --- a/dzgui/api/steam.py +++ b/dzgui/api/steam.py @@ -389,6 +389,17 @@ def get_running_app() -> int | None: return None +def get_last_updated(path: Path, appid: int) -> str: + root_path = get_app_path(path, appid) + acf = root_path.joinpath(f"steamapps/appmanifest_{appid}.acf") + return ACF(acf).get_last_updated() + +def get_last_played(path: Path, appid: int) -> str: + root_path = get_app_path(path, appid) + acf = root_path.joinpath(f"steamapps/appmanifest_{appid}.acf") + # TODO: make tests for this, use fixtures + return ACF(acf).get_last_played() + def get_app_allows_downloads(path: Path, appid: int) -> bool: try: root_path = get_app_path(path, appid) diff --git a/dzgui/lib/dayzquery b/dzgui/lib/dayzquery index 07483b8..fe413df 160000 --- a/dzgui/lib/dayzquery +++ b/dzgui/lib/dayzquery @@ -1 +1 @@ -Subproject commit 07483b88ed096327ebca752f5e177011b604d7fe +Subproject commit fe413df8e8f35cfb9302a657b5ec0b6ede0d4c2d diff --git a/dzgui/views/pages/options.py b/dzgui/views/pages/options.py index ebce129..eab871e 100644 --- a/dzgui/views/pages/options.py +++ b/dzgui/views/pages/options.py @@ -2,6 +2,7 @@ from pathlib import Path from typing import Callable, TYPE_CHECKING from dzgui.api import pefile as PeFile +from dzgui.api.steam import get_last_played, get_last_updated from dzgui.config import query from dzgui.const.constants import ( @@ -340,8 +341,10 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore [LeftLabel(options.flatpak_label), self.flatpak_toggle], ) - self.dayz_version_label = Gtk.Label(label=strings.null) - self.dayz_exp_version_label = Gtk.Label(label=strings.null) + self.dayz_version_label = Gtk.Label(label=strings.null, halign=Gtk.Align.START) + self.dayz_exp_version_label = Gtk.Label( + label=strings.null, halign=Gtk.Align.START + ) version_rows = [ [LeftLabel(APPNAME_DAYZ), self.dayz_version_label], @@ -467,10 +470,18 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore dayz_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ) if dayz_version is None: dayz_version = strings.null + else: + last_updated = get_last_updated(steam_path, APPID_DAYZ) + if last_updated is not None: + dayz_version += f" (updated at {last_updated})" dayz_exp_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ_EXP) if dayz_exp_version is None: dayz_exp_version = strings.null + else: + last_updated = get_last_updated(steam_path, APPID_DAYZ_EXP) + if last_updated is not None: + dayz_exp_version += f" (updated at {last_updated})" self.dayz_version_label.set_text(dayz_version) self.dayz_exp_version_label.set_text(dayz_exp_version) diff --git a/tests/test_app_download_settings.py b/tests/test_app_download_settings.py index 957fd2a..ad2639b 100644 --- a/tests/test_app_download_settings.py +++ b/tests/test_app_download_settings.py @@ -3,7 +3,7 @@ import pytest from _pytest.monkeypatch import MonkeyPatch from pathlib import Path -from dzgui.api.steam import get_app_allows_downloads +from dzgui.api.steam import get_app_allows_downloads, get_last_updated from tests.fixtures import fixture_path pytestmark = pytest.mark.apitest @@ -43,6 +43,14 @@ def patch_api() -> None: mp.undo() +def test_no_last_update(steam_path) -> None: + assert get_last_updated(steam_path, 555) is None + + +def test_last_update(steam_path) -> None: + assert get_last_updated(steam_path, 444) == "2026-10-22 00:09:33" + + def test_app_allows_downloads(steam_path) -> None: assert get_app_allows_downloads(steam_path, 111) is True