From 0abb7d3df9ce0850728d80b467c2ac39d626b7bb Mon Sep 17 00:00:00 2001 From: GeoffreyCoulaud Date: Mon, 1 May 2023 00:30:13 +0200 Subject: [PATCH] WIP location (to be discarded) --- src/importer/location.py | 31 +++++++++---- src/importer/source.py | 17 ++++++-- src/importer/sources/lutris_source.py | 63 +++++++++++++++------------ 3 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/importer/location.py b/src/importer/location.py index 5aafb83..ee664fe 100644 --- a/src/importer/location.py +++ b/src/importer/location.py @@ -1,20 +1,35 @@ from dataclasses import dataclass from functools import cached_property from pathlib import Path +from os import PathLike @dataclass class Location(): - """Abstraction for a location that can be overriden by a schema key""" + """Abstraction for a location that has multiple candidate paths""" - win = None + candidates: list[PathLike] = None - default: str = None - key: str = None + def __init__(self, *candidates): + self.candidates = list() + self.candidates.extend(candidates) + return self + + def add(self, canddiate): + """Add a candidate (last evaluated)""" + self.candidates.append(canddiate) + return self + + def add_override(self, candidate): + """Add a canddiate (first evaluated)""" + self.candidates.insert(0, candidate) + return self @cached_property def path(self): - override = Path(self.win.schema.get_string(self.path_override_key)) - if override.exists(): - return override - return self.path_default \ No newline at end of file + """Chosen path depending on availability on the disk.""" + for candidate in self.candidates: + p = Path(candidate).expanduser() + if p.exists: + return p + return None \ No newline at end of file diff --git a/src/importer/source.py b/src/importer/source.py index 0b4517b..d9685c1 100644 --- a/src/importer/source.py +++ b/src/importer/source.py @@ -27,16 +27,20 @@ class Source(Iterable): """Source of games. Can be a program location on disk with a config file that points to game for example""" win = None - name: str = "GenericSource" - variant: str = None + schema_keys: dict - # Format to construct the executable command for a game. - # Available field names depend on the implementation + name: str + variant: str executable_format: str def __init__(self, win) -> None: super().__init__() self.win = win + self.__init_schema_keys__() + + def __init_schema_keys__(self): + """Initialize schema keys needed by the source if necessary""" + raise NotImplementedError() @property def full_name(self): @@ -57,4 +61,9 @@ class Source(Iterable): def __iter__(self): """Get the source's iterator, to use in for loops""" + raise NotImplementedError() + + def __init_locations__(self): + """Initialize locations needed by the source. + Extended and called by **final** children.""" raise NotImplementedError() \ No newline at end of file diff --git a/src/importer/sources/lutris_source.py b/src/importer/sources/lutris_source.py index fa6d7f6..28e1f2a 100644 --- a/src/importer/sources/lutris_source.py +++ b/src/importer/sources/lutris_source.py @@ -4,6 +4,7 @@ from sqlite3 import connect from cartridges.game2 import Game from cartridges.importer.source import Source, SourceIterator +from cartridges.importer.location import Location class LutrisSourceIterator(SourceIterator): @@ -72,44 +73,50 @@ class LutrisSource(Source): name = "Lutris" executable_format = "xdg-open lutris:rungameid/{game_id}" + schema_keys = { + "location": None, + "cache_location": None + } - location = None - cache_location = None + def __init__(self, win) -> None: + super().__init__(win) + self.location = Location() + self.cache_location = Location() def __iter__(self): return LutrisSourceIterator(source=self) - # TODO find a way to no duplicate this code - # Ideas: - # - Location class (verbose, set in __init__) - # - Schema key override decorator () - - # Lutris location property - @cached_property - def location(self): - ovr = Path(self.win.schema.get_string(self.location_key)) - if ovr.exists(): return ovr - return self.location_default - - # Lutris cache location property - @cached_property - def cache_location(self): - ovr = Path(self.win.schema.get_string(self.cache_location_key)) - if ovr.exists(): return ovr - return self.cache_location_default + def __init_locations__(self): + super().__init_locations__() + self.location.add_override(self.win.schema.get_string(self.schema_keys["location"])) + self.cache_location.add_override(self.win.schema.get_string(self.schema_keys["cache_location"])) class LutrisNativeSource(LutrisSource): + """Class representing an installation of Lutris using native packaging""" + variant = "native" - location_key = "lutris-location" - location_default = Path("~/.local/share/lutris/").expanduser() - cache_location_key = "lutris-cache-location" - cache_location_default = location_default / "covers" + schema_keys = { + "location": "lutris-location", + "cache_location": "lutris-cache-location" + } + + def __init_locations__(self): + super().__init_locations__() + self.location.add("~/.local/share/lutris/") + self.cache_location.add("~/.local/share/lutris/covers") class LutrisFlatpakSource(LutrisSource): + """Class representing an installation of Lutris using flatpak""" + variant = "flatpak" - location_key = "lutris-flatpak-location" - location_default = Path("~/.var/app/net.lutris.Lutris/data/lutris").expanduser() - cache_location_key = "lutris-flatpak-cache-location" - cache_location_default = location_default / "covers" \ No newline at end of file + schema_keys = { + "location": "lutris-flatpak-location", + "cache_location": "lutris-flatpak-cache-location" + } + + def __init_locations__(self): + super().__init_locations__() + self.location.add("~/.var/app/net.lutris.Lutris/data/lutris") + self.cache_location.add("~/.var/app/net.lutris.Lutris/data/lutris/covers") \ No newline at end of file