jam-cloud/ruby/lib/jam_ruby/models/active_music_session.rb

831 lines
28 KiB
Ruby
Raw Normal View History

2014-05-06 13:34:38 +00:00
module JamRuby
class ActiveMusicSession < ActiveRecord::Base
@@log = Logging.logger[ActiveMusicSession]
2014-05-06 13:34:38 +00:00
self.primary_key = 'id'
2014-05-06 22:50:41 +00:00
self.table_name = 'active_music_sessions'
2015-01-11 20:15:47 +00:00
attr_accessor :legal_terms, :max_score, :opening_jam_track, :opening_recording, :opening_backing_track, :opening_metronome
2014-05-06 13:34:38 +00:00
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id", :inverse_of => :playing_sessions
belongs_to :claimed_recording_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_claimed_recordings, :foreign_key => "claimed_recording_initiator_id"
belongs_to :jam_track, :class_name => "JamRuby::JamTrack", :foreign_key => "jam_track_id", :inverse_of => :playing_sessions
belongs_to :jam_track_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_jam_tracks, :foreign_key => "jam_track_initiator_id"
2015-01-11 20:15:47 +00:00
belongs_to :backing_track_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_jam_tracks, :foreign_key => "backing_track_initiator_id"
belongs_to :metronome_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_jam_tracks, :foreign_key => "metronome_initiator_id"
has_one :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => 'music_session_id'
2014-05-06 13:34:38 +00:00
has_one :mount, :class_name => "JamRuby::IcecastMount", :inverse_of => :music_session, :foreign_key => 'music_session_id'
belongs_to :creator, :class_name => 'JamRuby::User', :foreign_key => :user_id
2014-05-06 13:34:38 +00:00
has_many :connections, :class_name => "JamRuby::Connection", foreign_key: :music_session_id
2014-05-06 13:34:38 +00:00
has_many :users, :through => :connections, :class_name => "JamRuby::User"
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session, foreign_key: :music_session_id
2014-05-06 13:34:38 +00:00
has_many :chats, :class_name => "JamRuby::ChatMessages", :foreign_key => "session_id"
validates :creator, :presence => true
validate :creator_is_musician
validate :validate_opening_recording, :if => :opening_recording
validate :validate_opening_jam_track, :if => :opening_jam_track
2015-01-11 20:15:47 +00:00
validate :validate_opening_backing_track, :if => :opening_backing_track
validate :validate_opening_metronome, :if => :opening_metronome
2014-05-06 13:34:38 +00:00
after_create :started_session
after_destroy do |obj|
JamRuby::MusicSession.removed_music_session(obj.id)
end
#default_scope :select => "*, 0 as score"
def attributes
super.merge('max_score' => self.max_score)
end
def max_score
nil unless has_attribute?(:max_score)
read_attribute(:max_score).to_i
end
before_create :create_uuid
def create_uuid
#self.id = SecureRandom.uuid
end
def before_destroy
feed = Feed.find_by_music_session_id(self.id)
unless feed.nil?
feed.active = false
feed.save
end
2014-05-06 13:34:38 +00:00
self.mount.destroy if self.mount
end
def creator_is_musician
unless creator.musician?
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
end
end
def validate_opening_recording
unless claimed_recording_id_was.nil?
errors.add(:claimed_recording, ValidationMessages::CLAIMED_RECORDING_ALREADY_IN_PROGRESS)
end
if is_jam_track_open?
errors.add(:claimed_recording, ValidationMessages::JAM_TRACK_ALREADY_OPEN)
end
2015-01-11 20:15:47 +00:00
if is_backing_track_open?
errors.add(:claimed_recording, ValidationMessages::BACKING_TRACK_ALREADY_OPEN)
end
if is_metronome_open?
errors.add(:claimed_recording, ValidationMessages::METRONOME_ALREADY_OPEN)
end
end
def validate_opening_jam_track
2015-01-11 20:15:47 +00:00
validate_other_audio(:jam_track)
end
def validate_opening_backing_track
validate_other_audio(:backing_track)
end
def validate_opening_metronome
validate_other_audio(:metronome)
end
def validate_other_audio(error_key)
# validate that there is no metronome already open in this session
if metronome_active_was
2015-01-11 20:15:47 +00:00
errors.add(error_key, ValidationMessages::METRONOME_ALREADY_OPEN)
end
# validate that there is no backing track already open in this session
if backing_track_path_was.present?
2015-01-11 20:15:47 +00:00
errors.add(error_key, ValidationMessages::BACKING_TRACK_ALREADY_OPEN)
end
# validate that there is no jam track already open in this session
if jam_track_id_was.present?
2015-01-11 20:15:47 +00:00
errors.add(error_key, ValidationMessages::JAM_TRACK_ALREADY_OPEN)
end
# validate that there is no recording being made
if is_recording?
2015-01-11 20:15:47 +00:00
errors.add(error_key, ValidationMessages::RECORDING_ALREADY_IN_PROGRESS)
end
# validate that there is no recording being played back to the session
if is_playing_recording?
2015-01-11 20:15:47 +00:00
errors.add(error_key, ValidationMessages::CLAIMED_RECORDING_ALREADY_IN_PROGRESS)
2014-05-06 13:34:38 +00:00
end
end
# returns an array of client_id's that are in this session
# if as_musician is nil, all connections in the session ,regardless if it's a musician or not or not
# you can also exclude a client_id from the returned set by setting exclude_client_id
def get_connection_ids(options = {})
as_musician = options[:as_musician]
exclude_client_id = options[:exclude_client_id]
where = { :music_session_id => self.id }
where[:as_musician] = as_musician unless as_musician.nil?
exclude = "client_id != '#{exclude_client_id}'"unless exclude_client_id.nil?
Connection.select(:client_id).where(where).where(exclude).map(&:client_id)
end
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
def self.index(current_user, options = {})
participants = options[:participants]
genres = options[:genres]
keyword = options[:keyword]
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
query = ActiveMusicSession
.joins(
%Q{
INNER JOIN
2014-05-06 22:50:41 +00:00
music_sessions
ON
active_music_sessions.id = music_sessions.id
}
)
2014-05-06 13:34:38 +00:00
.joins(
%Q{
INNER JOIN
connections
ON
2014-05-06 22:50:41 +00:00
active_music_sessions.id = connections.music_session_id
2014-05-06 13:34:38 +00:00
}
)
.joins(
%Q{
LEFT OUTER JOIN
friendships
ON
connections.user_id = friendships.user_id
AND
friendships.friend_id = '#{current_user.id}'
}
)
.joins(
%Q{
LEFT OUTER JOIN
invitations
ON
2014-05-06 22:50:41 +00:00
invitations.music_session_id = active_music_sessions.id
2014-05-06 13:34:38 +00:00
AND
invitations.receiver_id = '#{current_user.id}'
}
)
.group(
%Q{
2014-05-06 22:50:41 +00:00
active_music_sessions.id
2014-05-06 13:34:38 +00:00
}
)
.order(
%Q{
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
2014-05-06 22:50:41 +00:00
active_music_sessions.created_at DESC
2014-05-06 13:34:38 +00:00
}
)
if as_musician
query = query.where(
%Q{
musician_access = true
OR
invitations.id IS NOT NULL
}
)
else
# if you are trying to join the session as a fan/listener,
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
2014-05-06 22:50:41 +00:00
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = active_music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
query = query.where('music_sessions.fan_access = true')
2014-05-06 22:50:41 +00:00
query = query.where("(active_music_sessions.created_at < icecast_servers.config_updated_at)")
2014-05-06 13:34:38 +00:00
end
2014-05-06 22:50:41 +00:00
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
2014-05-06 13:34:38 +00:00
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
2014-05-06 22:50:41 +00:00
query = query.where("music_sessions.genre_id in (?)", genres) unless genres.nil?
2014-05-06 13:34:38 +00:00
if my_bands_only
query = query.joins(
%Q{
LEFT OUTER JOIN
bands_musicians
ON
bands_musicians.user_id = '#{current_user.id}'
}
)
end
if my_bands_only || friends_only
query = query.where(
%Q{
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
OR
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
}
)
end
return query
end
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
# note, this is mostly the same as above but includes paging through the result and and scores.
# thus it needs the client_id...
def self.nindex(current_user, options = {})
client_id = options[:client_id]
participants = options[:participants]
genres = options[:genres]
keyword = options[:keyword]
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
offset = options[:offset]
limit = options[:limit]
connection = Connection.where(client_id: client_id).first!
locidispid = connection.locidispid
query = ActiveMusicSession
2014-05-06 22:50:41 +00:00
.select("active_music_sessions.*, max(coalesce(current_scores.score, 1000)) as max_score") # 1000 is higher than the allowed max of 999
2014-05-06 13:34:38 +00:00
.joins(
%Q{
INNER JOIN
2014-05-06 22:50:41 +00:00
music_sessions
2014-05-06 13:34:38 +00:00
ON
active_music_sessions.id = music_sessions.id
2014-05-06 13:34:38 +00:00
}
)
.joins(
%Q{
INNER JOIN
connections
ON
2014-05-06 22:50:41 +00:00
active_music_sessions.id = connections.music_session_id
2014-05-06 13:34:38 +00:00
}
)
.joins(
%Q{
LEFT OUTER JOIN
current_scores
ON
current_scores.alocidispid = connections.locidispid
AND
current_scores.blocidispid = #{locidispid}
}
)
.joins(
%Q{
LEFT OUTER JOIN
friendships
ON
connections.user_id = friendships.user_id
AND
friendships.friend_id = '#{current_user.id}'
}
)
.joins(
%Q{
LEFT OUTER JOIN
invitations
ON
2014-05-06 22:50:41 +00:00
invitations.music_session_id = active_music_sessions.id
2014-05-06 13:34:38 +00:00
AND
invitations.receiver_id = '#{current_user.id}'
}
)
.group(
%Q{
2014-05-06 22:50:41 +00:00
active_music_sessions.id
2014-05-06 13:34:38 +00:00
}
)
.order(
%Q{
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
2014-05-06 22:50:41 +00:00
active_music_sessions.created_at DESC
2014-05-06 13:34:38 +00:00
}
)
2015-01-12 06:20:19 +00:00
query = query.offset(offset) if offset
query = query.limit(limit) if limit
2014-05-06 13:34:38 +00:00
if as_musician
query = query.where(
%Q{
musician_access = true
OR
2014-05-06 22:50:41 +00:00
music_sessions.user_id = '#{current_user.id}'
2014-05-06 13:34:38 +00:00
OR
invitations.id IS NOT NULL
}
)
else
# if you are trying to join the session as a fan/listener,
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
2014-05-06 22:50:41 +00:00
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = active_music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
query = query.where('music_sessions.fan_access = true')
2014-05-06 22:50:41 +00:00
query = query.where("(active_music_sessions.created_at < icecast_servers.config_updated_at)")
2014-05-06 13:34:38 +00:00
end
2014-05-06 22:50:41 +00:00
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
2014-05-06 13:34:38 +00:00
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
2014-05-06 22:50:41 +00:00
query = query.where("music_sessions.genre_id in (?)", genres) unless genres.nil?
2014-05-06 13:34:38 +00:00
if my_bands_only
query = query.joins(
%Q{
LEFT OUTER JOIN
bands_musicians
ON
bands_musicians.user_id = '#{current_user.id}'
}
)
end
if my_bands_only || friends_only
query = query.where(
%Q{
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
OR
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
}
)
end
return query
end
# initialize the two temporary tables we use to drive ams_index and ams_users
def self.ams_init(current_user, options = {})
2014-08-18 15:37:55 +00:00
my_locidispid = current_user.last_jam_locidispid
# 13 is an average audio gear value we use if they have not qualified any gear
2014-08-18 15:37:55 +00:00
my_audio_latency = current_user.last_jam_audio_latency || 13
locidispid_expr = my_locidispid ? "#{my_locidispid}::bigint" : '0::bigint'
self.connection.execute("select ams_index('#{current_user.id}'::varchar, #{locidispid_expr}, #{my_audio_latency}::integer)").check
end
# Generate a list of music sessions (that are active) filtered by genre, language, keyword, and sorted
# (and tagged) by rsvp'd (1st), invited (2nd), and musician can join (3rd). within a group tagged the
# same, sorted by score. date seems irrelevant as these are active sessions. ams_init must be called
# first.
def self.ams_query(current_user, options = {})
session_id = options[:session_id]
client_id = options[:client_id]
genre = options[:genre]
lang = options[:lang]
keyword = options[:keyword]
offset = options[:offset]
limit = options[:limit]
day = options[:day]
timezone_offset = options[:timezone_offset]
query = MusicSession
.select('music_sessions.*')
# this is not really needed when ams_music_session_tmp is joined
# unless there is something specific we need out of active_music_sessions
# query = query.joins(
# %Q{
# INNER JOIN
# active_music_sessions
# ON
# active_music_sessions.id = music_sessions.id
# }
# )
# .select('1::integer as tag, 15::integer as latency')
# integrate ams_music_session_tmp into the processing
# then we can join ams_music_session_tmp and not join active_music_sessions
query = query.joins(
%Q{
INNER JOIN
ams_music_session_tmp
ON
ams_music_session_tmp.music_session_id = music_sessions.id
}
)
.select('ams_music_session_tmp.tag, ams_music_session_tmp.latency')
query = query.order(
%Q{
tag, latency, music_sessions.id
}
)
.group(
%Q{
tag, latency, music_sessions.id
}
)
# if not specified, default offset to 0
offset ||= 0
offset = offset.to_i
# if not specified, default limit to 20
limit ||= 20
limit = limit.to_i
query = query.offset(offset)
query = query.limit(limit)
query = query.where("music_sessions.genre_id = ?", genre) unless genre.blank?
query = query.where('music_sessions.language = ?', lang) unless lang.blank?
query = query.where('music_sessions.id = ?', session_id) unless session_id.blank?
query = query.where("(description_tsv @@ to_tsquery('jamenglish', ?))", ActiveRecord::Base.connection.quote(keyword) + ':*') unless keyword.blank?
if !day.blank? && !timezone_offset.blank?
begin
day = Date.parse(day)
next_day = day + 1
timezone_offset = timezone_offset.to_i
2014-06-26 02:50:20 +00:00
if timezone_offset > 0
timezone_offset = "+#{timezone_offset}"
end
query = query.where("scheduled_start BETWEEN TIMESTAMP WITH TIME ZONE '#{day} 00:00:00#{timezone_offset}'
AND TIMESTAMP WITH TIME ZONE '#{next_day} 00:00:00#{timezone_offset}'")
rescue Exception => e
# do nothing. bad date probably
@@log.warn("unable to parse day=#{day}, timezone_offset=#{timezone_offset}, e=#{e}")
end
end
return query
end
# returns the set of users in a music_sessions and the music_session they are in and their latency.
# ams_init must be called first.
# user.audio_latency / 2 , + other_user.audio_latency of them / 2, + network latency /2
2014-06-16 20:58:44 +00:00
def self.ams_users
2014-08-18 15:37:55 +00:00
return User.select('users.*, ams_users_tmp.music_session_id, ams_users_tmp.full_score, ams_users_tmp.audio_latency, ams_users_tmp.internet_score')
.joins(
%Q{
INNER JOIN
ams_users_tmp
ON
ams_users_tmp.user_id = users.id
}
)
.order('ams_users_tmp.music_session_id, ams_users_tmp.user_id')
end
# wrap me in a transaction!
# note that these queries must be actualized before the end of the transaction
# else the temporary tables created by sms_init will be gone.
def self.ams_index(current_user, params)
ActiveMusicSession.ams_init(current_user, params)
music_sessions = ActiveMusicSession.ams_query(current_user, params).all
music_session_users = ActiveMusicSession.ams_users.all
user_scores = {}
music_session_users.each do |user|
2014-08-18 15:37:55 +00:00
user_scores[user.id] = {full_score: user.full_score, audio_latency: user.audio_latency, internet_score: user.internet_score}
end
[music_sessions, user_scores]
end
2014-10-06 21:17:46 +00:00
def self.participant_create(user, music_session_id, client_id, as_musician, tracks, audio_latency, video_sources=nil)
2014-05-20 13:26:32 +00:00
music_session = MusicSession.find(music_session_id)
# USERS ARE ALREADY IN SESSION
2014-05-20 13:26:32 +00:00
if music_session.active_music_session
connection = nil
2014-09-14 19:12:25 +00:00
active_music_session = music_session.active_music_session
2014-05-20 13:26:32 +00:00
ActiveRecord::Base.transaction do
active_music_session.with_lock do # VRFS-1297
active_music_session.tick_track_changes
2014-10-06 21:17:46 +00:00
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, video_sources)
2014-05-20 13:26:32 +00:00
if connection.errors.any?
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
end
end
unless connection.errors.any?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(music_session_id, user.id, client_id, tracks)
if as_musician
# send to session participants
2014-09-14 19:12:25 +00:00
Notification.send_session_join(active_music_session, connection, user)
2014-05-20 13:26:32 +00:00
# send "musician joined session" notification only if it's not a band session since there will be a "band joined session" notification
if music_session.band.nil?
Notification.send_musician_session_join(music_session, user)
2014-05-20 13:26:32 +00:00
end
end
end
connection
# FIRST USER TO JOIN SESSION
2014-05-20 13:26:32 +00:00
else
return_value = nil
time = Benchmark.realtime do
ActiveRecord::Base.transaction do
# we need to lock the icecast server in this transaction for writing, to make sure thath IcecastConfigWriter
# doesn't dumpXML as we are changing the server's configuraion
icecast_server = IcecastServer.find_best_server_for_user(user) if music_session.fan_access
icecast_server.lock! if icecast_server
# check if we are connected to rabbitmq
active_music_session = ActiveMusicSession.new
active_music_session.id = music_session.id # copy the .id from music_session to active_music_session
active_music_session.creator = user
if music_session.fan_access
# create an icecast mount since regular users can listen in to the broadcast
active_music_session.mount = IcecastMount.build_session_mount(music_session, active_music_session, icecast_server)
end
active_music_session.save
unless active_music_session.errors.any?
2014-05-22 08:02:48 +00:00
music_session.started_at = active_music_session.created_at
music_session.save(:validate => false)
2014-05-20 13:26:32 +00:00
# save session parameters for next session
User.save_session_settings(user, music_session)
# auto-join this user into the newly created session
as_musician = true
2014-10-06 21:17:46 +00:00
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, video_sources)
2014-05-20 13:26:32 +00:00
unless connection.errors.any?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(active_music_session.id, user.id, client_id, tracks)
# only send this notification if it's a band session
unless music_session.band.nil?
Notification.send_band_session_join(music_session, music_session.band)
else
Notification.send_musician_session_join(music_session, user)
2014-05-20 13:26:32 +00:00
end
2014-05-21 16:24:40 +00:00
return_value = connection
2014-05-20 13:26:32 +00:00
else
return_value = connection
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
else
return_value = active_music_session
# rollback the transaction to make sure nothing is disturbed in the database
raise ActiveRecord::Rollback
end
end
end
if time > 2
Logging.logger[self].warn "creating a music session took #{time*1000} milliseconds"
end
return_value
end
end
2014-05-06 13:34:38 +00:00
# Verifies that the specified user can delete this music session
def can_delete? user
# the creator can delete
self.creator == user
end
def access? user
music_session.part_of_session? user
end
def most_recent_recording
recordings.where(:music_session_id => self.id).order('created_at desc').limit(1).first
end
def is_jam_track_open?
!self.jam_track.nil?
end
2015-01-11 20:15:47 +00:00
def is_backing_track_open?
self.backing_track_path.present?
2015-01-11 20:15:47 +00:00
end
def is_metronome_open?
self.metronome_active.present?
2015-01-11 20:15:47 +00:00
end
2014-05-06 13:34:38 +00:00
# is this music session currently recording?
def is_recording?
recordings.where(:duration => nil).count > 0
end
def is_playing_recording?
!self.claimed_recording.nil?
end
def recording
recordings.where(:duration => nil).first
end
# stops any active recording
def stop_recording
current_recording = self.recording
current_recording.stop unless current_recording.nil?
end
def claimed_recording_start(owner, claimed_recording)
self.claimed_recording = claimed_recording
self.claimed_recording_initiator = owner
self.opening_recording = true
2014-05-06 13:34:38 +00:00
self.save
self.opening_recording = false
2014-05-06 13:34:38 +00:00
end
def claimed_recording_stop
self.claimed_recording = nil
self.claimed_recording_initiator = nil
self.save
end
def invitations
music_session.invitations
end
2014-05-06 13:34:38 +00:00
def invited_musicians
music_session.invited_musicians
end
def join_requests
music_session.join_requests
end
def fan_invitations
music_session.fan_invitations
end
def to_s
description
end
def musician_access
music_session.musician_access
end
def fan_access
music_session.fan_access
end
def description
music_session.description
end
2014-06-18 14:54:08 +00:00
def name
music_session.name
end
2014-05-06 13:34:38 +00:00
def genre
music_session.genre
end
def fan_chat
music_session.fan_chat
end
def band
music_session.band
2014-05-06 13:34:38 +00:00
end
def approval_required
music_session.approval_required
2014-05-06 13:34:38 +00:00
end
def music_notations
music_session.music_notations
end
# Verifies that the specified user can join this music session
def can_join? user, as_musician
music_session.can_join? user, as_musician
end
# Verifies that the specified user can see this music session
def can_see? user
music_session.can_see? user
end
2014-05-06 13:34:38 +00:00
def tick_track_changes
self.track_changes_counter += 1
self.save!(:validate => false)
end
def connected_participant_count
Connection.where(:music_session_id => self.id,
:aasm_state => Connection::CONNECT_STATE.to_s,
:as_musician => true)
.count
end
def started_session
raise "active_music_sessions.id must be set by caller" unless self.id
# associate this active_music_session with the music_session formally
session = MusicSession.find(self.id)
session.active_music_session = self
self.music_session = session # needed because of the Google Analytics below in some test cases
session.scheduled_start = self.created_at unless session.scheduled_start
session.save!
feed = Feed.find_by_music_session_id(self.id)
# this should never be hit since the feed entry is created when the music_session record is created
if feed.nil?
feed = Feed.new
feed.music_session_id = self.id
end
feed.active = true
feed.save
2014-05-06 13:34:38 +00:00
GoogleAnalyticsEvent.track_session_duration(self)
GoogleAnalyticsEvent.track_band_real_session(self)
end
def open_jam_track(user, jam_track)
self.jam_track = jam_track
self.jam_track_initiator = user
self.opening_jam_track = true
self.save
self.opening_jam_track = false
end
def close_jam_track
self.jam_track = nil
self.jam_track_initiator = nil
self.save
end
2014-05-06 13:34:38 +00:00
# @param backing_track_path is a relative path:
def open_backing_track(user, backing_track_path)
self.backing_track_path = backing_track_path
self.backing_track_initiator = user
self.opening_backing_track = true
self.save
self.opening_backing_track = false
end
def close_backing_track
self.backing_track_path = nil
self.backing_track_initiator = nil
self.save
end
def open_metronome(user)
self.metronome_active = true
self.metronome_initiator = user
self.opening_metronome = true
self.save
self.opening_metronome = false
end
def close_metronome
self.metronome_active = false
self.metronome_initiator = nil
self.save
end
2014-05-06 13:34:38 +00:00
def self.sync(session_history)
music_session = MusicSession.find_by_id(session_history.id)
if music_session.nil?
music_session = MusicSession.new
music_session.id = session_history.id
end
music_session.user_id = session_history.creator.id
music_session.band_id = session_history.band.id unless session_history.band.nil?
session_history.save!
end
end
end