🎨 SourceIterator can yield addtitional data
SourceIterator-s can yield a game and a tuple of additional data. This data will be passed to the Store, Pipeline and Managers.
This commit is contained in:
@@ -3,9 +3,9 @@ import logging
|
||||
from gi.repository import Adw, Gio, Gtk
|
||||
|
||||
from src import shared
|
||||
from src.game import Game
|
||||
from src.utils.task import Task
|
||||
from src.store.pipeline import Pipeline
|
||||
from src.store.managers.manager import Manager
|
||||
from src.importer.sources.source import Source
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ class Importer:
|
||||
def source_task_thread_func(self, _task, _obj, data, _cancellable):
|
||||
"""Source import task code"""
|
||||
|
||||
source: Source
|
||||
source, *_rest = data
|
||||
|
||||
# Early exit if not installed
|
||||
@@ -107,20 +108,35 @@ class Importer:
|
||||
while True:
|
||||
# Handle exceptions raised when iterating
|
||||
try:
|
||||
game = next(iterator)
|
||||
iteration_result = next(iterator)
|
||||
except StopIteration:
|
||||
break
|
||||
except Exception as exception: # pylint: disable=broad-exception-caught
|
||||
logging.exception(
|
||||
msg=f"Exception in source {source.id}",
|
||||
exc_info=exception,
|
||||
"Exception in source %s", source.id, exc_info=exception
|
||||
)
|
||||
continue
|
||||
if game is None:
|
||||
|
||||
# Handle the result depending on its type
|
||||
if isinstance(iteration_result, Game):
|
||||
game = iteration_result
|
||||
additional_data = tuple()
|
||||
elif isinstance(iteration_result, tuple):
|
||||
game, additional_data = iteration_result
|
||||
elif iteration_result is None:
|
||||
continue
|
||||
else:
|
||||
# Warn source implementers that an invalid type was produced
|
||||
# Should not happen on production code
|
||||
logging.warn(
|
||||
"%s produced an invalid iteration return type %s",
|
||||
source.id,
|
||||
type(iteration_result),
|
||||
)
|
||||
continue
|
||||
|
||||
# Register game
|
||||
pipeline: Pipeline = shared.store.add_game(game)
|
||||
pipeline: Pipeline = shared.store.add_game(game, additional_data)
|
||||
if pipeline is not None:
|
||||
logging.info("Imported %s (%s)", game.name, game.game_id)
|
||||
pipeline.connect("advanced", self.pipeline_advanced_callback)
|
||||
|
||||
@@ -48,12 +48,9 @@ class ItchSourceIterator(SourceIterator):
|
||||
"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)
|
||||
additional_data = (row[3], row[2])
|
||||
game = Game(values, allow_side_effects=False)
|
||||
yield (game, additional_data)
|
||||
|
||||
|
||||
class ItchSource(Source):
|
||||
|
||||
@@ -3,12 +3,15 @@ from abc import abstractmethod
|
||||
from collections.abc import Iterable, Iterator
|
||||
from functools import wraps
|
||||
from pathlib import Path
|
||||
from typing import Generator, Optional
|
||||
from typing import Generator, Any
|
||||
|
||||
from src import shared
|
||||
from src.game import Game
|
||||
from src.utils.decorators import replaced_by_path
|
||||
|
||||
# Type of the data returned by iterating on a Source
|
||||
SourceIterationResult = None | Game | tuple[Game, tuple[Any]]
|
||||
|
||||
|
||||
class SourceIterator(Iterator):
|
||||
"""Data producer for a source of games"""
|
||||
@@ -24,11 +27,11 @@ class SourceIterator(Iterator):
|
||||
def __iter__(self) -> "SourceIterator":
|
||||
return self
|
||||
|
||||
def __next__(self) -> Optional[Game]:
|
||||
def __next__(self) -> SourceIterationResult:
|
||||
return next(self.generator)
|
||||
|
||||
@abstractmethod
|
||||
def generator_builder(self) -> Generator[Optional[Game], None, None]:
|
||||
def generator_builder(self) -> Generator[SourceIterationResult, None, None]:
|
||||
"""
|
||||
Method that returns a generator that produces games
|
||||
* Should be implemented as a generator method
|
||||
@@ -49,7 +52,6 @@ class Source(Iterable):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.available_on = set()
|
||||
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
|
||||
Reference in New Issue
Block a user