From 97b770cbf29f78faf7dc31793e4c54a64bf0bd37 Mon Sep 17 00:00:00 2001 From: GeoffreyCoulaud Date: Wed, 31 May 2023 22:43:30 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Various=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Platform-dependent sources - Added heroic schema keys - Moved location and is_installed to Source --- data/hu.kramo.Cartridges.gschema.xml.in | 48 ++++++++++++++----------- src/importer/sources/heroic_source.py | 31 ++++++---------- src/importer/sources/lutris_source.py | 22 ++---------- src/importer/sources/source.py | 42 +++++++++++++++++++--- src/importer/sources/steam_source.py | 23 +++--------- 5 files changed, 81 insertions(+), 85 deletions(-) diff --git a/data/hu.kramo.Cartridges.gschema.xml.in b/data/hu.kramo.Cartridges.gschema.xml.in index a2f04de..0ae63b7 100644 --- a/data/hu.kramo.Cartridges.gschema.xml.in +++ b/data/hu.kramo.Cartridges.gschema.xml.in @@ -1,9 +1,9 @@ - - - false - + + + false + false @@ -44,21 +44,27 @@ true + "~/.config/heroic/" + + "~/.var/app/com.heroicgameslauncher.hgl/config/heroic/" - - true - - - true - - - true - + + "" + + + true + + + true + + + true + true - + "~/.var/app/com.usebottles.bottles/data/bottles/" @@ -79,7 +85,7 @@ false - + 1110 @@ -92,13 +98,13 @@ - - - - - + + + + + "a-z" - + \ No newline at end of file diff --git a/src/importer/sources/heroic_source.py b/src/importer/sources/heroic_source.py index 1dc1d8f..9b44b7a 100644 --- a/src/importer/sources/heroic_source.py +++ b/src/importer/sources/heroic_source.py @@ -1,5 +1,5 @@ import json -from abc import abstractmethod +import logging from hashlib import sha256 from json import JSONDecodeError from pathlib import Path @@ -8,7 +8,7 @@ from typing import Generator, Optional, TypedDict from src import shared from src.game import Game -from src.importer.sources.source import Source, SourceIterator +from src.importer.sources.source import NTSource, PosixSource, Source, SourceIterator from src.utils.decorators import ( replaced_by_env_path, replaced_by_path, @@ -87,9 +87,9 @@ class HeroicSourceIterator(SourceIterator): def sub_sources_generator(self): """Generator method producing games from all the Heroic sub-sources""" - for key, sub_source in self.sub_sources.items(): + for _key, sub_source in self.sub_sources.items(): # Skip disabled sub-sources - if not shared.schema.get_boolean("heroic-import-" + key): + if not shared.schema.get_boolean("heroic-import-" + sub_source["service"]): continue # Load games from JSON try: @@ -124,32 +124,19 @@ class HeroicSource(Source): name = "Heroic" executable_format = "xdg-open heroic://launch/{app_name}" - @property - @abstractmethod - def location(self) -> Path: - pass - @property def game_id_format(self) -> str: """The string format used to construct game IDs""" return self.name.lower() + "_{service}_{game_id}" - @property - def is_installed(self): - # pylint: disable=pointless-statement - try: - self.location - except FileNotFoundError: - return False - return True - def __iter__(self): return HeroicSourceIterator(source=self) -class HeroicNativeSource(HeroicSource): +class HeroicNativeSource(HeroicSource, PosixSource): variant = "native" + @property @replaced_by_schema_key("heroic-location") @replaced_by_env_path("XDG_CONFIG_HOME", "heroic/") @replaced_by_path("~/.config/heroic/") @@ -157,19 +144,21 @@ class HeroicNativeSource(HeroicSource): raise FileNotFoundError() -class HeroicFlatpakSource(HeroicSource): +class HeroicFlatpakSource(HeroicSource, PosixSource): variant = "flatpak" + @property @replaced_by_schema_key("heroic-flatpak-location") @replaced_by_path("~/.var/app/com.heroicgameslauncher.hgl/config/heroic/") def location(self) -> Path: raise FileNotFoundError() -class HeroicWindowsSource(HeroicSource): +class HeroicWindowsSource(HeroicSource, NTSource): variant = "windows" executable_format = "start heroic://launch/{app_name}" + @property @replaced_by_schema_key("heroic-windows-location") @replaced_by_env_path("appdata", "heroic/") def location(self) -> Path: diff --git a/src/importer/sources/lutris_source.py b/src/importer/sources/lutris_source.py index 663ba9a..befadc4 100644 --- a/src/importer/sources/lutris_source.py +++ b/src/importer/sources/lutris_source.py @@ -1,11 +1,9 @@ -from abc import abstractmethod -from pathlib import Path from sqlite3 import connect from time import time from src import shared from src.game import Game -from src.importer.sources.source import Source, SourceIterator +from src.importer.sources.source import PosixSource, Source, SourceIterator from src.utils.decorators import replaced_by_path, replaced_by_schema_key from src.utils.save_cover import resize_cover, save_cover @@ -78,29 +76,15 @@ class LutrisSource(Source): name = "Lutris" executable_format = "xdg-open lutris:rungameid/{game_id}" - @property - @abstractmethod - def location(self) -> Path: - pass - @property def game_id_format(self): return super().game_id_format + "_{game_internal_id}" - @property - def is_installed(self): - # pylint: disable=pointless-statement - try: - self.location - except FileNotFoundError: - return False - return True - def __iter__(self): return LutrisSourceIterator(source=self) -class LutrisNativeSource(LutrisSource): +class LutrisNativeSource(LutrisSource, PosixSource): variant = "native" @property @@ -110,7 +94,7 @@ class LutrisNativeSource(LutrisSource): raise FileNotFoundError() -class LutrisFlatpakSource(LutrisSource): +class LutrisFlatpakSource(LutrisSource, PosixSource): variant = "flatpak" @property diff --git a/src/importer/sources/source.py b/src/importer/sources/source.py index 2506edb..c65a845 100644 --- a/src/importer/sources/source.py +++ b/src/importer/sources/source.py @@ -1,5 +1,7 @@ +import os from abc import abstractmethod from collections.abc import Iterable, Iterator +from pathlib import Path from typing import Optional from src.game import Game @@ -30,6 +32,11 @@ class Source(Iterable): name: str variant: str + available_on: set[str] + + def __init__(self) -> None: + super().__init__() + self.available_on = set() @property def full_name(self) -> str: @@ -52,16 +59,41 @@ class Source(Iterable): """The string format used to construct game IDs""" return self.name.lower() + "_{game_id}" + @property + def is_installed(self): + # pylint: disable=pointless-statement + try: + self.location + except FileNotFoundError: + return False + return os.name in self.available_on + + @property + @abstractmethod + def location(self) -> Path: + """The source's location on disk""" + @property @abstractmethod def executable_format(self) -> str: """The executable format used to construct game executables""" - @property - @abstractmethod - def is_installed(self) -> bool: - """Whether the source is detected as installed""" - @abstractmethod def __iter__(self) -> SourceIterator: """Get the source's iterator, to use in for loops""" + + +class NTSource(Source): + """Mixin for sources available on Windows""" + + def __init__(self) -> None: + super().__init__() + self.available_on.add("nt") + + +class PosixSource(Source): + """Mixin for sources available on POXIX-compliant systems""" + + def __init__(self) -> None: + super().__init__() + self.available_on.add("posix") diff --git a/src/importer/sources/steam_source.py b/src/importer/sources/steam_source.py index 1a13899..312551a 100644 --- a/src/importer/sources/steam_source.py +++ b/src/importer/sources/steam_source.py @@ -1,12 +1,11 @@ import re -from abc import abstractmethod from pathlib import Path from time import time from typing import Iterator from src import shared from src.game import Game -from src.importer.sources.source import Source, SourceIterator +from src.importer.sources.source import NTSource, PosixSource, Source, SourceIterator from src.utils.decorators import ( replaced_by_env_path, replaced_by_path, @@ -94,25 +93,11 @@ class SteamSource(Source): name = "Steam" executable_format = "xdg-open steam://rungameid/{game_id}" - @property - @abstractmethod - def location(self) -> Path: - pass - - @property - def is_installed(self): - # pylint: disable=pointless-statement - try: - self.location - except FileNotFoundError: - return False - return True - def __iter__(self): return SteamSourceIterator(source=self) -class SteamNativeSource(SteamSource): +class SteamNativeSource(SteamSource, PosixSource): variant = "native" @property @@ -124,7 +109,7 @@ class SteamNativeSource(SteamSource): raise FileNotFoundError() -class SteamFlatpakSource(SteamSource): +class SteamFlatpakSource(SteamSource, PosixSource): variant = "flatpak" @property @@ -134,7 +119,7 @@ class SteamFlatpakSource(SteamSource): raise FileNotFoundError() -class SteamWindowsSource(SteamSource): +class SteamWindowsSource(SteamSource, NTSource): variant = "windows" executable_format = "start steam://rungameid/{game_id}"