* VRFS-1089 - jamadmin creation of recordings done

This commit is contained in:
Seth Call 2014-02-13 16:41:50 +00:00
parent 69523e0e07
commit 5ba4e97dca
39 changed files with 532 additions and 181 deletions

View File

@ -99,7 +99,12 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
controller 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 def create
@jam_ruby_user = JamRuby::User.new(params[:jam_ruby_user]) @jam_ruby_user = JamRuby::User.new(params[:jam_ruby_user])

View File

@ -10,19 +10,37 @@ ActiveAdmin.register JamRuby::Recording, :as => 'Recording' do
form :partial => 'form' form :partial => 'form'
controller do 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 def new
@recording = JamRuby::Recording.new @recording = JamRuby::Recording.new
super super
end end
def create def create
owner = User.find_by_email!(params[:jam_ruby_recording][:owner]) params.merge! initialize_client_tokens(params)
band = User.find_by_band!(params[:jam_ruby_recording][:band]) create!
recording = Recording.new
recording.owner = owner
recording.band = band
recording.save
redirect_to("/admin/recordings/#{recording.id}")
end end
def edit def edit
@ -30,26 +48,12 @@ ActiveAdmin.register JamRuby::Recording, :as => 'Recording' do
super super
end end
def update def update
owner = User.find_by_email!(params[:jam_ruby_recording][:owner]) params.merge! initialize_client_tokens(params)
band = Band.find_by_name!(params[:jam_ruby_recording][:band])
recorded_tracks = params[:jam_ruby_recording][:recorded_tracks] update! do |format|
recorded_tracks.each do |recorded_track| format.html { redirect_to edit_admin_recording_url(params[:jam_ruby_recording]) }
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
end end
resource.owner = owner
resource.band = band
resource.save
redirect_to("/admin/recordings/#{resource.id}")
end end
end end

View File

@ -1,11 +1,12 @@
// //= require active_admin/base // //= require active_admin/base
//= require jquery //= require jquery
//= require jquery_ujs //= require jquery_ujs
//= require jquery.ui.core //= require jquery-ui
//= require jquery.ui.widget // require jquery.ui.core
//= require jquery.ui.datepicker // require jquery.ui.widget
//= require jquery.ui.dialog // require jquery.ui.datepicker
//= require jquery.ui.autocomplete // require jquery.ui.dialog
// require jquery.ui.autocomplete
//= require cocoon //= require cocoon
//= require active_admin/application //= require active_admin/application
//= require autocomplete-rails //= require autocomplete-rails

View File

@ -2,10 +2,16 @@
class ImageUploader < CarrierWave::Uploader::Base class ImageUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader include CarrierWaveDirect::Uploader
include CarrierWave::MimeTypes include CarrierWave::MimeTypes
process :set_content_type 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. # Add a white list of extensions which are allowed to be uploaded.
def extension_white_list def extension_white_list
%w(jpg jpeg gif png) %w(jpg jpeg gif png)

View File

@ -1,10 +1,15 @@
= f.inputs name: 'Claimed Recording' do = 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 %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'} %div{style: 'display:none'}
= #f.input :should_retry, :as => :hidden, :input_html => {:value => '0' }

View File

@ -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| %> %h2 Instructions
<%= f.semantic_errors *f.object.errors.keys %> %h3 Overview
<%= f.inputs do %> %p Make each recorded track first, then the mix, and then finally the claimed recordings.
<%= f.input :owner, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path %> %h3 Entering users and bands
<%= f.input :band, :as => :autocomplete, :url => autocomplete_band_name_admin_bands_path %> %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| %> = semantic_form_for([:admin, @recording], :html => {:multipart => true}, :url => @recording.new_record? ? admin_recordings_path : "/admin/recordings/#{@recording.id}") do |f|
<%= render 'recorded_track', f: recorded_track %> = f.semantic_errors *f.object.errors.keys
<% end %> = 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.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.actions %> = f.input :owner_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[owner_id]" }
<% end %>
= 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)
}
});
});

View File

