sessions / 4b005e0e5b52376c38b9e8f009c80c5319bd9ff1

/home/powellc/src/code.unbl.ink/secstate/vrobbler

This commit has no recorded session.

diff

ignore whitespace

commit 4b005e0e5b52376c38b9e8f009c80c5319bd9ff1Author: Colin Powell <colin@unbl.ink>Date:   Sat Jul 4 01:47:15 2026 -0400    [boardgames] Lookup expansions async for URL scrobblesdiff --git a/PROJECT.org b/PROJECT.orgindex 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.pyindex 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.pynew file mode 100644index 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.pyindex 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}")