Code some part of the create profile page. Now it can load versions and types.

This commit is contained in:
wei
2026-07-30 21:43:19 +08:00
parent 3a4c1f42b2
commit 8d865c92a9
9 changed files with 468 additions and 183 deletions
+146
View File
@@ -0,0 +1,146 @@
import json
import time
import traceback
from pathlib import Path
from uuid import uuid4
from PySide6.QtCore import QObject
from core_lib.common.common import FileObject
from core_lib.common.exception import VersionManifestFetchException, VersionManifestSaveException, \
NoSpecifiedVersionKeyException
from core_lib.game.version_info import fetch_and_save_version_manifest, get_specific_version_manifest_url_and_hash
class ManifestManager:
def __init__(self, app):
self.app = app
self.widget_mgr = app.widget_manager
#
# ============ Version Data Cache ============
#
@property
def version_manifest_path(self) -> Path:
return Path(self.app.work_dir, "versions", "version_manifest_v2.json")
def get_specific_version_manifest_path(self, target_version: str) -> Path | None:
return Path(self.app.work_dir, "versions", target_version, f"{target_version}.json")
def switch_between_specific_path(self, specified_ver: str | None = None):
if specified_ver is None:
path = self.version_manifest_path
else:
path = self.get_specific_version_manifest_path(specified_ver)
return path
def _cache_version_manifest(self, specified_ver: str | None = None, root_manifest: dict | None = None) \
-> tuple[bool, dict | None]:
data = None
path = self.switch_between_specific_path(specified_ver)
try:
data = fetch_and_save_version_manifest(path, target_version=specified_ver, root_manifest=root_manifest)
except VersionManifestFetchException as e:
self.widget_mgr.signal.show_error_message.emit(
e.user_message,
)
except VersionManifestSaveException as e:
self.widget_mgr.signal.show_error_message.emit(
e.user_message,
)
except Exception as e:
self.widget_mgr.signal.show_and_print_error_message.emit(
{
"error": traceback.format_exception(e),
"title": "Cache Error",
"message": "An unexpected error occurred while caching version manifest."
}
)
return True if data else False, data
def _read_cached_version_manifest(self, specified_ver: str = None) -> dict | None:
path = self.switch_between_specific_path(specified_ver)
if not path.exists():
self.widget_mgr.signal.show_error_message.emit(
"Version manifest missing after check. Please try again later.",
)
return None
try:
version_manifest = json.loads(path.read_text())
return version_manifest
except Exception as e:
self.widget_mgr.signal.show_and_print_error_message.emit(
{
"error": traceback.format_exception(e),
"title": "Cache Error",
"message": "Unable to read version manifest."
}
)
return None
def get_cached_version_manifest(self, specified_ver: str = None, max_age: int = 3600) -> dict | None:
path = self.switch_between_specific_path(specified_ver)
file = FileObject(path)
sha1 = None
root_manifest = None
if specified_ver:
root_manifest = self.get_cached_version_manifest()
if root_manifest is None:
return None
try:
_, sha1 = get_specific_version_manifest_url_and_hash(root_manifest, specified_ver)
except NoSpecifiedVersionKeyException as e:
self.widget_mgr.signal.show_error_message.emit(
f"Version {specified_ver} does not exist in version manifest.\n{e.user_message}"
)
return None
if file.exists:
age = time.time() - path.stat().st_mtime
# For root manifest
if not specified_ver and age < max_age:
return self._read_cached_version_manifest()
# Below are all for specific ver
if specified_ver and sha1 is None:
self.app.logger.warning("Specified version '{}' hash doesn't exist.".format(specified_ver))
# Also check sha1
if specified_ver and age < max_age and file.verify("sha1", sha1):
return self._read_cached_version_manifest(specified_ver)
result, data = self._cache_version_manifest(specified_ver, root_manifest=root_manifest)
if not result:
return None
return data
def create_download_progress_callback(self, progress_title: str):
task_id = uuid4().hex
signals = self.widget_mgr.download_signal
signals.started.emit(task_id, progress_title)
def callback(name, percent):
signals.progress.emit(
task_id,
f"Downloading {name}",
percent,
)
return callback, task_id
class GameManager(QObject):
def __init__(self, app, parent=None):
super(GameManager, self).__init__(parent)
self.app = app
self.widget_mgr = app.widget_manager
self.manifest = ManifestManager(self.app)
-5
View File
@@ -1,5 +0,0 @@
from PySide6.QtCore import QObject
class RocketLauncher(QObject):
pass
+16 -16
View File
@@ -1,24 +1,13 @@
import queue
import threading
from PySide6.QtCore import QObject, Signal, Slot
from PySide6.QtWidgets import QProgressDialog
from PySide6.QtCore import QObject, Signal
from core_lib.qt import messagebox
class AskForRequest:
def __init__(self, title, message):
self.title = title
self.message = message
self.result_queue = queue.Queue(maxsize=1)
class SignalTransferItem:
def __init__(self):
self.result_queue = queue.Queue()
self.wait_event = threading.Event()
self.details = None # Set this if flag use_plain_text is enabled
# flags
self.use_plain_text = True
def wait(self, timeout: int | None = 10):
return self.wait_event.wait(timeout)
@@ -28,12 +17,23 @@ class AskForRequest:
except queue.Empty:
return None
class AskForRequest(SignalTransferItem):
def __init__(self, title, message):
super(AskForRequest, self).__init__()
self.title = title
self.message = message
self.result_queue = queue.Queue(maxsize=1)
self.details = None # Set this if flag use_plain_text is enabled
# flags
self.use_plain_text = True
class SelectPathRequest(AskForRequest):
def __init__(self, title, message, filter_raw=None):
super().__init__(title, message)
self.filter = filter_raw
class WidgetManager(QObject):
def __init__(self):
super(WidgetManager, self).__init__()