@ -1,18 +1,21 @@
= f.inputs name: 'Track' do = f.inputs name: 'Mix' do
%ol.nested-fields %ol.nested-fields
= puts "f.object #{f.object.url}" - if f.object.new_record?
= 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" } %p{style: 'margin-left:10px'}
= f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_recorded_track[user_id]" } %i before you can upload, you must select 'Update Recording'
= f.input :instrument, collection: Instrument.all - else
= f.input :sound, :as => :select, collection: options_for_select(RecordedTrack::SOUND, 'stereo') = f.input :ogg_url, :as => :file
= f.input :url, :as => :file - unless f.object.nil? || f.object[:ogg_url].nil?
- unless f.object.nil? && f.object.url.nil? .current_file_holder{style: 'margin-bottom:10px'}
%a{href: f.object.sign_url} current file %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

View File

@ -1,4 +1,25 @@
li.control-group nested-fields = f.inputs name: 'Track' do
div.controls
= f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path %ol.nested-fields
= f.input :instrument, :collection => Instrument.all = 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'

View File

@ -87,7 +87,7 @@ module JamAdmin
# set to false to instead use amazon. You will also need to supply amazon secrets # set to false to instead use amazon. You will also need to supply amazon secrets
config.store_artifacts_to_disk = false 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 # these only need to be set if store_artifact_to_files = false
config.aws_access_key_id = ENV['AWS_KEY'] 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_id = ENV['TWITTER_APP_ID'] || 'nQj2oEeoJZxECC33tiTuIg'
config.twitter_app_secret = ENV['TWITTER_APP_SECRET'] || 'Azcy3QqfzYzn2fsojFPYXcn72yfwa0vG6wWDrZ3KT8' 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
end end

View File

@ -4,20 +4,9 @@ CarrierWave.root = Rails.root.join(Rails.public_path).to_s
CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT'] CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT']
CarrierWave.configure do |config| CarrierWave.configure do |config|
if JamAdmin::Application.config.store_artifacts_to_disk
config.storage = :file config.storage = Rails.application.config.store_artifacts_to_disk ? :file : :fog
else JamRuby::UploaderConfiguration.set_aws_private_configuration(config)
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
end end
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'

View File

@ -103,4 +103,5 @@ share_token_2.sql
large_photo_url.sql large_photo_url.sql
add_secret_to_user_authorization.sql add_secret_to_user_authorization.sql
track_connection_id_not_null.sql track_connection_id_not_null.sql
recordings_all_discarded.sql recordings_all_discarded.sql
recordings_via_admin_web.sql

7
ruby/.simplecov Normal file
View File

@ -0,0 +1,7 @@
SimpleCov.start do
add_filter "/test/"
add_filter "/bin/"
add_filter "/scripts/"
add_filter "/tmp/"
add_filter "/vendor/"
end

View File

@ -43,7 +43,8 @@ gem 'oj'
gem 'builder' gem 'builder'
group :test do 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 "rspec", "2.11"
gem 'spork', '0.9.0' gem 'spork', '0.9.0'
gem 'database_cleaner', '0.7.0' gem 'database_cleaner', '0.7.0'

View File

@ -45,8 +45,11 @@ require "jam_ruby/init"
require "jam_ruby/app/mailers/user_mailer" require "jam_ruby/app/mailers/user_mailer"
require "jam_ruby/app/mailers/invited_user_mailer" require "jam_ruby/app/mailers/invited_user_mailer"
require "jam_ruby/app/mailers/corp_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/artifact_uploader"
require "jam_ruby/app/uploaders/perf_data_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/lib/desk_multipass"
require "jam_ruby/amqp/amqp_connection_manager" require "jam_ruby/amqp/amqp_connection_manager"
require "jam_ruby/message_factory" require "jam_ruby/message_factory"

View File

@ -1,7 +1,12 @@
# encoding: utf-8 # 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 RMagick or MiniMagick support:
# include CarrierWave::RMagick # include CarrierWave::RMagick
# include CarrierWave::MiniMagick # include CarrierWave::MiniMagick

View File

