🎨 Various code style / behaviour fixes

- Merged platform sources when possible
- Added URLExecutableSource class
- Moved replaced_by_schema_key to utils/decorators
- Better retryable exception handling in some managers
-  Split SteamHelper into SteamFileHelper and SteamAPIHelper
- Delegated SteamRateLimiter creation to SteamAPIManager init
- Using additional_data for appid in SteamAPIManager
- Added Windows support for Legendary
- Stylistic changed suggested by pylint
This commit is contained in:
GeoffreyCoulaud
2023-06-10 02:59:41 +02:00
parent 070d875ff8
commit 842f9fe522
17 changed files with 182 additions and 224 deletions

View File

@@ -6,14 +6,16 @@ from typing import Iterable
from src import shared
from src.game import Game
from src.importer.sources.source import (
LinuxSource,
Source,
SourceIterationResult,
SourceIterator,
WindowsSource,
URLExecutableSource,
)
from src.utils.decorators import replaced_by_env_path, replaced_by_path
from src.utils.steam import SteamHelper, SteamInvalidManifestError
from src.utils.decorators import (
replaced_by_env_path,
replaced_by_path,
replaced_by_schema_key,
)
from src.utils.steam import SteamFileHelper, SteamInvalidManifestError
class SteamSourceIterator(SourceIterator):
@@ -22,11 +24,11 @@ class SteamSourceIterator(SourceIterator):
def get_manifest_dirs(self) -> Iterable[Path]:
"""Get dirs that contain steam app manifests"""
libraryfolders_path = self.source.location / "steamapps" / "libraryfolders.vdf"
with open(libraryfolders_path, "r") as file:
with open(libraryfolders_path, "r", encoding="utf-8") as file:
contents = file.read()
return [
Path(path) / "steamapps"
for path in re.findall('"path"\s+"(.*)"\n', contents, re.IGNORECASE)
for path in re.findall('"path"\\s+"(.*)"\n', contents, re.IGNORECASE)
]
def get_manifests(self) -> Iterable[Path]:
@@ -50,15 +52,15 @@ class SteamSourceIterator(SourceIterator):
manifests = self.get_manifests()
for manifest in manifests:
# Get metadata from manifest
steam = SteamHelper()
steam = SteamFileHelper()
try:
local_data = steam.get_manifest_data(manifest)
except (OSError, SteamInvalidManifestError):
continue
# Skip non installed games
INSTALLED_MASK: int = 4
if not int(local_data["stateflags"]) & INSTALLED_MASK:
installed_mask = 4
if not int(local_data["stateflags"]) & installed_mask:
continue
# Skip duplicate appids
@@ -85,40 +87,24 @@ class SteamSourceIterator(SourceIterator):
/ "librarycache"
/ f"{appid}_library_600x900.jpg"
)
additional_data = {"local_image_path": image_path}
additional_data = {"local_image_path": image_path, "steam_appid": appid}
# Produce game
yield (game, additional_data)
class SteamSource(Source):
class SteamSource(URLExecutableSource):
name = "Steam"
location_key = "steam-location"
def __iter__(self):
return SteamSourceIterator(source=self)
class SteamLinuxSource(SteamSource, LinuxSource):
variant = "linux"
executable_format = "xdg-open steam://rungameid/{game_id}"
iterator_class = SteamSourceIterator
url_format = "steam://rungameid/{game_id}"
available_on = set(("linux", "win32"))
@property
@SteamSource.replaced_by_schema_key()
@replaced_by_schema_key
@replaced_by_path("~/.var/app/com.valvesoftware.Steam/data/Steam/")
@replaced_by_env_path("XDG_DATA_HOME", "Steam/")
@replaced_by_path("~/.steam/")
@replaced_by_path("~/.local/share/Steam/")
def location(self):
raise FileNotFoundError()
class SteamWindowsSource(SteamSource, WindowsSource):
variant = "windows"
executable_format = "start steam://rungameid/{game_id}"
@property
@SteamSource.replaced_by_schema_key()
@replaced_by_env_path("programfiles(x86)", "Steam")
def location(self):
raise FileNotFoundError()