73 lines
2.5 KiB
Ruby
73 lines
2.5 KiB
Ruby
|
|
class DownloadsController < ApplicationController
|
||
|
|
|
||
|
|
skip_before_action :store_location, only: :show
|
||
|
|
before_action :load_work, only: :show
|
||
|
|
before_action :check_download_posted_status, only: :show
|
||
|
|
before_action :check_download_visibility, only: :show
|
||
|
|
around_action :remove_downloads, only: :show
|
||
|
|
|
||
|
|
def show
|
||
|
|
respond_to :html, :pdf, :mobi, :epub, :azw3
|
||
|
|
@download = Download.new(@work, mime_type: request.format)
|
||
|
|
@download.generate
|
||
|
|
|
||
|
|
# Make sure we were able to generate the download.
|
||
|
|
unless @download.exists?
|
||
|
|
flash[:error] = ts("We were not able to render this work. Please try again in a little while or try another format.")
|
||
|
|
redirect_to work_path(@work)
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
# Send file synchronously so we don't delete it before we have finished
|
||
|
|
# sending it
|
||
|
|
File.open(@download.file_path, 'r') do |f|
|
||
|
|
send_data f.read, filename: "#{@download.file_name}.#{@download.file_type}", type: @download.mime_type
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
protected
|
||
|
|
|
||
|
|
# Set up the work and check revealed status
|
||
|
|
# Once a format has been created, we want nginx to be able to serve
|
||
|
|
# it directly, without going through Rails again (until the work changes).
|
||
|
|
# This means no processing per user. Consider this the "published" version.
|
||
|
|
# It can't contain unposted chapters, nor unrevealed creators, even
|
||
|
|
# if the creator is the one requesting the download.
|
||
|
|
def load_work
|
||
|
|
unless AdminSetting.current.downloads_enabled?
|
||
|
|
flash[:error] = ts("Sorry, downloads are currently disabled.")
|
||
|
|
redirect_back_or_default works_path
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
@work = Work.find(params[:id])
|
||
|
|
end
|
||
|
|
|
||
|
|
# We're currently just writing everything to tmp and feeding them through
|
||
|
|
# nginx so we don't want to keep the files around.
|
||
|
|
def remove_downloads
|
||
|
|
yield
|
||
|
|
ensure
|
||
|
|
@download.remove
|
||
|
|
end
|
||
|
|
|
||
|
|
# We can't use check_visibility because this controller doesn't have access to
|
||
|
|
# cookies on production or staging.
|
||
|
|
def check_download_visibility
|
||
|
|
return unless @work.hidden_by_admin || @work.in_unrevealed_collection?
|
||
|
|
message = if @work.hidden_by_admin
|
||
|
|
ts("Sorry, you can't download a work that has been hidden by an admin.")
|
||
|
|
else
|
||
|
|
ts("Sorry, you can't download an unrevealed work.")
|
||
|
|
end
|
||
|
|
flash[:error] = message
|
||
|
|
redirect_to work_path(@work)
|
||
|
|
end
|
||
|
|
|
||
|
|
def check_download_posted_status
|
||
|
|
return if @work.posted
|
||
|
|
flash[:error] = ts("Sorry, you can't download a draft.")
|
||
|
|
redirect_to work_path(@work)
|
||
|
|
end
|
||
|
|
end
|