diff --git a/PROJECT.org b/PROJECT.org index 4004bd8..5edbb6e 100644 --- a/PROJECT.org +++ b/PROJECT.org @@ -88,7 +88,7 @@ fetching and simple saving. *** Metadata sources **** Scraper -* Backlog [1/21] :vrobbler:project:personal: +* Backlog [2/22] :vrobbler:project:personal: ** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :bug:music:scrobbles: :PROPERTIES: :ID: 702462cf-d54b-48c6-8a7c-78b8de751deb @@ -590,6 +590,10 @@ We should rename `email_scrobble_board_game` to reflect the fact that it's just a helper method to create board game scrobbles given a json blob. It's independent of the email flow it was originally creatdd for +** DONE [#A] Concurrent reading trend does not consolidate on single book :trends:reading: +:PROPERTIES: +:ID: fe220f55-7e0d-2a17-2477-a5aa7c4a1f2c +:END: ** DONE [#B] Trends dont seem to look very far back :trends: :PROPERTIES: :ID: ffcfba3f-5a93-9ee0-9680-666e6eccd684 diff --git a/vrobbler/apps/trends/trends/concurrent.py b/vrobbler/apps/trends/trends/concurrent.py index eb9ac4b..d970537 100644 --- a/vrobbler/apps/trends/trends/concurrent.py +++ b/vrobbler/apps/trends/trends/concurrent.py @@ -216,43 +216,57 @@ def compute_concurrent_reading(user, period="all_time"): anchor_to_paired = _find_concurrent(anchor_scrobbles, paired_scrobbles) paired_by_pk = {s.pk: s for s in paired_scrobbles} - books = [] + books_by_uuid = {} for anchor in anchor_scrobbles: paired_pks = anchor_to_paired.get(anchor.pk, []) if not paired_pks: continue - tracks_by_name = defaultdict(int) - track_details = {} + book = anchor.book + book_uuid = str(book.uuid) if book and book.uuid else "" + book_key = book_uuid or str(book) if book else "Unknown" + + if book_key not in books_by_uuid: + books_by_uuid[book_key] = { + "book_title": str(book) if book else "Unknown", + "book_uuid": book_uuid, + "total_sessions": 0, + "tracks_by_name": defaultdict(int), + "track_details": {}, + } + + books_by_uuid[book_key]["total_sessions"] += len(paired_pks) + for p_pk in paired_pks: ps = paired_by_pk[p_pk] track = ps.track if track is None: continue name = str(track) - tracks_by_name[name] += 1 - if name not in track_details: - track_details[name] = { + books_by_uuid[book_key]["tracks_by_name"][name] += 1 + if name not in books_by_uuid[book_key]["track_details"]: + books_by_uuid[book_key]["track_details"][name] = { "track_name": name, "track_uuid": str(track.uuid) if track.uuid else "", "artist_name": str(track.artist) if track.artist else "", } - book = anchor.book + books = [] + for bd in books_by_uuid.values(): books.append( { - "book_title": str(book) if book else "Unknown", - "book_uuid": str(book.uuid) if book and book.uuid else "", - "total_sessions": len(paired_pks), + "book_title": bd["book_title"], + "book_uuid": bd["book_uuid"], + "total_sessions": bd["total_sessions"], "tracks": sorted( [ - {**track_details[name], "count": count} - for name, count in tracks_by_name.items() + {**bd["track_details"][name], "count": count} + for name, count in bd["tracks_by_name"].items() ], key=lambda x: x["count"], reverse=True, - )[:20], + )[:5], } )