@ -1,38 +1,23 @@
class RecordedTrackUploader < CarrierWave::Uploader::Base class MixUploader < CarrierWave::Uploader::Base
# include CarrierWaveDirect::Uploader # include CarrierWaveDirect::Uploader
include CarrierWave::MimeTypes include CarrierWave::MimeTypes
process :set_content_type process :set_content_type
process :add_metadata process :add_metadata
version :mp3_url do
process :create_mp3
def full_filename(file)
model.filename('mp3') if model.id
end
end
def initialize(*) def initialize(*)
super super
JamRuby::UploaderConfiguration.set_aws_private_configuration(self) JamRuby::UploaderConfiguration.set_aws_private_configuration(self)
end 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. # Add a white list of extensions which are allowed to be uploaded.
def extension_white_list def extension_white_list
%w(ogg) %w(ogg)
@ -47,6 +32,50 @@ class RecordedTrackUploader < CarrierWave::Uploader::Base
end end
def filename def filename
model.filename if model.id model.filename('ogg') if model.id
end 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 end

View File

@ -2,6 +2,11 @@
class PerfDataUploader < CarrierWave::Uploader::Base class PerfDataUploader < CarrierWave::Uploader::Base
def initialize(*)
super
JamRuby::UploaderConfiguration.set_aws_private_configuration(self)
end
# Include RMagick or MiniMagick support: # Include RMagick or MiniMagick support:
# include CarrierWave::RMagick # include CarrierWave::RMagick
# include CarrierWave::MiniMagick # include CarrierWave::MiniMagick

View File

@ -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

View File

@ -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

View File

@ -60,6 +60,10 @@ module ValidationMessages
BAD_UPLOAD = "incorrectly uploaded" BAD_UPLOAD = "incorrectly uploaded"
PART_NOT_STARTED = "not started" PART_NOT_STARTED = "not started"
UPLOAD_FAILURES_EXCEEDED = "exceeded" 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 # music sessions
MUST_BE_A_MUSICIAN = "must be a musician" MUST_BE_A_MUSICIAN = "must be a musician"

View File

@ -8,7 +8,6 @@ module JamRuby
self.primary_key = 'id' self.primary_key = 'id'
attr_accessible :version, :uri, :sha1, :environment, :product, as: :admin attr_accessible :version, :uri, :sha1, :environment, :product, as: :admin
mount_uploader :uri, ArtifactUploader mount_uploader :uri, ArtifactUploader
validates :version, :presence => true validates :version, :presence => true

View File

@ -1,12 +1,7 @@
module JamRuby module JamRuby
class ClaimedRecording < ActiveRecord::Base class ClaimedRecording < ActiveRecord::Base
validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true attr_accessible :name, :description, :is_public, :is_downloadable, :genre_id, :recording_id, :user_id, as: :admin
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
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings
belongs_to :user, :class_name => "JamRuby::User", :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_many :playing_sessions, :class_name => "JamRuby::MusicSession"
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id' 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 before_create :generate_share_token
SHARE_TOKEN_LENGTH = 8 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 # user must own this object
# params is a hash, and everything is optional # params is a hash, and everything is optional
def update_fields(user, params) def update_fields(user, params)

View File

@ -7,8 +7,27 @@ module JamRuby
before_destroy :delete_s3_files before_destroy :delete_s3_files
self.primary_key = 'id' 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) def self.schedule(recording)
@ -17,8 +36,8 @@ module JamRuby
mix = Mix.new mix = Mix.new
mix.recording = recording mix.recording = recording
mix.save mix.save
mix.ogg_url = construct_filename(mix.created_at, recording.id, mix.id, type='ogg') 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[:mp3_url] = construct_filename(mix.created_at, recording.id, mix.id, type='mp3')
if mix.save if mix.save
mix.enqueue mix.enqueue
end end
@ -83,9 +102,9 @@ module JamRuby
def s3_url(type='ogg') def s3_url(type='ogg')
if type == 'ogg' if type == 'ogg'
s3_manager.s3_url(ogg_url) s3_manager.s3_url(self[:ogg_url])
else else
s3_manager.s3_url(mp3_url) s3_manager.s3_url(self[:mp3_url])
end end
@ -98,31 +117,33 @@ module JamRuby
def sign_url(expiration_time = 120, type='ogg') def sign_url(expiration_time = 120, type='ogg')
# expire link in 1 minute--the expectation is that a client is immediately following this link # expire link in 1 minute--the expectation is that a client is immediately following this link
if type == 'ogg' 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 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
end end
def sign_put(expiration_time = 3600 * 24, type='ogg') def sign_put(expiration_time = 3600 * 24, type='ogg')
if 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 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
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 private
def delete_s3_files def delete_s3_files
s3_manager.delete(filename(type='ogg')) s3_manager.delete(filename(type='ogg')) if self[:ogg_url]
s3_manager.delete(filename(type='mp3')) s3_manager.delete(filename(type='mp3')) if self[:mp3_url]
end 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') def self.construct_filename(created_at, recording_id, id, type='ogg')
raise "unknown ID" unless id raise "unknown ID" unless id

