diff --git a/db/up/store_s3_filenames.sql b/db/up/store_s3_filenames.sql index 875664d09..2c9950b3a 100644 --- a/db/up/store_s3_filenames.sql +++ b/db/up/store_s3_filenames.sql @@ -4,9 +4,9 @@ DELETE FROM mixes; -- store full path to s3 bucket for mix and recorded_track -ALTER TABLE recorded_tracks ADD COLUMN url varchar(1024) NOT NULL; +ALTER TABLE recorded_tracks ADD COLUMN url varchar(1024); -ALTER TABLE mixes ADD COLUMN url varchar(1024) NOT NULL; +ALTER TABLE mixes ADD COLUMN url varchar(1024); -- greater than 64 bytes come back from amazon for upload ids ALTER TABLE recorded_tracks ALTER COLUMN upload_id TYPE varchar(1024); @@ -28,3 +28,17 @@ ALTER TABLE recorded_tracks ADD COLUMN upload_failures int NOT NULL DEFAULT 0; -- track error counts for the current part ALTER TABLE recorded_tracks ADD COLUMN part_failures int NOT NULL DEFAULT 0; + +-- create a auto-incrementing primary key for recorded_tracks +-- create a auto-incrementing primary key for mixes +-- and have them share the same sequence +CREATE SEQUENCE tracks_next_tracker_seq; +ALTER TABLE recorded_tracks ALTER COLUMN id DROP DEFAULT; +ALTER TABLE mixes ALTER COLUMN id DROP DEFAULT; +ALTER TABLE recorded_tracks ALTER COLUMN id TYPE BIGINT USING 0; +ALTER TABLE mixes ALTER COLUMN id TYPE BIGINT USINg 0; +ALTER TABLE recorded_tracks ALTER COLUMN id SET DEFAULT nextval('tracks_next_tracker_seq'); +ALTER TABLE mixes ALTER COLUMN id SET DEFAULT nextval('tracks_next_tracker_seq'); + +--ALTER TABLE recorded_tracks ADD COLUMN next_tracker bigint NOT NULL DEFAULT nextval('tracks_next_tracker_seq'); +--ALTER TABLE mixes ADD COLUMN next_tracker bigint NOT NULL DEFAULT nextval('tracks_next_tracker_seq'); diff --git a/ruby/lib/jam_ruby/message_factory.rb b/ruby/lib/jam_ruby/message_factory.rb index ae522ef84..51df0e0d5 100644 --- a/ruby/lib/jam_ruby/message_factory.rb +++ b/ruby/lib/jam_ruby/message_factory.rb @@ -52,14 +52,15 @@ end # create a login ack (login was successful) - def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected) + def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected, user_id) login_ack = Jampb::LoginAck.new( :public_ip => public_ip, :client_id => client_id, :token => token, :heartbeat_interval => heartbeat_interval, :music_session_id => music_session_id, - :reconnected => reconnected + :reconnected => reconnected, + :user_id => user_id ) return Jampb::ClientMessage.new( diff --git a/ruby/lib/jam_ruby/models/mix.rb b/ruby/lib/jam_ruby/models/mix.rb index b36735dfc..05be52b41 100644 --- a/ruby/lib/jam_ruby/models/mix.rb +++ b/ruby/lib/jam_ruby/models/mix.rb @@ -15,7 +15,7 @@ module JamRuby mix = Mix.new mix.recording = recording mix.manifest = manifest - mix.id = SecureRandom.uuid # so that we can save url too + mix.save mix.url = construct_filename(recording.id, mix.id) mix.save mix @@ -72,6 +72,7 @@ module JamRuby end def self.construct_filename(recording_id, id) + raise "unknown ID" unless id "recordings/#{recording_id}/mix-#{id}.ogg" end diff --git a/ruby/lib/jam_ruby/models/recorded_track.rb b/ruby/lib/jam_ruby/models/recorded_track.rb index a297e996a..8b22e86a2 100644 --- a/ruby/lib/jam_ruby/models/recorded_track.rb +++ b/ruby/lib/jam_ruby/models/recorded_track.rb @@ -77,9 +77,11 @@ module JamRuby recorded_track.user = track.connection.user recorded_track.instrument = track.instrument recorded_track.sound = track.sound - recorded_track.url = construct_filename(recording.id, track.id) recorded_track.next_part_to_upload = 0 recorded_track.file_offset = 0 + recorded_track.save + recorded_track.url = construct_filename(recording.id, track.id) + recorded_track.save recorded_track end @@ -99,8 +101,6 @@ module JamRuby # if for some reason the server thinks the client can't carry on with the upload, # this resets everything to the initial state def reset_upload - puts "resetttttted" - self.upload_failures = self.upload_failures + 1 self.part_failures = 0 self.file_offset = 0 @@ -158,6 +158,7 @@ module JamRuby end def self.construct_filename(recording_id, track_id) + raise "unknown ID" unless track_id "recordings/#{recording_id}/track-#{track_id}.ogg" end end diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 744762e37..18b2054de 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -37,15 +37,14 @@ module JamRuby recording.music_session = music_session recording.owner = owner recording.band = music_session.band - recording.id = SecureRandom.uuid # set the recording so that RecordedTrack.create_from_track has an id already on recording - music_session.connections.each do |connection| - connection.tracks.each do |track| - recording.recorded_tracks << RecordedTrack.create_from_track(track, recording) + if recording.save + music_session.connections.each do |connection| + connection.tracks.each do |track| + recording.recorded_tracks << RecordedTrack.create_from_track(track, recording) + end end end - - recording.save end @@ -139,15 +138,16 @@ module JamRuby files end - def self.list_downloads(user, limit = 100, since = Date.new(1)) + def self.list_downloads(user, limit = 100, since = 0) + since = 0 unless since || since == '' # guard against nil downloads = [] # That second join is important. It's saying join off of recordings, NOT user. If you take out the # ":recordings =>" part, you'll just get the recorded_tracks that I played. Very different! User.joins(:recordings).joins(:recordings => :recorded_tracks) - .order(%Q{ recordings.created_at }) + .order(%Q{ recorded_tracks.id }) .where(%Q{ recorded_tracks.fully_uploaded = TRUE }) - .where('recorded_tracks.created_at > ?', since) + .where('recorded_tracks.id > ?', since) .where(:id => user.id).limit(limit).each do |theuser| theuser.recordings.each do |recording| recording.recorded_tracks.each do |recorded_track| @@ -160,19 +160,20 @@ module JamRuby :length => recorded_track.length, :md5 => recorded_track.md5, :url => recorded_track.filename, - :created_at => recorded_track.created_at + :next => recorded_track.id } ) end end end - latest_recorded_track = downloads[-1][:created_at] if downloads.length > 0 + latest_recorded_track = downloads[-1][:next] if downloads.length > 0 + # HOW TO LIMIT ON USER User.joins(:recordings).joins(:recordings => :mixes) - .order('recordings.created_at') + .order('mixes.id') .where('mixes.completed_at IS NOT NULL') - .where('mixes.created_at > ?', since) + .where('mixes.id > ?', since) .limit(limit).each do |theuser| theuser.recordings.each do |recording| recording.mixes.each do |mix| @@ -184,14 +185,15 @@ module JamRuby :length => mix.length, :md5 => mix.md5, :url => mix.filename, - :created_at => mix.created_at + :created_at => mix.created_at, + :next => mix.id } ) end end end - latest_mix = downloads[-1][:created_at] if downloads.length > 0 + latest_mix = downloads[-1][:next] if downloads.length > 0 if !latest_mix.nil? && !latest_recorded_track.nil? next_date = [latest_mix, latest_recorded_track].max @@ -201,31 +203,46 @@ module JamRuby next_date = latest_mix end + if next_date.nil? + next_date = since # echo back to the client the same value they passed in, if there are no results + end + { 'downloads' => downloads, - 'next' => next_date + 'next' => next_date.to_s } end - def self.list_uploads(user, limit = 100, since = Date.new(1)) + def self.list_uploads(user, limit = 100, since = 0) + since = 0 unless since || since == '' # guard against nil + uploads = [] RecordedTrack .joins(:recording) .where(:user_id => user.id) .where(:fully_uploaded => false) + .where('recorded_tracks.id > ?', since) .where("upload_failures <= #{RecordedTrack::MAX_UPLOAD_FAILURES}") - .where("duration IS NOT NULL").each do |recorded_track| + .where("duration IS NOT NULL") + .order('recorded_tracks.id') + .limit(limit).each do |recorded_track| uploads.push({ :type => "recorded_track", :client_track_id => recorded_track.client_track_id, :recording_id => recorded_track.recording_id, - :created_at => recorded_track.created_at + :next => recorded_track.id }) end + next_value = uploads.length > 0 ? uploads[-1][:next].to_s : nil + if next_value.nil? + next_value = since # echo back to the client the same value they passed in, if there are no results + end + + { "uploads" => uploads, - "next" => uploads.length > 0 ? uploads[-1][:created_at] : nil + "next" => next_value.to_s } end diff --git a/ruby/spec/jam_ruby/models/recording_spec.rb b/ruby/spec/jam_ruby/models/recording_spec.rb index 10490a662..b77c72492 100644 --- a/ruby/spec/jam_ruby/models/recording_spec.rb +++ b/ruby/spec/jam_ruby/models/recording_spec.rb @@ -194,6 +194,18 @@ describe Recording do expect { ClaimedRecording.find(@claimed_recording.id) }.to raise_error end + it "should use the since parameter when restricting uploads" do + stub_const("APP_CONFIG", app_config) + @recording = Recording.start(@music_session, @user) + @recording.stop + @recording.reload + @genre = FactoryGirl.create(:genre) + @recording.claim(@user, "Recording", "Recording Description", @genre, true, true) + uploads = Recording.list_uploads(@user) + uploads["uploads"].length.should == 1 + Recording.list_uploads(@user, 10, uploads["next"])["uploads"].length.should == 0 + end + it "should return a file list for a user properly" do pending stub_const("APP_CONFIG", app_config) diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb index b50894558..9a43ca42f 100644 --- a/ruby/spec/spec_helper.rb +++ b/ruby/spec/spec_helper.rb @@ -62,7 +62,8 @@ Spork.prefork do config.filter_run :focus # you can mark a test as slow so that developers won't commonly hit it, but build server will http://blog.davidchelimsky.net/2010/06/14/filtering-examples-in-rspec-2/ - config.filter_run_excluding slow: true unless ENV['RUN_SLOW_TESTS'] == "1" + config.filter_run_excluding slow: true unless ENV['RUN_SLOW_TESTS'] == "1" || ENV['SLOW'] == "1" || ENV['ALL_TESTS'] == "1" + config.filter_run_excluding aws: true unless ENV['RUN_AWS_TESTS'] == "1" || ENV['AWS'] == "1" || ENV['ALL_TESTS'] == "1" config.before(:suite) do DatabaseCleaner.strategy = :truncation, {:except => %w[instruments genres] } diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb index 54f403ee1..40d2aae14 100644 --- a/web/app/controllers/api_recordings_controller.rb +++ b/web/app/controllers/api_recordings_controller.rb @@ -11,7 +11,9 @@ class ApiRecordingsController < ApiController # Returns all files this user should be uploading from his client def list_uploads begin - render :json => Recording.list_uploads(current_user, params[:limit], params[:since]), :status => 200 + result = Recording.list_uploads(current_user, params[:limit], params[:since]) + puts result.inspect + render :json => result, :status => 200 rescue render :json => { :message => "could not produce list of files" }, :status => 403 end @@ -68,7 +70,7 @@ class ApiRecordingsController < ApiController # keep will kick off a mix, as well as create a claimed recording for the creator def claim - claim = @recording.claim(current_user, params[:name], Genre.find(params[:genre_id]), params[:is_public], params[:is_downloadable]) + claim = @recording.claim(current_user, params[:name], params[:description], Genre.find(params[:genre_id]), params[:is_public], params[:is_downloadable]) claim.save if claim.errors.any? diff --git a/web/app/views/clients/_recordingFinishedDialog.html.erb b/web/app/views/clients/_recordingFinishedDialog.html.erb index b59125b1c..4193782a2 100644 --- a/web/app/views/clients/_recordingFinishedDialog.html.erb +++ b/web/app/views/clients/_recordingFinishedDialog.html.erb @@ -3,12 +3,93 @@