rails_imager 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0764ea29875ab7576c668c8e792b8866eca1c1c7
4
- data.tar.gz: f9235dcafccd09e9df9f8ba7c7ffc910714c125a
3
+ metadata.gz: fd9b2fe3759e88819d0db1f9b3af5fba8e6d576a
4
+ data.tar.gz: 39f8ba07520ec430d733ddfefedf5342707ec07c
5
5
  SHA512:
6
- metadata.gz: 241f39a3ce37651a208763b4c68cf394c9225f0de676a3b87899ed80347a7fe8b38624262d1d5dbbfba572b75f9078cc686a70cc4c481334173ae34389881d10
7
- data.tar.gz: 3abb94d5b7a48a4d6e25264fefd98a6f71a8b198f693de8eb29f629aea976f9488c1158cd3fe757c6f367b7ee54285f10286c693543a609cfd70373dc1d45369
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
- rimger = RailsImager::ImageHandler.new
8
- image_params = params[:image] || {}
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
- # Check for invalid parameters.
11
- image_params.each do |key, val|
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
- image_path = "#{Rails.public_path}/#{params[:id]}"
16
- image_path = File.realpath(image_path)
17
- validate_path(image_path)
53
+ return false
54
+ end
55
+
56
+ def set_headers
57
+ response.last_modified = @mod_time
18
58
 
19
- rimger.handle(
20
- :controller => self,
21
- :fpath => image_path,
22
- :params => image_params
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
- private
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 validate_path(image_path)
29
- raise "No such file: '#{image_path}'." unless File.exists?(image_path)
30
- raise "Image wasn't in the public folder: '#{image_path}'." unless image_path.start_with?(Rails.public_path.to_s)
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
- if path.class.name == "Paperclip::Attachment"
6
- raise "Paperclip path does not start with public path: #{path.path}" unless path.path.to_s.start_with?(Rails.public_path.to_s)
7
- path_without_public = path.path.to_s.gsub("#{Rails.public_path}/", "")
8
- raise "Path didn't change '#{path.path}' - '#{path_without_public}'." if path.path.to_s == path_without_public
9
- path = path_without_public
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
- newpath = ""
15
+ check_arguments(args)
13
16
 
14
- if args[:url]
15
- args.delete(:url)
16
- newpath << "#{request.protocol}#{request.host_with_port}"
17
- elsif args[:mailer]
18
- args.delete(:mailer)
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
- # Check for invalid parameters.
34
- args.each do |key, val|
35
- raise ArgumentError, "Invalid parameter: '#{key}'." unless RailsImager::ImageHandler::PARAMS_ARGS.include?(key)
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
- newpath << "/rails_imager/images/"
41
- newpath << path
43
+ return pre_path
44
+ end
45
+
46
+ def url_encoded_arguments(args)
47
+ path = ""
42
48
 
43
- if args && args.any?
44
- newpath << "?"
45
-
46
- first = true
47
- args.each do |key, val|
48
- if first
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 newpath
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
@@ -1,3 +1,3 @@
1
1
  module RailsImager
2
- VERSION = "0.0.18"
2
+ VERSION = "0.0.19"
3
3
  end
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
- require path
16
- raise LoadError, "Not autoloaded: #{name}" unless const_defined?(name)
17
- return const_get(name)
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.18
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-05-14 00:00:00.000000000 Z
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.4
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.4
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.7
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,4 +0,0 @@
1
- module RailsImager
2
- class ApplicationController < ActionController::Base
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module RailsImager
2
- module ApplicationHelper
3
- end
4
- end
@@ -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