sudara/alonetone

View on GitHub
app/models/listen.rb

Summary

Maintainability
A
0 mins
Test Coverage
class Listen < ActiveRecord::Base
  include SoftDeletion

  @@launch_date = 'Tue Jan 01 00:00:00 +0100 2008'.to_time

  scope :from_user,  -> { where('listener_id != ""') }
  scope :downloads,  -> { where(source: 'download') }
  scope :between,    ->(start, finish) { where('listens.created_at BETWEEN ? AND ?', start, finish) }
  scope :since,      ->(date) { where('listens.created_at > ?', date) }

  # A "Listen" occurs when a user listens to another users track
  belongs_to :asset, counter_cache: true, touch: true

  belongs_to :listener, class_name: 'User', foreign_key: 'listener_id', optional: true

  belongs_to :track_owner, class_name: 'User', counter_cache: true

  before_save :truncate_user_agent

  def source
    self[:source] || 'direct hit'
  end

  def self.total
    count(:all)
  end

  def self.today
    where(created_at: Time.now.at_beginning_of_day..Time.now).count
  end

  def self.count_within_a_month(options = {})
    options[:conditions] = ['listens.created_at > ?', 30.days.ago.at_midnight]
    count(:all, options)
  end

  def self.source_chart
    data = count_within_a_month(
      group: :source,
      order: 'count_all DESC',
      limit: 10
    )

    various = count_within_a_month - data.collect(&:last).sum

    data['various other sources'] = various
    data
  end

  def self.monthly_chart
    monthly_counts = []
    count_back_the_months(Time.now.months_ago(1)) { |month|
      monthly_counts << monthly_listen_count_for(month)
    }
    monthly_counts
  end

  def self.last_30_days_chart
    data = count :all,
      conditions: ['listens.created_at > ?', 30.days.ago.at_midnight],
      group: 'DATE(listens.created_at)'

    data = data.collect(&:last)

    chart = Gchart.line(
      size: '500x150',
      data: data,
      background: 'e1e2e1',
      axis_with_labels: 'r,x',
      axis_labels: [GchartHelpers.zero_half_max(data.max),
                             "30 days ago|15 days ago|Today"],
      line_colors: 'cc3300',
      custom: 'chm=B,ff9933,0,0,0'
    )
  end

  def self.most_active_ips(limit = 25)
    Listen.where('created_at > ?', 30.days.ago)
          .order('count_all DESC')
          .group(:ip).limit(limit).count
  end

  def self.most_active_tracks(limit = 25)
    Listen.from('listens IGNORE INDEX(index_listens_on_asset_id)')
          .where('created_at > ?', 30.days.ago).order('count_all DESC')
          .group(:asset).limit(limit).count
  end

  def self.find_user_by_ip(ip)
      Listen.find(:first, conditions: ['ip = ? AND listener_id IS NOT NULL', ip]).listener
  rescue StandardError
      nil
  end

  protected

  # iterate through the months
  def self.count_back_the_months(date = Time.now, &block)
    # throw back the first date
    yield date

    # now, decrease by one month until we hit the start
    count_back_the_months(date.months_ago(1), &block) if date > @@launch_date
  end

  def self.monthly_listen_count_for(date = Time.now)
    # returns [count, year_month_label]
    [Listen.where('created_at > ? AND created_at < ?',
       date.beginning_of_month, date.end_of_month).count,
      date.strftime('%b %y').to_s]
  end

  def truncate_user_agent
    self.user_agent = user_agent.try(:slice, 0, 255)
    self.source = source.try(:slice, 0, 255)
  end
end

# == Schema Information
#
# Table name: listens
#
#  id             :integer          not null, primary key
#  city           :string(255)
#  country        :string(255)
#  deleted_at     :datetime
#  ip             :string(255)
#  source         :string(255)
#  user_agent     :string(255)
#  created_at     :datetime
#  updated_at     :datetime
#  asset_id       :integer
#  listener_id    :integer
#  track_owner_id :integer
#
# Indexes
#
#  index_listens_on_asset_id                       (asset_id)
#  index_listens_on_created_at                     (created_at)
#  index_listens_on_listener_id                    (listener_id)
#  index_listens_on_track_owner_id                 (track_owner_id)
#  index_listens_on_track_owner_id_and_created_at  (track_owner_id,created_at)
#