otwarchive-symphonyarchive/app/controllers/downloads_controller.rb

73 lines
2.5 KiB
Ruby
Raw Permalink Normal View History

2026-03-11 22:22:11 +00:00
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