diff --git a/lib/music_library/scrobble_activity.ex b/lib/music_library/scrobble_activity.ex index 512b976f..7bba0bbf 100644 --- a/lib/music_library/scrobble_activity.ex +++ b/lib/music_library/scrobble_activity.ex @@ -1,7 +1,9 @@ defmodule MusicLibrary.ScrobbleActivity do - alias LastFm.Scrobble + import Ecto.Query + + alias LastFm.{Scrobble, Track} alias MusicBrainz.Release - alias MusicLibrary.{Artists, Collection, Secrets, Wishlist} + alias MusicLibrary.{Artists, Collection, Repo, Secrets, Wishlist} def can_scrobble? do Secrets.get("last_fm_session_key") !== nil @@ -200,4 +202,46 @@ defmodule MusicLibrary.ScrobbleActivity do |> Enum.reject(fn musicbrainz_id -> musicbrainz_id == "" end) |> MapSet.new() end + + @doc """ + Gets the top albums by scrobble count for the given number of days. + Returns a list of maps with album information and play counts. + """ + def get_top_albums_by_days(days, limit \\ 10) do + cutoff_timestamp = + DateTime.utc_now() + |> DateTime.add(-days, :day) + |> DateTime.to_unix() + + query = + from t in Track, + where: t.scrobbled_at_uts >= ^cutoff_timestamp, + group_by: [ + fragment("json_extract(album, '$.title')"), + fragment("json_extract(artist, '$.name')") + ], + select: %{ + album_title: fragment("json_extract(album, '$.title')"), + artist_name: fragment("json_extract(artist, '$.name')"), + play_count: count(t.scrobbled_at_uts), + cover_url: fragment("max(?)", t.cover_url), + album_mbid: fragment("json_extract(album, '$.musicbrainz_id')") + }, + order_by: [desc: count(t.scrobbled_at_uts)], + limit: ^limit + + Repo.all(query) + end + + @doc """ + Gets top albums for multiple time periods (30, 90, 365 days). + Returns a map with the results for each period. + """ + def get_top_albums_by_periods(limit \\ 10) do + %{ + last_30_days: get_top_albums_by_days(30, limit), + last_90_days: get_top_albums_by_days(90, limit), + last_365_days: get_top_albums_by_days(365, limit) + } + end end diff --git a/lib/music_library_web/live/stats_live/index.ex b/lib/music_library_web/live/stats_live/index.ex index efd9e974..605cbc8f 100644 --- a/lib/music_library_web/live/stats_live/index.ex +++ b/lib/music_library_web/live/stats_live/index.ex @@ -76,6 +76,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do recent_tracks = LastFm.get_scrobbled_tracks() records_by_artists = Collection.count_records_by_artist(limit: 20) records_by_genre = Collection.count_records_by_genre(limit: 20) + top_albums = ScrobbleActivity.get_top_albums_by_periods(10) if connected?(socket) do LastFm.subscribe_to_feed() @@ -98,7 +99,8 @@ defmodule MusicLibraryWeb.StatsLive.Index do page_title: gettext("Stats"), current_section: :stats, records_by_artist: records_by_artists, - records_by_genre: records_by_genre + records_by_genre: records_by_genre, + top_albums: top_albums )} end diff --git a/lib/music_library_web/live/stats_live/index.html.heex b/lib/music_library_web/live/stats_live/index.html.heex index 988b9ba5..9f92196d 100644 --- a/lib/music_library_web/live/stats_live/index.html.heex +++ b/lib/music_library_web/live/stats_live/index.html.heex @@ -112,6 +112,92 @@ +
+ {album.artist_name} +
++ {album.album_title} +
++ {album.artist_name} +
++ {album.album_title} +
++ {album.artist_name} +
++ {album.album_title} +
+