class ApiRecordingsController < ApiController before_filter :api_signed_in_user, :except => [ :add_like ] before_filter :lookup_recording, :only => [ :show, :stop, :claim, :discard, :keep, :delete_claim, :add_timeline, :add_video_data, :delete_video_data, :mobile_upload, :mobile_update, :mobile_upload_download, :mobile_upload_delete ] before_filter :lookup_recorded_track, :only => [ :download, :upload_next_part, :upload_sign, :upload_part_complete, :upload_complete ] before_filter :lookup_recorded_backing_track, :only => [ :backing_track_download, :backing_track_upload_next_part, :backing_track_upload_sign, :backing_track_upload_part_complete, :backing_track_upload_complete ] before_filter :lookup_recorded_video, :only => [ :video_upload_sign, :video_upload_start, :video_upload_complete ] before_filter :lookup_stream_mix, :only => [ :upload_next_part_stream_mix, :upload_sign_stream_mix, :upload_part_complete_stream_mix, :upload_complete_stream_mix ] respond_to :json def log @log || Logging.logger[ApiRecordingsController] end def mobile_upload mobile_rec = @recording.mobile_recording if mobile_rec mru = MobileRecordingUpload.create(mobile_rec, request.body, params[:file_name]) unless mobile_rec.errors.any? render :json => @recording, :status => 200 return end end response.status = :unprocessable_entity render nothing: true end def mobile_upload_download mobile_rec = @recording.mobile_recording if mobile_rec && mobile_rec.mobile_recording_upload redirect_to mobile_rec.mobile_recording_upload.sign_url return end response.status = :unprocessable_entity render nothing: true end def mobile_upload_delete mobile_rec = @recording.mobile_recording if mobile_rec mobile_rec.mobile_recording_upload.try(:destroy) render :json => {}, status: 204 return end response.status = :unprocessable_entity render nothing: true end def mobile_update mobile_rec = @recording.mobile_recording if mobile_rec mobile_rec.data_blob = JSON.parse(request.body.read) mobile_rec.save unless mobile_rec.errors.any? render :json => @recording, :status => 200 return end end response.status = :unprocessable_entity render nothing: true end def create if request.headers['Jamk-Mobile-Env'] json = JSON.parse(request.body.read) record_params = { name: json['title'], description: json['description'], genre: json['genre']['id'], record_video: json['isVideo'], is_public: false, # NOTE: figure out why we need this one and the yt one upload_to_youtube: false, } result = Recording.create_immediately(current_user, record_params) unless result.errors.any? mr = MobileRecording.new mr.data_blob = json mr.recording = result mr.save! render :json => result, :status => 200 return end end response.status = :unprocessable_entity render nothing: true end def index # lists recordings created by for the current user @recordings = Recording.list_recordings(current_user, params[:created_by]) end # Returns all files this user should be uploading from his client def list_uploads begin result = Recording.list_uploads(current_user, params[:limit], params[:since]) render :json => result, :status => 200 rescue render :json => { :message => "could not produce list of files" }, :status => 403 end end # Returns all files that the user can download def list_downloads begin render :json => Recording.list_downloads(current_user, params[:limit], params[:since]), :status => 200 rescue render :json => { :message => "could not produce list of files" }, :status => 403 end end def show end def show_recorded_track @recorded_track = RecordedTrack.find_by_recording_id_and_client_track_id(params[:id], params[:track_id]) end def show_recorded_backing_track @recorded_backing_track = RecordedBackingTrack.find_by_recording_id_and_client_track_id(params[:id], params[:track_id]) end def download # track raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_track.can_download?(current_user) @recorded_track.current_user = current_user @recorded_track.update_download_count @recorded_track.valid? if !@recorded_track.errors.any? @recorded_track.save! redirect_to @recorded_track.sign_url(120, false) # !is_native_client? - no indicator to indicate this else render :json => { :message => "download limit surpassed" }, :status => 404 end end def backing_track_download raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_backing_track.can_download?(current_user) @recorded_backing_track.current_user = current_user @recorded_backing_track.update_download_count @recorded_backing_track.valid? if !@recorded_backing_track.errors.any? @recorded_backing_track.save! redirect_to @recorded_backing_track.sign_url(120, false) # !is_native_client? - no indicator to indicate this else render :json => { :message => "download limit surpassed" }, :status => 404 end end def create_immediately @recording = Recording.create_immediately(current_user, params) if @recording.errors.any? response.status = :unprocessable_entity respond_with @recording else respond_with @recording, responder: ApiResponder, :location => api_recordings_detail_url(@recording) end end def start music_session = ActiveMusicSession.find(params[:music_session_id]) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless music_session.users.exists?(current_user.id) @recording = Recording.start(music_session, current_user, record_video: params[:record_video]) if @recording.errors.any? response.status = :unprocessable_entity respond_with @recording else respond_with @recording, responder: ApiResponder, :location => api_recordings_detail_url(@recording) end end def stop # only allow the creator to stop the recording if @recording.can_stop?(current_user) == false raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR end @recording.stop if @recording.errors.any? response.status = :unprocessable_entity respond_with @recording else respond_with @recording, responder: ApiResponder, :location => api_recordings_detail_url(@recording) end end # claim will create a claimed recording for the creator def claim claim = @recording.claim(current_user, params[:name], params[:description], Genre.find_by_id(params[:genre]), params[:is_public], params[:upload_to_youtube]) if claim.errors.any? response.status = :unprocessable_entity respond_with claim else respond_with claim, responder: ApiResponder, :location => api_session_detail_url(claim) end end def delete_claim claim = @recording.claim_for_user(current_user) if claim claim.discard(current_user) if claim.errors.any? response.status = :unprocessable_entity respond_with claim end end respond_with @recording end def add_comment if params[:id].blank? render :json => { :message => "Recording ID is required" }, :status => 400 return end if params[:user_id].blank? render :json => { :message => "User ID is required" }, :status => 400 return end if params[:comment].blank? render :json => { :message => "Comment is required" }, :status => 400 return end comment = RecordingComment.new comment.recording_id = params[:id] comment.creator_id = params[:user_id] comment.comment = @@html_encoder.encode(params[:comment]) comment.ip_address = request.remote_ip comment.save if comment.errors.any? render :json => { :errors => comment.errors }, :status => 422 return else render :json => {}, :status => 201 return end end def add_like if params[:id].blank? render :json => { :message => "Recording ID is required" }, :status => 400 return end liker = RecordingLiker.new liker.recording_id = params[:id] liker.liker_id = params[:user_id] liker.claimed_recording_id = params[:claimed_recording_id] liker.favorite = true liker.ip_address = request.remote_ip liker.save if liker.errors.any? render :json => { :errors => liker.errors }, :status => 422 return else render :json => {}, :status => 201 return end end # discard will tell the server the user has no interest in the recording def discard @recording.discard(current_user) render :json => {}, :status => 200 end def upload_next_part # track length = params[:length] md5 = params[:md5] @recorded_track.upload_next_part(length, md5) if @recorded_track.errors.any? response.status = :unprocessable_entity # this is not typical, but please don't change this line unless you are sure it won't break anything # this is needed because after_rollback in the RecordedTrackObserver touches the model and something about it's # state doesn't cause errors to shoot out like normal. render :json => { :errors => @recorded_track.errors }, :status => 422 else result = { :part => @recorded_track.next_part_to_upload, :offset => @recorded_track.file_offset.to_s } render :json => result, :status => 200 end end def upload_sign # track render :json => @recorded_track.upload_sign(params[:md5]), :status => 200 end def upload_part_complete # track part = params[:part] offset = params[:offset] @recorded_track.upload_part_complete(part, offset) if @recorded_track.errors.any? response.status = :unprocessable_entity respond_with @recorded_track else render :json => {}, :status => 200 end end def upload_complete # track @recorded_track.upload_complete @recorded_track.recording.upload_complete if @recorded_track.errors.any? response.status = :unprocessable_entity respond_with @recorded_track return else render :json => {}, :status => 200 end end def backing_track_upload_next_part length = params[:length] md5 = params[:md5] @recorded_backing_track.upload_next_part(length, md5) if @recorded_backing_track.errors.any? response.status = :unprocessable_entity # this is not typical, but please don't change this line unless you are sure it won't break anything # this is needed because after_rollback in the RecordedTrackObserver touches the model and something about it's # state doesn't cause errors to shoot out like normal. render :json => { :errors => @recorded_backing_track.errors }, :status => 422 else result = { :part => @recorded_backing_track.next_part_to_upload, :offset => @recorded_backing_track.file_offset.to_s } render :json => result, :status => 200 end end def backing_track_upload_sign render :json => @recorded_backing_track.upload_sign(params[:md5]), :status => 200 end def backing_track_upload_part_complete part = params[:part] offset = params[:offset] @recorded_backing_track.upload_part_complete(part, offset) if @recorded_backing_track.errors.any? response.status = :unprocessable_entity respond_with @recorded_backing_track else render :json => {}, :status => 200 end end def backing_track_upload_complete @recorded_backing_track.upload_complete @recorded_backing_track.recording.upload_complete if @recorded_backing_track.errors.any? response.status = :unprocessable_entity respond_with @recorded_backing_track return else render :json => {}, :status => 200 end end # POST /api/recordings/:id/videos/:video_id/upload_sign def video_upload_sign length = params[:length] @youtube_client.sign_youtube_upload(current_user, @recorded_video.url, length) end # POST /api/recordings/:id/videos/:video_id/upload_complete def video_upload_start length = params[:length] @youtube_client.youtube_upload_status(current_user, @recorded_video.url, length) end # POST /api/recordings/:id/videos/:video_id/upload_complete def video_upload_complete if @youtube_client.complete_upload(@recorded_video) render :status => 200 else render :status => 422 end end def upload_next_part_stream_mix length = params[:length] md5 = params[:md5] @quick_mix.upload_next_part(length, md5) if @quick_mix.errors.any? response.status = :unprocessable_entity # this is not typical, but please don't change this line unless you are sure it won't break anything # this is needed because after_rollback in the RecordedTrackObserver touches the model and something about it's # state doesn't cause errors to shoot out like normal. render :json => { :errors => @quick_mix.errors }, :status => 422 else result = { :part => @quick_mix.next_part_to_upload, :offset => @quick_mix.file_offset.to_s } render :json => result, :status => 200 end end def upload_sign_stream_mix render :json => @quick_mix.upload_sign(params[:md5]), :status => 200 end def upload_part_complete_stream_mix part = params[:part] offset = params[:offset] @quick_mix.upload_part_complete(part, offset) if @quick_mix.errors.any? response.status = :unprocessable_entity respond_with @quick_mix else render :json => {}, :status => 200 end end def upload_complete_stream_mix @quick_mix.upload_complete if @quick_mix.errors.any? response.status = :unprocessable_entity respond_with @quick_mix return else render :json => {}, :status => 200 end end # metadata def add_timeline @recording.add_timeline(params) render :json => {}, :status => 200 end def add_video_data @recording.add_video_data(current_user, params) video_id = params[:video_id] video_url = "https://www.youtube.com/watch?v=#{video_id}" body = "" body << "Youtube URL: #{video_url}\n\n" body << "User: " + current_user.admin_url + "\n\n" body << "Recording Landing: #{recording_detail_url(@recording.id)}\n" private_public = @recording.is_public? ? 'Public' : 'Private' AdminMailer.social({ subject:"#{private_public } Video Uploaded by #{current_user.name}", body:body }).deliver_now render :json => {}, :status => 200 end def delete_video_data @recording.add_video_data({:video_id => nil}) render :json => {}, :status => 200 end private def lookup_recording @recording = Recording.find(params[:id]) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recording.has_access?(current_user) end def lookup_recorded_track @recorded_track = RecordedTrack.find_by_recording_id_and_client_track_id!(params[:id], params[:track_id]) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_track.recording.has_access?(current_user) end def lookup_recorded_backing_track @recorded_backing_track = RecordedBackingTrack.find_by_recording_id_and_client_track_id!(params[:id], params[:track_id]) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_backing_track.recording.has_access?(current_user) end def lookup_stream_mix @quick_mix = QuickMix.find_by_recording_id_and_user_id!(params[:id], current_user.id) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @quick_mix.recording.has_access?(current_user) end def lookup_recorded_video @recorded_video = RecordedVideo.find_by_recording_id_and_client_video_source_id!(params[:id], params[:video_id]) raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_video.recording.has_access?(current_user) end end # class