|
|
@@ -0,0 +1,81 @@ |
|
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 |
+ |
unless params[:user_id] && (@user = User.find_by(login: params[:user_id])) |
|
12 |
+ |
flash[:error] = ts('downloads are restricted to users only') |
|
13 |
+ |
redirect_to users_path |
|
14 |
+ |
return |
|
15 |
+ |
end |
|
16 |
+ |
|
|
17 |
+ |
respond_to :html, :pdf, :mobi, :epub, :azw3 |
|
18 |
+ |
@download = Download.new(@work, mime_type: request.format) |
|
19 |
+ |
@download.generate |
|
20 |
+ |
|
|
21 |
+ |
# Make sure we were able to generate the download. |
|
22 |
+ |
unless @download.exists? |
|
23 |
+ |
flash[:error] = ts("We were not able to render this work. Please try again in a little while or try another format.") |
|
24 |
+ |
redirect_to work_path(@work) |
|
25 |
+ |
return |
|
26 |
+ |
end |
|
27 |
+ |
|
|
28 |
+ |
# Send file synchronously so we don't delete it before we have finished |
|
29 |
+ |
# sending it |
|
30 |
+ |
File.open(@download.file_path, 'r') do |f| |
|
31 |
+ |
send_data f.read, filename: "#{@download.file_name}.#{@download.file_type}", type: @download.mime_type |
|
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 |