Cleanup:
* Use `vars()` instead of directly accessing `__dict__` * Remove `auto_update` from RareGame's metadata * Correct check for updating the Steam App ID (We want to keep any changes from the user) * Collect both Wine and Proton prefixes when removing overlay registry keys. * Add few convenience functions in config_helper and paths.
This commit is contained in:
parent
75c8e8d817
commit
89df9806b5
|
@ -83,7 +83,7 @@ class GameMetadataView(QTreeView, SideTabContents):
|
|||
self.set_title.emit(self.rgame.app_title)
|
||||
self.model.clear()
|
||||
try:
|
||||
self.model.load(view.__dict__)
|
||||
self.model.load(vars(view))
|
||||
except Exception as e:
|
||||
pass
|
||||
self.resizeColumnToContents(0)
|
||||
|
|
|
@ -201,7 +201,7 @@ class RareLauncher(RareApp):
|
|||
|
||||
def send_message(self, message: BaseModel):
|
||||
if self.socket:
|
||||
self.socket.write(json.dumps(message.__dict__).encode("utf-8"))
|
||||
self.socket.write(json.dumps(vars(message)).encode("utf-8"))
|
||||
self.socket.flush()
|
||||
else:
|
||||
self.logger.error("Can't send message")
|
||||
|
|
|
@ -20,7 +20,7 @@ from rare.shared.game_process import GameProcess
|
|||
from rare.shared.image_manager import ImageManager
|
||||
from rare.utils.paths import data_dir, get_rare_executable
|
||||
from rare.utils.steam_grades import get_rating
|
||||
from rare.utils.config_helper import add_envvar, remove_envvar
|
||||
from rare.utils.config_helper import add_envvar
|
||||
|
||||
logger = getLogger("RareGame")
|
||||
|
||||
|
@ -28,7 +28,6 @@ logger = getLogger("RareGame")
|
|||
class RareGame(RareGameSlim):
|
||||
@dataclass
|
||||
class Metadata:
|
||||
auto_update: bool = False
|
||||
queued: bool = False
|
||||
queue_pos: Optional[int] = None
|
||||
last_played: datetime = datetime.min
|
||||
|
@ -41,20 +40,19 @@ class RareGame(RareGameSlim):
|
|||
@classmethod
|
||||
def from_dict(cls, data: Dict):
|
||||
return cls(
|
||||
auto_update=data.get("auto_update", False),
|
||||
queued=data.get("queued", False),
|
||||
queue_pos=data.get("queue_pos", None),
|
||||
last_played=datetime.fromisoformat(data["last_played"]) if data.get("last_played", None) else datetime.min,
|
||||
grant_date=datetime.fromisoformat(data["grant_date"]) if data.get("grant_date", None) else None,
|
||||
last_played=datetime.fromisoformat(x) if (x := data.get("last_played", None)) else datetime.min,
|
||||
grant_date=datetime.fromisoformat(x) if (x := data.get("grant_date", None)) else None,
|
||||
steam_appid=data.get("steam_appid", None),
|
||||
steam_grade=data.get("steam_grade", None),
|
||||
steam_date=datetime.fromisoformat(data["steam_date"]) if data.get("steam_date", None) else datetime.min,
|
||||
steam_date=datetime.fromisoformat(x) if (x := data.get("steam_date", None)) else datetime.min,
|
||||
tags=data.get("tags", []),
|
||||
)
|
||||
|
||||
def as_dict(self):
|
||||
@property
|
||||
def __dict__(self):
|
||||
return dict(
|
||||
auto_update=self.auto_update,
|
||||
queued=self.queued,
|
||||
queue_pos=self.queue_pos,
|
||||
last_played=self.last_played.isoformat() if self.last_played else datetime.min,
|
||||
|
@ -144,13 +142,14 @@ class RareGame(RareGameSlim):
|
|||
def __load_metadata_json() -> Dict:
|
||||
if RareGame.__metadata_json is None:
|
||||
metadata = {}
|
||||
file = os.path.join(data_dir(), "game_meta.json")
|
||||
try:
|
||||
with open(os.path.join(data_dir(), "game_meta.json"), "r") as metadata_fh:
|
||||
metadata = json.load(metadata_fh)
|
||||
with open(file, "r") as f:
|
||||
metadata = json.load(f)
|
||||
except FileNotFoundError:
|
||||
logger.info("Game metadata json file does not exist.")
|
||||
logger.info("%s does not exist", file)
|
||||
except json.JSONDecodeError:
|
||||
logger.warning("Game metadata json file is corrupt.")
|
||||
logger.warning("%s is corrupt", file)
|
||||
finally:
|
||||
RareGame.__metadata_json = metadata
|
||||
return RareGame.__metadata_json
|
||||
|
@ -167,9 +166,9 @@ class RareGame(RareGameSlim):
|
|||
with RareGame.__metadata_lock:
|
||||
metadata: Dict = self.__load_metadata_json()
|
||||
# pylint: disable=unsupported-assignment-operation
|
||||
metadata[self.app_name] = self.metadata.as_dict()
|
||||
with open(os.path.join(data_dir(), "game_meta.json"), "w") as metadata_json:
|
||||
json.dump(metadata, metadata_json, indent=2)
|
||||
metadata[self.app_name] = vars(self.metadata)
|
||||
with open(os.path.join(data_dir(), "game_meta.json"), "w+") as file:
|
||||
json.dump(metadata, file, indent=2)
|
||||
|
||||
def update_game(self):
|
||||
self.game = self.core.get_game(
|
||||
|
@ -468,8 +467,10 @@ class RareGame(RareGameSlim):
|
|||
return self.metadata.steam_appid
|
||||
|
||||
def set_steam_grade(self, appid: int, grade: str) -> None:
|
||||
if appid or self.steam_appid is None:
|
||||
if appid and self.steam_appid is None:
|
||||
add_envvar(self.app_name, "SteamAppId", str(appid))
|
||||
add_envvar(self.app_name, "SteamGameId", str(appid))
|
||||
add_envvar(self.app_name, "STEAM_COMPAT_APP_ID", str(appid))
|
||||
self.metadata.steam_appid = appid
|
||||
self.metadata.steam_grade = grade
|
||||
self.metadata.steam_date = datetime.utcnow()
|
||||
|
|
|
@ -42,7 +42,7 @@ class InstallOptionsModel:
|
|||
def as_install_kwargs(self) -> Dict:
|
||||
return {
|
||||
k: getattr(self, k)
|
||||
for k in self.__dict__
|
||||
for k in vars(self)
|
||||
if k not in ["update", "silent", "create_shortcut", "overlay", "install_prereqs"]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Dict
|
||||
|
||||
|
||||
class Actions:
|
||||
|
@ -15,7 +16,7 @@ class BaseModel:
|
|||
app_name: str
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, data: dict):
|
||||
def from_json(cls, data: Dict):
|
||||
return cls(
|
||||
action=data["action"],
|
||||
app_name=data["app_name"]
|
||||
|
@ -28,9 +29,9 @@ class FinishedModel(BaseModel):
|
|||
playtime: int # seconds
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, data):
|
||||
def from_json(cls, data: Dict):
|
||||
return cls(
|
||||
**BaseModel.from_json(data).__dict__,
|
||||
**vars(BaseModel.from_json(data)),
|
||||
exit_code=data["exit_code"],
|
||||
playtime=data["playtime"],
|
||||
)
|
||||
|
@ -47,7 +48,7 @@ class StateChangedModel(BaseModel):
|
|||
new_state: int
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, data):
|
||||
def from_json(cls, data: Dict):
|
||||
return cls(
|
||||
action=data["action"],
|
||||
app_name=data["app_name"],
|
||||
|
@ -60,8 +61,8 @@ class ErrorModel(BaseModel):
|
|||
error_string: str
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, data):
|
||||
def from_json(cls, data: Dict):
|
||||
return cls(
|
||||
**BaseModel.from_json(data).__dict__,
|
||||
**vars(BaseModel.from_json(data)),
|
||||
error_string=data["error_string"]
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ from rare.lgndr.glue.arguments import LgndrUninstallGameArgs
|
|||
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
||||
from rare.models.game import RareGame
|
||||
from rare.models.install import UninstallOptionsModel
|
||||
from rare.utils import config_helper
|
||||
from rare.utils import config_helper as config
|
||||
from rare.utils.paths import desktop_links_supported, desktop_link_types, desktop_link_path
|
||||
from .worker import Worker
|
||||
|
||||
|
@ -31,7 +31,7 @@ def uninstall_game(
|
|||
|
||||
logger.info('Removing registry entries...')
|
||||
if platform.system() != "Window":
|
||||
prefixes = config_helper.get_wine_prefixes()
|
||||
prefixes = config.get_prefixes()
|
||||
if platform.system() == "Darwin":
|
||||
# TODO: add crossover support
|
||||
pass
|
||||
|
@ -65,10 +65,10 @@ def uninstall_game(
|
|||
)
|
||||
if not keep_config:
|
||||
logger.info("Removing sections in config file")
|
||||
config_helper.remove_section(rgame.app_name)
|
||||
config_helper.remove_section(f"{rgame.app_name}.env")
|
||||
config.remove_section(rgame.app_name)
|
||||
config.remove_section(f"{rgame.app_name}.env")
|
||||
|
||||
config_helper.save_config()
|
||||
config.save_config()
|
||||
|
||||
return status.success, status.message
|
||||
|
||||
|
|
|
@ -67,9 +67,7 @@ def get_game_envvar(option: str, app_name: Optional[str] = None, fallback: Any =
|
|||
|
||||
|
||||
def get_proton_compat_data(app_name: Optional[str] = None, fallback: Any = None) -> str:
|
||||
_compat = _config.get("default.env", "STEAM_COMPAT_DATA_PATH", fallback=fallback)
|
||||
if app_name is not None:
|
||||
_compat = _config.get(f'{app_name}.env', "STEAM_COMPAT_DATA_PATH", fallback=_compat)
|
||||
_compat = get_game_envvar("STEAM_COMPAT_DATA_PATH", app_name, fallback=fallback)
|
||||
# return os.path.join(_compat, "pfx") if _compat else fallback
|
||||
return _compat
|
||||
|
||||
|
@ -87,10 +85,47 @@ def get_wine_prefixes() -> Set[str]:
|
|||
_prefixes = []
|
||||
for name, section in _config.items():
|
||||
pfx = section.get("WINEPREFIX") or section.get("wine_prefix")
|
||||
if not pfx:
|
||||
pfx = os.path.join(compatdata, "pfx") if (compatdata := section.get("STEAM_COMPAT_DATA_PATH")) else ""
|
||||
if pfx:
|
||||
_prefixes.append(pfx)
|
||||
_prefixes = [os.path.expanduser(prefix) for prefix in _prefixes]
|
||||
return {p for p in _prefixes if os.path.isdir(p)}
|
||||
|
||||
|
||||
def get_proton_prefixes() -> Set[str]:
|
||||
_prefixes = []
|
||||
for name, section in _config.items():
|
||||
pfx = os.path.join(compatdata, "pfx") if (compatdata := section.get("STEAM_COMPAT_DATA_PATH")) else ""
|
||||
if pfx:
|
||||
_prefixes.append(pfx)
|
||||
_prefixes = [os.path.expanduser(prefix) for prefix in _prefixes]
|
||||
return {p for p in _prefixes if os.path.isdir(p)}
|
||||
|
||||
|
||||
def get_prefixes() -> Set[str]:
|
||||
return get_wine_prefixes().union(get_proton_prefixes())
|
||||
|
||||
|
||||
def prefix_exists(pfx: str) -> bool:
|
||||
return os.path.isdir(pfx) and os.path.isfile(os.path.join(pfx, "user.reg"))
|
||||
|
||||
|
||||
def get_prefix(app_name: str = "default") -> Optional[str]:
|
||||
_compat_path = _config.get(f"{app_name}.env", "STEAM_COMPAT_DATA_PATH", fallback=None)
|
||||
if _compat_path and prefix_exists(_compat_prefix := os.path.join(_compat_path, "pfx")):
|
||||
return _compat_prefix
|
||||
|
||||
_wine_prefix = _config.get(f"{app_name}.env", "WINEPREFIX", fallback=None)
|
||||
_wine_prefix = _config.get(app_name, "wine_prefix", fallback=_wine_prefix)
|
||||
if _wine_prefix and prefix_exists(_wine_prefix):
|
||||
return _wine_prefix
|
||||
|
||||
_compat_path = _config.get(f"default.env", "STEAM_COMPAT_DATA_PATH", fallback=None)
|
||||
if _compat_path and prefix_exists(_compat_prefix := os.path.join(_compat_path, "pfx")):
|
||||
return _compat_prefix
|
||||
|
||||
_wine_prefix = _config.get(f"default.env", "WINEPREFIX", fallback=None)
|
||||
_wine_prefix = _config.get("default", "wine_prefix", fallback=_wine_prefix)
|
||||
if _wine_prefix and prefix_exists(_wine_prefix):
|
||||
return _wine_prefix
|
||||
|
||||
return None
|
||||
|
|
|
@ -36,6 +36,12 @@ def lock_file() -> Path:
|
|||
return Path(QStandardPaths.writableLocation(QStandardPaths.TempLocation), "Rare.lock")
|
||||
|
||||
|
||||
def config_dir() -> Path:
|
||||
# FIXME: This returns ~/.config/Rare/Rare/ for some reason while the settings are in ~/.config/Rare/Rare.conf
|
||||
# Take the parent for now, but this should be investigated
|
||||
return Path(QStandardPaths.writableLocation(QStandardPaths.AppConfigLocation)).parent
|
||||
|
||||
|
||||
def data_dir() -> Path:
|
||||
return Path(QStandardPaths.writableLocation(QStandardPaths.AppDataLocation))
|
||||
|
||||
|
|
Loading…
Reference in a new issue