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