diff --git a/src/importer/sources/itch_source.py b/src/importer/sources/itch_source.py new file mode 100644 index 0000000..1b90ffc --- /dev/null +++ b/src/importer/sources/itch_source.py @@ -0,0 +1,86 @@ +from sqlite3 import connect +from pathlib import Path +from time import time +from typing import Optional, Generator + +from src import shared +from src.utils.decorators import replaced_by_env_path, replaced_by_path +from src.game import Game +from src.importer.sources.source import ( + Source, + SourceIterator, + LinuxSource, + WindowsSource, +) + + +class ItchSourceIterator(SourceIterator): + source: "ItchSource" + + def generator_builder(self) -> Generator[Optional[Game], None, None]: + """Generator method producing games""" + + # Query the database + db_request = """ + SELECT + games.id, + games.title, + games.cover_url, + games.still_cover_url, + caves.id + FROM + 'caves' + INNER JOIN + 'games' + ON + caves.game_id = games.id + ; + """ + connection = connect(self.source.location / "db" / "butler.db") + cursor = connection.execute(db_request) + + # Create games from the db results + for row in cursor: + values = { + "version": shared.SPEC_VERSION, + "added": int(time()), + "source": self.source.id, + "game_id": self.source.game_id_format.format(game_id=row[0]), + "executable": self.source.executable_format.format(cave_id=row[4]), + } + yield Game(values, allow_side_effects=False) + + # TODO pass image URIs to the pipeline somehow + # - Add a reserved field to the Game object + # - Reconstruct those from the pipeline (we already have them) + # - Pass game and additional data to the pipeline separately (requires deep changes) + + +class ItchSource(Source): + name = "Itch" + location_key = "itch-location" + + def __iter__(self) -> SourceIterator: + return ItchSourceIterator(self) + + +class ItchLinuxSource(ItchSource, LinuxSource): + variant = "linux" + executable_format = "xdg-open itch://caves/{cave_id}/launch" + + @ItchSource.replaced_by_schema_key() + @replaced_by_path("~/.var/app/io.itch.itch/config/itch/") + @replaced_by_env_path("XDG_DATA_HOME", "itch/") + @replaced_by_path("~/.config/itch") + def location(self) -> Path: + raise FileNotFoundError() + + +class ItchWindowsSource(ItchSource, WindowsSource): + variant = "windows" + executable_format = "start itch://caves/{cave_id}/launch" + + @ItchSource.replaced_by_schema_key() + @replaced_by_env_path("appdata", "itch/") + def location(self) -> Path: + raise FileNotFoundError()