module JamRuby class JamTrack < ActiveRecord::Base include JamRuby::S3ManagerMixin TIME_SIGNATURES = %w{4/4 3/4 2/4 6/8 5/8'} STATUS = %w{Staging Production Retired} RECORDING_TYPE = %w{Cover Original} PRO = %w{ASCAP BMI SESAC} SALES_REGION = ['United States', 'Worldwide'] PRODUCT_TYPE = 'JamTrack' @@log = Logging.logger[JamTrack] mount_uploader :preview_url, JamTrackUploader attr_accessor :uploading_preview attr_accessible :name, :description, :bpm, :time_signature, :status, :recording_type, :original_artist, :songwriter, :publisher, :licensor, :licensor_id, :pro, :genre, :genre_id, :sales_region, :price, :reproduction_royalty, :public_performance_royalty, :reproduction_royalty_amount, :licensor_royalty_amount, :pro_royalty_amount, :plan_code, :initial_play_silence, :jam_track_tracks_attributes, :jam_track_tap_ins_attributes, :version, :jmep_json, :jmep_text, :pro_ascap, :pro_bmi, :pro_sesac, :preview_start_time_raw, as: :admin validates :name, presence: true, uniqueness: true, length: {maximum: 200} validates :plan_code, presence: true, uniqueness: true, length: {maximum: 50 } validates :description, length: {maximum: 1000} validates :time_signature, inclusion: {in: [nil] + [''] + TIME_SIGNATURES} # the empty string is needed because of activeadmin validates :status, inclusion: {in: [nil] + STATUS} validates :recording_type, inclusion: {in: [nil] + RECORDING_TYPE} validates :original_artist, length: {maximum: 200} validates :songwriter, length: {maximum: 1000} validates :publisher, length: {maximum: 1000} validates :sales_region, inclusion: {in: [nil] + SALES_REGION} validates_format_of :price, with: /^\d+\.*\d{0,2}$/ validates :version, presence: true validates :preview_start_time, numericality: {only_integer: true}, length: {in: 1..1000}, :allow_nil => true validates :pro_ascap, inclusion: {in: [true, false]} validates :pro_bmi, inclusion: {in: [true, false]} validates :pro_sesac, inclusion: {in: [true, false]} validates :public_performance_royalty, inclusion: {in: [nil, true, false]} validates :reproduction_royalty, inclusion: {in: [nil, true, false]} validates :public_performance_royalty, inclusion: {in: [nil, true, false]} validates_format_of :reproduction_royalty_amount, with: /^\d+\.*\d{0,3}$/ validates_format_of :licensor_royalty_amount, with: /^\d+\.*\d{0,3}$/ belongs_to :genre, class_name: "JamRuby::Genre" belongs_to :licensor , class_name: 'JamRuby::JamTrackLicensor', foreign_key: 'licensor_id' has_many :jam_track_tracks, :class_name => "JamRuby::JamTrackTrack", order: 'position ASC' has_many :jam_track_tap_ins, :class_name => "JamRuby::JamTrackTapIn", order: 'offset_time ASC' has_many :jam_track_rights, :class_name => "JamRuby::JamTrackRight" #, inverse_of: 'jam_track', :foreign_key => "jam_track_id" has_many :owners, :through => :jam_track_rights, :class_name => "JamRuby::User", :source => :user has_many :playing_sessions, :class_name => "JamRuby::ActiveMusicSession" has_many :recordings, :class_name => "JamRuby::Recording" accepts_nested_attributes_for :jam_track_tracks, allow_destroy: true accepts_nested_attributes_for :jam_track_tap_ins, allow_destroy: true class << self def index(options, user) limit = options[:limit] limit ||= 20 limit = limit.to_i start = options[:start].presence start = start.to_i || 0 query = JamTrack.joins(:jam_track_tracks) .paginate(page: 1 + start/limit, per_page: limit) if options[:show_purchased_only] query = query.joins(:jam_track_rights) query = query.where("jam_track_rights.user_id = ?", user.id) end query = query.where("jam_tracks.status = ?", 'Production') unless user.admin query = query.where("jam_tracks.genre_id = '#{options[:genre]}'") unless options[:genre].blank? query = query.where("jam_track_tracks.instrument_id = '#{options[:instrument]}'") unless options[:instrument].blank? query = query.where("jam_tracks.sales_region = '#{options[:availability]}'") unless options[:availability].blank? query = query.group("jam_tracks.id") query = query.order('jam_tracks.name') if query.length == 0 [query, nil] elsif query.length < limit [query, nil] else [query, start + limit] end end end # create name of the file def preview_filename "jam_track_previews/#{self.original_artist}/#{self.name}/preview-44100.ogg" 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) s3_manager.sign_url(self[:preview_url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) end def master_track JamTrackTrack.where(jam_track_id: self.id).where(track_type: 'Master').first end def can_download?(user) owners.include?(user) end def right_for_user(user) jam_track_rights.where("user_id=?", user).first end end end