downloads_controller.rb
· 2.6 KiB · Ruby
Raw
class DownloadsController < ApplicationController
skip_before_action :store_location, only: :show
before_action :users_only
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
if current_user.present?
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
else
flash[:error] = ts("downloads are for users only")
redirect_to work_path(@work)
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 @admin_settings.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
if !@download.nil?
@download.remove
end
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
| 1 | class DownloadsController < ApplicationController |
| 2 | |
| 3 | skip_before_action :store_location, only: :show |
| 4 | before_action :users_only |
| 5 | before_action :load_work, only: :show |
| 6 | before_action :check_download_posted_status, only: :show |
| 7 | before_action :check_download_visibility, only: :show |
| 8 | around_action :remove_downloads, only: :show |
| 9 | |
| 10 | def show |
| 11 | if current_user.present? |
| 12 | |
| 13 | respond_to :html, :pdf, :mobi, :epub, :azw3 |
| 14 | @download = Download.new(@work, mime_type: request.format) |
| 15 | @download.generate |
| 16 | |
| 17 | # Make sure we were able to generate the download. |
| 18 | unless @download.exists? |
| 19 | flash[:error] = ts("We were not able to render this work. Please try again in a little while or try another format.") |
| 20 | redirect_to work_path(@work) |
| 21 | return |
| 22 | end |
| 23 | |
| 24 | # Send file synchronously so we don't delete it before we have finished |
| 25 | # sending it |
| 26 | File.open(@download.file_path, 'r') do |f| |
| 27 | send_data f.read, filename: "#{@download.file_name}.#{@download.file_type}", type: @download.mime_type |
| 28 | end |
| 29 | else |
| 30 | flash[:error] = ts("downloads are for users only") |
| 31 | redirect_to work_path(@work) |
| 32 | end |
| 33 | end |
| 34 | |
| 35 | protected |
| 36 | |
| 37 | # Set up the work and check revealed status |
| 38 | # Once a format has been created, we want nginx to be able to serve |
| 39 | # it directly, without going through Rails again (until the work changes). |
| 40 | # This means no processing per user. Consider this the "published" version. |
| 41 | # It can't contain unposted chapters, nor unrevealed creators, even |
| 42 | # if the creator is the one requesting the download. |
| 43 | def load_work |
| 44 | unless @admin_settings.downloads_enabled? |
| 45 | flash[:error] = ts("Sorry, downloads are currently disabled.") |
| 46 | redirect_back_or_default works_path |
| 47 | return |
| 48 | end |
| 49 | |
| 50 | @work = Work.find(params[:id]) |
| 51 | end |
| 52 | |
| 53 | # We're currently just writing everything to tmp and feeding them through |
| 54 | # nginx so we don't want to keep the files around. |
| 55 | def remove_downloads |
| 56 | yield |
| 57 | ensure |
| 58 | if !@download.nil? |
| 59 | @download.remove |
| 60 | end |
| 61 | end |
| 62 | |
| 63 | # We can't use check_visibility because this controller doesn't have access to |
| 64 | # cookies on production or staging. |
| 65 | def check_download_visibility |
| 66 | return unless @work.hidden_by_admin || @work.in_unrevealed_collection? |
| 67 | message = if @work.hidden_by_admin |
| 68 | ts("Sorry, you can't download a work that has been hidden by an admin.") |
| 69 | else |
| 70 | ts("Sorry, you can't download an unrevealed work.") |
| 71 | end |
| 72 | flash[:error] = message |
| 73 | redirect_to work_path(@work) |
| 74 | end |
| 75 | |
| 76 | def check_download_posted_status |
| 77 | return if @work.posted |
| 78 | flash[:error] = ts("Sorry, you can't download a draft.") |
| 79 | redirect_to work_path(@work) |
| 80 | end |
| 81 | end |