From 17706f3f56e6e3a329619431587d8bb542e5e8bf Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Sat, 8 Aug 2026 12:33:15 -0400 Subject: [PATCH] [project] Groom backlog --- PROJECT.org | 302 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 215 insertions(+), 87 deletions(-) diff --git a/PROJECT.org b/PROJECT.org index e49b1af..45a1892 100644 --- a/PROJECT.org +++ b/PROJECT.org @@ -19,6 +19,31 @@ to be sometimes cathartic and sometimes functional as I try to remember when I did a thing. * Backlog [2/26] :vrobbler:project:personal: +** TODO [#C] Configure IMAP folder/start in user profile :imap:settings: +*** Description + +Refactor the IMAP import flow as something that can be configured in a tab of the user profile's settings. + +*** Implementation + +Mostly I used webdav now, but we should maintain IMAP importing as an option in user settings. + +- File: ~vrobbler/apps/scrobbles/importers/imap.py~ (line 30) +- Mailbox folder is hardcoded to ="INBOX"=. Should be configurable in the + user's IMAP profile settings, especially for users with complex folder structures. + +** TODO [#C] Verify Last.fm timestamp timezone handling :lastfm:timestamps: +*** Description + +Last.FM timezone handling may not work 100% correctly. And maybe that's okay. + +*** Implementation + +- File: ~vrobbler/apps/scrobbles/importers/lastfm.py~ (line 148) +- A TODO questions whether the current =utcfromtimestamp()= + =.replace()= + pattern is correct. The commented-out =datetime.fromtimestamp(..., UTC)= + may be the right approach. Needs review. + ** TODO [#C] After transition to linux add curl_cffi as webpage scrapper again :webpages:metadata: :PROPERTIES: :ID: d3cce1a7-d540-4d66-bf66-e75378e4eac7 @@ -339,6 +364,162 @@ placed in the media directory: And this should all be done in a celery task that is just kicked off by the "Export" button on the frontend +** TODO [#C] Implement loguru into project :feature:loguru:logging: +:PROPERTIES: +:ID: efcd0c0a-db81-4518-9c23-5505d59e8ef5 +:END: + +*** Description + +Would be great to formalize how we log so we can search for errors and such more +easily. And our exposure to PII is really low at this point in the project, +so we can probably use backtrace=True and diagnose=True to help us root cause +bugs faster. + +** TODO [#C] Make podcast date format configurable in settings :podcasts:configuration: +:PROPERTIES: +:ID: b01a94f8-328f-41ed-a62e-8b99c755b82d +:END: + +*** Description + +=PODCAST_DATE_FORMAT= is hardcoded to ="YYYY-MM-DD"=. Should be in Django settings or environment variables for deploy-specific configuration. + +File: ~vrobbler/apps/podcasts/utils.py~ (line 13) + +** TODO [#C] Extract zombie scrobble query into custom manager :refactoring:manager: +:PROPERTIES: +:ID: 79c874e1-ca6f-4bce-9259-e3eebdca8a41 +:END: + +*** Description + +The zombie scrobble cleanup query lives in a utility function. Should be a +custom model manager method (e.g. =Scrobble.objects.zombies()=). + +File: ~vrobbler/apps/scrobbles/utils.py~ (line 204) + +** TODO [#C] Allow profile to set start of week :profiles:configuration: +:PROPERTIES: +:ID: 0449279a-9550-430e-be0c-816df7273080 +:END: + +*** Description +=start_of_week()= and =end_of_week()= use Monday as default. Should be a user +profile setting for different cultural week start conventions. + +File: ~vrobbler/apps/profiles/utils.py~ (lines 39, 44) + +** TODO [#C] Add constants for data dictionary keys (multiple files) :refactoring:constants: +:PROPERTIES: +:ID: d4415f9b-620a-4be7-925d-fa71c02ba1d1 +:END: + +*** Description +Multiple files use magic string literals for dict keys. Should be extracted to +named constants for maintainability. + +- Files: + - ~vrobbler/apps/locations/models.py~ (line 63) -- ="lat"=, ="lon"= etc. + - ~vrobbler/apps/webpages/models.py~ (line 290) -- ="url"= + - ~vrobbler/apps/scrobbles/importers/tsv.py~ (line 55) -- ="S"= completion status + +** TODO [#C] Add track number and rating to CSV export :export:metadata: + +*** Description + +Track number and rating are missing in the CSV export of scrobbles. + +*** Implementation +Also need to generally clean up how exporting works. + +- File: ~vrobbler/apps/scrobbles/export.py~ (lines 51-52) +- Track number is hardcoded to =0= and rating is hardcoded to ="S"=. + The data model may need extension to support these fields. + +** TODO [#C] Simplify Track creation API in scrobblers :refactoring:api: + - File: ~vrobbler/apps/scrobbles/scrobblers.py~ (line 79) + - =Track.find_or_create()= requires individual kwargs extracted from =post_data=. + Should accept a dict or have a cleaner unified interface. + +** TODO [#C] Enrich books/authors after creation (recurring pattern) :books:enrichment: + +*** Description + +Generally move enrichment of media to follow-up tasks, so long as we have media length and +title from the input source. + +*** Implementation + - Files: + - ~vrobbler/apps/books/models.py~ (lines 239, 320, 548) + - ~vrobbler/apps/books/koreader.py~ (lines 79, 119) + - Multiple places where Authors and Books are created without follow-up enrichment. + Should fire async enrichment tasks (Celery) after creation. + +** TODO [#C] Enrich TMDB resultw with TMDB URL :videos:enrichment: + - File: ~vrobbler/apps/videos/sources/tmdb.py~ (lines 46, 56) + - Cover URLs are constructed but the actual TMDB page URL for the movie/show + is not stored. Minor enrichment. + +** TODO [#C] Enrich bricksets from website on creation :bricksets:enrichment: +*** Implementation +- File: ~vrobbler/apps/bricksets/models.py~ (line 75) +- =BrickSet.find_or_create()= only stores the set number. Should fetch additional + data (name, piece count, image) from brickset.com or similar. + +** TODO [#B] Make WebDAV paths configurable per-user :webdav:settings: +*** Description + +This may be a no-op now. A lot of webdav code has changed. + +*** Implementation + +- File: ~vrobbler/apps/scrobbles/importers/webdav.py~ (lines 125, 410) +- Both the GPX path and scale path are hardcoded via =DEFAULT_GPX_PATH= and + =DEFAULT_SCALE_PATH=. Should be configurable in user profile settings. +** TODO [#B] Add auto-population of serial scrobble IDs for bricksets :bricksets:serials: +:PROPERTIES: +:ID: 69dcb387-c7f0-40d0-895f-60d79c664b10 +:END: + +*** Implementation + +When scrobbling bricksets (LEGO), should check for past scrobbles and auto-populate a serial scrobble ID for tracking multiple builds of the same set. + +File: ~vrobbler/apps/scrobbles/scrobblers.py~ (line 1245) +** TODO [#B] Raise exception on WebDAV fetch failure :webdav:error-handling: +*** Implementation + +- File: ~vrobbler/apps/books/koreader.py~ (line 418) +- =fetch_file_from_webdav()= returns an empty string on failure, which could + silently propagate. Should raise an exception for proper error handling. + +** TODO [#B] Make book matching use Google Books ID or author name :books:matching: +*** Description + +This may be a no-op situation as we've moved away from Google Books. But maybe we haven't. + +*** Implementation + +- File: ~vrobbler/apps/books/models.py~ (line 270) +- =Book.find_or_create()= only matches by =original_title=, which is fragile. + Should also match by Google Books ID or author name (like Track does). + +** TODO [#B] TODOIST_* variable names flagged as TODOs (false positives) :tasks:metadata:cleanup: +*** Description + +Need to clean up how we store task data in logdata. + +*** Implementation + +Should clean up the task logdata dict so that we have fewer source-specific names, try to generalize task detail implementation from the input source, while keeping the full task payload for future reference. + +- Files: + - ~vrobbler/settings.py~ (lines 72-73) -- =TODOIST_CLIENT_ID=, =TODOIST_CLIENT_SECRET= + - ~vrobbler/apps/scrobbles/constants.py~ (line 39) -- =TODOIST_TASK_URL= + - ~vrobbler/apps/tasks/models.py~ (line 13) -- =TODOIST_TASK_URL= +- These are variable/constant names for the Todoist integration, not actual + TODOs. No action needed, but worth noting they show up in searches. ** TODO [#B] Add AllTrails as a source for Trail data :trails:feature: :PROPERTIES: :ID: 39313362-cdfe-46e7-bbd4-9139a65c0b3c @@ -398,6 +579,39 @@ needed import celery task. This is how the WebDAV celery task currently works. This would also be an opporunity to clean up the code around WebDAV imports and make them more re-usable for other import services. +** TODO [#B] Allow browing a user's favorited media :favorites:feature: +:PROPERTIES: +:ID: 5c2cf004-d01f-4576-9bbb-974235e7408a +:END: + +*** Description + +We should have a global view `/favorites/` that shows the logged in users's +favorited media objects. + +** TODO [#B] Find page numbers for comic books from ComicVine :feature:books: +:PROPERTIES: +:ID: 79f867c3-1288-4143-b6bf-2a452983ee9f +:END: +** TODO [#B] Is there way to create unique slugs for media instances :media_types: +** TODO [#B] Add async media enrichment after scrobbling (recurring pattern) :async:enrichment: +- Files: ~vrobbler/apps/scrobbles/scrobblers.py~ (lines 1179, 1211, 1244) +- Three separate TODOs for beer, puzzle, and brickset scrobbles all request + firing an async process to enrich media after creation. This is the same + pattern repeated across media types -- should be solved generically. + +** TODO [#B] Auto sync board game scrobbles to BGG :boardgames: + +*** Description + +** TODO [#B] Scrape ComicBookRoundUp ratings for comic book metadata :books:feature:comicbook: +:PROPERTIES: +:ID: b3cc57ca-3d2c-468d-ab7c-c47f1120309b +:END: + +*** Description +As an example https://comicbookroundup.com/comic-books/reviews/humanoids-publishing/the-history-of-science-fiction + ** TODO [#A] Add an exception list of artists as a constant that are exempted from splitting :music:artists:metadata: :PROPERTIES: :ID: fd86a11a-73ec-470d-b5e3-2d90ba9137c8 @@ -430,89 +644,6 @@ async with the POST data stored in the log["raw_data"] and used by the celery en to go try to enrich the media instance. Should this enrichment fail, tag the scrobble as "enrichment-failed" log a warning and move on. -** TODO [#B] Allow browing a user's favorited media :favorites:feature: -:PROPERTIES: -:ID: 5c2cf004-d01f-4576-9bbb-974235e7408a -:END: - -*** Description - -We should have a global view `/favorites/` that shows the logged in users's -favorited media objects. - -** TODO [#B] Find page numbers for comic books from ComicVine :feature:books: -:PROPERTIES: -:ID: 79f867c3-1288-4143-b6bf-2a452983ee9f -:END: -** TODO [#C] Implement loguru into project :feature:loguru:logging: -:PROPERTIES: -:ID: efcd0c0a-db81-4518-9c23-5505d59e8ef5 -:END: - -*** Description - -Would be great to formalize how we log so we can search for errors and such more -easily. And our exposure to PII is really low at this point in the project, -so we can probably use backtrace=True and diagnose=True to help us root cause -bugs faster. - -** TODO [#B] Scrape ComicBookRoundUp ratings for comic book metadata :books:feature:comicbook: -:PROPERTIES: -:ID: b3cc57ca-3d2c-468d-ab7c-c47f1120309b -:END: - -*** Description -As an example https://comicbookroundup.com/comic-books/reviews/humanoids-publishing/the-history-of-science-fiction - -** TODO [#C] Make podcast date format configurable in settings :podcasts:configuration: -:PROPERTIES: -:ID: b01a94f8-328f-41ed-a62e-8b99c755b82d -:END: - -*** Description - -=PODCAST_DATE_FORMAT= is hardcoded to ="YYYY-MM-DD"=. Should be in Django settings or environment variables for deploy-specific configuration. - -File: ~vrobbler/apps/podcasts/utils.py~ (line 13) - -** TODO [#C] Extract zombie scrobble query into custom manager :refactoring:manager: -:PROPERTIES: -:ID: 79c874e1-ca6f-4bce-9259-e3eebdca8a41 -:END: - -*** Description - -The zombie scrobble cleanup query lives in a utility function. Should be a -custom model manager method (e.g. =Scrobble.objects.zombies()=). - -File: ~vrobbler/apps/scrobbles/utils.py~ (line 204) - -** TODO [#C] Allow profile to set start of week :profiles:configuration: -:PROPERTIES: -:ID: 0449279a-9550-430e-be0c-816df7273080 -:END: - -*** Description -=start_of_week()= and =end_of_week()= use Monday as default. Should be a user -profile setting for different cultural week start conventions. - -File: ~vrobbler/apps/profiles/utils.py~ (lines 39, 44) - -** TODO [#C] Add constants for data dictionary keys (multiple files) :refactoring:constants: -:PROPERTIES: -:ID: d4415f9b-620a-4be7-925d-fa71c02ba1d1 -:END: - -*** Description -Multiple files use magic string literals for dict keys. Should be extracted to -named constants for maintainability. - -- Files: - - ~vrobbler/apps/locations/models.py~ (line 63) -- ="lat"=, ="lon"= etc. - - ~vrobbler/apps/webpages/models.py~ (line 290) -- ="url"= - - ~vrobbler/apps/scrobbles/importers/tsv.py~ (line 55) -- ="S"= completion status - -** TODO [#B] Is there way to create unique slugs for media instances :media_types: ** TODO [#A] Update how board game scrobbles work :boardgames: *** Description @@ -528,10 +659,6 @@ The Edit log form should have from top to bottom: - 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) -** TODO [#B] Auto sync board game scrobbles to BGG :boardgames: - -*** Description - ** TODO [#A] Add trends tests for concurrent trends :trends:tests:concurrent: :PROPERTIES: :ID: ca613753-d203-4429-b062-36e3312bca82 @@ -556,6 +683,7 @@ Added a `workouts` Django app so we can scrobble gym sessions. - Templates, admin, DRF viewsets (`exercises`, `workout-routines`), MCP tools, and `tests/workouts_tests/` (unit conversion, form round-trips, importer, imperial POST) included. +** TODO [#A] Dedup track scrobbles from lastfm import :importers:lastfm:tracks: ** DONE [#A] Fix celery task prioritization especially for agent sessions :celery:tasks:agents: :PROPERTIES: :ID: 672c81bf-bba9-a963-e8ac-52246d976cea