preston/bittorious

View on GitHub
app/controllers/torrents_controller.rb

Summary

Maintainability
A
45 mins
Test Coverage
class TorrentsController < ApplicationController

    before_action :allow_cors, only: [:index, :show]

    # respond_to :json, :html, :xml, :rss
    before_action :set_params_from_torrent, only: [:create]

    load_resource :feed # Need to load the feed before the torrent resource is authorized.
    load_and_authorize_resource :torrent, except: [:show, :create] # through: :feed,

    skip_before_action :authenticate_user!, only: [:show, :index]

    layout false

    def create
        @torrent = Torrent.new(torrent_params)
        @torrent.user = current_user
        @torrent.data = request[:torrent][:file].read
        # @torrent.feed = @feed
        @feed = Feed.find(request[:feed_id]) # Must be set prior to metadata reprocessing.
        @torrent.feed = @feed
        authorize! :create, @feed.torrents.build

        @torrent.reprocess_meta
        respond_to do |format|
            format.json do
                if @torrent.save
                    render json: @torrent, except: [:data]
                else
                    render json: { errors: @torrent.errors }, except: [:data], status: :unprocessable_entity
                end
            end
        end
    end

    def index
        # FIXME: Shouldn't cancancan do this automatically???
        authorize! :index, Feed.find(request[:feed_id])
        @torrents = Torrent.where(feed_id: params[:feed_id]).accessible_by(current_ability)

        respond_to do |f|
            # f.json { render json: @torrents, include: [{ user: { only: [:id, :name] } }], methods: [:seed_count, :peer_count], except: [:data] }
            f.json { render }
        end
    end

    def show
        @torrent = Torrent.find(params[:id])
        # This is kinda weird, because it depends on the public/private nature of the feed.
        if @torrent.feed.enable_public_archiving
        # Go for it.
        else
          authorize! :show, @torrent
        end
        respond_to do |format|
            format.json { render json: @torrent, except: [:data], include: [{ user: { only: [:id, :name] } }, :active_peers] }
            format.torrent { send_data(@torrent.data_for_user(current_user, announce_url), type: :torrent, filename: "#{@torrent.name}.torrent") }
            # format.json { render :json => {:id => resource.id, :name => resource.name, :meta_html => render_to_string('_meta_data', :formats => :html, :layout => false, :locals => {:meta_data => resource.tracker.meta_data})}}
        end
    end

    def update
        respond_to do |format|
            if @torrent.update(torrent_params)
                format.json { render json: @torrent.to_json }
            else
                format.json { render json: @torrent.errors.full_messages, status: :unprocessable_entity }
            end
        end
    end

    def destroy
        @torrent.destroy
        respond_to do |format|
            format.json { render json: @torrent.to_json }
        end
    end

    private

    def set_params_from_torrent
        unless request.params['torrent']['torrent_file'].blank?
            torrent_params = request.params['torrent']
            b =
                if torrent_params['torrent_file'].respond_to?(:path)
                    BEncode.load_file(torrent_params['torrent_file'].path)
                else
                    b64_file_contents = torrent_params['torrent_file'].read
                    # set it back
                    torrent_params['torrent_file'].rewind
                    BEncode.load(b64_file_contents)
                end
            request.params['torrent']['info_hash'] = Digest::SHA1.hexdigest b['info'].bencode
            if torrent_params['name'].blank? && torrent_params['torrent_file'].respond_to?(:original_filename)
                request.params['torrent']['name'] = torrent_params['torrent_file'].original_filename.gsub(/\.torrent$/, '')
            end
        end
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def torrent_params
        params.require(:torrent).permit(
            :feed_id, :name, :file
        ) #:user_id, :info_hash, :size, :feed_id, :private_info_hash)
    end
end