rails_imager 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/rails_imager/images_controller.rb +182 -21
- data/app/helpers/rails_imager/images_helper.rb +67 -45
- data/lib/rails_imager/version.rb +1 -1
- data/lib/rails_imager.rb +12 -6
- metadata +12 -15
- data/app/controllers/rails_imager/application_controller.rb +0 -4
- data/app/helpers/rails_imager/application_helper.rb +0 -4
- data/lib/rails_imager/image_handler.rb +0 -256
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd9b2fe3759e88819d0db1f9b3af5fba8e6d576a
|
4
|
+
data.tar.gz: 39f8ba07520ec430d733ddfefedf5342707ec07c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f1569d9140d97e751f842f2d74e03088c49d2a07e723238b1264c4a69a4caf390340569998427c1580b7c85a379ce932131a58907c6c22dc2d138ab2578af8c
|
7
|
+
data.tar.gz: 137034cb9d007fe284496e1b3c55e2506b3cff718dd8a707836cf30686e729c23d7cc983c7917cf9d60ec9f8b96b769e2ea51f58792d095f651d6a541ee865e8
|
@@ -1,32 +1,193 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require_dependency "rails_imager/application_controller"
|
4
|
-
|
5
1
|
class RailsImager::ImagesController < ApplicationController
|
2
|
+
PARAMS_ARGS = [:width, :height, :smartsize, :maxwidth, :maxheight, :rounded_corners, :border, :border_color, :force]
|
3
|
+
|
6
4
|
def show
|
7
|
-
|
8
|
-
|
5
|
+
set_and_validate_parameters
|
6
|
+
set_path
|
7
|
+
@mod_time = File.mtime(@full_path)
|
8
|
+
generate_cache_name
|
9
|
+
generate_cache if should_generate_cache?
|
10
|
+
set_headers
|
11
|
+
|
12
|
+
if not_modified? && !force?
|
13
|
+
render :nothing => true, :status => "304 Not Modified"
|
14
|
+
else
|
15
|
+
send_file @cache_path, :type => "image/png", :disposition => "inline", :filename => "picture.png"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_path
|
22
|
+
@path = "#{Rails.public_path}/#{params[:id]}"
|
23
|
+
@full_path = File.realpath(@path)
|
24
|
+
validate_path
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_and_validate_parameters
|
28
|
+
@image_params = params[:image] || {}
|
29
|
+
@image_params.each do |key, val|
|
30
|
+
raise ArgumentError, "Invalid parameter: '#{key}'." unless PARAMS_ARGS.map{ |param| param.to_s }.include?(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def force?
|
35
|
+
if @image_params[:force] && @image_params[:force].to_s == "true"
|
36
|
+
return true
|
37
|
+
else
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def not_modified?
|
43
|
+
if request.headers["HTTP_IF_MODIFIED_SINCE"]
|
44
|
+
if_mod_since_time = Datet.in(request.headers["HTTP_IF_MODIFIED_SINCE"]).time
|
45
|
+
else
|
46
|
+
if_mod_since_time = request.if_modified_since
|
47
|
+
end
|
9
48
|
|
10
|
-
|
11
|
-
|
12
|
-
raise ArgumentError, "Invalid parameter: '#{key}'." unless RailsImager::ImageHandler::PARAMS_ARGS.map{ |param| param.to_s }.include?(key)
|
49
|
+
if if_mod_since_time && if_mod_since_time.utc.to_s == @mod_time.utc.to_s
|
50
|
+
return true
|
13
51
|
end
|
14
52
|
|
15
|
-
|
16
|
-
|
17
|
-
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_headers
|
57
|
+
response.last_modified = @mod_time
|
18
58
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
59
|
+
if force?
|
60
|
+
response.headers["Expires"] = Time.now.httpdate
|
61
|
+
else
|
62
|
+
response.headers["Expires"] = 2.hours.from_now.httpdate
|
63
|
+
end
|
24
64
|
end
|
25
65
|
|
26
|
-
|
66
|
+
def validate_path
|
67
|
+
raise "No such file: '#{@full_path}'." unless File.exists?(@full_path)
|
68
|
+
raise "Image wasn't in the public folder: '#{@full_path}'." unless @full_path.start_with?(File.realpath(Rails.public_path.to_s))
|
69
|
+
end
|
27
70
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
71
|
+
def generate_cache_name
|
72
|
+
@cache_name = ::Knj::Strings.sanitize_filename(@path)
|
73
|
+
@cache_name << "__ARGS_"
|
74
|
+
|
75
|
+
PARAMS_ARGS.each do |val|
|
76
|
+
next if val.to_s == "force"
|
77
|
+
@cache_name << "_#{val}-#{@image_params[val]}"
|
78
|
+
end
|
79
|
+
|
80
|
+
@cache_path = "#{cache_directory}/#{@cache_name}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def cache_directory
|
84
|
+
require "tmpdir"
|
85
|
+
cache_path = "#{Dir.tmpdir}/rails-imager-cache"
|
86
|
+
Dir.mkdir(cache_path) unless Dir.exists?(cache_path)
|
87
|
+
return cache_path
|
88
|
+
end
|
89
|
+
|
90
|
+
def should_generate_cache?
|
91
|
+
return true if force?
|
92
|
+
|
93
|
+
if File.exists?(@cache_path)
|
94
|
+
if File.mtime(@cache_path) < File.mtime(@full_path)
|
95
|
+
return true
|
96
|
+
else
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
else
|
100
|
+
return true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_cache
|
105
|
+
@image = ::Magick::Image.read(@full_path).first
|
106
|
+
@image.format = "png"
|
107
|
+
apply_image_changes
|
108
|
+
@image.write(@cache_path)
|
109
|
+
end
|
110
|
+
|
111
|
+
#Create a new image-object based on the given image-object and the parameters.
|
112
|
+
def apply_image_changes
|
113
|
+
@image_width = @image.columns
|
114
|
+
@image_height = @image.rows
|
115
|
+
|
116
|
+
if @image_params[:width].to_i > 0
|
117
|
+
@width = @image_params[:width].to_i
|
118
|
+
else
|
119
|
+
@width = @image_width
|
120
|
+
end
|
121
|
+
|
122
|
+
if @image_params[:height].to_i > 0
|
123
|
+
@height = @image_params[:height].to_i
|
124
|
+
else
|
125
|
+
@height = @image_height
|
126
|
+
end
|
127
|
+
|
128
|
+
calcuate_sizes
|
129
|
+
@image = @image.resize(@width, @height) if @width != @image_width || @height != @image_height
|
130
|
+
apply_rounded_corners if @image_params[:rounded_corners]
|
131
|
+
end
|
132
|
+
|
133
|
+
def calcuate_sizes
|
134
|
+
validate_and_set_smartsize if @image_params[:smartsize]
|
135
|
+
validate_and_set_max_width
|
136
|
+
validate_and_set_max_height
|
137
|
+
calculate_missing_width if @image_params[:height] && !@image_params[:width]
|
138
|
+
calculate_missing_height if @image_params[:width] && !@image_params[:height]
|
139
|
+
end
|
140
|
+
|
141
|
+
def calculate_missing_height
|
142
|
+
@height = (@image_height.to_f / (@image_width.to_f / @width.to_f)).to_i
|
143
|
+
end
|
144
|
+
|
145
|
+
def calculate_missing_width
|
146
|
+
@width = (@image_width.to_f / (@image_height.to_f / @height.to_f)).to_i
|
147
|
+
end
|
148
|
+
|
149
|
+
def validate_and_set_smartsize
|
150
|
+
if @image_width > @image_height
|
151
|
+
@width = @image_params[:smartsize].to_i
|
152
|
+
calculate_missing_height
|
153
|
+
else
|
154
|
+
@height = @image_params[:smartsize].to_i
|
155
|
+
calculate_missing_width
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def validate_and_set_max_width
|
160
|
+
if @image_params[:maxwidth]
|
161
|
+
maxwidth = @image_params[:maxwidth].to_i
|
162
|
+
|
163
|
+
if @width > maxwidth
|
164
|
+
@width = maxwidth
|
165
|
+
calculate_missing_height
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def validate_and_set_max_height
|
171
|
+
if @image_params[:maxheight]
|
172
|
+
maxheight = @image_params[:maxheight].to_i
|
173
|
+
|
174
|
+
if @height > maxheight
|
175
|
+
@height = maxheight
|
176
|
+
calculate_missing_width
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def apply_rounded_corners
|
182
|
+
@image = @image.clone
|
183
|
+
@image.format = "png" # Needs PNG format for transparency.
|
184
|
+
args = {:img => @image, :radius => @image_params[:rounded_corners].to_i}
|
185
|
+
|
186
|
+
if @image_params[:border] && @image_params[:border_color]
|
187
|
+
args[:border] = @image_params[:border].to_i
|
188
|
+
args[:border_color] = @image_params[:border_color]
|
189
|
+
end
|
190
|
+
|
191
|
+
::Knj::Image.rounded_corners(args)
|
31
192
|
end
|
32
193
|
end
|
@@ -2,63 +2,85 @@ require "uri"
|
|
2
2
|
|
3
3
|
module RailsImager::ImagesHelper
|
4
4
|
def rails_imager_p(path, args = {})
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
path = path_from_arg(path)
|
6
|
+
|
7
|
+
if args.delete(:url)
|
8
|
+
newpath = "#{request.protocol}#{request.host_with_port}"
|
9
|
+
elsif args.delete(:mailer)
|
10
|
+
newpath = mailer_pre_path
|
11
|
+
else
|
12
|
+
newpath = ""
|
10
13
|
end
|
11
14
|
|
12
|
-
|
15
|
+
check_arguments(args)
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if ActionMailer::Base.default_url_options[:protocol]
|
21
|
-
newpath << ActionMailer::Base.default_url_options[:protocol]
|
22
|
-
else
|
23
|
-
newpath << "http://"
|
24
|
-
end
|
25
|
-
|
26
|
-
newpath << ActionMailer::Base.default_url_options[:host]
|
27
|
-
|
28
|
-
if ActionMailer::Base.default_url_options[:port]
|
29
|
-
newpath << ":#{ActionMailer::Base.default_url_options[:port]}"
|
30
|
-
end
|
17
|
+
newpath << "/rails_imager/images/"
|
18
|
+
newpath << path
|
19
|
+
|
20
|
+
if args && args.any?
|
21
|
+
newpath << "?"
|
22
|
+
newpath << url_encoded_arguments(args)
|
31
23
|
end
|
32
24
|
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
return newpath
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def mailer_pre_path
|
31
|
+
if ActionMailer::Base.default_url_options[:protocol]
|
32
|
+
pre_path = ActionMailer::Base.default_url_options[:protocol]
|
33
|
+
else
|
34
|
+
pre_path = "http://"
|
36
35
|
end
|
37
36
|
|
37
|
+
pre_path << ActionMailer::Base.default_url_options[:host]
|
38
38
|
|
39
|
+
if ActionMailer::Base.default_url_options[:port]
|
40
|
+
pre_path << ":#{ActionMailer::Base.default_url_options[:port]}"
|
41
|
+
end
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
return pre_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def url_encoded_arguments(args)
|
47
|
+
path = ""
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
first = false
|
50
|
-
else
|
51
|
-
newpath << "&"
|
52
|
-
end
|
53
|
-
|
54
|
-
realkey = "image[#{key}]"
|
55
|
-
|
56
|
-
newpath << URI.encode(realkey.to_s)
|
57
|
-
newpath << "="
|
58
|
-
newpath << URI.encode(val.to_s)
|
49
|
+
first = true
|
50
|
+
args.each do |key, val|
|
51
|
+
if first
|
52
|
+
first = false
|
53
|
+
else
|
54
|
+
path << "&"
|
59
55
|
end
|
56
|
+
|
57
|
+
realkey = "image[#{key}]"
|
58
|
+
|
59
|
+
path << URI.encode(realkey)
|
60
|
+
path << "="
|
61
|
+
path << URI.encode(val.to_s)
|
60
62
|
end
|
61
63
|
|
62
|
-
return
|
64
|
+
return path
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_arguments(args)
|
68
|
+
# Check for invalid parameters.
|
69
|
+
args.each do |key, val|
|
70
|
+
raise ArgumentError, "Invalid parameter: '#{key}'." unless RailsImager::ImagesController::PARAMS_ARGS.include?(key)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def path_from_arg(path)
|
75
|
+
if path.class.name == "Paperclip::Attachment"
|
76
|
+
raise "Paperclip path does not start with public path: #{path.path}" unless path.path.to_s.start_with?(Rails.public_path.to_s)
|
77
|
+
path_without_public = path.path.to_s.gsub("#{Rails.public_path}/", "")
|
78
|
+
raise "Path didn't change '#{path.path}' - '#{path_without_public}'." if path.path.to_s == path_without_public
|
79
|
+
return path_without_public
|
80
|
+
elsif path.is_a?(String)
|
81
|
+
return path
|
82
|
+
else
|
83
|
+
raise "Unknown argument: #{path_from_arg}"
|
84
|
+
end
|
63
85
|
end
|
64
86
|
end
|
data/lib/rails_imager/version.rb
CHANGED
data/lib/rails_imager.rb
CHANGED
@@ -1,19 +1,25 @@
|
|
1
1
|
require "rails/engine"
|
2
2
|
require "rails_imager/engine"
|
3
3
|
require "string-cases"
|
4
|
+
require "datet"
|
5
|
+
require "knjrbfw"
|
6
|
+
require "RMagick" unless ::Kernel.const_defined?(:RMagick)
|
4
7
|
|
5
8
|
module RailsImager
|
6
9
|
def self.const_missing(name)
|
7
10
|
if name.to_s.end_with?("Controller")
|
8
|
-
path = "#{File.dirname(__FILE__)}/../app/controllers/rails_imager/#{::StringCases.camel_to_snake(name)}"
|
11
|
+
path = "#{File.dirname(__FILE__)}/../app/controllers/rails_imager/#{::StringCases.camel_to_snake(name)}.rb"
|
9
12
|
elsif name.to_s.end_with?("Helper")
|
10
|
-
path = "#{File.dirname(__FILE__)}/../app/helpers/rails_imager/#{::StringCases.camel_to_snake(name)}"
|
13
|
+
path = "#{File.dirname(__FILE__)}/../app/helpers/rails_imager/#{::StringCases.camel_to_snake(name)}.rb"
|
11
14
|
else
|
12
|
-
path = "#{File.dirname(__FILE__)}/rails_imager/#{::StringCases.camel_to_snake(name)}"
|
15
|
+
path = "#{File.dirname(__FILE__)}/rails_imager/#{::StringCases.camel_to_snake(name)}.rb"
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
if File.exists?(path)
|
19
|
+
require path
|
20
|
+
return const_get(name) if const_defined?(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
super
|
18
24
|
end
|
19
25
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_imager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kaspernj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.0.
|
19
|
+
version: 4.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.0.
|
26
|
+
version: 4.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: knjrbfw
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,21 +143,18 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
-
- app/helpers/rails_imager/application_helper.rb
|
147
|
-
- app/helpers/rails_imager/images_helper.rb
|
148
|
-
- app/assets/javascripts/rails_imager/images.js
|
149
|
-
- app/assets/javascripts/rails_imager/application.js
|
150
146
|
- app/assets/stylesheets/rails_imager/application.css
|
151
147
|
- app/assets/stylesheets/rails_imager/images.css
|
148
|
+
- app/assets/javascripts/rails_imager/images.js
|
149
|
+
- app/assets/javascripts/rails_imager/application.js
|
150
|
+
- app/helpers/rails_imager/images_helper.rb
|
152
151
|
- app/controllers/rails_imager/images_controller.rb
|
153
|
-
- app/controllers/rails_imager/application_controller.rb
|
154
152
|
- app/views/layouts/rails_imager/application.html.erb
|
155
153
|
- config/routes.rb
|
154
|
+
- lib/rails_imager.rb
|
155
|
+
- lib/tasks/rails_imager_tasks.rake
|
156
156
|
- lib/rails_imager/engine.rb
|
157
157
|
- lib/rails_imager/version.rb
|
158
|
-
- lib/rails_imager/image_handler.rb
|
159
|
-
- lib/tasks/rails_imager_tasks.rake
|
160
|
-
- lib/rails_imager.rb
|
161
158
|
- MIT-LICENSE
|
162
159
|
- Rakefile
|
163
160
|
homepage: http://www.github.com/kaspernj/rails_imager
|
@@ -179,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
176
|
version: '0'
|
180
177
|
requirements: []
|
181
178
|
rubyforge_project:
|
182
|
-
rubygems_version: 2.0.
|
179
|
+
rubygems_version: 2.0.14
|
183
180
|
signing_key:
|
184
181
|
specification_version: 4
|
185
182
|
summary: Automatic resizing, bordering and more of images.
|
@@ -1,256 +0,0 @@
|
|
1
|
-
require "RMagick"
|
2
|
-
require "knjrbfw"
|
3
|
-
require "tmpdir"
|
4
|
-
require "datet"
|
5
|
-
|
6
|
-
class RailsImager::ImageHandler
|
7
|
-
PARAMS_ARGS = [:width, :height, :smartsize, :maxwidth, :maxheight, :rounded_corners, :border, :border_color, :force]
|
8
|
-
|
9
|
-
#This is the default cache which is plased in the temp-directory, so it will be cleared on every restart. It should always exist.
|
10
|
-
DEFAULT_CACHE_DIR = "#{Dir.tmpdir}/rails-imager-cache"
|
11
|
-
Dir.mkdir(DEFAULT_CACHE_DIR) unless Dir.exists?(DEFAULT_CACHE_DIR)
|
12
|
-
|
13
|
-
#Default arguments unless something else is given in constructor.
|
14
|
-
DEFAULT_ARGS = {
|
15
|
-
:cache_dir => DEFAULT_CACHE_DIR
|
16
|
-
}
|
17
|
-
|
18
|
-
INITIALIZE_ALLOWED_ARGS = [:cache_dir]
|
19
|
-
#Initializes the RailsImager.
|
20
|
-
def initialize(args = {})
|
21
|
-
args.each do |key, val|
|
22
|
-
raise "Invalid argument: '#{key}'." unless INITIALIZE_ALLOWED_ARGS.include?(key)
|
23
|
-
end
|
24
|
-
|
25
|
-
@args = DEFAULT_ARGS.merge(args)
|
26
|
-
end
|
27
|
-
|
28
|
-
IMG_FROM_PARAMS_ALLOWED_ARGS = [:image, :params]
|
29
|
-
#Create a new image-object based on the given image-object and the parameters.
|
30
|
-
def img_from_params(args)
|
31
|
-
args.each do |key, val|
|
32
|
-
raise "Invalid argument: '#{key}'." unless IMG_FROM_PARAMS_ALLOWED_ARGS.include?(key)
|
33
|
-
end
|
34
|
-
|
35
|
-
#Set up vars.
|
36
|
-
img = args[:image]
|
37
|
-
raise "No image given." unless img
|
38
|
-
raise "Wrong image-object given: '#{img.class.name}'." unless img.is_a?(Magick::Image)
|
39
|
-
|
40
|
-
params = args[:params]
|
41
|
-
raise "No params given." unless params
|
42
|
-
|
43
|
-
img_width = img.columns
|
44
|
-
img_height = img.rows
|
45
|
-
|
46
|
-
width = img_width
|
47
|
-
height = img_height
|
48
|
-
|
49
|
-
width = params[:width].to_i if params[:width].to_i > 0
|
50
|
-
height = params[:height].to_i if params[:height].to_i > 0
|
51
|
-
|
52
|
-
#Check arguments and manipulate image.
|
53
|
-
if params[:smartsize]
|
54
|
-
if img_width > img_height
|
55
|
-
width = params[:smartsize].to_i
|
56
|
-
height = (img_height.to_f / (img_width.to_f / width.to_f)).to_i
|
57
|
-
else
|
58
|
-
height = params[:smartsize].to_i
|
59
|
-
width = (img_width.to_f / (img_height.to_f / height.to_f)).to_i
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
if params[:maxwidth]
|
64
|
-
maxwidth = params[:maxwidth].to_i
|
65
|
-
|
66
|
-
if width > maxwidth
|
67
|
-
height = (img_height.to_f / (img_width.to_f / maxwidth.to_f)).to_i
|
68
|
-
width = maxwidth
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
if params[:maxheight]
|
73
|
-
maxheight = params[:maxheight].to_i
|
74
|
-
|
75
|
-
if height > maxheight
|
76
|
-
width = (img_width.to_f / (img_height.to_f / maxheight.to_f)).to_i
|
77
|
-
height = maxheight
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
if params[:width] && !params[:height]
|
82
|
-
height = (img_height.to_f / (img_width.to_f / width.to_f)).to_i
|
83
|
-
elsif params[:height] && !params[:width]
|
84
|
-
width = (img_width.to_f / (img_height.to_f / height.to_f)).to_i
|
85
|
-
elsif params[:width] && params[:height]
|
86
|
-
width = params[:width].to_i
|
87
|
-
height = params[:height].to_i
|
88
|
-
end
|
89
|
-
|
90
|
-
if width != img_width || height != img_height
|
91
|
-
img = img.resize(width, height)
|
92
|
-
end
|
93
|
-
|
94
|
-
if params[:rounded_corners]
|
95
|
-
img = img.clone
|
96
|
-
img.format = "png" # Needs PNG format for transparency.
|
97
|
-
args = {:img => img, :radius => params[:rounded_corners].to_i}
|
98
|
-
|
99
|
-
if params[:border] && params[:border_color]
|
100
|
-
args[:border] = params[:border].to_i
|
101
|
-
args[:border_color] = params[:border_color]
|
102
|
-
end
|
103
|
-
|
104
|
-
Knj::Image.rounded_corners(args)
|
105
|
-
end
|
106
|
-
|
107
|
-
return img
|
108
|
-
end
|
109
|
-
|
110
|
-
CACHENAME_FROM_PARAMS_ALLOWED_ARGS = [:params, :image, :fpath]
|
111
|
-
#Returns the path to a cached object based on the given filepath, image and request-parameters.
|
112
|
-
def cachename_from_params(args)
|
113
|
-
args.each do |key, val|
|
114
|
-
raise "Invalid argument: '#{key}'." unless CACHENAME_FROM_PARAMS_ALLOWED_ARGS.include?(key)
|
115
|
-
end
|
116
|
-
|
117
|
-
params = args[:params]
|
118
|
-
raise "No params was given." unless params
|
119
|
-
|
120
|
-
if args[:image] && !args[:image].filename.to_s.strip.empty?
|
121
|
-
name = Knj::Strings.sanitize_filename(args[:image].filename)
|
122
|
-
elsif args[:fpath]
|
123
|
-
name = Knj::Strings.sanitize_filename(args[:fpath])
|
124
|
-
else
|
125
|
-
raise "No image or fpath was given."
|
126
|
-
end
|
127
|
-
|
128
|
-
name << "__ARGS__"
|
129
|
-
|
130
|
-
PARAMS_ARGS.each do |val|
|
131
|
-
name += "_" unless name.empty?
|
132
|
-
name += "#{val}-#{params[val]}"
|
133
|
-
end
|
134
|
-
|
135
|
-
return name
|
136
|
-
end
|
137
|
-
|
138
|
-
FORCE_CACHE_FROM_PARAMS_ALLOWED_ARGS = [:fpath, :image, :request, :params]
|
139
|
-
# Checks if a cache-file is created for the given filepath or image. If not then it will be created. If the cache-object is too old, then it will updated. Then returns the path to the cache-object in the end.
|
140
|
-
def force_cache_from_request(args)
|
141
|
-
args.each do |key, val|
|
142
|
-
raise "Invalid argument: '#{key}'." if !FORCE_CACHE_FROM_PARAMS_ALLOWED_ARGS.include?(key)
|
143
|
-
end
|
144
|
-
|
145
|
-
img = nil
|
146
|
-
|
147
|
-
if args[:fpath] && !args[:fpath].to_s.strip.empty?
|
148
|
-
fpath = args[:fpath]
|
149
|
-
elsif args[:image] && !args[:image].filename.to_s.strip.empty?
|
150
|
-
fpath = args[:image].filename
|
151
|
-
img = args[:image]
|
152
|
-
else
|
153
|
-
raise "No image or filename was given."
|
154
|
-
end
|
155
|
-
|
156
|
-
request = args[:request]
|
157
|
-
raise "Invalid request: '#{request.class.name}'." if !request
|
158
|
-
params = args[:params]
|
159
|
-
raise "No parameters on that request: '#{params.class.name}'." if !params
|
160
|
-
|
161
|
-
mod_time = File.mtime(fpath)
|
162
|
-
cachename = self.cachename_from_params(:fpath => fpath, :params => params)
|
163
|
-
cachepath = "#{@args[:cache_dir]}/#{cachename}"
|
164
|
-
not_modified = false
|
165
|
-
headers = request.headers
|
166
|
-
|
167
|
-
if !File.exists?(cachepath) || File.mtime(cachepath) < File.mtime(fpath)
|
168
|
-
should_generate = true
|
169
|
-
else
|
170
|
-
should_generate = false
|
171
|
-
end
|
172
|
-
|
173
|
-
if should_generate
|
174
|
-
img = ::Magick::Image.read(fpath).first unless img
|
175
|
-
img.format = "png"
|
176
|
-
img = self.img_from_params(:image => img, :params => params)
|
177
|
-
img.write(cachepath)
|
178
|
-
else
|
179
|
-
if_mod_since_time = nil
|
180
|
-
if headers["HTTP_IF_MODIFIED_SINCE"]
|
181
|
-
if_mod_since_time = Datet.in(headers["HTTP_IF_MODIFIED_SINCE"]).time
|
182
|
-
else
|
183
|
-
if_mod_since_time = request.if_modified_since
|
184
|
-
end
|
185
|
-
|
186
|
-
not_modified = true if if_mod_since_time && if_mod_since_time.utc.to_s == mod_time.utc.to_s
|
187
|
-
end
|
188
|
-
|
189
|
-
return {
|
190
|
-
:cachepath => cachepath,
|
191
|
-
:generated => should_generate,
|
192
|
-
:not_modified => not_modified,
|
193
|
-
:mod_time => mod_time,
|
194
|
-
}
|
195
|
-
end
|
196
|
-
|
197
|
-
HANDLE_ALLOWED_ARGS = [:fpath, :image, :controller, :params]
|
198
|
-
#Automatically handles the image with generation, cache control and more.
|
199
|
-
def handle(args)
|
200
|
-
args.each do |key, val|
|
201
|
-
raise "Invalid argument: '#{key}'." unless HANDLE_ALLOWED_ARGS.include?(key)
|
202
|
-
end
|
203
|
-
|
204
|
-
controller = args[:controller]
|
205
|
-
raise "No controller was given." unless controller
|
206
|
-
request = controller.request
|
207
|
-
params = args[:params]
|
208
|
-
raise "No params was given." unless params
|
209
|
-
|
210
|
-
if args[:image]
|
211
|
-
fpath = args[:image].filename
|
212
|
-
elsif args[:fpath]
|
213
|
-
fpath = args[:fpath]
|
214
|
-
end
|
215
|
-
|
216
|
-
raise "No filepath was given." if !fpath
|
217
|
-
res = self.force_cache_from_request(:fpath => fpath, :request => request, :params => params)
|
218
|
-
|
219
|
-
if params[:force] && params[:force] != "0"
|
220
|
-
force = true
|
221
|
-
else
|
222
|
-
force = false
|
223
|
-
end
|
224
|
-
|
225
|
-
controller.response.headers["Last-Modified"] = res[:mod_time].httpdate
|
226
|
-
|
227
|
-
if force
|
228
|
-
controller.response.headers["Expires"] = Time.now.httpdate
|
229
|
-
else
|
230
|
-
controller.response.headers["Expires"] = 2.hours.from_now.httpdate
|
231
|
-
end
|
232
|
-
|
233
|
-
if res[:not_modified] && !force
|
234
|
-
controller.render :nothing => true, :status => "304 Not Modified"
|
235
|
-
else
|
236
|
-
controller.send_file res[:cachepath], :type => "image/png", :disposition => "inline", :filename => "picture.png"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
#Yields every cache-file to the block. If the block returns true, then the cache-file will be deleted. If no block is given all the cache will be deleted.
|
241
|
-
def clear_cache(&blk)
|
242
|
-
Dir.foreach(@args[:cache_dir]) do |file|
|
243
|
-
next if file == "." || file == ".."
|
244
|
-
fn = "#{@args[:cache_dir]}/#{file}"
|
245
|
-
next unless File.file?(fn)
|
246
|
-
|
247
|
-
if blk == nil
|
248
|
-
res = true
|
249
|
-
else
|
250
|
-
res = yield(fn)
|
251
|
-
end
|
252
|
-
|
253
|
-
File.unlink(fn) if res == true
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|