diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb index 79890b3cf..7f8f1f2f6 100644 --- a/admin/app/admin/jam_ruby_users.rb +++ b/admin/app/admin/jam_ruby_users.rb @@ -99,7 +99,12 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do controller do - autocomplete :user, :email, :full => true + # this actually searches on first name, last name, and email, because of get_autocomplete_items defined below + autocomplete :user, :email, :full => true, :display_value => :autocomplete_display_name + + def get_autocomplete_items(parameters) + items = User.select("DISTINCT email, first_name, last_name, id").where(["email ILIKE ? OR first_name ILIKE ? OR last_name ILIKE ?", "%#{parameters[:term]}%", "%#{parameters[:term]}%", "%#{parameters[:term]}%"]) + end def create @jam_ruby_user = JamRuby::User.new(params[:jam_ruby_user]) diff --git a/admin/app/admin/recordings.rb b/admin/app/admin/recordings.rb index 210509560..eb0ac1fc1 100644 --- a/admin/app/admin/recordings.rb +++ b/admin/app/admin/recordings.rb @@ -10,19 +10,37 @@ ActiveAdmin.register JamRuby::Recording, :as => 'Recording' do form :partial => 'form' controller do + + def initialize_client_tokens(params) + + recording = params[:jam_ruby_recording] + return params unless recording + + recorded_tracks = recording[:recorded_tracks_attributes] + return params unless recorded_tracks + + recorded_tracks.each do |key, recorded_track| + recorded_track[:client_id] = nil if recorded_track[:client_id] == "" + recorded_track[:client_track_id] = nil if recorded_track[:client_track_id] == "" + recorded_track[:track_id] = nil if recorded_track[:track_id] == "" + + recorded_track[:client_id] ||= recorded_track[:user_id] if recorded_track[:user_id] + recorded_track[:client_track_id] ||= SecureRandom.uuid + recorded_track[:track_id] ||= SecureRandom.uuid + end + + params + end + def new @recording = JamRuby::Recording.new + super end def create - owner = User.find_by_email!(params[:jam_ruby_recording][:owner]) - band = User.find_by_band!(params[:jam_ruby_recording][:band]) - recording = Recording.new - recording.owner = owner - recording.band = band - recording.save - redirect_to("/admin/recordings/#{recording.id}") + params.merge! initialize_client_tokens(params) + create! end def edit @@ -30,26 +48,12 @@ ActiveAdmin.register JamRuby::Recording, :as => 'Recording' do super end - def update - owner = User.find_by_email!(params[:jam_ruby_recording][:owner]) - band = Band.find_by_name!(params[:jam_ruby_recording][:band]) - recorded_tracks = params[:jam_ruby_recording][:recorded_tracks] - recorded_tracks.each do |recorded_track| - track = RecordedTrack.new - track.client_id ||= 'fake' - track.track_id ||= 'fake' - track.client_track_id ||= 'fake' - track.sound ||= 'stereo' - track.recording = resource - track.user = User.find_by_email!(recorded_track[:user]) - track.instrument = Instrument.find_by_instrument!(recorded_track[:instrument]) - resource.recorded_tracks << track + params.merge! initialize_client_tokens(params) + + update! do |format| + format.html { redirect_to edit_admin_recording_url(params[:jam_ruby_recording]) } end - resource.owner = owner - resource.band = band - resource.save - redirect_to("/admin/recordings/#{resource.id}") end end diff --git a/admin/app/assets/javascripts/active_admin.js b/admin/app/assets/javascripts/active_admin.js index 8d8a2f0b3..088012d98 100644 --- a/admin/app/assets/javascripts/active_admin.js +++ b/admin/app/assets/javascripts/active_admin.js @@ -1,11 +1,12 @@ // //= require active_admin/base //= require jquery //= require jquery_ujs -//= require jquery.ui.core -//= require jquery.ui.widget -//= require jquery.ui.datepicker -//= require jquery.ui.dialog -//= require jquery.ui.autocomplete +//= require jquery-ui +// require jquery.ui.core +// require jquery.ui.widget +// require jquery.ui.datepicker +// require jquery.ui.dialog +// require jquery.ui.autocomplete //= require cocoon //= require active_admin/application //= require autocomplete-rails diff --git a/admin/app/uploaders/image_uploader.rb b/admin/app/uploaders/image_uploader.rb index bde053642..f094084d4 100644 --- a/admin/app/uploaders/image_uploader.rb +++ b/admin/app/uploaders/image_uploader.rb @@ -2,10 +2,16 @@ class ImageUploader < CarrierWave::Uploader::Base include CarrierWaveDirect::Uploader - include CarrierWave::MimeTypes process :set_content_type + + def initialize(*) + super + JamRuby::UploaderConfiguration.set_aws_public_configuration(self) + end + + # Add a white list of extensions which are allowed to be uploaded. def extension_white_list %w(jpg jpeg gif png) diff --git a/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml b/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml index 2b5c974db..617084abf 100644 --- a/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml +++ b/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml @@ -1,10 +1,15 @@ = f.inputs name: 'Claimed Recording' do - = link_to_remove_association "Delete Claimed Recording", f, class: 'button', style: 'margin-left:10px; position: relative; top: -37px; left: 50px;' %ol.nested-fields - + = f.input :name, :hint => 'This is entered in the post-recording dialog. It will be displayed in jam-web.' + = f.input :description, :hint => 'This is entered in the post-recording dialog. It will be displayed in jam-web.' + = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { id: "jam_ruby_claimed_recording_user_id", name: "", id_element: "#WILL_BE_OVERRIDDEN_BY_JS_IN_RECORDED_FORM" } + = f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_claimed_recording[user_id]" } + = f.input :genre, collection: Genre.all, :member_label => :description + = f.input :is_public + = f.input :is_downloadable + = link_to_remove_association "Delete Claimed Recording", f, class: 'button', style: 'margin-left:10px' %div{style: 'display:none'} - = #f.input :should_retry, :as => :hidden, :input_html => {:value => '0' } diff --git a/admin/app/views/admin/recordings/_form.html.haml b/admin/app/views/admin/recordings/_form.html.haml index ceb327eb9..8d172f364 100644 --- a/admin/app/views/admin/recordings/_form.html.haml +++ b/admin/app/views/admin/recordings/_form.html.haml @@ -1,15 +1,63 @@ -<%= semantic_form_for([:admin, @recording], :html => {:multipart => true}, :url => @recording.new_record? ? admin_recordings_path : "/admin/recordings/#{@recording.id}") do |f| %> - <%= f.semantic_errors *f.object.errors.keys %> - <%= f.inputs do %> - <%= f.input :owner, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path %> - <%= f.input :band, :as => :autocomplete, :url => autocomplete_band_name_admin_bands_path %> +%h2 Instructions +%h3 Overview +%p Make each recorded track first, then the mix, and then finally the claimed recordings. +%h3 Entering users and bands +%p Autocomplete is used to supply users and bands. Just starting typing and pick from the resulting options. +%h3 Adding Tracks and Mixes +%p To add a track or mix, you first click 'Add track' or 'Add mix', and fill out any values present. However, to upload an ogg file for a mix or track, you must first click 'Update Recording' after you initially click 'Add Track/Mix'. When the form re-displays after the update, you will then seen an upload file input. Finally, after you have uploaded an ogg file, you can then click the Download link to verify your ogg file, or mp3, in the case of mixes. +%h4 Specific to Mixes +%ul + %li When you first click 'Add Mix', there is nothing to fill out. So click 'Add Mix', then click 'Update Recording'. The page will prompt you, as well. + %li When you upload a mix ogg file, it will be converted to mp3 too. This makes the request take a little bit of time. Just wait it out. +%h3 Add Claimed Recordings +%p Once your recorded tracks are added, you then want to add one Claimed Recording for each user you want to have access to the recording. Making a claimed recording is basically making a recording 'visible' for a given user. The user must have a recorded track to have a claimed recording. +%h3 Validations +%p It should not be possible to create an invalid recording/track/mix/claim; there are a great deal of validations that will prevent you from doing something invalid. If you find otherwise, please fill out a JIRA . - <%= f.fields_for :recorded_tracks do |recorded_track| %> - <%= render 'recorded_track', f: recorded_track %> - <% end %> += semantic_form_for([:admin, @recording], :html => {:multipart => true}, :url => @recording.new_record? ? admin_recordings_path : "/admin/recordings/#{@recording.id}") do |f| + = f.semantic_errors *f.object.errors.keys + = f.inputs name: 'Recording Fields' do - <%= link_to_add_association 'add track', f, :recorded_tracks %> + = f.input :name, :hint => 'something to remember this recording by. This is used solely for display in jam-admin; nowhere else.' - <% end %> - <%= f.actions %> -<% end %> + = f.input :owner, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { :id => "jam_ruby_recording_owner", :name => "", :id_element => "#jam_ruby_recording_owner_id" } + = f.input :owner_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[owner_id]" } + + = f.input :band, :as => :autocomplete, :url => autocomplete_band_name_admin_bands_path, :input_html => { :id => "jam_ruby_recording_band", :name => "", :id_element => "#jam_ruby_recording_band_id" } + = f.input :band_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[band_id]" } + + = f.semantic_fields_for :recorded_tracks do |recorded_track, index| + = render 'recorded_track_fields', f: recorded_track + .links + = link_to_add_association 'Add Track', f, :recorded_tracks, class: 'button', style: 'margin:20px;padding:10px 20px' + + = f.semantic_fields_for :mixes do |mix, index| + = render 'mix_fields', f: mix + .links + = link_to_add_association 'Add Mix', f, :mixes, class: 'button', style: 'margin:20px; padding:10px 20px' + + = f.semantic_fields_for :claimed_recordings do |claimed_recording, index| + = render 'claimed_recording_fields', f: claimed_recording + .links + = link_to_add_association 'Add Claimed Recording', f, :claimed_recordings, class: 'button', style: 'margin:20px; padding:10px 20px' + + = f.actions + + +:javascript + $(document).ready( function() { + $('body').on('cocoon:before-insert', function(e, insertedItem) { + + // handle recorded tracks + var idForHiddenUserId = $('input[class="jam_ruby_recorded_track[user_id]"]', insertedItem).attr('id'); + if(idForHiddenUserId) { + $('input[id="jam_ruby_recorded_track_user_id"]', insertedItem).attr('data-id-element', '#' + idForHiddenUserId) + } + + // handle claimed recordings + idForHiddenUserId = $('input[class="jam_ruby_claimed_recording[user_id]"]', insertedItem).attr('id'); + if(idForHiddenUserId) { + $('input[id="jam_ruby_claimed_recording_user_id"]', insertedItem).attr('data-id-element', '#' + idForHiddenUserId) + } + }); + }); diff --git a/admin/app/views/admin/recordings/_mix_fields.html.haml b/admin/app/views/admin/recordings/_mix_fields.html.haml index fe6b7dc99..115976bc1 100644 --- a/admin/app/views/admin/recordings/_mix_fields.html.haml +++ b/admin/app/views/admin/recordings/_mix_fields.html.haml @@ -1,18 +1,21 @@ -= f.inputs name: 'Track' do += f.inputs name: 'Mix' do %ol.nested-fields - = puts "f.object #{f.object.url}" - = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { id: "jam_ruby_recorded_track_user_id", name: "", id_element: "#WILL_BE_OVERRIDDEN_BY_JS_IN_RECORDED_FORM" } - = f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_recorded_track[user_id]" } - = f.input :instrument, collection: Instrument.all - = f.input :sound, :as => :select, collection: options_for_select(RecordedTrack::SOUND, 'stereo') - = f.input :url, :as => :file - - unless f.object.nil? && f.object.url.nil? - %a{href: f.object.sign_url} current file + - if f.object.new_record? + %p{style: 'margin-left:10px'} + %i before you can upload, you must select 'Update Recording' + - else + = f.input :ogg_url, :as => :file + - unless f.object.nil? || f.object[:ogg_url].nil? + .current_file_holder{style: 'margin-bottom:10px'} + %a{href: f.object.sign_url(3600, 'ogg'), style: 'padding:0 0 0 20px'} Download OGG + %a{href: f.object.sign_url(3600, 'mp3'), style: 'padding:0 0 0 20px'} Download MP3 + + %div{style: 'display:none'} + = f.input :should_retry, :as => :hidden, :input_html => {:value => '0' } + + = link_to_remove_association "Delete Mix", f, class: 'button', style: 'margin-left:10px' + - = f.input :client_id, as: :hidden - = f.input :track_id, as: :hidden - = f.input :client_track_id, as: :hidden - = link_to_remove_association "remove track", f diff --git a/admin/app/views/admin/recordings/_recorded_track_fields.html.haml b/admin/app/views/admin/recordings/_recorded_track_fields.html.haml index 4c7c3fdc6..617f50dbe 100644 --- a/admin/app/views/admin/recordings/_recorded_track_fields.html.haml +++ b/admin/app/views/admin/recordings/_recorded_track_fields.html.haml @@ -1,4 +1,25 @@ -li.control-group nested-fields - div.controls - = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path - = f.input :instrument, :collection => Instrument.all \ No newline at end of file += f.inputs name: 'Track' do + + %ol.nested-fields + = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { id: "jam_ruby_recorded_track_user_id", name: "", id_element: "#WILL_BE_OVERRIDDEN_BY_JS_IN_RECORDED_FORM" } + = f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_recorded_track[user_id]" } + = f.input :instrument, collection: Instrument.all + = f.input :sound, :as => :select, collection: options_for_select(RecordedTrack::SOUND, 'stereo') + + - if f.object.new_record? + %i before you can upload, you must select 'Update Recording' + - else + = f.input :url, :as => :file + - unless f.object.nil? || f.object[:url].nil? + .current_file_holder{style: 'margin-bottom:10px'} + %a{href: f.object.sign_url(3600), style: 'padding:0 0 0 20px'} Download + + %div{style: 'display:none'} + = f.input :client_id, as: :hidden + = f.input :track_id, as: :hidden + = f.input :client_track_id, as: :hidden + + = link_to_remove_association "Delete Track", f, class: 'button', style: 'margin-left:10px' + + + diff --git a/admin/config/application.rb b/admin/config/application.rb index 3ddc73a81..48690b907 100644 --- a/admin/config/application.rb +++ b/admin/config/application.rb @@ -87,7 +87,7 @@ module JamAdmin # set to false to instead use amazon. You will also need to supply amazon secrets config.store_artifacts_to_disk = false - config.storage_type = :fog + #config.storage_type = :fog # these only need to be set if store_artifact_to_files = false config.aws_access_key_id = ENV['AWS_KEY'] @@ -117,5 +117,7 @@ module JamAdmin config.twitter_app_id = ENV['TWITTER_APP_ID'] || 'nQj2oEeoJZxECC33tiTuIg' config.twitter_app_secret = ENV['TWITTER_APP_SECRET'] || 'Azcy3QqfzYzn2fsojFPYXcn72yfwa0vG6wWDrZ3KT8' + + config.ffmpeg_path = ENV['FFMPEG_PATH'] || (File.exist?('/usr/local/bin/ffmpeg') ? '/usr/local/bin/ffmpeg' : '/usr/bin/ffmpeg') end end diff --git a/admin/config/initializers/carrierwave.rb b/admin/config/initializers/carrierwave.rb index f00908608..888373e84 100644 --- a/admin/config/initializers/carrierwave.rb +++ b/admin/config/initializers/carrierwave.rb @@ -4,20 +4,9 @@ CarrierWave.root = Rails.root.join(Rails.public_path).to_s CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT'] CarrierWave.configure do |config| - if JamAdmin::Application.config.store_artifacts_to_disk - config.storage = :file - else - config.storage = :fog - config.fog_credentials = { - :provider => 'AWS', - :aws_access_key_id => JamAdmin::Application.config.aws_access_key_id, - :aws_secret_access_key => JamAdmin::Application.config.aws_secret_access_key, - :region => JamAdmin::Application.config.aws_region, - } - config.fog_directory = JamAdmin::Application.config.aws_bucket_public # required - config.fog_public = true # optional, defaults to true - config.fog_attributes = {'Cache-Control'=>"max-age=#{JamAdmin::Application.config.aws_cache}"} # optional, defaults to {} - end + + config.storage = Rails.application.config.store_artifacts_to_disk ? :file : :fog + JamRuby::UploaderConfiguration.set_aws_private_configuration(config) end require 'carrierwave/orm/activerecord' diff --git a/db/manifest b/db/manifest index 981182ab1..69f76d7bf 100755 --- a/db/manifest +++ b/db/manifest @@ -103,4 +103,5 @@ share_token_2.sql large_photo_url.sql add_secret_to_user_authorization.sql track_connection_id_not_null.sql -recordings_all_discarded.sql \ No newline at end of file +recordings_all_discarded.sql +recordings_via_admin_web.sql \ No newline at end of file diff --git a/ruby/.simplecov b/ruby/.simplecov new file mode 100644 index 000000000..001eb3ab5 --- /dev/null +++ b/ruby/.simplecov @@ -0,0 +1,7 @@ +SimpleCov.start do + add_filter "/test/" + add_filter "/bin/" + add_filter "/scripts/" + add_filter "/tmp/" + add_filter "/vendor/" +end diff --git a/ruby/Gemfile b/ruby/Gemfile index 989804c45..cf01f710b 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -43,7 +43,8 @@ gem 'oj' gem 'builder' group :test do - gem "factory_girl", '4.1.0' + gem 'simplecov', '~> 0.7.1' + gem 'factory_girl', '4.1.0' gem "rspec", "2.11" gem 'spork', '0.9.0' gem 'database_cleaner', '0.7.0' diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index d955642b4..2cc0844f4 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -45,8 +45,11 @@ require "jam_ruby/init" require "jam_ruby/app/mailers/user_mailer" require "jam_ruby/app/mailers/invited_user_mailer" require "jam_ruby/app/mailers/corp_mailer" +require "jam_ruby/app/uploaders/uploader_configuration" require "jam_ruby/app/uploaders/artifact_uploader" require "jam_ruby/app/uploaders/perf_data_uploader" +require "jam_ruby/app/uploaders/recorded_track_uploader" +require "jam_ruby/app/uploaders/mix_uploader" require "jam_ruby/lib/desk_multipass" require "jam_ruby/amqp/amqp_connection_manager" require "jam_ruby/message_factory" diff --git a/ruby/lib/jam_ruby/app/uploaders/artifact_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/artifact_uploader.rb index 89dc991e1..652e877c2 100644 --- a/ruby/lib/jam_ruby/app/uploaders/artifact_uploader.rb +++ b/ruby/lib/jam_ruby/app/uploaders/artifact_uploader.rb @@ -1,7 +1,12 @@ # encoding: utf-8 - class ArtifactUploader < CarrierWave::Uploader::Base +class ArtifactUploader < CarrierWave::Uploader::Base + + def initialize(*) + super + JamRuby::UploaderConfiguration.set_aws_public_configuration(self) + end # Include RMagick or MiniMagick support: # include CarrierWave::RMagick # include CarrierWave::MiniMagick diff --git a/ruby/lib/jam_ruby/app/uploaders/mix_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/mix_uploader.rb index 441dcdfa3..f672d804f 100644 --- a/ruby/lib/jam_ruby/app/uploaders/mix_uploader.rb +++ b/ruby/lib/jam_ruby/app/uploaders/mix_uploader.rb @@ -1,38 +1,23 @@ -class RecordedTrackUploader < CarrierWave::Uploader::Base +class MixUploader < CarrierWave::Uploader::Base # include CarrierWaveDirect::Uploader include CarrierWave::MimeTypes process :set_content_type process :add_metadata + version :mp3_url do + process :create_mp3 + + def full_filename(file) + model.filename('mp3') if model.id + end + end + def initialize(*) super JamRuby::UploaderConfiguration.set_aws_private_configuration(self) end - def add_metadata - - # add this metadata to ogg file without disturbing audio - #JamRecordingId=af9f1598-2243-4c21-98c1-5e0c56da5b89 - #JamTrackId=5b1c3ef4-01d7-471e-8684-e2a5743ffd26 - #JamClientId=8331bcec-7810-42c1-9f39-a5c129406e85 - #JamType=LocalTrack - - # secret sauce is -codec copy, and a bunch of -metadata arguments. - # after done, stomp input file with new one - - input_file = current_path - output_file = current_path + '.new.ogg' - ffmpeg_cmd = "#{APP_CONFIG.ffmpeg_path} -i \"#{input_file}\" -codec copy -metadata JamRecordingId=#{model.recording_id} -metadata JamTrackId=#{model.client_track_id} -metadata JamClientId=#{model.client_id} -metadata JamType=LocalTrack \"#{output_file}\"" - system(ffmpeg_cmd) - - unless $? == 0 - raise "ffmpeg failed" - end - - FileUtils.mv output_file, input_file - end - # Add a white list of extensions which are allowed to be uploaded. def extension_white_list %w(ogg) @@ -47,6 +32,50 @@ class RecordedTrackUploader < CarrierWave::Uploader::Base end def filename - model.filename if model.id + model.filename('ogg') if model.id end + + + def add_metadata + # add this metadata to ogg file without disturbing audio + # JamRecordingId=438 + # JamMixId=438 + # JamType=Mix + # secret sauce is -codec copy, and a bunch of -metadata arguments. + # after done, stomp input file with new one + + input_file = current_path + output_file = current_path + '.new.ogg' + ffmpeg_cmd = "#{APP_CONFIG.ffmpeg_path} -i \"#{input_file}\" -codec copy -metadata JamRecordingId=#{model.recording_id} -metadata JamMixId=#{model.id} -metadata JamType=Mix \"#{output_file}\"" + system(ffmpeg_cmd) + + unless $? == 0 + raise "ffmpeg metadata copy failed" + end + + FileUtils.mv output_file, input_file + end + + def create_mp3 + # add this metadata to mp3 file + # JamRecordingId=438 + # JamMixId=438 + # JamType=Mix + input_file = current_path + output_file = current_path + '.new.mp3' + ffmpeg_cmd = "#{APP_CONFIG.ffmpeg_path} -i \"#{input_file}\" -ab 128k -metadata JamRecordingId=#{model.recording_id} -metadata JamMixId=#{model.id} -metadata JamType=Mix \"#{output_file}\"" + system(ffmpeg_cmd) + + unless $? == 0 + raise "ffmpeg mp3 convert failed" + end + + model.mp3_md5 = Digest::MD5.file(output_file).hexdigest + model.mp3_length = File.size(output_file) + model.mp3_url = model.filename('mp3') + file.instance_variable_set(:@content_type, 'audio/mpeg') + + FileUtils.mv output_file, input_file + end + end diff --git a/ruby/lib/jam_ruby/app/uploaders/perf_data_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/perf_data_uploader.rb index fbcbb5a40..acd56f4a0 100644 --- a/ruby/lib/jam_ruby/app/uploaders/perf_data_uploader.rb +++ b/ruby/lib/jam_ruby/app/uploaders/perf_data_uploader.rb @@ -2,6 +2,11 @@ class PerfDataUploader < CarrierWave::Uploader::Base + def initialize(*) + super + JamRuby::UploaderConfiguration.set_aws_private_configuration(self) + end + # Include RMagick or MiniMagick support: # include CarrierWave::RMagick # include CarrierWave::MiniMagick diff --git a/ruby/lib/jam_ruby/app/uploaders/recorded_track_uploader.rb b/ruby/lib/jam_ruby/app/uploaders/recorded_track_uploader.rb index e69de29bb..441dcdfa3 100644 --- a/ruby/lib/jam_ruby/app/uploaders/recorded_track_uploader.rb +++ b/ruby/lib/jam_ruby/app/uploaders/recorded_track_uploader.rb @@ -0,0 +1,52 @@ +class RecordedTrackUploader < CarrierWave::Uploader::Base + # include CarrierWaveDirect::Uploader + include CarrierWave::MimeTypes + + process :set_content_type + process :add_metadata + + def initialize(*) + super + JamRuby::UploaderConfiguration.set_aws_private_configuration(self) + end + + def add_metadata + + # add this metadata to ogg file without disturbing audio + #JamRecordingId=af9f1598-2243-4c21-98c1-5e0c56da5b89 + #JamTrackId=5b1c3ef4-01d7-471e-8684-e2a5743ffd26 + #JamClientId=8331bcec-7810-42c1-9f39-a5c129406e85 + #JamType=LocalTrack + + # secret sauce is -codec copy, and a bunch of -metadata arguments. + # after done, stomp input file with new one + + input_file = current_path + output_file = current_path + '.new.ogg' + ffmpeg_cmd = "#{APP_CONFIG.ffmpeg_path} -i \"#{input_file}\" -codec copy -metadata JamRecordingId=#{model.recording_id} -metadata JamTrackId=#{model.client_track_id} -metadata JamClientId=#{model.client_id} -metadata JamType=LocalTrack \"#{output_file}\"" + system(ffmpeg_cmd) + + unless $? == 0 + raise "ffmpeg failed" + end + + FileUtils.mv output_file, input_file + end + + # Add a white list of extensions which are allowed to be uploaded. + def extension_white_list + %w(ogg) + end + + def store_dir + nil + end + + def md5 + @md5 ||= ::Digest::MD5.file(current_path).hexdigest + end + + def filename + model.filename if model.id + end +end diff --git a/ruby/lib/jam_ruby/app/uploaders/uploader_configuration.rb b/ruby/lib/jam_ruby/app/uploaders/uploader_configuration.rb index e69de29bb..fd36dfd37 100644 --- a/ruby/lib/jam_ruby/app/uploaders/uploader_configuration.rb +++ b/ruby/lib/jam_ruby/app/uploaders/uploader_configuration.rb @@ -0,0 +1,32 @@ +module JamRuby + + # https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3a-Define-different-storage-configuration-for-each-Uploader. + + # these methods should be called in initialize() of uploaders to override their configuration + + class UploaderConfiguration + def self.set_aws_public_configuration(config) + config.fog_credentials = { + :provider => 'AWS', + :aws_access_key_id => APP_CONFIG.aws_access_key_id, + :aws_secret_access_key => APP_CONFIG.aws_secret_access_key, + :region => APP_CONFIG.aws_region, + } + config.fog_directory = APP_CONFIG.aws_bucket_public # required + config.fog_public = true # optional, defaults to true + config.fog_attributes = {'Cache-Control'=>"max-age=#{APP_CONFIG.aws_cache}"} # optional, defaults to {} + end + + def self.set_aws_private_configuration(config) + config.fog_credentials = { + :provider => 'AWS', + :aws_access_key_id => APP_CONFIG.aws_access_key_id, + :aws_secret_access_key => APP_CONFIG.aws_secret_access_key, + :region => APP_CONFIG.aws_region, + } + config.fog_directory = APP_CONFIG.aws_bucket # required + config.fog_public = false # optional, defaults to true + config.fog_attributes = {'Cache-Control'=>"max-age=#{APP_CONFIG.aws_cache}"} # optional, defaults to {} + end + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/constants/validation_messages.rb b/ruby/lib/jam_ruby/constants/validation_messages.rb index c46d08ab3..8c2b8d3df 100644 --- a/ruby/lib/jam_ruby/constants/validation_messages.rb +++ b/ruby/lib/jam_ruby/constants/validation_messages.rb @@ -60,6 +60,10 @@ module ValidationMessages BAD_UPLOAD = "incorrectly uploaded" PART_NOT_STARTED = "not started" UPLOAD_FAILURES_EXCEEDED = "exceeded" + ONLY_ONE_MIX = "can not be multiple" + + # claimed recordings + NOT_PART_OF_RECORDING = "not a part of this recording" # music sessions MUST_BE_A_MUSICIAN = "must be a musician" diff --git a/ruby/lib/jam_ruby/models/artifact_update.rb b/ruby/lib/jam_ruby/models/artifact_update.rb index 65cd7af3d..2a5b45a7b 100644 --- a/ruby/lib/jam_ruby/models/artifact_update.rb +++ b/ruby/lib/jam_ruby/models/artifact_update.rb @@ -8,7 +8,6 @@ module JamRuby self.primary_key = 'id' attr_accessible :version, :uri, :sha1, :environment, :product, as: :admin - mount_uploader :uri, ArtifactUploader validates :version, :presence => true diff --git a/ruby/lib/jam_ruby/models/claimed_recording.rb b/ruby/lib/jam_ruby/models/claimed_recording.rb index 9aab4acd7..ff9438bc4 100644 --- a/ruby/lib/jam_ruby/models/claimed_recording.rb +++ b/ruby/lib/jam_ruby/models/claimed_recording.rb @@ -1,12 +1,7 @@ module JamRuby class ClaimedRecording < ActiveRecord::Base - validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true - validates :description, no_profanity: true, length: {maximum: 8000} - validates :is_public, :inclusion => {:in => [true, false]} - validates :is_downloadable, :inclusion => {:in => [true, false]} - validates :genre, presence: true - validates_uniqueness_of :recording_id, :scope => :user_id + attr_accessible :name, :description, :is_public, :is_downloadable, :genre_id, :recording_id, :user_id, as: :admin belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings @@ -15,10 +10,26 @@ module JamRuby has_many :playing_sessions, :class_name => "JamRuby::MusicSession" has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id' + + validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true + validates :description, no_profanity: true, length: {maximum: 8000} + validates :is_public, :inclusion => {:in => [true, false]} + validates :is_downloadable, :inclusion => {:in => [true, false]} + validates :genre, presence: true + validates :user, presence: true + validates_uniqueness_of :user_id, :scope => :recording_id + validate :user_belongs_to_recording + + before_create :generate_share_token SHARE_TOKEN_LENGTH = 8 + def user_belongs_to_recording + if user && recording && !recording.users.exists?(user) + errors.add(:user, ValidationMessages::NOT_PART_OF_RECORDING) + end + end # user must own this object # params is a hash, and everything is optional def update_fields(user, params) diff --git a/ruby/lib/jam_ruby/models/mix.rb b/ruby/lib/jam_ruby/models/mix.rb index 9ec1c1e66..9cfc1fcc2 100644 --- a/ruby/lib/jam_ruby/models/mix.rb +++ b/ruby/lib/jam_ruby/models/mix.rb @@ -7,8 +7,27 @@ module JamRuby before_destroy :delete_s3_files self.primary_key = 'id' - belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :mixes + attr_accessible :ogg_url, :should_retry, as: :admin + attr_writer :is_skip_mount_uploader + + belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :mixes, :foreign_key => 'recording_id' + + mount_uploader :ogg_url, MixUploader + + + before_validation do + # this should be an activeadmin only path, because it's using the mount_uploader (whereas the client does something completely different) + if ogg_url.present? && ogg_url.respond_to?(:file) && ogg_url_changed? + self.ogg_length = ogg_url.file.size + self.ogg_md5 = ogg_url.md5 + self.completed = true + self.started_at = Time.now + self.completed_at = Time.now + # do not set marking_complete = true; use of marking_complete is a client-centric design, + # and setting to true causes client-centric validations + end + end def self.schedule(recording) @@ -17,8 +36,8 @@ module JamRuby mix = Mix.new mix.recording = recording mix.save - mix.ogg_url = construct_filename(mix.created_at, recording.id, mix.id, type='ogg') - mix.mp3_url = construct_filename(mix.created_at, recording.id, mix.id, type='mp3') + mix[:ogg_url] = construct_filename(mix.created_at, recording.id, mix.id, type='ogg') + mix[:mp3_url] = construct_filename(mix.created_at, recording.id, mix.id, type='mp3') if mix.save mix.enqueue end @@ -83,9 +102,9 @@ module JamRuby def s3_url(type='ogg') if type == 'ogg' - s3_manager.s3_url(ogg_url) + s3_manager.s3_url(self[:ogg_url]) else - s3_manager.s3_url(mp3_url) + s3_manager.s3_url(self[:mp3_url]) end @@ -98,31 +117,33 @@ module JamRuby def sign_url(expiration_time = 120, type='ogg') # expire link in 1 minute--the expectation is that a client is immediately following this link if type == 'ogg' - s3_manager.sign_url(self.ogg_url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) + s3_manager.sign_url(self[:ogg_url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) else - s3_manager.sign_url(self.mp3_url, {:expires => expiration_time, :response_content_type => 'audio/mp3', :secure => false}) + s3_manager.sign_url(self[:mp3_url], {:expires => expiration_time, :response_content_type => 'audio/mp3', :secure => false}) end end def sign_put(expiration_time = 3600 * 24, type='ogg') if type == 'ogg' - s3_manager.sign_url(self.ogg_url, {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put) + s3_manager.sign_url(self[:ogg_url], {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put) else - s3_manager.sign_url(self.mp3_url, {:expires => expiration_time, :content_type => 'audio/mp3', :secure => false}, :put) + s3_manager.sign_url(self[:mp3_url], {:expires => expiration_time, :content_type => 'audio/mp3', :secure => false}, :put) end end + + def filename(type='ogg') + # construct a path for s3 + Mix.construct_filename(self.created_at, self.recording_id, self.id, type) + end + private def delete_s3_files - s3_manager.delete(filename(type='ogg')) - s3_manager.delete(filename(type='mp3')) + s3_manager.delete(filename(type='ogg')) if self[:ogg_url] + s3_manager.delete(filename(type='mp3')) if self[:mp3_url] end - def filename(type='ogg') - # construct a path for s3 - Mix.construct_filename(self.created_at, self.recording.id, self.id, type) - end def self.construct_filename(created_at, recording_id, id, type='ogg') raise "unknown ID" unless id diff --git a/ruby/lib/jam_ruby/models/recorded_track.rb b/ruby/lib/jam_ruby/models/recorded_track.rb index 5ea21b734..ee0cefa08 100644 --- a/ruby/lib/jam_ruby/models/recorded_track.rb +++ b/ruby/lib/jam_ruby/models/recorded_track.rb @@ -8,12 +8,17 @@ module JamRuby self.table_name = "recorded_tracks" self.primary_key = 'id' - attr_accessible :discard + attr_accessor :marking_complete + attr_writer :is_skip_mount_uploader + + attr_accessible :discard, :user, :user_id, :instrument_id, :sound, :client_id, :track_id, :client_track_id, :url, as: :admin SOUND = %w(mono stereo) MAX_PART_FAILURES = 3 MAX_UPLOAD_FAILURES = 10 - + + mount_uploader :url, RecordedTrackUploader + belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :recorded_tracks belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :recorded_tracks belongs_to :instrument, :class_name => "JamRuby::Instrument" @@ -24,12 +29,28 @@ module JamRuby validates :client_track_id, :presence => true validates :md5, :presence => true, :if => :upload_starting? validates :length, length: {minimum: 1, maximum: 1024 * 1024 * 256 }, if: :upload_starting? # 256 megs max. is this reasonable? surely... + validates :user, presence: true + validates :instrument, presence: true - before_destroy :delete_s3_files # DO THIS TOMORROW + before_destroy :delete_s3_files validate :validate_fully_uploaded validate :validate_part_complete validate :validate_too_many_upload_failures + before_save :sanitize_active_admin + skip_callback :save, :before, :store_picture!, if: :is_skip_mount_uploader? + + before_validation do + # this should be an activeadmin only path, because it's using the mount_uploader (whereas the client does something completely different) + if url.present? && url.respond_to?(:file) && url_changed? + self.length = url.file.size + self.md5 = url.md5 + self.fully_uploaded = true + # do not set marking_complete = true; use of marking_complete is a client-centric design, + # and setting to true causes client-centric validations + end + end + def musician self.user end @@ -49,12 +70,11 @@ module JamRuby end def validate_fully_uploaded - if fully_uploaded && fully_uploaded_was + if marking_complete && fully_uploaded && fully_uploaded_was errors.add(:fully_uploaded, ValidationMessages::ALREADY_UPLOADED) end end - def validate_part_complete # if we see a transition from is_part_uploading from true to false, we validate @@ -77,6 +97,10 @@ module JamRuby end end + def sanitize_active_admin + self.user_id = nil if self.user_id == '' + end + # Copy an ephemeral track to create a saved one. Some fields are ok with defaults def self.create_from_track(track, recording) recorded_track = self.new @@ -89,14 +113,16 @@ module JamRuby recorded_track.sound = track.sound recorded_track.next_part_to_upload = 0 recorded_track.file_offset = 0 + recorded_track.is_skip_mount_uploader = true recorded_track.save recorded_track.url = construct_filename(recorded_track.created_at, recording.id, track.client_track_id) recorded_track.save + recorded_track.is_skip_mount_uploader = false recorded_track end def sign_url(expiration_time = 120) - s3_manager.sign_url(self.url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) + s3_manager.sign_url(self[:url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) end def upload_start(length, md5) @@ -147,6 +173,7 @@ module JamRuby def upload_complete # validate from happening twice by :validate_fully_uploaded self.fully_uploaded = true + self.marking_complete = true save end @@ -155,15 +182,15 @@ module JamRuby RecordedTrack.update_all("part_failures = #{self.part_failures}", "id = '#{self.id}'") end + def filename + # construct a path from s3 + RecordedTrack.construct_filename(self.created_at, self.recording.id, self.client_track_id) + end + private def delete_s3_files - s3_manager.delete(url) - end - - def filename - # construct a path for s3 - RecordedTrack.construct_filename(self.created_at, self.recording.id, self.client_track_id) + s3_manager.delete(self[:url]) if self[:url] end def self.construct_filename(created_at, recording_id, client_track_id) diff --git a/ruby/lib/jam_ruby/models/recorded_track_observer.rb b/ruby/lib/jam_ruby/models/recorded_track_observer.rb index 8ad806704..7cd538f1b 100644 --- a/ruby/lib/jam_ruby/models/recorded_track_observer.rb +++ b/ruby/lib/jam_ruby/models/recorded_track_observer.rb @@ -25,7 +25,7 @@ module JamRuby end # if we detect that this just became fully uploaded -- if so, tell s3 to put the parts together - if !recorded_track.fully_uploaded_was && recorded_track.fully_uploaded + if recorded_track.marking_complete && !recorded_track.fully_uploaded_was && recorded_track.fully_uploaded multipart_success = false begin diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index c55b21c99..631431928 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -3,24 +3,34 @@ module JamRuby self.primary_key = 'id' - attr_accessible :name, :description, :genre, :is_public, :is_downloadable + attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :is_downloadable, as: :admin - has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :recording + has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :recording, :foreign_key => 'recording_id', :dependent => :destroy has_many :users, :through => :recorded_tracks, :class_name => "JamRuby::User" - has_many :mixes, :class_name => "JamRuby::Mix", :inverse_of => :recording - has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id + has_many :mixes, :class_name => "JamRuby::Mix", :inverse_of => :recording, :foreign_key => 'recording_id', :dependent => :destroy + has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id, :dependent => :destroy has_many :comments, :class_name => "JamRuby::RecordingComment", :foreign_key => "recording_id" has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "recording_id" has_many :plays, :class_name => "JamRuby::RecordingPlay", :foreign_key => "recording_id" - belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings + belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings, :foreign_key => 'owner_id' belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings belongs_to :music_session, :class_name => "JamRuby::MusicSession", :inverse_of => :recordings + accepts_nested_attributes_for :recorded_tracks, :mixes, :claimed_recordings, allow_destroy: true + validate :not_already_recording, :on => :create validate :not_still_finalizing_previous, :on => :create validate :not_playback_recording, :on => :create validate :already_stopped_recording + validate :only_one_mix + + before_save :sanitize_active_admin + + def sanitize_active_admin + self.owner_id = nil if self.owner_id == '' + self.band_id = nil if self.band_id == '' + end def comment_count self.comments.size @@ -74,6 +84,14 @@ module JamRuby end end + + def only_one_mix + # we leave mixes as has_many because VRFS-1089 was very hard to do with has_one + cocoon add/remove + if mixes.length > 1 + errors.add(:mixes, ValidationMessages::ONLY_ONE_MIX) + end + end + def recorded_tracks_for_user(user) unless self.users.exists?(user) raise PermissionError, "user was not in this session" @@ -195,7 +213,7 @@ module JamRuby :recording_id => recorded_track.recording_id, :length => recorded_track.length, :md5 => recorded_track.md5, - :url => recorded_track.url, + :url => recorded_track[:url], :next => recorded_track.id } ) diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 15af1ec0f..d8e3263ff 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -38,7 +38,7 @@ module JamRuby has_many :bands, :through => :band_musicians, :class_name => "JamRuby::Band" # recordings - has_many :owned_recordings, :class_name => "JamRuby::Recording" + has_many :owned_recordings, :class_name => "JamRuby::Recording", :foreign_key => 'owner_id' has_many :recordings, :through => :claimed_recordings, :class_name => "JamRuby::Recording" has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :user has_many :playing_claimed_recordings, :class_name => "JamRuby::MusicSession", :inverse_of => :claimed_recording_initiator @@ -212,7 +212,7 @@ module JamRuby end def name - return "#{first_name} #{last_name}" + "#{first_name} #{last_name}" end def location @@ -1126,6 +1126,16 @@ module JamRuby iu end + # both email and name helps someone understand/recall/verify who they are looking at + def autocomplete_display_name + "#{email} (#{name})" + end + + # used by formtastic for display + def to_label + autocomplete_display_name + end + # devise compatibility #def encrypted_password diff --git a/ruby/spec/jam_ruby/models/claimed_recording_spec.rb b/ruby/spec/jam_ruby/models/claimed_recording_spec.rb index 9b0026c6e..836b69ad9 100644 --- a/ruby/spec/jam_ruby/models/claimed_recording_spec.rb +++ b/ruby/spec/jam_ruby/models/claimed_recording_spec.rb @@ -109,7 +109,7 @@ describe ClaimedRecording do make_claim duplicate = @recording.claim(@user, "name", "description", @genre, true, true) duplicate.valid?.should be_false - duplicate.errors[:recording_id].should == ['has already been taken'] + duplicate.errors[:user_id].should == ['has already been taken'] end end diff --git a/ruby/spec/jam_ruby/models/recorded_track_spec.rb b/ruby/spec/jam_ruby/models/recorded_track_spec.rb index c8e3b2c8a..f374bd489 100644 --- a/ruby/spec/jam_ruby/models/recorded_track_spec.rb +++ b/ruby/spec/jam_ruby/models/recorded_track_spec.rb @@ -41,8 +41,8 @@ describe RecordedTrack do it "gets a url for the track" do @recorded_track = RecordedTrack.create_from_track(@track, @recording) - @recorded_track.save.should be_true - @recorded_track.url.should == "recordings/#{@recorded_track.created_at.strftime('%m-%d-%Y')}/#{@recording.id}/track-#{@track.client_track_id}.ogg" + @recorded_track.errors.any?.should be_false + @recorded_track[:url].should == "recordings/#{@recorded_track.created_at.strftime('%m-%d-%Y')}/#{@recording.id}/track-#{@track.client_track_id}.ogg" end it "signs url" do diff --git a/ruby/spec/jam_ruby/models/recording_spec.rb b/ruby/spec/jam_ruby/models/recording_spec.rb index 0cebe3880..6cf118e1e 100644 --- a/ruby/spec/jam_ruby/models/recording_spec.rb +++ b/ruby/spec/jam_ruby/models/recording_spec.rb @@ -24,9 +24,8 @@ describe Recording do user2_recorded_tracks.length.should == 1 user2_recorded_tracks[0].should == user2.recorded_tracks[0] - RecordedTrack.update(user1_recorded_tracks, :discard => true) - user1_recorded_tracks[0].reload - user1_recorded_tracks[0].discard.should be_true + user1_recorded_tracks[0].discard = true + user1_recorded_tracks[0].save! end it "should set up the recording properly when recording is started with 1 user in the session" do diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb index 052a7d1fa..8b747ead5 100644 --- a/ruby/spec/spec_helper.rb +++ b/ruby/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'simplecov' require 'support/utilities' require 'active_record' require 'jam_db' diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb index 6bbcbacdb..ef2e28292 100644 --- a/ruby/spec/support/utilities.rb +++ b/ruby/spec/support/utilities.rb @@ -77,6 +77,29 @@ def app_config "#{external_protocol}#{external_hostname}#{(external_port == 80 || external_port == 443) ? '' : ':' + external_port.to_s}" end + def aws_access_key_id + 'AKIAJESQY24TOT542UHQ' + end + + def aws_secret_access_key + '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' + end + + def aws_region + 'us-east-1' + end + + def aws_bucket + 'jamkazam-testing' + end + + def aws_bucket_public + 'jamkazam-testing-public' + end + + def aws_cache + '315576000' + end private diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb index 984443712..16a197fcf 100644 --- a/web/app/controllers/api_music_sessions_controller.rb +++ b/web/app/controllers/api_music_sessions_controller.rb @@ -208,10 +208,10 @@ class ApiMusicSessionsController < ApiController return end - if SampleApp::Application.config.storage_type == :fog + if Rails.application.config.storage_type == :fog uri = @perfdata.uri - s3 = AWS::S3.new(:access_key_id => SampleApp::Application.config.aws_access_key_id, - :secret_access_key => SampleApp::Application.config.aws_secret_access_key) + s3 = AWS::S3.new(:access_key_id => Rails.application.config.aws_access_key_id, + :secret_access_key => Rails.application.config.aws_secret_access_key) bucket = s3.buckets[SampleApp::Application.config.aws_bucket] expire = Time.now + 20.years diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb index 59ac5c6fd..b20133833 100644 --- a/web/app/controllers/api_users_controller.rb +++ b/web/app/controllers/api_users_controller.rb @@ -490,12 +490,11 @@ class ApiUsersController < ApiController end # This part is the piece that really needs to be decomposed into a library... - if SampleApp::Application.config.storage_type == :fog - s3 = AWS::S3.new(:access_key_id => SampleApp::Application.config.aws_access_key_id, - :secret_access_key => SampleApp::Application.config.aws_secret_access_key) - # Fixme: Should we use the same bucket for everything? - bucket = s3.buckets[SampleApp::Application.config.aws_bucket] - url = bucket.objects[@dump.uri].url_for(:write, :expires => SampleApp::Application.config.crash_dump_data_signed_url_timeout, :'response_content_type' => 'application/octet-stream').to_s + if Rails.application.config.storage_type == :fog + s3 = AWS::S3.new(:access_key_id => Rails.application.config.aws_access_key_id, + :secret_access_key => Rails.application.config.aws_secret_access_key) + bucket = s3.buckets[Rails.application.config.aws_bucket] + url = bucket.objects[@dump.uri].url_for(:write, :expires => Rails.application.config.crash_dump_data_signed_url_timeout, :'response_content_type' => 'application/octet-stream').to_s logger.debug("crash_dump can upload to url #{url}") diff --git a/web/app/views/api_claimed_recordings/show.rabl b/web/app/views/api_claimed_recordings/show.rabl index 1db99c371..56cd305de 100644 --- a/web/app/views/api_claimed_recordings/show.rabl +++ b/web/app/views/api_claimed_recordings/show.rabl @@ -24,11 +24,23 @@ child(:recording => :recording) { } child(:mixes => :mixes) { - attributes :id, :mp3_url, :ogg_url, :is_completed + attributes :id, :is_completed + + node :mp3_url do |mix| + mix[:url] + end + + node :ogg_url do |mix| + mix[:url] + end } child(:recorded_tracks => :recorded_tracks) { - attributes :id, :fully_uploaded, :url, :client_track_id, :client_id, :instrument_id + attributes :id, :fully_uploaded, :client_track_id, :client_id, :instrument_id + + node :url do |recorded_track| + recorded_track[:url] + end child(:user => :user) { attributes :id, :first_name, :last_name, :name, :city, :state, :country, :photo_url diff --git a/web/app/views/api_music_sessions/show.rabl b/web/app/views/api_music_sessions/show.rabl index 6121cb111..1962111fb 100644 --- a/web/app/views/api_music_sessions/show.rabl +++ b/web/app/views/api_music_sessions/show.rabl @@ -59,11 +59,23 @@ node(:claimed_recording, :if => lambda { |music_session| music_session.users.exi } child(:mixes => :mixes) { - attributes :id, :mp3_url, :ogg_url, :is_completed + attributes :id, :is_completed + + node :mp3_url do |mix| + mix[:url] + end + + node :ogg_url do |mix| + mix[:url] + end } child(:recorded_tracks => :recorded_tracks) { - attributes :id, :fully_uploaded, :url, :client_track_id, :client_id, :instrument_id + attributes :id, :fully_uploaded, :client_track_id, :client_id, :instrument_id + + node :url do |recorded_track| + recorded_track[:url] + end child(:user => :user) { attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url diff --git a/web/app/views/api_recordings/show.rabl b/web/app/views/api_recordings/show.rabl index 0ece6725a..9da99c52a 100644 --- a/web/app/views/api_recordings/show.rabl +++ b/web/app/views/api_recordings/show.rabl @@ -3,7 +3,11 @@ object @recording attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count child(:recorded_tracks => :recorded_tracks) { - attributes :id, :fully_uploaded, :url, :client_track_id, :client_id, :instrument_id + attributes :id, :fully_uploaded, :client_track_id, :client_id, :instrument_id + + node :url do |recorded_track| + recorded_track[:url] + end child(:user => :user) { attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url diff --git a/web/config/initializers/carrierwave.rb b/web/config/initializers/carrierwave.rb index 52f19fce3..05f035f6a 100644 --- a/web/config/initializers/carrierwave.rb +++ b/web/config/initializers/carrierwave.rb @@ -4,16 +4,8 @@ CarrierWave.root = Rails.root.join(Rails.public_path).to_s CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT'] CarrierWave.configure do |config| - config.storage = SampleApp::Application.config.storage_type - config.fog_credentials = { - :provider => 'AWS', - :aws_access_key_id => SampleApp::Application.config.aws_access_key_id, - :aws_secret_access_key => SampleApp::Application.config.aws_secret_access_key, - :region => SampleApp::Application.config.aws_region, - } - config.fog_directory = SampleApp::Application.config.aws_bucket_public # required - config.fog_public = true # optional, defaults to true - config.fog_attributes = {'Cache-Control'=>"max-age=#{SampleApp::Application.config.aws_cache}"} # optional, defaults to {} + config.storage = Rails.application.config.storage_type + JamRuby::UploaderConfiguration.set_aws_private_configuration(config) end diff --git a/web/spec/controllers/claimed_recordings_spec.rb b/web/spec/controllers/claimed_recordings_spec.rb index 7b787e43b..ad16980b6 100644 --- a/web/spec/controllers/claimed_recordings_spec.rb +++ b/web/spec/controllers/claimed_recordings_spec.rb @@ -35,7 +35,7 @@ describe ApiClaimedRecordingsController do json["recording"]["band"].should be_nil json["recording"]["recorded_tracks"].length.should == 1 json["recording"]["recorded_tracks"].first["id"].should == @recording.recorded_tracks.first.id - json["recording"]["recorded_tracks"].first["url"].should == @recording.recorded_tracks.first.url + json["recording"]["recorded_tracks"].first["url"].should == @recording.recorded_tracks.first[:url] json["recording"]["recorded_tracks"].first["instrument_id"].should == @instrument.id json["recording"]["recorded_tracks"].first["user"]["id"].should == @user.id end