View File

@ -8,12 +8,17 @@ module JamRuby
self.table_name = "recorded_tracks" self.table_name = "recorded_tracks"
self.primary_key = 'id' 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) SOUND = %w(mono stereo)
MAX_PART_FAILURES = 3 MAX_PART_FAILURES = 3
MAX_UPLOAD_FAILURES = 10 MAX_UPLOAD_FAILURES = 10
mount_uploader :url, RecordedTrackUploader
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :recorded_tracks belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :recorded_tracks
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :recorded_tracks belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :recorded_tracks
belongs_to :instrument, :class_name => "JamRuby::Instrument" belongs_to :instrument, :class_name => "JamRuby::Instrument"
@ -24,12 +29,28 @@ module JamRuby
validates :client_track_id, :presence => true validates :client_track_id, :presence => true
validates :md5, :presence => true, :if => :upload_starting? 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 :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_fully_uploaded
validate :validate_part_complete validate :validate_part_complete
validate :validate_too_many_upload_failures 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 def musician
self.user self.user
end end
@ -49,12 +70,11 @@ module JamRuby
end end
def validate_fully_uploaded 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) errors.add(:fully_uploaded, ValidationMessages::ALREADY_UPLOADED)
end end
end end
def validate_part_complete def validate_part_complete
# if we see a transition from is_part_uploading from true to false, we validate # if we see a transition from is_part_uploading from true to false, we validate
@ -77,6 +97,10 @@ module JamRuby
end end
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 # Copy an ephemeral track to create a saved one. Some fields are ok with defaults
def self.create_from_track(track, recording) def self.create_from_track(track, recording)
recorded_track = self.new recorded_track = self.new
@ -89,14 +113,16 @@ module JamRuby
recorded_track.sound = track.sound recorded_track.sound = track.sound
recorded_track.next_part_to_upload = 0 recorded_track.next_part_to_upload = 0
recorded_track.file_offset = 0 recorded_track.file_offset = 0
recorded_track.is_skip_mount_uploader = true
recorded_track.save recorded_track.save
recorded_track.url = construct_filename(recorded_track.created_at, recording.id, track.client_track_id) recorded_track.url = construct_filename(recorded_track.created_at, recording.id, track.client_track_id)
recorded_track.save recorded_track.save
recorded_track.is_skip_mount_uploader = false
recorded_track recorded_track
end end
def sign_url(expiration_time = 120) 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 end
def upload_start(length, md5) def upload_start(length, md5)
@ -147,6 +173,7 @@ module JamRuby
def upload_complete def upload_complete
# validate from happening twice by :validate_fully_uploaded # validate from happening twice by :validate_fully_uploaded
self.fully_uploaded = true self.fully_uploaded = true
self.marking_complete = true
save save
end end
@ -155,15 +182,15 @@ module JamRuby
RecordedTrack.update_all("part_failures = #{self.part_failures}", "id = '#{self.id}'") RecordedTrack.update_all("part_failures = #{self.part_failures}", "id = '#{self.id}'")
end end
def filename
# construct a path from s3
RecordedTrack.construct_filename(self.created_at, self.recording.id, self.client_track_id)
end
private private
def delete_s3_files def delete_s3_files
s3_manager.delete(url) s3_manager.delete(self[:url]) if self[:url]
end
def filename
# construct a path for s3
RecordedTrack.construct_filename(self.created_at, self.recording.id, self.client_track_id)
end end
def self.construct_filename(created_at, recording_id, client_track_id) def self.construct_filename(created_at, recording_id, client_track_id)

