weathermen/soundstorm

View on GitHub
app/controllers/tracks_controller.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

class TracksController < ApplicationController
  swagger_controller :tracks, 'Track Management and Uploading'

  before_action :authenticate_user!, except: %i[index show listen]
  before_action :cache_page, only: :show
  before_action :find_variant_from_content_type, only: :show

  skip_before_action :doorkeeper_authorize!, only: %i[show listen]

  swagger_api :show do
    summary "View a track's information"

    param :path, :user_id, :string, :required, 'Username'
    param :path, :id, :string, :required, 'Track Name'

    response :unauthorized
  end
  def show
    @user = User.find_by!(name: params[:user_id])
    @track = @user.tracks.find(params[:id])
    @title = "#{@track.name} by #{@user.name}"

    respond_to do |format|
      format.html     # show.html.haml      - Web Page
      format.m3u8 do  # show.m3u8.erb       - Stream
        @track.listens.create(ip_address: request.ip, user: current_user)

        render :show
      end
      format.json     # show.json.jbuilder  - JSON API Response
      format.xml      # show.xml.builder    - OEmbed API Response
      format.mp3 do  # MP3 File Download
        return head :unauthorized unless @track.downloadable?

        @track.listens.create(ip_address: request.ip, user: current_user)

        send_data @track.audio.download,
          content_type: :mp3,
          filename: @track.filename,
          disposition: 'attachment'
      end
    end
  end

  def new
    @track = current_user.tracks.build
  end

  def edit
    @track = current_user.tracks.find(params[:id])
    @title = t('.title', track: @track.name)
  end

  swagger_api :create do
    summary 'Upload a new track'

    param :form, 'track[name]', :string, :required, 'Name of the track'
    param :form, 'track[audio]', :string, :required, 'Audio file'
    param :form, 'track[description]', :string, :optional, 'Description of the track'
    param :form, 'track[downloadable]', :boolean, :optional, 'Whether the track can be downloaded (default: true)'

    response :unauthorized
    response :unprocessable_entity
  end
  def create
    @track = current_user.tracks.build(new_track_params)

    respond_to do |format|
      if @track.save
        flash[:notice] = t('.success', name: @track.name)

        format.html { redirect_to [@track.user, @track] }
        format.json { render json: @track, status: :created }
      else
        errors = @track.errors.full_messages.to_sentence
        flash[:alert] = t('.failure', errors: errors)

        format.html { render :new }
        format.json { render json: @track, status: :unprocessable_entity }
      end
    end
  end

  swagger_api :update do
    summary 'Edit an existing track'

    param :path, :id, :integer, :required, 'ID of the Track'
    param :form, 'track[name]', :string, :optional, 'Name of the track'
    param :form, 'track[description]', :string, :optional, 'Description of the track'
    param :form, 'track[downloadable]', :boolean, :optional, 'Whether the track can be downloaded'

    response :unauthorized
    response :unprocessable_entity
  end
  def update
    @track = current_user.tracks.find(params[:id])

    respond_to do |format|
      if @track.update(edit_track_params)
        flash[:notice] = t('.success', name: @track.name)

        format.html { redirect_to [current_user, @track] }
        format.json { render json: @track }
      else
        flash[:notice] = t('.failure', errors: @track.errors.full_messages.to_sentence)

        format.html { render :new }
        format.json { render json: { errors: @track.errors }, status: :unprocessable_entity }
      end
    end
  end

  swagger_api :destroy do
    summary 'Delete a track'

    param :path, :id, :integer, :required, 'ID of the Track'

    response :unauthorized
    response :unprocessable_entity
  end
  def destroy
    @track = current_user.tracks.find(params[:id])

    respond_to do |format|
      if @track.destroy
        flash[:notice] = t('.success', name: @track.name)

        format.html { redirect_to current_user }
        format.json { render json: @track }
      else
        flash[:notice] = t('.failure', errors: @track.errors.full_messages.to_sentence)

        format.html { render :new }
        format.json { render json: { errors: @track.errors }, status: :unprocessable_entity }
      end
    end
  end

  private

  def new_track_params
    params.require(:track).permit(:name, :audio, :description)
  end

  def edit_track_params
    params.require(:track).permit(:name, :description)
  end

  def variant_request?
    request.content_type.include('+')
  end

  def find_variant_from_content_type
    variant = if request.media_type.include? '+'
      request.media_type.split('+').last
    elsif params[:variant].present?
      request.variant = params[:variant].to_sym
    end

    request.variant = variant if variant.present?
  end
end