require 'aws-sdk' class ApiMusicSessionsController < ApiController # have to be signed in currently to see this screen before_filter :api_signed_in_user, :except => [ :add_like, :show, :history_show ] before_filter :lookup_session, only: [:show, :update, :delete, :claimed_recording_start, :claimed_recording_stop, :track_sync] skip_before_filter :api_signed_in_user, only: [:perf_upload] respond_to :json def index # returns a list of sessions which are hopefully interesting to you as three buckets (concatenated). The 1st bucket # is those session to which you've been invited. The 2nd bucket is those sessions which are about a band that you # are in or in which a friend is participating. The 3rd bucket is everything else (sessions - invites - friends - bands). # params[:participants] is either nil, meaning "everything", or it's an array of musician ids # params[:genres] is either nil, meaning "everything", or it's an array of genre ids # params[:friends_only] does the obvious. you get invited and friends sessions only. # params[:my_bands_only] also does the obvious. you get invited and bands sessions only. # params[:keyword] matches only sessions with that text in the description # params[:as_musician] only returns sessions you can join as a musician (if true) or listen to a fan (if false) # Importantly, friends_only and my_bands_only are ORed not ANDed. So, if you specify both as true, you'll get more # results than if only one or the other is true, not fewer. if either is true you won't see the "everything else" # sessions. @music_sessions = MusicSession.index(current_user, participants: params[:participants], genres: params[:genres], friends_only: params[:friends_only], my_bands_only: params[:my_bands_only], keyword: params[:keyword], as_musician: params[:as_musician]) end def nindex # returns a list of sessions which are hopefully interesting to you as three buckets (concatenated). The 1st bucket # is those session to which you've been invited. The 2nd bucket is those sessions which are about a band that you # are in or in which a friend is participating. The 3rd bucket is everything else (sessions - invites - friends - bands). # pretty much the same as #index above, except scores are also returned. # params[:client_id] is the client_id of the client making the call. needed to resovle scoring. # params[:participants] is either nil, meaning "everything", or it's an array of musician ids # params[:genres] is either nil, meaning "everything", or it's an array of genre ids # params[:friends_only] does the obvious. you get invited and friends sessions only. # params[:my_bands_only] also does the obvious. you get invited and bands sessions only. # params[:keyword] matches only sessions with that text in the description # params[:as_musician] only returns sessions you can join as a musician (if true) or listen to a fan (if false) # params[:offset] also does the obvious, starts at offset in the results (e.g. 0) # params[:limit] also does the obvious, limits number of rows returned (e.g. 20) # Importantly, friends_only and my_bands_only are ORed not ANDed. So, if you specify both as true, you'll get more # results than if only one or the other is true, not fewer. if either is true you won't see the "everything else" # sessions. @music_sessions = MusicSession.nindex(current_user, client_id: params[:client_id], participants: params[:participants], genres: params[:genres], friends_only: params[:friends_only], my_bands_only: params[:my_bands_only], keyword: params[:keyword], as_musician: params[:as_musician], offset: params[:offset], limit: params[:limit]) end def create client_id = params[:client_id] if client_id.nil? raise JamArgumentError, "client_id must be specified" end if !params[:intellectual_property] raise JamArgumentError, "You must agree to the intellectual property terms" end band = Band.find(params[:band]) unless params[:band].nil? @music_session = MusicSessionManager.new.create( current_user, client_id, params[:description], params[:musician_access], params[:approval_required], params[:fan_chat], params[:fan_access], band, params[:genres], params[:tracks], params[:legal_terms]) if @music_session.errors.any? # we have to do this because api_session_detail_url will fail with a bad @music_session response.status = :unprocessable_entity respond_with @music_session else respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session) end end def show unless @music_session.can_see? current_user raise ActiveRecord::RecordNotFound end end def update @music_session = MusicSessionManager.new.update( @music_session, params[:description], params[:genres], params[:musician_access], params[:approval_required], params[:fan_chat], params[:fan_access]) if @music_session.errors.any? # we have to do this because api_session_detail_url will fail with a bad @music_session response.status = :unprocessable_entity respond_with @music_session else respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session) end end def participant_show @connection = Connection.find_by_client_id(params[:id]) end def participant_create @connection = MusicSessionManager.new.participant_create( current_user, params[:id], params[:client_id], params[:as_musician], params[:tracks]) if @connection.errors.any? response.status = :unprocessable_entity respond_with @connection else respond_with @connection, responder: ApiResponder, :location => api_session_participant_detail_url(@connection.client_id) end end def participant_delete client_id = params[:id] if client_id.present? && client_id != 'undefined' @connection = Connection.find_by_client_id!(client_id) music_session = MusicSession.find(@connection.music_session_id) MusicSessionManager.new.participant_delete(current_user, @connection, music_session) end respond_with @connection, responder: ApiResponder end def participant_rating if @history = MusicSessionUserHistory.latest_history(params[:client_id]) if request.post? @history.add_rating(params[:rating], params[:comment]) @history.save if @history.errors.any? response.status = :unprocessable_entity respond_with @history else if @history.good_rating? && @history.user.first_good_music_session_at.nil? @history.user.first_good_music_session_at = Time.now @history.user.save end render :json => {}, :status => :ok end elsif request.get? render :json => { :should_rate_session => @history.should_rate_session? }, :status => :ok end else render :json => { :message => ValidationMessages::SESSION_NOT_FOUND }, :status => 404 end end def track_index @tracks = Track.index(current_user, params[:id]) end def track_show begin @track = Track.joins(:connection) .where(:connections => {:user_id => "#{current_user.id}"}) .find(params[:track_id]) rescue ActiveRecord::RecordNotFound render :json => { :message => ValidationMessages::TRACK_NOT_FOUND }, :status => 404 end end def track_sync @tracks = MusicSessionManager.new.sync_tracks(@music_session, params[:client_id], params[:tracks]) unless @tracks.kind_of? Array # we have to do this because api_session_detail_url will fail with a bad @tracks response.status = :unprocessable_entity respond_with @tracks else respond_with @tracks, responder: ApiResponder end end def track_create @track = Track.save(nil, params[:connection_id], params[:instrument_id], params[:sound], params[:client_track_id]) respond_with @track, responder: ApiResponder, :status => 201, :location => api_session_track_detail_url(@track.connection.music_session, @track) end def track_update begin @track = Track.save(params[:track_id], nil, params[:instrument_id], params[:sound], params[:client_track_id]) respond_with @track, responder: ApiResponder, :status => 200 rescue ActiveRecord::RecordNotFound render :json => { :message => ValidationMessages::TRACK_NOT_FOUND }, :status => 404 end end def track_destroy begin @track = Track.find(params[:track_id]) unless @track.nil? @track.delete respond_with responder: ApiResponder, :status => 204 end rescue ActiveRecord::RecordNotFound render :json => { :message => ValidationMessages::TRACK_NOT_FOUND }, :status => 404 end end def perf_upload # example of using curl to access this API: # curl -L -T some_file -X PUT http://localhost:3000/api/sessions/[SESSION_ID]/perf.json?client_id=[CLIENT_ID] music_session_history = MusicSessionHistory.find(params[:id]) msuh = MusicSessionUserHistory.find_by_client_id(params[:client_id]) @perfdata = MusicSessionPerfData.new @perfdata.client_id = params[:client_id] @perfdata.music_session_history = music_session_history unless @perfdata.save # we have to do this because api_session_detail_url will fail with a bad @music_session response.status = :unprocessable_entity respond_with @perfdata return end if Rails.application.config.storage_type == :fog uri = @perfdata.uri 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 read_url = bucket.objects[uri].url_for(:read, :expires => expire, :'response_content_type' => 'text/csv').to_s @perfdata.update_attribute(:uri, read_url) logger.debug("*** client can read url #{read_url}") write_url = bucket.objects[uri].url_for(:write, :expires => expire, :'response_content_type' => 'text/csv').to_s logger.debug("*** client can upload to url #{write_url}") redirect_to write_url else if params[:redirected_back].nil? || !params[:redirected_back] # first time that a client has asked to do a PUT (not redirected back here) redirect_to request.fullpath + '&redirected_back=true' else # we should store it here to aid in development, but we don't have to until someone wants the feature # so... just return 200 render :json => { :id => @perfdata.id }, :status => 200 end end end def add_comment if params[:id].blank? render :json => { :message => "Session 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 = MusicSessionComment.new comment.music_session_id = params[:id] comment.creator_id = params[:user_id] comment.comment = params[:comment] comment.ip_address = request.remote_ip comment.save if comment.errors.any? render :json => { :message => "Unexpected error occurred" }, :status => 500 return else render :json => {}, :status => 201 return end end def add_like if params[:id].blank? render :json => { :message => "Session ID is required" }, :status => 400 return end liker = MusicSessionLiker.new liker.music_session_id = params[:id] liker.liker_id = params[:user_id] liker.ip_address = request.remote_ip liker.save if liker.errors.any? render :json => { :message => "Unexpected error occurred" }, :status => 500 return else render :json => {}, :status => 201 return end end def history_show @history = MusicSessionHistory.find(params[:id]) end def claimed_recording_start @music_session.claimed_recording_start(current_user, ClaimedRecording.find(params[:claimed_recording_id])) if @music_session.errors.any? # we have to do this because api_session_detail_url will fail with a bad @music_session response.status = :unprocessable_entity respond_with @music_session else respond_with @music_session, responder: ApiResponder end end def claimed_recording_stop @music_session.claimed_recording_stop if @music_session.errors.any? # we have to do this because api_session_detail_url will fail with a bad @music_session response.status = :unprocessable_entity respond_with @music_session else respond_with @music_session, responder: ApiResponder end end private def lookup_session @music_session = MusicSession.find(params[:id]) end end