Show top artists in stats page

This commit is contained in:
Claudio Ortolina
2025-06-16 16:47:35 +03:00
parent 53e7818130
commit 9b20db762d
5 changed files with 139 additions and 0 deletions
+50
View File
@@ -240,6 +240,40 @@ defmodule MusicLibrary.ScrobbleActivity do
Repo.all(query)
end
@doc """
Gets the top artists by scrobble count for the given number of days.
Returns a list of maps with artist information and play counts.
"""
def get_top_artists_by_days(days, opts) do
limit = Keyword.get(opts, :limit, 10)
current_time = Keyword.get_lazy(opts, :current_time, &DateTime.utc_now/0)
timezone = Keyword.get(opts, :timezone, &resolve_timezone!/0)
cutoff_timestamp =
current_time
|> DateTime.add(-days, :day)
|> NaiveDateTime.beginning_of_day()
|> DateTime.from_naive!(timezone)
|> DateTime.to_unix()
query =
from t in Track,
where: t.scrobbled_at_uts >= ^cutoff_timestamp,
group_by: [
fragment("json_extract(artist, '$.name')"),
fragment("json_extract(artist, '$.musicbrainz_id')")
],
select: %{
artist_name: fragment("json_extract(artist, '$.name')"),
artist_musicbrainz_id: fragment("json_extract(artist, '$.musicbrainz_id')"),
play_count: count(t.scrobbled_at_uts)
},
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, along with collected and
@@ -268,6 +302,22 @@ defmodule MusicLibrary.ScrobbleActivity do
}
end
@doc """
Gets top artists for multiple time periods (30, 90, 365 days).
Returns a map with the results for each period.
"""
def get_top_artists_by_periods(opts) do
last_30_days = get_top_artists_by_days(30, opts)
last_90_days = get_top_artists_by_days(90, opts)
last_365_days = get_top_artists_by_days(365, opts)
%{
last_30_days: last_30_days,
last_90_days: last_90_days,
last_365_days: last_365_days
}
end
defp resolve_timezone! do
Application.get_env(:music_library, MusicLibraryWeb)
|> Keyword.fetch!(:timezone)