View File

@ -25,7 +25,7 @@ module JamRuby
end end
# if we detect that this just became fully uploaded -- if so, tell s3 to put the parts together # 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 multipart_success = false
begin begin

View File

@ -3,24 +3,34 @@ module JamRuby
self.primary_key = 'id' 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 :users, :through => :recorded_tracks, :class_name => "JamRuby::User"
has_many :mixes, :class_name => "JamRuby::Mix", :inverse_of => :recording 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 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 :comments, :class_name => "JamRuby::RecordingComment", :foreign_key => "recording_id"
has_many :likes, :class_name => "JamRuby::RecordingLiker", :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" 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 :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
belongs_to :music_session, :class_name => "JamRuby::MusicSession", :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_already_recording, :on => :create
validate :not_still_finalizing_previous, :on => :create validate :not_still_finalizing_previous, :on => :create
validate :not_playback_recording, :on => :create validate :not_playback_recording, :on => :create
validate :already_stopped_recording 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 def comment_count
self.comments.size self.comments.size
@ -74,6 +84,14 @@ module JamRuby
end end
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) def recorded_tracks_for_user(user)
unless self.users.exists?(user) unless self.users.exists?(user)
raise PermissionError, "user was not in this session" raise PermissionError, "user was not in this session"
@ -195,7 +213,7 @@ module JamRuby
:recording_id => recorded_track.recording_id, :recording_id => recorded_track.recording_id,
:length => recorded_track.length, :length => recorded_track.length,
:md5 => recorded_track.md5, :md5 => recorded_track.md5,
:url => recorded_track.url, :url => recorded_track[:url],
:next => recorded_track.id :next => recorded_track.id
} }
) )

View File

@ -38,7 +38,7 @@ module JamRuby
has_many :bands, :through => :band_musicians, :class_name => "JamRuby::Band" has_many :bands, :through => :band_musicians, :class_name => "JamRuby::Band"
# recordings # 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 :recordings, :through => :claimed_recordings, :class_name => "JamRuby::Recording"
has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :user 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 has_many :playing_claimed_recordings, :class_name => "JamRuby::MusicSession", :inverse_of => :claimed_recording_initiator
@ -212,7 +212,7 @@ module JamRuby
end end
def name def name
return "#{first_name} #{last_name}" "#{first_name} #{last_name}"
end end
def location def location
@ -1126,6 +1126,16 @@ module JamRuby
iu iu
end 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 # devise compatibility
#def encrypted_password #def encrypted_password

View File

@ -109,7 +109,7 @@ describe ClaimedRecording do
make_claim make_claim
duplicate = @recording.claim(@user, "name", "description", @genre, true, true) duplicate = @recording.claim(@user, "name", "description", @genre, true, true)
duplicate.valid?.should be_false 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
end end

View File

@ -41,8 +41,8 @@ describe RecordedTrack do
it "gets a url for the track" do it "gets a url for the track" do
@recorded_track = RecordedTrack.create_from_track(@track, @recording) @recorded_track = RecordedTrack.create_from_track(@track, @recording)
@recorded_track.save.should be_true @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" @recorded_track[:url].should == "recordings/#{@recorded_track.created_at.strftime('%m-%d-%Y')}/#{@recording.id}/track-#{@track.client_track_id}.ogg"
end end
it "signs url" do it "signs url" do

View File

@ -24,9 +24,8 @@ describe Recording do
user2_recorded_tracks.length.should == 1 user2_recorded_tracks.length.should == 1
user2_recorded_tracks[0].should == user2.recorded_tracks[0] user2_recorded_tracks[0].should == user2.recorded_tracks[0]
RecordedTrack.update(user1_recorded_tracks, :discard => true) user1_recorded_tracks[0].discard = true
user1_recorded_tracks[0].reload user1_recorded_tracks[0].save!
user1_recorded_tracks[0].discard.should be_true
end end
it "should set up the recording properly when recording is started with 1 user in the session" do it "should set up the recording properly when recording is started with 1 user in the session" do

