module JamRuby # describes an audio track (like the drums, or guitar) that comprises a JamTrack class JamTrackTrack < ActiveRecord::Base include JamRuby::S3ManagerMixin # there should only be one Master per JamTrack, but there can be N Track per JamTrack TRACK_TYPE = %w{Track Master} @@log = Logging.logger[JamTrackTrack] mount_uploader :url_48, JamTrackTrackUploader mount_uploader :url_44, JamTrackTrackUploader attr_accessible :jam_track_id, :track_type, :instrument, :instrument_id, :position, :part, as: :admin attr_accessible :url_44, :url_48, :md5_44, :md5_48, :length_44, :length_48, :preview_start_time_raw, as: :admin attr_accessor :original_audio_s3_path, :skip_uploader validates :position, presence: true, numericality: {only_integer: true}, length: {in: 1..1000} validates :part, length: {maximum: 25} validates :track_type, inclusion: {in: TRACK_TYPE } validates :preview_start_time, numericality: {only_integer: true}, length: {in: 1..1000}, :allow_nil => true validates_uniqueness_of :position, scope: :jam_track_id validates_uniqueness_of :part, scope: [:jam_track_id, :instrument_id] # validates :jam_track, presence: true belongs_to :instrument, class_name: "JamRuby::Instrument" belongs_to :jam_track, class_name: "JamRuby::JamTrack" has_many :recorded_jam_track_tracks, :class_name => "JamRuby::RecordedJamTrackTrack", :foreign_key => :jam_track_track_id, :dependent => :destroy # create storage directory that will house this jam_track, as well as def store_dir "jam_track_tracks" end # create name of the file def filename(original_name) "#{store_dir}/#{jam_track.original_artist}/#{jam_track.name}/#{original_name}" end # create name of the file def preview_filename filename("#{File.basename(self["url_44"], ".ogg")}-preview.ogg") end def has_preview? !self["preview_url"].nil? end # creates a short-lived URL that has access to the object. # the idea is that this is used when a user who has the rights to this tries to download this JamTrack # we would verify their rights (can_download?), and generates a URL in response to the click so that they can download # but the url is short lived enough so that it wouldn't be easily shared def preview_sign_url(expiration_time = 120) s3_manager.sign_url(self[:preview_url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) end def manually_uploaded_filename(mounted_as) if track_type == 'Master' filename("Master Mix-#{mounted_as == :url_48 ? '48000' : '44100'}.ogg") else filename("#{jam_track.name} Stem - #{instrument.description}-#{part}-#{mounted_as == :url_48 ? '48000' : '44100'}.ogg") end end def url_by_sample_rate(sample_rate=48) field_name = (sample_rate==48) ? "url_48" : "url_44" self[field_name] end # creates a short-lived URL that has access to the object. # the idea is that this is used when a user who has the rights to this tries to download this JamTrack # we would verify their rights (can_download?), and generates a URL in response to the click so that they can download # but the url is short lived enough so that it wouldn't be easily shared def sign_url(expiration_time = 120, sample_rate=48) s3_manager.sign_url(url_by_sample_rate(sample_rate), {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) end def can_download?(user) # I think we have to make a special case for 'previews', but maybe that's just up to the controller to not check can_download? jam_track.owners.include?(user) end def move_up #normalize_position if self.position > 1 # Switch with previous previous_track = self.jam_track.jam_track_tracks.where("position=?", self.position-1).first if previous_track JamTrack.transaction do previous_track.position,self.position = self.position,previous_track.position previous_track.save(validate:false) self.save(validate:false) end end end end def move_down count=normalize_position if self.position < count # Switch with next: next_track = self.jam_track.jam_track_tracks.where("position=?", self.position+1).first if next_track next_track.position,self.position = self.position,next_track.position next_track.save(validate:false) self.save(validate:false) end end end private def normalize_position parent = self.jam_track position = 0 if parent JamTrack.transaction do parent.jam_track_tracks.each do |jtt| position += 1 if jtt.position != position jtt.position = position jtt.save(validate:false) end end end end position end # normalize_position end # class end # module