🎨 Various changes

- Changed source additional data to dict
- Moved local cover saving into a manager
- Added stub for itch cover manager
This commit is contained in:
GeoffreyCoulaud
2023-06-07 15:00:42 +02:00
parent 98f02da36c
commit 5dc6ec899a
18 changed files with 106 additions and 54 deletions

View File

@@ -27,7 +27,7 @@ class AsyncManager(Manager):
self.cancellable = Gio.Cancellable()
def process_game(
self, game: Game, additional_data: tuple, callback: Callable[["Manager"], Any]
self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any]
) -> None:
"""Create a task to process the game in a separate thread"""
task = Task.new(None, self.cancellable, self._task_callback, (callback,))

View File

@@ -10,7 +10,7 @@ class DisplayManager(Manager):
run_after = set((SteamAPIManager, SGDBManager))
def manager_logic(self, game: Game, _additional_data: tuple) -> None:
def manager_logic(self, game: Game, _additional_data: dict) -> None:
# TODO decouple a game from its widget
shared.win.games[game.game_id] = game
game.update()

View File

@@ -8,5 +8,5 @@ class FileManager(AsyncManager):
run_after = set((SteamAPIManager,))
def manager_logic(self, game: Game, _additional_data: tuple) -> None:
def manager_logic(self, game: Game, _additional_data: dict) -> None:
game.save()

View File

@@ -0,0 +1,19 @@
from urllib3.exceptions import SSLError
import requests
from requests import HTTPError
from src.game import Game
from src.store.managers.async_manager import AsyncManager
from src.store.managers.local_cover_manager import LocalCoverManager
class ItchCoverManager(AsyncManager):
"""Manager in charge of downloading the game's cover from itch.io"""
run_after = set((LocalCoverManager,))
retryable_on = set((HTTPError, SSLError))
def manager_logic(self, game: Game, additional_data: dict) -> None:
# TODO move itch cover logic here
pass

View File

@@ -0,0 +1,23 @@
from pathlib import Path
from src.game import Game
from src.store.managers.manager import Manager
from src.store.managers.steam_api_manager import SteamAPIManager
from src.utils.save_cover import save_cover, resize_cover
class LocalCoverManager(Manager):
"""Manager in charge of adding the local cover image of the game"""
run_after = set((SteamAPIManager,))
def manager_logic(self, game: Game, additional_data: dict) -> None:
# Ensure that the cover path is in the additional data
try:
image_path: Path = additional_data["local_image_path"]
except KeyError:
return
if not image_path.is_file():
return
# Save the image
save_cover(game.game_id, resize_cover(image_path))

View File

@@ -49,7 +49,7 @@ class Manager:
return errors
@abstractmethod
def manager_logic(self, game: Game, additional_data: tuple) -> None:
def manager_logic(self, game: Game, additional_data: dict) -> None:
"""
Manager specific logic triggered by the run method
* Implemented by final child classes
@@ -59,7 +59,7 @@ class Manager:
"""
def execute_resilient_manager_logic(
self, game: Game, additional_data: tuple, try_index: int = 0
self, game: Game, additional_data: dict, try_index: int = 0
) -> None:
"""Execute the manager logic and handle its errors by reporting them or retrying"""
try:
@@ -93,7 +93,7 @@ class Manager:
)
def process_game(
self, game: Game, additional_data: tuple, callback: Callable[["Manager"], Any]
self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any]
) -> None:
"""Pass the game through the manager"""
self.execute_resilient_manager_logic(game, additional_data)

View File

@@ -2,6 +2,8 @@ from urllib3.exceptions import SSLError
from src.game import Game
from src.store.managers.async_manager import AsyncManager
from src.store.managers.itch_cover_manager import ItchCoverManager
from src.store.managers.local_cover_manager import LocalCoverManager
from src.store.managers.steam_api_manager import SteamAPIManager
from src.utils.steamgriddb import HTTPError, SGDBAuthError, SGDBHelper
@@ -9,10 +11,10 @@ from src.utils.steamgriddb import HTTPError, SGDBAuthError, SGDBHelper
class SGDBManager(AsyncManager):
"""Manager in charge of downloading a game's cover from steamgriddb"""
run_after = set((SteamAPIManager,))
run_after = set((SteamAPIManager, LocalCoverManager, ItchCoverManager))
retryable_on = set((HTTPError, SSLError))
def manager_logic(self, game: Game, _additional_data: tuple) -> None:
def manager_logic(self, game: Game, _additional_data: dict) -> None:
try:
sgdb = SGDBHelper()
sgdb.conditionaly_update_cover(game)

View File

@@ -15,11 +15,10 @@ class SteamAPIManager(AsyncManager):
retryable_on = set((HTTPError, SSLError))
def manager_logic(self, game: Game, _additional_data: tuple) -> None:
def manager_logic(self, game: Game, _additional_data: dict) -> None:
# Skip non-steam games
if not game.source.startswith("steam_"):
return
# Get online metadata
appid = str(game.game_id).split("_")[-1]
steam = SteamHelper()

View File

@@ -11,14 +11,14 @@ class Pipeline(GObject.Object):
"""Class representing a set of managers for a game"""
game: Game
additional_data: tuple
additional_data: dict
waiting: set[Manager]
running: set[Manager]
done: set[Manager]
def __init__(
self, game: Game, additional_data: tuple, managers: Iterable[Manager]
self, game: Game, additional_data: dict, managers: Iterable[Manager]
) -> None:
super().__init__()
self.game = game

View File

@@ -21,7 +21,7 @@ class Store:
self.managers.add(manager)
def add_game(
self, game: Game, additional_data: tuple, replace=False
self, game: Game, additional_data: dict, replace=False
) -> Pipeline | None:
"""Add a game to the app if not already there