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

187 lines
5.2 KiB
Ruby

module JamRuby
class Track < ActiveRecord::Base
self.table_name = "tracks"
self.primary_key = 'id'
default_scope { order('created_at ASC') }
attr_accessor :musician, :instrument_ids
SOUND = %w(mono stereo)
belongs_to :connection, :class_name => "JamRuby::Connection", :inverse_of => :tracks, :foreign_key => 'connection_id'
belongs_to :instrument, :class_name => "JamRuby::Instrument", :inverse_of => :tracks
validates :sound, :inclusion => {:in => SOUND}
validates :connection, presence: true
validates :client_track_id, presence: true
#validates :client_resource_id, presence: true
def user
self.connection.user
end
def musician
@musician
end
def musician=(user)
@musician = user
end
def self.index(current_user, music_session_id)
query = Track
.joins(
%Q{
INNER JOIN
connections
ON
connections.music_session_id = '#{music_session_id}'
AND
connections.id = connection_id
AND
connections.user_id = '#{current_user.id}'
INNER JOIN
music_sessions
ON
music_sessions.id = '#{music_session_id}'
AND
music_sessions.user_id = '#{current_user.id}'
}
)
return query
end
def self.diff_track(track_class, existing_tracks, new_tracks, &blk)
result = []
if new_tracks.length == 0
existing_tracks.delete_all
else
# we will prune from this as we find matching tracks
to_delete = Set.new(existing_tracks)
to_add = Array.new(new_tracks)
existing_tracks.each do |existing_track|
new_tracks.each do |new_track|
if new_track[:id] == existing_track.id || new_track[:client_track_id] == existing_track.client_track_id
to_delete.delete(existing_track)
to_add.delete(new_track)
blk.call(existing_track, new_track)
result.push(existing_track)
if existing_track.save
next
else
result = existing_track
raise ActiveRecord::Rollback
end
end
end
end
to_add.each do |new_track|
existing_track = track_class.new
blk.call(existing_track, new_track)
if existing_track.save
result.push(existing_track)
else
result = existing_track
raise ActiveRecord::Rollback
end
end
to_delete.each do |delete_me|
delete_me.delete
end
end
result
end
# this is a bit different from a normal track synchronization in that the client just sends up all tracks,
# ... some may already exist
def self.sync(clientId, tracks, backing_tracks = [], metronome_open = false)
result = {}
backing_tracks = [] unless backing_tracks
tracks = [] unless tracks
Track.transaction do
connection = Connection.find_by_client_id!(clientId)
# synchronize metronome_open on connection
if connection.metronome_open != metronome_open
Connection.where(:id => connection.id).update_all(:metronome_open => metronome_open)
end
# each time tracks are synced we have to update the entry in music_sessions_user_history
msh = MusicSessionUserHistory.find_by_client_id!(clientId)
instruments = []
tracks.each do |track|
instruments << track[:instrument_id]
end
result[:tracks] = diff_track(Track, connection.tracks, tracks) do |track_record, track_info|
track_record.connection = connection
track_record.client_track_id = track_info[:client_track_id]
track_record.client_resource_id = track_info[:client_resource_id]
track_record.instrument_id = track_info[:instrument_id]
track_record.sound = track_info[:sound]
end
result[:backing_tracks] = diff_track(BackingTrack, connection.backing_tracks, backing_tracks) do |track_record, track_info|
track_record.connection = connection
track_record.client_track_id = track_info[:client_track_id]
track_record.client_resource_id = track_info[:client_resource_id]
track_record.filename = track_info[:filename]
end
msh.instruments = instruments.join("|")
if !msh.save
raise ActiveRecord::Rollback
end
end
result
end
def self.save(id, connection_id, instrument_id, sound, client_track_id, client_resource_id)
if id.nil?
track = Track.new
track.connection_id = connection_id
else
track = Track.find(id)
end
unless instrument_id.nil?
track.instrument_id = instrument_id
end
unless sound.nil?
track.sound = sound
end
unless client_track_id.nil?
track.client_track_id = client_track_id
end
unless client_resource_id.nil?
track.client_resource_id = resource_id
end
track.updated_at = Time.now
track.save
return track
end
end
end