plays-hub/app/models/statistics.rb

79 lines
2.5 KiB
Ruby

class Statistics
attr_reader :user
def initialize(user)
@user = user
end
def total_plays
Activity.where(user: user).count
end
def total_plays_year
year_start = Date.today.beginning_of_year
Activity.where(user: user, created_at: year_start..Date.today.end_of_day).count
end
def activity_by_day
start_date = 1.year.ago.to_date
end_date = Date.today
activities = Activity.where(user: user, created_at: start_date.beginning_of_day..end_date.end_of_day)
activities.group("DATE(created_at)").count.transform_keys { |d| d.to_s }
end
def top_artists_all_time
Activity.where(user: user)
.group(:item_title).order("count_id DESC").limit(5).count(:id)
end
def top_artists_year
year_start = Date.today.beginning_of_year
Activity.where(user: user, created_at: year_start..Date.today.end_of_day)
.group(:item_title).order("count_id DESC").limit(5).count(:id)
end
def top_artists_upcoming
upcoming_start = 30.days.ago.to_date
upcoming_end = Date.today
Activity.where(user: user, started_at: upcoming_start.beginning_of_day..upcoming_end.end_of_day)
.group(:item_title).order("count_id DESC").limit(5).count(:id)
end
def since_date
Activity.where(user: user).order(:created_at).limit(1).pick(:created_at)
end
# Returns a hash with streak info: :start_date, :end_date, :length, :total_plays, :most_played_song, :most_played_song_count
def longest_streak
days = activity_by_day.keys.map { |d| Date.parse(d) }.sort
return nil if days.empty?
streaks = []
current_streak = []
days.each_with_index do |day, i|
if i == 0 || day == days[i-1] + 1
current_streak << day
else
streaks << current_streak
current_streak = [day]
end
end
streaks << current_streak unless current_streak.empty?
best = streaks.max_by(&:length)
return nil unless best && best.length > 0
streak_start = best.first
streak_end = best.last
plays = Activity.where(user: user, created_at: streak_start.beginning_of_day..streak_end.end_of_day)
total_plays = plays.count
song_counts = plays.group(:item_title).order('count_id DESC').limit(1).count(:id)
most_played_song, most_played_song_count = song_counts.first || [nil, 0]
{
start_date: streak_start,
end_date: streak_end,
length: best.length,
total_plays: total_plays,
most_played_song: most_played_song,
most_played_song_count: most_played_song_count
}
end
end