diff --git a/PROJECT.org b/PROJECT.org index 8a02e8f..4ac2b88 100644 --- a/PROJECT.org +++ b/PROJECT.org @@ -88,7 +88,7 @@ fetching and simple saving. *** Metadata sources **** Scraper -* Backlog [2/26] :vrobbler:project:personal: +* Backlog [3/27] :vrobbler:project:personal: ** TODO [#C] After transition to linux add curl_cffi as webpage scrapper again :webpages:metadata: ** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :bug:music:scrobbles: :PROPERTIES: @@ -604,6 +604,21 @@ a helper method to create board game scrobbles given a json blob. It's independent of the email flow it was originally creatdd for ** TODO [#B] Is there way to create unique slugs for media instances :media_types: +** TODO [#A] Update how board game scrobbles work :boardgames: + +*** Description + +When we scrobble a board game from a BGG URL, instead of going to the media +detail page, we should go to the scrobble detail page, with the Edit Log form +expanded by default. + +The Edit log form should have from top to bottom: + + - Board/Variant (one or many BoardGameVariant in a multi-select widget) + - People (which should be similar to the Bird widget on BirdLocation and allow setting per user score, win true/false, rank, new true/false, seat_ordrer) + - Expansion ids (which should a multi-select widget of expansions for this game) + - Location (which should be a drop down of BoardGameLocations for this user) + ** DONE [#A] Add BoardGameVariant model :boardgames: :PROPERTIES: :ID: 0ffb20d5-252f-b13d-473d-5529014602ff @@ -631,21 +646,10 @@ expansions for the board game when creating it for the first time. We should also create a managemnt script to update existing board games. -** TODO [#A] Update how board game scrobbles work :boardgames: - -*** Description - -When we scrobble a board game from a BGG URL, instead of going to the media -detail page, we should go to the scrobble detail page, with the Edit Log form -expanded by default. - -The Edit log form should have from top to bottom: - - - Board/Variant (one or many BoardGameVariant in a multi-select widget) - - People (which should be similar to the Bird widget on BirdLocation and allow setting per user score, win true/false, rank, new true/false, seat_ordrer) - - Expansion ids (which should a multi-select widget of expansions for this game) - - Location (which should be a drop down of BoardGameLocations for this user) - +** DONE [#A] Board game expansion lookup should be async on URL scrobbles :boardgames: +:PROPERTIES: +:ID: 968d8dde-f906-cdf0-af4e-b87ce28ddbbb +:END: * Version 58.8 [1/1] ** DONE [#B] Clean up trend templates :trends:templates: :PROPERTIES: diff --git a/vrobbler/apps/boardgames/models.py b/vrobbler/apps/boardgames/models.py index 0d0e6a2..dee66ea 100644 --- a/vrobbler/apps/boardgames/models.py +++ b/vrobbler/apps/boardgames/models.py @@ -382,7 +382,12 @@ class BoardGame(ScrobblableMixin): self.cover.save(fname, ContentFile(r.content), save=True) @classmethod - def find_or_create(cls, lookup_id: str, data: dict[str, Any] = {}) -> "BoardGame": + def find_or_create( + cls, + lookup_id: str, + data: dict[str, Any] = {}, + defer_expansions: bool = False, + ) -> "BoardGame": """Given a Lookup ID (either BGG or BGA ID), return a board game object""" game = cls.objects.filter(bggeek_id=lookup_id).first() if not game: @@ -438,9 +443,14 @@ class BoardGame(ScrobblableMixin): publisher, _ = BoardGamePublisher.objects.get_or_create(name=name) game.publishers.add(publisher) - from boardgames.utils import fetch_and_link_expansions + if defer_expansions: + from boardgames.tasks import fetch_board_game_expansions - fetch_and_link_expansions(game, expansions) + fetch_board_game_expansions.delay(game.id, expansions) + else: + from boardgames.utils import fetch_and_link_expansions + + fetch_and_link_expansions(game, expansions) return game diff --git a/vrobbler/apps/boardgames/tasks.py b/vrobbler/apps/boardgames/tasks.py new file mode 100644 index 0000000..d748ecd --- /dev/null +++ b/vrobbler/apps/boardgames/tasks.py @@ -0,0 +1,29 @@ +import logging + +from celery import shared_task + +logger = logging.getLogger(__name__) + + +@shared_task +def fetch_board_game_expansions(board_game_id, expansions_data): + from boardgames.models import BoardGame + from boardgames.utils import fetch_and_link_expansions + + game = BoardGame.objects.filter(id=board_game_id).first() + if not game: + logger.warning( + "Board game not found for expansion linking", + extra={"board_game_id": board_game_id}, + ) + return + + fetch_and_link_expansions(game, expansions_data) + logger.info( + "Linked expansions for board game", + extra={ + "board_game_id": board_game_id, + "title": game.title, + "count": len(expansions_data), + }, + ) diff --git a/vrobbler/apps/scrobbles/scrobblers.py b/vrobbler/apps/scrobbles/scrobblers.py index 88e6dce..c7c3e1a 100644 --- a/vrobbler/apps/scrobbles/scrobblers.py +++ b/vrobbler/apps/scrobbles/scrobblers.py @@ -371,7 +371,7 @@ def manual_scrobble_board_game( source: str = "BGG", action: Optional[str] = None, ) -> Scrobble | None: - boardgame = BoardGame.find_or_create(bggeek_id) + boardgame = BoardGame.find_or_create(bggeek_id, defer_expansions=True) if not boardgame: logger.error(f"No board game found for ID {bggeek_id}")