View File

@ -1,3 +1,4 @@
require 'simplecov'
require 'support/utilities' require 'support/utilities'
require 'active_record' require 'active_record'
require 'jam_db' require 'jam_db'

View File

@ -77,6 +77,29 @@ def app_config
"#{external_protocol}#{external_hostname}#{(external_port == 80 || external_port == 443) ? '' : ':' + external_port.to_s}" "#{external_protocol}#{external_hostname}#{(external_port == 80 || external_port == 443) ? '' : ':' + external_port.to_s}"
end 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 private

View File

@ -208,10 +208,10 @@ class ApiMusicSessionsController < ApiController
return return
end end
if SampleApp::Application.config.storage_type == :fog if Rails.application.config.storage_type == :fog
uri = @perfdata.uri uri = @perfdata.uri
s3 = AWS::S3.new(:access_key_id => SampleApp::Application.config.aws_access_key_id, s3 = AWS::S3.new(:access_key_id => Rails.application.config.aws_access_key_id,
:secret_access_key => SampleApp::Application.config.aws_secret_access_key) :secret_access_key => Rails.application.config.aws_secret_access_key)
bucket = s3.buckets[SampleApp::Application.config.aws_bucket] bucket = s3.buckets[SampleApp::Application.config.aws_bucket]
expire = Time.now + 20.years expire = Time.now + 20.years

View File

@ -490,12 +490,11 @@ class ApiUsersController < ApiController
end end
# This part is the piece that really needs to be decomposed into a library... # This part is the piece that really needs to be decomposed into a library...
if SampleApp::Application.config.storage_type == :fog if Rails.application.config.storage_type == :fog
s3 = AWS::S3.new(:access_key_id => SampleApp::Application.config.aws_access_key_id, s3 = AWS::S3.new(:access_key_id => Rails.application.config.aws_access_key_id,
:secret_access_key => SampleApp::Application.config.aws_secret_access_key) :secret_access_key => Rails.application.config.aws_secret_access_key)
# Fixme: Should we use the same bucket for everything? bucket = s3.buckets[Rails.application.config.aws_bucket]
bucket = s3.buckets[SampleApp::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
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
logger.debug("crash_dump can upload to url #{url}") logger.debug("crash_dump can upload to url #{url}")

View File

@ -24,11 +24,23 @@ child(:recording => :recording) {
} }
child(:mixes => :mixes) { 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) { 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) { child(:user => :user) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :photo_url attributes :id, :first_name, :last_name, :name, :city, :state, :country, :photo_url

View File

@ -59,11 +59,23 @@ node(:claimed_recording, :if => lambda { |music_session| music_session.users.exi
} }
child(:mixes => :mixes) { 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) { 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) { child(:user => :user) {
attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url

View File

@ -3,7 +3,11 @@ object @recording
attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count
child(:recorded_tracks => :recorded_tracks) { 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) { child(:user => :user) {
attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url

View File

@ -4,16 +4,8 @@ CarrierWave.root = Rails.root.join(Rails.public_path).to_s
CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT'] CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT']
CarrierWave.configure do |config| CarrierWave.configure do |config|
config.storage = SampleApp::Application.config.storage_type config.storage = Rails.application.config.storage_type
config.fog_credentials = { JamRuby::UploaderConfiguration.set_aws_private_configuration(config)
: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 {}
end end

View File

@ -35,7 +35,7 @@ describe ApiClaimedRecordingsController do
json["recording"]["band"].should be_nil json["recording"]["band"].should be_nil
json["recording"]["recorded_tracks"].length.should == 1 json["recording"]["recorded_tracks"].length.should == 1
json["recording"]["recorded_tracks"].first["id"].should == @recording.recorded_tracks.first.id 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["instrument_id"].should == @instrument.id
json["recording"]["recorded_tracks"].first["user"]["id"].should == @user.id json["recording"]["recorded_tracks"].first["user"]["id"].should == @user.id
end end