From c802759e424478d12bac73b83aa29f8986eeceff Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 8 Sep 2015 15:30:44 -0500 Subject: [PATCH] * wip --- db/up/mixdown.sql | 4 +- ruby/lib/jam_ruby/models/jam_track_mixdown.rb | 3 +- .../models/jam_track_mixdown_package.rb | 4 +- .../api_jam_track_mixdowns_controller.rb | 86 ++++++++----- .../views/api_jam_track_mixdowns/create.rabl | 3 + .../api_jam_track_mixdowns_controller_spec.rb | 113 +++++++++++++++++- 6 files changed, 181 insertions(+), 32 deletions(-) create mode 100644 web/app/views/api_jam_track_mixdowns/create.rabl diff --git a/db/up/mixdown.sql b/db/up/mixdown.sql index 357bf0ac8..6ccefb113 100644 --- a/db/up/mixdown.sql +++ b/db/up/mixdown.sql @@ -11,7 +11,7 @@ CREATE TABLE jam_track_mixdowns ( CREATE TABLE jam_track_mixdown_packages ( id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), - jam_track_mixdown_id VARCHAR(64) NOT NULL REFERENCES jam_track_mixdowns(id) ON DELETE SET NULL, + jam_track_mixdown_id VARCHAR(64) NOT NULL REFERENCES jam_track_mixdowns(id) ON DELETE CASCADE, file_type VARCHAR NOT NULL , sample_rate INTEGER NOT NULL, url VARCHAR(2048), @@ -36,6 +36,8 @@ CREATE TABLE jam_track_mixdown_packages ( first_downloaded TIMESTAMP, signing BOOLEAN NOT NULL DEFAULT FALSE, encrypt_type VARCHAR, + first_downloaded_at TIMESTAMP, + last_downloaded_at TIMESTAMP, version VARCHAR NOT NULL DEFAULT '1', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP diff --git a/ruby/lib/jam_ruby/models/jam_track_mixdown.rb b/ruby/lib/jam_ruby/models/jam_track_mixdown.rb index 9c9777462..c314c133f 100644 --- a/ruby/lib/jam_ruby/models/jam_track_mixdown.rb +++ b/ruby/lib/jam_ruby/models/jam_track_mixdown.rb @@ -45,9 +45,10 @@ module JamRuby end end - def self.create(name, user, jam_track, settings) + def self.create(name, description, user, jam_track, settings) mixdown = JamTrackMixdown.new mixdown.name = name + mixdown.description = description mixdown.user = user mixdown.jam_track = jam_track mixdown.settings = settings.to_json # RAILS 4 CAN REMOVE .to_json diff --git a/ruby/lib/jam_ruby/models/jam_track_mixdown_package.rb b/ruby/lib/jam_ruby/models/jam_track_mixdown_package.rb index 7be614d8a..4a73079f2 100644 --- a/ruby/lib/jam_ruby/models/jam_track_mixdown_package.rb +++ b/ruby/lib/jam_ruby/models/jam_track_mixdown_package.rb @@ -25,7 +25,7 @@ module JamRuby validates :file_type, inclusion: {in: FILE_TYPES} validates :sample_rate, inclusion: {in: SAMPLE_RATES} validates :encrypt_type, inclusion: {in: ENCRYPT_TYPES} - validates_uniqueness_of :file_type, scope: :sample_rate + validates_uniqueness_of :file_type, scope: [:sample_rate, :encrypt_type, :jam_track_mixdown_id] validates :signing, inclusion: {in: [true, false]} validates :signed, inclusion: {in: [true, false]} @@ -121,7 +121,7 @@ module JamRuby def enqueue begin - JamTrackMixdownPackager.where(:id => self.id).update_all(:signing_queued_at => Time.now, :signing_started_at => nil, :last_signed_at => nil) + JamTrackMixdownPackage.where(:id => self.id).update_all(:signing_queued_at => Time.now, :signing_started_at => nil, :last_signed_at => nil) Resque.enqueue(JamTrackMixdownPackager, self.id) true rescue Exception => e diff --git a/web/app/controllers/api_jam_track_mixdowns_controller.rb b/web/app/controllers/api_jam_track_mixdowns_controller.rb index 1864b2378..264fc8627 100644 --- a/web/app/controllers/api_jam_track_mixdowns_controller.rb +++ b/web/app/controllers/api_jam_track_mixdowns_controller.rb @@ -2,8 +2,8 @@ class ApiJamTrackMixdownsController < ApiController # have to be signed in currently to see this screen before_filter :api_signed_in_user - before_filter :lookup_jam_track_right, :only => [:download,:enqueue] - + before_filter :lookup_jam_track_mixdown, :only => [:download, :enqueue] + before_filter :lookup_jam_track_right, :only => [:download, :enqueue] respond_to :json def log @@ -17,49 +17,81 @@ class ApiJamTrackMixdownsController < ApiController render "api_jam_track_mixdowns/index", :layout => nil end + def create + @mixdown = JamTrackMixdown.create(params[:name], params[:description], current_user, JamTrack.find(params[:jamTrackID]), params[:settings]) + respond_with_model(@mixdown) + end + def download if @jam_track_right.valid? - all_fingerprint = params[:all_fp] - running_fingerprint = params[:running_fp] - - if Rails.application.config.guard_against_fraud - error = @jam_track_right.guard_against_fraud(current_user, {all:all_fingerprint, running: running_fingerprint}, request.remote_ip) - if error - log.warn("potential fraud detected: #{error}") - render :json => { :message => error }, :status => 403 - return - end + begin + @package = JamTrackMixdownPackage.where('jam_track_mixdown_id = ?', @jam_track_mixdown.id).where(file_type: params[:file_type]).where(encrypt_type: params[:encrypt_type]).where(sample_rate: params[:sample_rate]).first + rescue Exception => e + log.error("failed to find mixdown package", e) + render :json => {:message => "unable to locate mixdown package due to error; check arguments"}, :status => 404 + return end - sample_rate = params[:sample_rate].nil? ? nil : params[:sample_rate].to_i - if @jam_track_right && @jam_track_right.ready?(sample_rate) - @jam_track_right.update_download_count + @package = JamTrackMixdownPackage.create(@jam_track_mixdown, params[:file_type], params[:sample_rate], params[:encrypt_type]) unless @package + + if @package.errors.any? + respond_with_model(@package) + return + end + + if @package.ready? + @package.update_download_count now = Time.now - @jam_track_right.last_downloaded_at = now - @jam_track_right.first_downloaded_at = now if @jam_track_right.first_downloaded_at.nil? - @jam_track_right.save! - redirect_to @jam_track_right.sign_url(120, sample_rate) + @package.last_downloaded_at = now + @package.first_downloaded_at = now if @package.first_downloaded_at.nil? + @package.save! + redirect_to @package.sign_url(120) else - @jam_track_right.enqueue_if_needed(sample_rate) - render :json => { :message => "not available, digitally signing Jam Track offline." }, :status => 202 + @package.enqueue_if_needed + render :json => { :message => "not available, digitally signing Jam Track Mixdown offline." }, :status => 202 end else - render :json => { :message => "download limit surpassed", :errors=>@jam_track_right.errors }, :status => 403 + render :json => { :message => "download limit surpassed", :errors=>@package.errors }, :status => 403 end end def enqueue - sample_rate = params[:sample_rate].nil? ? nil : params[:sample_rate].to_i - enqueued = @jam_track_right.enqueue_if_needed(sample_rate) - log.debug("jamtrack #{enqueued ? "ENQUEUED" : "NOT ENQUEUED"}: jam_track_right=#{@jam_track_right.id} sample_rate=#{sample_rate} ") - render :json => { :message => "enqueued" }, :status => 200 + if @jam_track_right.valid? + + begin + @package = JamTrackMixdownPackage.where('jam_track_mixdown_id = ?', @jam_track_mixdown.id).where(file_type: params[:file_type]).where(encrypt_type: params[:encrypt_type]).where(sample_rate: params[:sample_rate]).first + rescue Exception => e + puts "enqueue failure #{e}" + log.error("failed to find mixdown package #{e}") + render :json => {:message => "unable to locate mixdown package due to error; check arguments"}, :status => 404 + return + end + + @package = JamTrackMixdownPackage.create(@jam_track_mixdown, params[:file_type], params[:sample_rate], params[:encrypt_type]) unless @package + + if @package.errors.any? + respond_with_model(@package) + return + end + + enqueued = @package.enqueue_if_needed + log.debug("jamtrack mixdown #{enqueued ? "ENQUEUED" : "NOT ENQUEUED"}: mixdown_package=#{@package.id} ") + render :json => { :message => "enqueued", id: @package.id }, :status => 200 + else + render :json => { :message => "download limit surpassed", :errors=>@package.errors }, :status => 403 + end + end private def lookup_jam_track_right - @jam_track_right = JamTrackRight.where("jam_track_id=? AND user_id=?", params[:id], current_user.id).first + @jam_track_right = JamTrackRight.where("jam_track_id=? AND user_id=?", @jam_track_mixdown.jam_track.id, current_user.id).first raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @jam_track_right end + def lookup_jam_track_mixdown + @jam_track_mixdown = JamTrackMixdown.find(params[:id]) + end + end # class ApiJamTracksController diff --git a/web/app/views/api_jam_track_mixdowns/create.rabl b/web/app/views/api_jam_track_mixdowns/create.rabl new file mode 100644 index 000000000..dde043534 --- /dev/null +++ b/web/app/views/api_jam_track_mixdowns/create.rabl @@ -0,0 +1,3 @@ +object @mixdown + +extends "api_jam_track_mixdowns/show" \ No newline at end of file diff --git a/web/spec/controllers/api_jam_track_mixdowns_controller_spec.rb b/web/spec/controllers/api_jam_track_mixdowns_controller_spec.rb index 7c2d72d1f..5dcb8874e 100644 --- a/web/spec/controllers/api_jam_track_mixdowns_controller_spec.rb +++ b/web/spec/controllers/api_jam_track_mixdowns_controller_spec.rb @@ -4,10 +4,14 @@ describe ApiJamTrackMixdownsController, type: :controller do render_views let(:user) { FactoryGirl.create(:user) } - let(:mixdown) { FactoryGirl.create(:jam_track_mixdown, user: user) } + let(:jam_track) { FactoryGirl.create(:jam_track) } + let(:mixdown) { FactoryGirl.create(:jam_track_mixdown, user: user, jam_track: jam_track) } + let(:jam_track_right) { FactoryGirl.create(:jam_track_right, jam_track: jam_track, user:user)} + let(:package) {FactoryGirl.create(:jam_track_mixdown_package, jam_track_mixdown: mixdown)} before(:each) do controller.current_user = user + JamTrackMixdown.destroy_all end describe "index" do @@ -33,5 +37,112 @@ describe ApiJamTrackMixdownsController, type: :controller do json["mixdowns"][0]["packages"][0]["signing_state"].should eq('QUIET') end end + + describe "create" do + + it "success" do + post :create, {:format => 'json', jamTrackID: jam_track.id, name: 'some name', description: 'some description', settings: {}} + + response.status.should eq(200) + + json = JSON.parse(response.body) + json["name"].should eq('some name') + json["jam_track_id"].should eq(jam_track.id) + json["description"].should eq('some description') + json["settings"].should eq({}) + json["packages"].should eq([]) + end + + it "validates name" do + post :create, {:format => 'json', jamTrackID: jam_track.id, description: 'some description', settings: {}} + + response.status.should eq(422) + + json = JSON.parse(response.body) + json["errors"]["name"].should eq(["can't be blank"]) + end + end + + describe "enqueue" do + it "success" do + + jam_track_right.touch + post :enqueue, {:format => 'json', id: mixdown.id, file_type: JamTrackMixdownPackage::FILE_TYPE_AAC, encrypt_type: nil, sample_rate: 48} + + response.status.should eq(200) + + json = JSON.parse(response.body) + json["message"].should eq("enqueued") + json["id"].should_not be_nil + + package = JamTrackMixdownPackage.find(json["id"]) + package.file_type.should eq(JamTrackMixdownPackage::FILE_TYPE_AAC) + package.encrypt_type.should eq(nil) + package.sample_rate.should eq(48) + end + + it "validates file_type" do + jam_track_right.touch + post :enqueue, {:format => 'json', id: mixdown.id, file_type: 'wrong', encrypt_type: nil, sample_rate: 48} + + response.status.should eq(422) + + json = JSON.parse(response.body) + json["errors"]["file_type"].should eq(["is not included in the list"]) + end + + it "finds existing package to enqueue" do + jam_track_right.touch + package.touch + JamTrackMixdownPackage.count.should eq(1) + + package.jam_track_mixdown.should eq(mixdown) + post :enqueue, {:format => 'json', id: mixdown.id, file_type: package.file_type, encrypt_type: package.encrypt_type, sample_rate: package.sample_rate} + + response.status.should eq(200) + + json = JSON.parse(response.body) + json["message"].should eq("enqueued") + json["id"].should eq(package.id) + JamTrackMixdownPackage.count.should eq(1) + end + end + + describe "download" do + + it "enqueues if not available" do + + jam_track_right.touch + package.touch + + post :download, {:format => 'json', id: mixdown.id, file_type: package.file_type, encrypt_type: package.encrypt_type, sample_rate: package.sample_rate} + + response.status.should eq(202) + + json = JSON.parse(response.body) + json["message"].should eq("not available, digitally signing Jam Track Mixdown offline.") + + package.reload + package.signing_state.should eq('QUEUED') + end + + it "success" do + + jam_track_right.touch + package.touch + package.enqueue_if_needed + package.signed = true + package.url = 'some/bogus/place' + package.save! + + post :download, {:format => 'json', id: mixdown.id, file_type: package.file_type, encrypt_type: package.encrypt_type, sample_rate: package.sample_rate} + + response.status.should eq(302) + + response['Location'].should include('/some/bogus/place') + + end + + end end