155 lines
6.8 KiB
Ruby
155 lines
6.8 KiB
Ruby
|
|
module JamRuby
|
|
class Feed < ActiveRecord::Base
|
|
|
|
belongs_to :recording, class_name: "JamRuby::Recording", inverse_of: :feed, foreign_key: 'recording_id'
|
|
belongs_to :music_session, class_name: "JamRuby::MusicSession", inverse_of: :feed, foreign_key: 'music_session_id'
|
|
|
|
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
|
|
SORT_TYPES = ['date', 'plays', 'likes']
|
|
TIME_RANGES = { "today" => 1 , "week" => 7, "month" => 30, "all" => 0}
|
|
TYPE_FILTERS = ['music_session', 'recording', 'all']
|
|
|
|
def self.index(user, params = {})
|
|
limit = params[:limit]
|
|
limit ||= 20
|
|
limit = limit.to_i
|
|
|
|
# validate sort
|
|
sort = params[:sort]
|
|
sort ||= 'date'
|
|
raise "not valid sort #{sort}" unless SORT_TYPES.include?(sort)
|
|
|
|
start = params[:start].presence
|
|
if sort == 'date'
|
|
start ||= FIXNUM_MAX
|
|
else
|
|
start ||= 0
|
|
end
|
|
start = start.to_i
|
|
|
|
time_range = params[:time_range]
|
|
time_range ||= 'month'
|
|
raise "not valid time_range #{time_range}" unless TIME_RANGES.has_key?(time_range)
|
|
|
|
type_filter = params[:type]
|
|
type_filter ||= 'all'
|
|
raise "not valid type #{type_filter}" unless TYPE_FILTERS.include?(type_filter)
|
|
|
|
target_user = params[:user]
|
|
target_band = params[:band]
|
|
|
|
#query = Feed.includes([:recording]).includes([:music_session]).limit(limit)
|
|
query = Feed.joins("LEFT OUTER JOIN recordings ON recordings.id = feeds.recording_id")
|
|
.joins("LEFT OUTER JOIN music_sessions ON music_sessions.id = feeds.music_session_id")
|
|
.limit(limit)
|
|
.where('recordings is NULL OR recordings.all_discarded = false') # remove any 'all_discarded recordings from the search results'
|
|
|
|
# handle sort
|
|
if sort == 'date'
|
|
query = query.where("feeds.id < #{start}")
|
|
query = query.order('feeds.id DESC')
|
|
elsif sort == 'plays'
|
|
query = query.offset(start)
|
|
query = query.order("COALESCE(recordings.play_count, music_sessions.play_count) DESC ")
|
|
elsif sort == 'likes'
|
|
query = query.offset(start)
|
|
query = query.order("COALESCE(recordings.like_count, music_sessions.like_count) DESC ")
|
|
else
|
|
raise "sort not implemented: #{sort}"
|
|
end
|
|
|
|
# handle time range
|
|
days = TIME_RANGES[time_range]
|
|
if days > 0
|
|
query = query.where("feeds.created_at > NOW() - '#{days} day'::INTERVAL")
|
|
end
|
|
|
|
# handle type filters
|
|
if type_filter == 'music_session'
|
|
query = query.where('feeds.music_session_id is not NULL')
|
|
elsif type_filter == 'recording'
|
|
query = query.where('feeds.recording_id is not NULL')
|
|
end
|
|
|
|
|
|
if target_user
|
|
|
|
if target_user != user.id
|
|
require_public_recordings = "claimed_recordings.is_public = TRUE AND"
|
|
require_public_sessions = "music_sessions.fan_access = TRUE AND"
|
|
end
|
|
|
|
query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND #{require_public_recordings} (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))")
|
|
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND #{require_public_sessions} music_sessions_user_history.user_id = '#{target_user}'")
|
|
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
|
if sort == 'plays'
|
|
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
|
elsif sort == 'likes'
|
|
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
|
end
|
|
query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL')
|
|
query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
|
|
|
elsif target_band
|
|
|
|
unless Band.find(target_band).users.include?(user)
|
|
require_public_recordings = "claimed_recordings.is_public = TRUE AND"
|
|
require_public_sessions = "music_sessions.fan_access = TRUE AND"
|
|
end
|
|
|
|
query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND #{require_public_recordings} recordings.band_id = '#{target_band}'")
|
|
query = query.where("music_sessions IS NULL OR #{require_public_sessions} music_sessions.band_id = '#{target_band}'")
|
|
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
|
if sort == 'plays'
|
|
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
|
elsif sort == 'likes'
|
|
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
|
end
|
|
query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL')
|
|
#query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
|
else
|
|
query = query.joins('LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND claimed_recordings.is_public = TRUE')
|
|
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND music_sessions.fan_access = TRUE")
|
|
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
|
if sort == 'plays'
|
|
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
|
elsif sort == 'likes'
|
|
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
|
end
|
|
query = query.where('recordings.id is NULL OR claimed_recordings.is_public = TRUE')
|
|
query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
|
end
|
|
|
|
|
|
|
|
|
|
if params[:hash]
|
|
if query.length == 0
|
|
{ query:query, next: nil}
|
|
elsif query.length < limit
|
|
{ query:query, next: nil}
|
|
else
|
|
if sort == 'date'
|
|
{ query:query, next: query.last.id}
|
|
else
|
|
{ query:query, next: start + limit}
|
|
end
|
|
end
|
|
else
|
|
if query.length == 0
|
|
[query, nil]
|
|
elsif query.length < limit
|
|
[query, nil]
|
|
else
|
|
if sort == 'date'
|
|
[query, query.last.id]
|
|
else
|
|
[query, start + limit]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|