jam-cloud/lib/jam_ruby/models/recording.rb

227 lines
7.3 KiB
Ruby
Raw Normal View History

2012-11-16 02:08:37 +00:00
module JamRuby
class Recording < ActiveRecord::Base
self.primary_key = 'id'
2013-01-22 22:03:23 +00:00
has_and_belongs_to_many :users, :class_name => "JamRuby::User"
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recording
2013-01-22 19:15:52 +00:00
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recording
2013-01-24 01:48:13 +00:00
belongs_to :music_session, :class_name => "JamRuby::MusicSession", :inverse_of => :recording
2013-01-22 19:15:52 +00:00
has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id
2012-11-16 02:08:37 +00:00
# genres
has_and_belongs_to_many :genres, :class_name => "JamRuby::Genre", :join_table => "recordings_genres"
# favorites
has_many :favorites, :class_name => "JamRuby::UserFavorite", :foreign_key => "recording_id"
has_many :inverse_favorites, :through => :favorites, :source => :recording, :class_name => "JamRuby::Recording"
2012-11-16 02:08:37 +00:00
validates :description, presence: true, length: { maximum: 200 }
def favorite_count
return self.favorites.size
end
2013-01-22 19:15:52 +00:00
# Start recording a session.
def self.start(music_session_id, creator_id)
2013-01-24 01:48:13 +00:00
# Use a transaction and lock to avoid races.
ActiveRecord::Base.transaction do
music_session = MusicSession.find(music_session_id, :lock => true)
2013-01-22 19:15:52 +00:00
2013-01-24 01:48:13 +00:00
if music_session.nil?
raise PermissionError, "the session has ended"
end
if music_session.recording
2013-01-22 19:15:52 +00:00
raise PermissionError, "the session is already being recorded"
2013-01-24 01:48:13 +00:00
end
music_session.recording = true
2013-01-22 19:15:52 +00:00
2013-01-24 01:48:13 +00:00
recording = Recording.new
recording.music_session = music_session
music_session.connections.each do |connection|
recording.users << connection.user
connection.tracks.each do |track|
RecordedTrack.create_from_track(track, recording)
end
2013-01-22 19:15:52 +00:00
end
2013-01-22 22:03:23 +00:00
2013-01-24 01:48:13 +00:00
music_session.genres.each do |genre|
recording.genres << genre
end
# Note that I believe this can be nil.
recording.band_id = music_session.band_id
recording.save
music_session.save
2013-01-22 22:03:23 +00:00
end
2013-01-22 19:15:52 +00:00
end
2013-01-24 01:48:13 +00:00
# Stop recording a session
def stop
# Use a transaction and lock to avoid races.
ActiveRecord::Base.transaction do
music_session = MusicSession.find(self.music_session_id, :lock => true)
if music_session.nil?
raise PermissionError, "the session has ended"
end
unless music_session.recording
raise PermissionError, "the session is not currently being recorded"
end
music_session.recording = false
music_session.save
end
end
2013-01-22 19:15:52 +00:00
def self.search(query, options = { :limit => 10 })
# only issue search if at least 2 characters are specified
if query.nil? || query.length < 2
return []
end
# create 'anded' statement
query = Search.create_tsquery(query)
if query.nil? || query.length == 0
return []
end
return Recording.where("description_tsv @@ to_tsquery('jamenglish', ?)", query).limit(options[:limit])
end
2013-01-22 19:15:52 +00:00
def self.save(id, is_public, description, genres, updater_id, owner_id, is_band)
2012-11-22 08:27:23 +00:00
2013-01-22 19:15:52 +00:00
# Spec: https://jamkazam.atlassian.net/wiki/display/PS/Product+Specification+-+Studio
# This is seriously wrong. A recording needs to be created from inside a session. I'm not sure who owns
# the recording, but I do know that it's affiliated with the session and then should be able to get the band id
# and probably all this other stuff (genre, etc) from that. I need to read the recording spec in more detail
# to figure that out. I'll read it on bart.
#
# The studio spec is the key here. A couple notes:
# * Multiple musicians are all associated with a recording -- everyone who is in the music session when the recording starts
# * Associating a band with the recording is optional
# * The recording needs to be associated with a music_session for sure. Probably also a set of tracks (NOT musicians). Then, on
# recording completion is when you have the track -> saved_track (rename this to recorded_track) transition.
# * The metadata in general is filled in *after* the recording ends. This is important because it means the save method below
# is sort of jacked.
2012-11-22 08:27:23 +00:00
creator = User.find(updater_id)
if is_band
band = Band.find(owner_id)
validate_user_is_band_member(creator, band)
else
user = User.find(owner_id)
validate_user_is_creator(user, creator)
validate_user_is_musician(user)
end
if id.nil?
validate_genres(genres, false)
recording = Recording.new()
2012-11-22 08:27:23 +00:00
recording.creator_id = updater_id
else
validate_genres(genres, true)
recording = Recording.find(id)
end
2012-11-22 08:27:23 +00:00
recording.updater_id = updater_id
# public flag
unless is_public.nil?
recording.public = is_public
end
# description
unless description.nil?
recording.description = description
end
# genres
unless genres.nil?
ActiveRecord::Base.transaction do
# delete all genres for this recording first
unless recording.id.nil? || recording.id.length == 0
recording.genres.delete_all
end
# loop through each genre in the array and save to the db
genres.each do |genre_id|
g = Genre.find(genre_id)
recording.genres << g
end
end
end
2012-11-22 08:27:23 +00:00
recording.updated_at = Time.now.getutc
# TODO: wrap in transaction with statements below
recording.save
2012-11-24 18:22:44 +00:00
if id.nil?
if is_band
recording.band_recordings << BandRecording.create(band_id: owner_id, recording_id: recording.id)
else
recording.musician_recordings << MusicianRecording.create(user_id: owner_id, recording_id: recording.id)
end
end
return recording
end
2012-11-22 08:27:23 +00:00
private
def self.validate_user_is_band_member(user, band)
unless band.users.exists? user
2012-11-24 18:22:44 +00:00
raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
2012-11-22 08:27:23 +00:00
end
end
def self.validate_user_is_creator(user, creator)
unless user.id == creator.id
2012-11-24 18:22:44 +00:00
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
2012-11-22 08:27:23 +00:00
end
end
def self.validate_user_is_musician(user)
unless user.musician?
2012-11-24 18:22:44 +00:00
raise PermissionError, ValidationMessages::USER_NOT_MUSICIAN_VALIDATION_ERROR
2012-11-22 08:27:23 +00:00
end
end
def self.validate_genres(genres, is_nil_ok)
if is_nil_ok && genres.nil?
return
end
if genres.nil?
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET
else
if genres.size < Limits::MIN_GENRES_PER_RECORDING
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET
end
if genres.size > Limits::MAX_GENRES_PER_RECORDING
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_LIMIT_EXCEEDED
end
end
end
2012-11-22 08:27:23 +00:00
=begin
def self.delete(id, owner_id, is_band)
if is_band?
2012-11-22 08:27:23 +00:00
JamRuby::Recording.delete_all "(user_id = '#{user_id}' AND follower_id = '#{follower_id}')"
else
end
end
2012-11-22 08:27:23 +00:00
=end
2012-11-16 02:08:37 +00:00
end
2013-01-22 22:03:23 +00:00
end