Added Itch source

- Added call stack to unretryable errors in managers
- Added existing itch cover downloading code
- Fixed importer not closing if no source enabled

TODO
- Tidying the itch cover downloading code
- If possible, make save_cover and resize_cover work in AsyncManager-s
This commit is contained in:
GeoffreyCoulaud
2023-06-07 15:33:00 +02:00
parent 5dc6ec899a
commit 9ebd7cf7ee
5 changed files with 69 additions and 19 deletions

View File

@@ -1,11 +1,15 @@
from urllib3.exceptions import SSLError
from pathlib import Path
import requests
from gi.repository import GdkPixbuf, Gio
from requests import HTTPError
from urllib3.exceptions import SSLError
from src import shared
from src.game import Game
from src.store.managers.async_manager import AsyncManager
from src.store.managers.local_cover_manager import LocalCoverManager
from src.utils.save_cover import resize_cover, save_cover
class ItchCoverManager(AsyncManager):
@@ -15,5 +19,43 @@ class ItchCoverManager(AsyncManager):
retryable_on = set((HTTPError, SSLError))
def manager_logic(self, game: Game, additional_data: dict) -> None:
# TODO move itch cover logic here
pass
# Get the first matching cover url
base_cover_url: str = additional_data.get("itch_cover_url", None)
still_cover_url: str = additional_data.get("itch_still_cover_url", None)
cover_url = still_cover_url or base_cover_url
if not cover_url:
return
# Download cover
tmp_file = Gio.File.new_tmp()[0]
with requests.get(cover_url, timeout=5) as cover:
cover.raise_for_status()
Path(tmp_file.get_path()).write_bytes(cover.content)
# TODO comment the following blocks of code
game_cover = GdkPixbuf.Pixbuf.new_from_stream_at_scale(
tmp_file.read(), 2, 2, False
).scale_simple(*shared.image_size, GdkPixbuf.InterpType.BILINEAR)
itch_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(tmp_file.read())
itch_pixbuf = itch_pixbuf.scale_simple(
shared.image_size[0],
itch_pixbuf.get_height() * (shared.image_size[0] / itch_pixbuf.get_width()),
GdkPixbuf.InterpType.BILINEAR,
)
itch_pixbuf.composite(
game_cover,
0,
(shared.image_size[1] - itch_pixbuf.get_height()) / 2,
itch_pixbuf.get_width(),
itch_pixbuf.get_height(),
0,
(shared.image_size[1] - itch_pixbuf.get_height()) / 2,
1.0,
1.0,
GdkPixbuf.InterpType.BILINEAR,
255,
)
# Resize and save the cover
save_cover(game.game_id, resize_cover(pixbuf=game_cover))

View File

@@ -65,32 +65,34 @@ class Manager:
try:
self.manager_logic(game, additional_data)
except Exception as error:
logging_args = (
type(error).__name__,
self.name,
f"{game.name} ({game.game_id})",
)
if error in self.continue_on:
# Handle skippable errors (skip silently)
return
elif error in self.retryable_on:
if try_index < self.max_tries:
# Handle retryable errors
logging_format = "Retrying %s in %s for %s"
logging.error("Retrying %s in %s for %s", *logging_args)
sleep(self.retry_delay)
self.execute_resilient_manager_logic(
game, additional_data, try_index + 1
)
else:
# Handle being out of retries
logging_format = "Out of retries dues to %s in %s for %s"
logging.error(
"Out of retries dues to %s in %s for %s", *logging_args
)
self.report_error(error)
else:
# Handle unretryable errors
logging_format = "Unretryable %s in %s for %s"
logging.error(
"Unretryable %s in %s for %s", *logging_args, exc_info=error
)
self.report_error(error)
# Finally log errors
logging.error(
logging_format,
type(error).__name__,
self.name,
f"{game.name} ({game.game_id})",
)
def process_game(
self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any]