robinboening-fleximage 1.0.4 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +1 -1
- data/README.rdoc +34 -255
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/fleximage/model.rb +12 -10
- data/lib/fleximage/operator/image_overlay.rb +1 -1
- data/lib/fleximage/operator/text.rb +2 -2
- data/lib/fleximage/rails3_view.rb +31 -0
- data/lib/fleximage/rmagick_image_patch.rb +3 -1
- data/lib/fleximage/view.rb +3 -3
- data/lib/fleximage.rb +12 -10
- data/{tasks → lib/tasks}/fleximage_tasks.rake +2 -2
- data/{fleximage.gemspec → robinboening-fleximage.gemspec} +13 -12
- data/test/rails_root/config/boot.rb +5 -5
- data/test/rails_root/config/environment.rb +1 -1
- data/test/rails_root/config/initializers/load_translations.rb +1 -1
- data/test/rails_root/public/dispatch.cgi +1 -1
- data/test/rails_root/public/dispatch.fcgi +1 -1
- data/test/rails_root/public/dispatch.rb +1 -1
- data/test/rails_root/vendor/plugins/fleximage/init.rb +1 -1
- data/test/test_helper.rb +8 -8
- data/test/unit/basic_model_test.rb +4 -4
- data/test/unit/temp_image_test.rb +2 -2
- metadata +22 -13
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
== fleximage 1.0.2 12-14-2009
|
2
2
|
|
3
|
-
* Don't prepend
|
3
|
+
* Don't prepend Rails.root to absolute image directory path
|
4
4
|
* Added support for an "image_format" magic database column
|
5
5
|
* Fixed an issue with saving temp images in Windows
|
6
6
|
* Fixed a temp image vulnerability with directory traversal
|
data/README.rdoc
CHANGED
@@ -1,257 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
=
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
=== 2. Image Rendering
|
35
|
-
|
36
|
-
The other half of the problem comes from the need to send the uploaded images back to the web browser. Most of the time, you need to display the image in different sizes or formats in different places on your site. For example, a product image in a store may need a square thumbnail image, a medium image for its focus page, and a large image for an "enlarge this photo" popup.
|
37
|
-
|
38
|
-
Fleximage uses a simple templating engine that allows you to re-render images exactly how you need them. Using the same "master image," many images can be rendered from the same source. You can even go beyond resizing; there is support for image overlays, text drawing, drop shadows, borders and more. The rendering engine is flexible and extensible to whatever your dynamic image needs are.
|
39
|
-
|
40
|
-
* Renderer implemented as template engine, which fits in perfectly with Rails 2 RESTful style format-sensitive views.
|
41
|
-
* Does not need to have everything resized on upload allowing your site layout the change later on, and all images will re-render themselves just right with your new rendering templates.
|
42
|
-
* Support for special effects like text, image or logo overlays, borders and shadows.
|
43
|
-
* Extensible by adding image operator classes which allow for reusable snippets of direct RMagick code.
|
44
|
-
* Requires absolutely zero controller code.
|
45
|
-
|
46
|
-
|
47
|
-
= Getting Started
|
48
|
-
|
49
|
-
== 1. Installation
|
50
|
-
|
51
|
-
Gem: (Recommended)
|
52
|
-
|
53
|
-
gem install fleximage
|
54
|
-
|
55
|
-
# in config/environment.rb
|
56
|
-
config.gem 'fleximage'
|
57
|
-
|
58
|
-
Plugin:
|
59
|
-
|
60
|
-
./script/plugin install git://github.com/Squeegy/fleximage.git
|
61
|
-
|
62
|
-
|
63
|
-
== 2. Activating your model
|
64
|
-
|
65
|
-
You need to let your model know it should be Fleximage-friendly. Lets say you have a model for photos.
|
66
|
-
|
67
|
-
# app/models/photo.rb
|
68
|
-
class Photo < ActiveRecord::Base
|
69
|
-
acts_as_fleximage :image_directory => 'public/images/uploaded_photos'
|
70
|
-
end
|
71
|
-
|
72
|
-
The :+image_directory+ option tells the plugin where to store your master images. This value is relative to your application root, and doesn't need to be in your public directory if you don't want it to be. This is where the source images will be that all your templates start with.
|
73
|
-
|
74
|
-
There are many other options for your model. Refer to the <tt>Fleximage::Model::ClassMethods</tt> class in the +rdoc+ for more information on these.
|
75
|
-
|
76
|
-
|
77
|
-
== 3. The upload form
|
78
|
-
|
79
|
-
Your users need a way to upload their images into your site. Here is how we might render a form to create a photo record.
|
80
|
-
|
81
|
-
# app/views/photos/new.html.erb
|
82
|
-
|
83
|
-
<% form_for @photo, :html => { :multipart => true } do |f| %>
|
84
|
-
<p>
|
85
|
-
<b>Name</b><br />
|
86
|
-
<%= f.text_field :name %>
|
87
|
-
</p>
|
88
|
-
|
89
|
-
<p>
|
90
|
-
<b>Author</b><br />
|
91
|
-
<%= f.text_field :author %>
|
92
|
-
</p>
|
93
|
-
|
94
|
-
<p>
|
95
|
-
<b>Upload Image</b><br />
|
96
|
-
<%= f.file_field :image_file %><br />
|
97
|
-
or URL: <%= f.text_field :image_file_url %>
|
98
|
-
</p>
|
99
|
-
|
100
|
-
<p>
|
101
|
-
<%= f.submit "Create" %>
|
102
|
-
</p>
|
103
|
-
<% end %>
|
104
|
-
|
105
|
-
*NOTE*: The ":html => { :multipart => true }" is *VERY* *IMPORTANT*. Without this snippet your browser will not send binary data to the server. If things aren't working, check to make sure you have this in your form declaration.
|
106
|
-
|
107
|
-
The relevant bit of our form code is:
|
108
|
-
|
109
|
-
<p>
|
110
|
-
<b>Upload Image</b><br />
|
111
|
-
<%= f.file_field :image_file %><br />
|
112
|
-
or URL: <%= f.text_field :image_file_url %>
|
113
|
-
</p>
|
114
|
-
|
115
|
-
First there is a file upload field, mapping the the "image_file" attribute of our model. When the user browses to a local file and uploads it, the model is waiting to accept an uploaded file on this attribute and will automatically open it and save it to disk for you.
|
116
|
-
|
117
|
-
Right along side the upload field is a simple text field, which maps to the "image_file_url" property. Your model also listens for assignment to this attribute to automatically fetch the contents of a URL and save it locally as the master image.
|
118
|
-
|
119
|
-
You can have just one of these fields, or both. The model will know how to do the right thing either way.
|
120
|
-
|
121
|
-
When the user submits the form, all you have to do is assign the form contents to your object in standard Rails fashion, and the image is uploaded and saved for you. Creating a new photo may look like this in your controller:
|
122
|
-
|
123
|
-
# app/controllers/photos_controller.rb
|
124
|
-
def create
|
125
|
-
@photo = Photo.new(params[:photo])
|
126
|
-
if @photo.save
|
127
|
-
redirect_to photo_url(@photo)
|
128
|
-
else
|
129
|
-
flash[:notice] = 'Your photo did not pass validation!'
|
130
|
-
render :action => 'new'
|
1
|
+
For all istructions refers to git://github.com/Squeegy/fleximage.
|
2
|
+
I add a rails3_view.rb to manage template in rails3.
|
3
|
+
|
4
|
+
#rails3_view.rb
|
5
|
+
|
6
|
+
module ActionView
|
7
|
+
module TemplateHandlers
|
8
|
+
class Rails3View < TemplateHandler
|
9
|
+
include Compilable
|
10
|
+
class TemplateDidNotReturnImage < RuntimeError #:nodoc:
|
11
|
+
end
|
12
|
+
|
13
|
+
def compile(template)
|
14
|
+
<<-CODE
|
15
|
+
@template_format = :flexi
|
16
|
+
controller.response.content_type ||= Mime::JPG
|
17
|
+
result = #{template.source}
|
18
|
+
requested_format = (params[:format] || :jpg).to_sym
|
19
|
+
begin
|
20
|
+
# Raise an error if object returned from template is not an image record
|
21
|
+
unless result.class.include?(Fleximage::Model::InstanceMethods)
|
22
|
+
raise TemplateDidNotReturnImage, ".flexi template was expected to return a model instance that acts_as_fleximage, but got an instance of instead."
|
23
|
+
end
|
24
|
+
# Figure out the proper format
|
25
|
+
raise 'Image must be requested with an image type format. jpg, gif and png only are supported.' unless [:jpg, :gif, :png].include?(requested_format)
|
26
|
+
result.output_image(:format => requested_format)
|
27
|
+
rescue Exception => e
|
28
|
+
e
|
29
|
+
end
|
30
|
+
CODE
|
31
|
+
ensure
|
32
|
+
GC.start
|
33
|
+
end
|
131
34
|
end
|
132
35
|
end
|
133
|
-
|
134
|
-
|
135
|
-
== 4. Linking to the generated images
|
136
|
-
|
137
|
-
Rails 2 has amazing support for format driven responses. Given a photo object, by default it would have an HTML view that describes information about that photo. With Fleximage, the JPG or (GIF or PNG) view can be the image data itself.
|
138
|
-
|
139
|
-
A photo HTML view may look like this:
|
140
|
-
|
141
|
-
# app/views/photos/show.html.erb
|
142
|
-
# http://mysite.com/photos/123
|
143
|
-
|
144
|
-
<p>
|
145
|
-
<%= image_tag formatted_photo_path(@photo, :jpg) %>
|
146
|
-
</p>
|
147
|
-
<p>
|
148
|
-
<b>Name:</b>
|
149
|
-
<%=h @photo.name %>
|
150
|
-
</p>
|
151
|
-
<p>
|
152
|
-
<b>Author:</b>
|
153
|
-
<%=h @photo.author %>
|
154
|
-
</p>
|
155
|
-
|
156
|
-
That image tag uses a Rails route as its +src+. In this case, that route corresponds to the <tt>.jpg</tt> format of the +photo+ resource, which would give us a URL like:
|
157
|
-
|
158
|
-
http://mysite.com/photos/123.jpg
|
159
|
-
|
160
|
-
This is the URL where the image will be.
|
161
|
-
|
162
|
-
|
163
|
-
== 5. Rendering the image
|
164
|
-
|
165
|
-
Now it's time to actually create a template to render the image. This happens through a special view with a .+flexi+ extension. This view template will pull out the master image for you, and send it to the browser as binary data after your processing of it done.
|
166
|
-
|
167
|
-
The filename of the template should look like this: <tt>action_name.jpg.flexi</tt>, where +action_name+ is the controller action that will render this view. The +jpg+ tells the controller to render this view when the +jpg+ format is asked for. The +flexi+ tells Rails to render this view with the Fleximage template engine, rather than +erb+, +builder+ or other template types.
|
168
|
-
|
169
|
-
The syntax of the view is pure ruby, but to process the image the view needs to call +operate+ on the instance of your model.
|
170
|
-
|
171
|
-
Here is the view to render a photo record at 320x240:
|
172
|
-
|
173
|
-
# app/views/photos/show.jpg.flexi
|
174
|
-
# http://mysite.com/photos/123.jpg
|
175
|
-
@photo.operate do |image|
|
176
|
-
image.resize '320x240'
|
177
|
-
end
|
178
|
-
|
179
|
-
Calling <tt>@photo.operate { |image| .. }</tt> prepares the model object for image processing and provides a ruby object that will allow you to perform image transformations. This example just resizes the image to 320x240, however many other operators are included.
|
180
|
-
|
181
|
-
Here is a .+flexi+ template that will do much more:
|
182
|
-
|
183
|
-
# app/views/show.jpg.flexi
|
184
|
-
@photo.operate do |image|
|
185
|
-
image.resize '640x480', :crop => true
|
186
|
-
image.image_overlay 'public/images/logo.png',
|
187
|
-
:alignment => :bottom_right,
|
188
|
-
:offset => '20x20'
|
189
|
-
image.border :size => 10, :color => 'green'
|
190
|
-
image.text 'I like Cheese'
|
191
|
-
image.unsharp_mask
|
192
|
-
image.shadow
|
193
|
-
end
|
194
|
-
|
195
|
-
This template will:
|
196
|
-
|
197
|
-
* Resize the image to exactly 640x480, cropping off any extra.
|
198
|
-
* Add a logo 20 pixels form the lower right corner
|
199
|
-
* Add a green 10 pixel border
|
200
|
-
* Write "I like Cheese" in the upper left corder
|
201
|
-
* Sharpen the image
|
202
|
-
* Add a black drop shadow on a white background
|
203
|
-
|
204
|
-
For more information on image operators, open up <tt>vendor/plugins/fleximage/rdoc/index.html</tt> in your installed plugin and check out the full for details about each operator:
|
205
|
-
|
206
|
-
* Fleximage::Operator::Border
|
207
|
-
* Fleximage::Operator::Crop
|
208
|
-
* Fleximage::Operator::ImageOverlay
|
209
|
-
* Fleximage::Operator::Resize
|
210
|
-
* Fleximage::Operator::Shadow
|
211
|
-
* Fleximage::Operator::Text
|
212
|
-
* Fleximage::Operator::Trim
|
213
|
-
* Fleximage::Operator::UnsharpMask
|
214
|
-
|
215
|
-
|
216
|
-
= Other Useful Information
|
217
|
-
|
218
|
-
== Image output format
|
219
|
-
|
220
|
-
You don't want to render JPGs? That's fine. Just link to the format you want (:+jpg+, :+gif+ or :+png+) and declare the your template name to match and the image will be rendered properly. For instance, this will render a +gif+.
|
221
|
-
|
222
|
-
# app/views/photos/show.html.erb
|
223
|
-
<%= image_tag photo_path(@photo, :gif) %>
|
224
|
-
|
225
|
-
# app/views/photos/show.gif.flexi
|
226
|
-
@photo.operate do |image|
|
227
|
-
@photo.resize '150x150', :crop => true
|
228
|
-
end
|
229
|
-
|
230
|
-
The Fleximage template engine will automatically detect the format that is being asked for, and render the right type of image.
|
231
|
-
|
232
|
-
== Converting/Upgrading your master image store
|
233
|
-
|
234
|
-
Are you upgrading your live app to the new file store creation date based format? Did you start out with PNG image storage, and later realize you need to store with the more space economic JPG instead? Not problem, Fleximage provides some rake tasks to help you out.
|
235
|
-
|
236
|
-
Each conversion rake task requires that you tell it the class for which that you are changing the file store. For example, if you want to change to the new creation date based storage structure, for the class +Photo+, you can run a rake task like this:
|
237
|
-
|
238
|
-
rake fleximage:convert:to_nested FLEXIMAGE_CLASS=Photo
|
239
|
-
|
240
|
-
Or if you want to run this on your production database
|
241
|
-
|
242
|
-
rake fleximage:convert:to_nested FLEXIMAGE_CLASS=Photo RAILS_ENV=production
|
243
|
-
|
244
|
-
*IMPORTANT*: These tasks manipulate the source files that make up your images. I take no responsibility if these rake tasks delete all your images. <b>It is highly advised you back up you master image directory before running any of these tasks on your production site.</b>
|
245
|
-
|
246
|
-
Here are all the conversion tasks:
|
247
|
-
|
248
|
-
* fleximage:convert:to_nested : Converts your master image store from the flat based path/to/images/123.png format to the creation date based format path/to/images/2008/11/12/123.png based format. Use this task if you are upgrading from an older version of Fleximage.
|
249
|
-
* fleximage:convert:to_flat : Converts your master image store from the creation date based path/to/images/2008/11/12/123.png format to the flat format path/to/images/123.png format. Note this will leave the date based directories in place, but they will be empty and can be easily manually deleted.
|
250
|
-
* fleximage:convert:to_jpg : Converts all your stored master images from PNG format to JPG format. This will compress your previously lossless master images.
|
251
|
-
* fleximage:convert:to_png : Converts all your stored master images from JPG format to PNG format.
|
252
|
-
|
253
|
-
After you run any of these tasks, make sure to update your model's class accessors +use_creation_date_based_directories+ and +image_storage_format+ to reflect the state of your image store. Otherwise, the plugin will not find you master images for rendering.
|
254
|
-
|
255
|
-
------
|
256
|
-
Copyright (c) 2008 Alex Wayne beautifulpixel.com, released under the MIT license.
|
257
|
-
Special Thanks to Chris Vannoy for intelligent code review, suggestions and contributions to making this plugin awesome.
|
36
|
+
end
|
data/Rakefile
CHANGED
@@ -40,7 +40,7 @@ EOF
|
|
40
40
|
gem.authors = `git log --pretty=format:"%an"`.split("\n").uniq.sort
|
41
41
|
gem.add_dependency "rmagick"
|
42
42
|
gem.add_dependency "aws-s3"
|
43
|
-
gem.add_development_dependency "rails", "
|
43
|
+
gem.add_development_dependency "rails", ">=3.0.0"
|
44
44
|
end
|
45
45
|
Jeweler::GemcutterTasks.new
|
46
46
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.6
|
data/lib/fleximage/model.rb
CHANGED
@@ -273,7 +273,7 @@ module Fleximage
|
|
273
273
|
raise 'No image directory was defined, cannot generate path' unless directory
|
274
274
|
|
275
275
|
# base directory
|
276
|
-
directory = "#{
|
276
|
+
directory = "#{Rails.root}/#{directory}" unless /^\// =~ directory
|
277
277
|
|
278
278
|
# specific creation date based directory suffix.
|
279
279
|
creation = self[:created_at] || self[:created_on]
|
@@ -335,9 +335,11 @@ module Fleximage
|
|
335
335
|
def image_file=(file)
|
336
336
|
if self.class.image_file_exists(file)
|
337
337
|
|
338
|
+
file_path = file.is_a?( ActionDispatch::Http::UploadedFile ) ? file.tempfile.path : file.path
|
339
|
+
|
338
340
|
# Create RMagick Image object from uploaded file
|
339
|
-
if
|
340
|
-
@uploaded_image = Magick::Image.read(
|
341
|
+
if file_path
|
342
|
+
@uploaded_image = Magick::Image.read(file_path).first
|
341
343
|
else
|
342
344
|
@uploaded_image = Magick::Image.from_blob(file.read).first
|
343
345
|
end
|
@@ -381,7 +383,7 @@ module Fleximage
|
|
381
383
|
def image_file_url=(file_url)
|
382
384
|
@image_file_url = file_url
|
383
385
|
if file_url =~ %r{^(https?|ftp)://}
|
384
|
-
file = open(file_url)
|
386
|
+
file = open(URI.parse(URI.encode(file_url)))
|
385
387
|
|
386
388
|
# Force a URL based file to have an original_filename
|
387
389
|
eval <<-CODE
|
@@ -421,13 +423,13 @@ module Fleximage
|
|
421
423
|
self.image_file_string = Base64.decode64(data)
|
422
424
|
end
|
423
425
|
|
424
|
-
# Sets the uploaded image to the name of a file in
|
426
|
+
# Sets the uploaded image to the name of a file in Rails.root/tmp that was just
|
425
427
|
# uploaded. Use as a hidden field in your forms to keep an uploaded image when
|
426
428
|
# validation fails and the form needs to be redisplayed
|
427
429
|
def image_file_temp=(file_name)
|
428
430
|
if !@uploaded_image && file_name && file_name.present? && file_name !~ %r{\.\./}
|
429
431
|
@image_file_temp = file_name
|
430
|
-
file_path = "#{
|
432
|
+
file_path = "#{Rails.root}/tmp/fleximage/#{file_name}"
|
431
433
|
|
432
434
|
@dont_save_temp = true
|
433
435
|
if File.exists?(file_path)
|
@@ -470,7 +472,7 @@ module Fleximage
|
|
470
472
|
# image.resize '320x240'
|
471
473
|
# end
|
472
474
|
def operate(&block)
|
473
|
-
|
475
|
+
self.tap do
|
474
476
|
proxy = ImageProxy.new(load_image, self)
|
475
477
|
block.call(proxy)
|
476
478
|
@output_image = proxy.image
|
@@ -663,7 +665,7 @@ module Fleximage
|
|
663
665
|
def save_temp_image(file)
|
664
666
|
file_name = file.respond_to?(:original_filename) ? file.original_filename : file.path
|
665
667
|
@image_file_temp = Time.now.to_f.to_s.sub('.', '_')
|
666
|
-
path = "#{
|
668
|
+
path = "#{Rails.root}/tmp/fleximage"
|
667
669
|
FileUtils.mkdir_p(path)
|
668
670
|
File.open("#{path}/#{@image_file_temp}", 'wb') do |f|
|
669
671
|
file.rewind
|
@@ -673,14 +675,14 @@ module Fleximage
|
|
673
675
|
|
674
676
|
# Delete the temp image after its no longer needed
|
675
677
|
def delete_temp_image
|
676
|
-
FileUtils.rm_rf "#{
|
678
|
+
FileUtils.rm_rf "#{Rails.root}/tmp/fleximage/#{@image_file_temp}"
|
677
679
|
end
|
678
680
|
|
679
681
|
# Load the default image, or raise an expection
|
680
682
|
def master_image_not_found
|
681
683
|
# Load the default image from a path
|
682
684
|
if self.class.default_image_path
|
683
|
-
@output_image = Magick::Image.read("#{
|
685
|
+
@output_image = Magick::Image.read("#{Rails.root}/#{self.class.default_image_path}").first
|
684
686
|
|
685
687
|
# Or create a default image
|
686
688
|
elsif self.class.default_image
|
@@ -7,7 +7,7 @@ module Fleximage
|
|
7
7
|
#
|
8
8
|
# image.resize(image_overlay_path, options = {})
|
9
9
|
#
|
10
|
-
# +image_overlay_path+ is the path, relative to +
|
10
|
+
# +image_overlay_path+ is the path, relative to +Rails.root+ where the image you want superimposed
|
11
11
|
# can be found.
|
12
12
|
#
|
13
13
|
# Use the following keys in the +options+ hash:
|
@@ -12,7 +12,7 @@ module Fleximage
|
|
12
12
|
# * antialias: true or false
|
13
13
|
# * color: string or <tt>color(r, g, b)</tt>
|
14
14
|
# * font_size: integer
|
15
|
-
# * font: path to a font file relative to +
|
15
|
+
# * font: path to a font file relative to +Rails.root+
|
16
16
|
# * rotate: degrees as an integer
|
17
17
|
# * shadow: <tt>{:blur => 1, :opacity => 1.0}</tt>
|
18
18
|
# * font_weight: RMagick font weight constant or value. See: http://www.imagemagick.org/RMagick/doc/draw.html#font_weight
|
@@ -75,7 +75,7 @@ module Fleximage
|
|
75
75
|
# assign font path with to rails root unless the path is absolute
|
76
76
|
if options[:font]
|
77
77
|
font = options[:font]
|
78
|
-
font = "#{
|
78
|
+
font = "#{Rails.root}/#{font}" unless font =~ %r{^(~?|[A-Za-z]:)/}
|
79
79
|
text.font = font
|
80
80
|
end
|
81
81
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActionView
|
2
|
+
module TemplateHandlers
|
3
|
+
class Rails3View < TemplateHandler
|
4
|
+
include Compilable
|
5
|
+
class TemplateDidNotReturnImage < RuntimeError #:nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
def compile(template)
|
9
|
+
<<-CODE
|
10
|
+
@template_format = :flexi
|
11
|
+
controller.response.content_type ||= Mime::JPG
|
12
|
+
result = #{template.source}
|
13
|
+
requested_format = (params[:format] || :jpg).to_sym
|
14
|
+
begin
|
15
|
+
# Raise an error if object returned from template is not an image record
|
16
|
+
unless result.class.include?(Fleximage::Model::InstanceMethods)
|
17
|
+
raise TemplateDidNotReturnImage, ".flexi template was expected to return a model instance that acts_as_fleximage, but got an instance of instead."
|
18
|
+
end
|
19
|
+
# Figure out the proper format
|
20
|
+
raise 'Image must be requested with an image type format. jpg, gif and png only are supported.' unless [:jpg, :gif, :png].include?(requested_format)
|
21
|
+
result.output_image(:format => requested_format)
|
22
|
+
rescue Exception => e
|
23
|
+
e
|
24
|
+
end
|
25
|
+
CODE
|
26
|
+
ensure
|
27
|
+
GC.start
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/fleximage/view.rb
CHANGED
@@ -28,14 +28,14 @@ module Fleximage
|
|
28
28
|
|
29
29
|
# Raise an error if object returned from template is not an image record
|
30
30
|
unless result.class.include?(Fleximage::Model::InstanceMethods)
|
31
|
-
raise TemplateDidNotReturnImage,
|
31
|
+
raise TemplateDidNotReturnImage,
|
32
32
|
".flexi template was expected to return a model instance that acts_as_fleximage, but got an instance of <#{result.class}> instead."
|
33
33
|
end
|
34
34
|
|
35
35
|
# Figure out the proper format
|
36
36
|
requested_format = (@view.params[:format] || :jpg).to_sym
|
37
37
|
unless [:jpg, :gif, :png].include?(requested_format)
|
38
|
-
raise 'Image must be requested with an image type format.
|
38
|
+
raise 'Image must be requested with an image type format. jpg, gif and png only are supported.'
|
39
39
|
end
|
40
40
|
|
41
41
|
# Set proper content type
|
@@ -54,4 +54,4 @@ module Fleximage
|
|
54
54
|
GC.start
|
55
55
|
end
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
data/lib/fleximage.rb
CHANGED
@@ -3,13 +3,7 @@ require 'base64'
|
|
3
3
|
require 'digest/sha1'
|
4
4
|
require 'aws/s3'
|
5
5
|
|
6
|
-
|
7
|
-
begin
|
8
|
-
require 'RMagick'
|
9
|
-
rescue MissingSourceFile => e
|
10
|
-
puts %{ERROR :: FlexImage requires the RMagick gem. http://rmagick.rubyforge.org/install-faq.html}
|
11
|
-
raise e
|
12
|
-
end
|
6
|
+
require 'RMagick' unless defined?(Magick)
|
13
7
|
|
14
8
|
# Apply a few RMagick patches
|
15
9
|
require 'fleximage/rmagick_image_patch'
|
@@ -27,15 +21,23 @@ end
|
|
27
21
|
require 'fleximage/model'
|
28
22
|
ActiveRecord::Base.class_eval { include Fleximage::Model }
|
29
23
|
|
24
|
+
# Image Creation
|
25
|
+
require 'fleximage/blank'
|
26
|
+
|
30
27
|
# Image Proxy
|
31
28
|
require 'fleximage/image_proxy'
|
32
29
|
|
33
30
|
# Setup View
|
34
|
-
ActionController::Base.exempt_from_layout :flexi
|
31
|
+
#ActionController::Base.exempt_from_layout :flexi
|
35
32
|
if defined?(ActionView::Template)
|
36
33
|
# Rails >= 2.1
|
37
|
-
|
38
|
-
|
34
|
+
if Rails.version.to_f >= 3
|
35
|
+
require 'fleximage/rails3_view'
|
36
|
+
ActionView::Template.register_template_handler :flexi, ActionView::TemplateHandlers::Rails3View
|
37
|
+
else
|
38
|
+
require 'fleximage/view'
|
39
|
+
ActionView::Template.register_template_handler :flexi, Fleximage::View
|
40
|
+
end
|
39
41
|
else
|
40
42
|
# Rails < 2.1
|
41
43
|
require 'fleximage/legacy_view'
|
@@ -26,8 +26,8 @@ namespace :fleximage do
|
|
26
26
|
creation = obj[:created_at] || obj[:created_on]
|
27
27
|
|
28
28
|
# Generate both types of file paths
|
29
|
-
flat_path = "#{
|
30
|
-
nested_path = "#{
|
29
|
+
flat_path = "#{Rails.root}/#{model_class.image_directory}/#{obj.id}.#{model_class.image_storage_format}"
|
30
|
+
nested_path = "#{Rails.root}/#{model_class.image_directory}/#{creation.year}/#{creation.month}/#{creation.day}/#{obj.id}.#{model_class.image_storage_format}"
|
31
31
|
|
32
32
|
# Assign old path and new path based on desired directory format
|
33
33
|
if to_format == :nested
|
@@ -4,16 +4,16 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{fleximage}
|
8
|
-
s.version = "1.0.
|
7
|
+
s.name = %q{robinboening-fleximage}
|
8
|
+
s.version = "1.0.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
11
|
+
s.authors = ["Ahmed Adam", "Alex Wayne", "Andrew White", "Duccio", "Heiner Wohner", "JJ Buckley", "Jason Lee", "Joshua Abbott", "Koji Ando", "Kouhei Sutou", "Lasse Jansen", "Lo\303\257c Guitaut", "Martin Vielsmaier", "Robin B\303\266ning", "Squeegy", "Thomas von Deyen", "Vannoy", "Wolfgang Klinger", "Wolfgang K\303\266lbl", "josei", "ralph"]
|
12
12
|
s.date = %q{2011-05-29}
|
13
13
|
s.description = %q{Fleximage is a Rails plugin that tries to make image uploading and rendering
|
14
14
|
super easy.
|
15
15
|
}
|
16
|
-
s.email = %q{
|
16
|
+
s.email = %q{robin.boening@nethosting4you.de}
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"README.rdoc"
|
19
19
|
]
|
@@ -24,7 +24,6 @@ super easy.
|
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"autotest.rb",
|
27
|
-
"fleximage.gemspec",
|
28
27
|
"init.rb",
|
29
28
|
"lib/dsl_accessor.rb",
|
30
29
|
"lib/fleximage.rb",
|
@@ -44,9 +43,11 @@ super easy.
|
|
44
43
|
"lib/fleximage/operator/text.rb",
|
45
44
|
"lib/fleximage/operator/trim.rb",
|
46
45
|
"lib/fleximage/operator/unsharp_mask.rb",
|
46
|
+
"lib/fleximage/rails3_view.rb",
|
47
47
|
"lib/fleximage/rmagick_image_patch.rb",
|
48
48
|
"lib/fleximage/view.rb",
|
49
|
-
"tasks/fleximage_tasks.rake",
|
49
|
+
"lib/tasks/fleximage_tasks.rake",
|
50
|
+
"robinboening-fleximage.gemspec",
|
50
51
|
"test/fixtures/100x1.jpg",
|
51
52
|
"test/fixtures/100x100.jpg",
|
52
53
|
"test/fixtures/1x1.jpg",
|
@@ -153,9 +154,9 @@ super easy.
|
|
153
154
|
"test/unit/temp_image_test.rb",
|
154
155
|
"test/unit/use_creation_date_based_directories_option_test.rb"
|
155
156
|
]
|
156
|
-
s.homepage = %q{http://github.com/
|
157
|
-
s.require_paths = [
|
158
|
-
s.rubygems_version = %q{1.
|
157
|
+
s.homepage = %q{http://github.com/robinboening/fleximage}
|
158
|
+
s.require_paths = ["lib"]
|
159
|
+
s.rubygems_version = %q{1.5.0}
|
159
160
|
s.summary = %q{Rails plugin for uploading images as resources, with support for resizing, text stamping, and other special effects.}
|
160
161
|
|
161
162
|
if s.respond_to? :specification_version then
|
@@ -164,16 +165,16 @@ super easy.
|
|
164
165
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
165
166
|
s.add_runtime_dependency(%q<rmagick>, [">= 0"])
|
166
167
|
s.add_runtime_dependency(%q<aws-s3>, [">= 0"])
|
167
|
-
s.add_development_dependency(%q<rails>, ["
|
168
|
+
s.add_development_dependency(%q<rails>, [">= 3.0.0"])
|
168
169
|
else
|
169
170
|
s.add_dependency(%q<rmagick>, [">= 0"])
|
170
171
|
s.add_dependency(%q<aws-s3>, [">= 0"])
|
171
|
-
s.add_dependency(%q<rails>, ["
|
172
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
172
173
|
end
|
173
174
|
else
|
174
175
|
s.add_dependency(%q<rmagick>, [">= 0"])
|
175
176
|
s.add_dependency(%q<aws-s3>, [">= 0"])
|
176
|
-
s.add_dependency(%q<rails>, ["
|
177
|
+
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
177
178
|
end
|
178
179
|
end
|
179
180
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Don't change this file!
|
2
2
|
# Configure your app in config/environment.rb and config/environments/*.rb
|
3
3
|
|
4
|
-
|
4
|
+
Rails.root = "#{File.dirname(__FILE__)}/.." unless defined?(Rails.root)
|
5
5
|
|
6
6
|
module Rails
|
7
7
|
class << self
|
@@ -21,7 +21,7 @@ module Rails
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def vendor_rails?
|
24
|
-
File.exist?("#{
|
24
|
+
File.exist?("#{Rails.root}/vendor/rails")
|
25
25
|
end
|
26
26
|
|
27
27
|
# FIXME : Ruby 1.9
|
@@ -30,7 +30,7 @@ module Rails
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def preinitializer_path
|
33
|
-
"#{
|
33
|
+
"#{Rails.root}/config/preinitializer.rb"
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,7 +43,7 @@ module Rails
|
|
43
43
|
|
44
44
|
class VendorBoot < Boot
|
45
45
|
def load_initializer
|
46
|
-
require "#{
|
46
|
+
require "#{Rails.root}/vendor/rails/railties/lib/initializer"
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -99,7 +99,7 @@ module Rails
|
|
99
99
|
|
100
100
|
private
|
101
101
|
def read_environment_rb
|
102
|
-
File.read("#{
|
102
|
+
File.read("#{Rails.root}/config/environment.rb")
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -26,7 +26,7 @@ Rails::Initializer.run do |config|
|
|
26
26
|
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
27
27
|
|
28
28
|
# Add additional load paths for your own custom dirs
|
29
|
-
# config.load_paths += %W( #{
|
29
|
+
# config.load_paths += %W( #{Rails.root}/extras )
|
30
30
|
|
31
31
|
# Force all environments to use the same logger level
|
32
32
|
# (by default production uses :info, the others :debug)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/local/bin/ruby
|
2
2
|
|
3
|
-
require File.dirname(__FILE__) + "/../config/environment" unless defined?(
|
3
|
+
require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails.root)
|
4
4
|
|
5
5
|
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
|
6
6
|
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# exceptions which forced the FastCGI instance to exit, great for debugging)
|
5
5
|
# and the number of requests to process before running garbage collection.
|
6
6
|
#
|
7
|
-
# By default, the FastCGI crash log is
|
7
|
+
# By default, the FastCGI crash log is Rails.root/log/fastcgi.crash.log
|
8
8
|
# and the GC period is nil (turned off). A reasonable number of requests
|
9
9
|
# could range from 10-100 depending on the memory footprint of your app.
|
10
10
|
#
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/local/bin/ruby
|
2
2
|
|
3
|
-
require File.dirname(__FILE__) + "/../config/environment" unless defined?(
|
3
|
+
require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails.root)
|
4
4
|
|
5
5
|
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
|
6
6
|
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
|
@@ -1,2 +1,2 @@
|
|
1
|
-
init_path = "#{
|
1
|
+
init_path = "#{Rails.root}/../../init.rb"
|
2
2
|
silence_warnings { eval(IO.read(init_path), binding, init_path) }
|
data/test/test_helper.rb
CHANGED
@@ -7,7 +7,7 @@ require 'test_help'
|
|
7
7
|
silence_warnings { RAILS_ENV = ENV['RAILS_ENV'] }
|
8
8
|
|
9
9
|
# Run the migrations
|
10
|
-
ActiveRecord::Migrator.migrate("#{
|
10
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
11
11
|
|
12
12
|
# Setup the fixtures path
|
13
13
|
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
@@ -38,28 +38,28 @@ class Test::Unit::TestCase #:nodoc:
|
|
38
38
|
def files(name)
|
39
39
|
case name
|
40
40
|
when :photo
|
41
|
-
MockFile.new("#{
|
41
|
+
MockFile.new("#{Rails.root}/../fixtures/photo.jpg")
|
42
42
|
|
43
43
|
when :not_a_photo
|
44
|
-
MockFile.new("#{
|
44
|
+
MockFile.new("#{Rails.root}/../fixtures/not_a_photo.xml")
|
45
45
|
|
46
46
|
when :web_photo
|
47
47
|
'http://www.google.com/intl/en_ALL/images/logo.gif'
|
48
48
|
|
49
49
|
when :cmyk
|
50
|
-
MockFile.new("#{
|
50
|
+
MockFile.new("#{Rails.root}/../fixtures/cmyk.jpg")
|
51
51
|
|
52
52
|
when :i100x100
|
53
|
-
MockFile.new("#{
|
53
|
+
MockFile.new("#{Rails.root}/../fixtures/100x100.jpg")
|
54
54
|
|
55
55
|
when :i1x100
|
56
|
-
MockFile.new("#{
|
56
|
+
MockFile.new("#{Rails.root}/../fixtures/1x100.jpg")
|
57
57
|
|
58
58
|
when :i100x1
|
59
|
-
MockFile.new("#{
|
59
|
+
MockFile.new("#{Rails.root}/../fixtures/100x1.jpg")
|
60
60
|
|
61
61
|
when :i1x1
|
62
|
-
MockFile.new("#{
|
62
|
+
MockFile.new("#{Rails.root}/../fixtures/1x1.jpg")
|
63
63
|
|
64
64
|
end
|
65
65
|
end
|
@@ -3,18 +3,18 @@ require File.dirname(__FILE__) + '/../../test/test_helper'
|
|
3
3
|
class FleximageBasicModelTest < Test::Unit::TestCase
|
4
4
|
def test_should_have_correct_file_path_with_creation_date_based_storage
|
5
5
|
p = PhotoBare.create(:image_file => files(:photo))
|
6
|
-
assert_equal "#{
|
6
|
+
assert_equal "#{Rails.root}/public/uploads/#{Time.now.year}/#{Time.now.month}/#{Time.now.day}/#{p.id}.png", p.file_path
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_should_have_correct_directory_path_with_creation_date_based_storage
|
10
10
|
p = PhotoBare.create(:image_file => files(:photo))
|
11
|
-
assert_equal "#{
|
11
|
+
assert_equal "#{Rails.root}/public/uploads/#{Time.now.year}/#{Time.now.month}/#{Time.now.day}", p.directory_path
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_should_have_correct_file_path_without_creation_date_based_storage
|
15
15
|
PhotoBare.use_creation_date_based_directories = false
|
16
16
|
p = PhotoBare.create(:image_file => files(:photo))
|
17
|
-
assert_equal "#{
|
17
|
+
assert_equal "#{Rails.root}/public/uploads/#{p.id}.png", p.file_path
|
18
18
|
ensure
|
19
19
|
PhotoBare.use_creation_date_based_directories = true
|
20
20
|
end
|
@@ -22,7 +22,7 @@ class FleximageBasicModelTest < Test::Unit::TestCase
|
|
22
22
|
def test_should_have_correct_directory_path_without_creation_date_based_storage
|
23
23
|
PhotoBare.use_creation_date_based_directories = false
|
24
24
|
p = PhotoBare.create(:image_file => files(:photo))
|
25
|
-
assert_equal "#{
|
25
|
+
assert_equal "#{Rails.root}/public/uploads", p.directory_path
|
26
26
|
ensure
|
27
27
|
PhotoBare.use_creation_date_based_directories = true
|
28
28
|
end
|
@@ -5,14 +5,14 @@ class FleximageTempImageTest < Test::Unit::TestCase
|
|
5
5
|
a1 = Avatar.new(:image_file => files(:photo))
|
6
6
|
assert !a1.save
|
7
7
|
assert_match /^\d+_\d+$/, a1.image_file_temp
|
8
|
-
assert File.exists?("#{
|
8
|
+
assert File.exists?("#{Rails.root}/tmp/fleximage/#{a1.image_file_temp}")
|
9
9
|
temp_file_path = a1.image_file_temp
|
10
10
|
|
11
11
|
a2 = Avatar.new(:username => 'Alex Wayne', :image_file_temp => temp_file_path)
|
12
12
|
|
13
13
|
assert a2.save
|
14
14
|
assert File.exists?(a2.file_path)
|
15
|
-
assert !File.exists?("#{
|
15
|
+
assert !File.exists?("#{Rails.root}/tmp/fleximage/#{temp_file_path}")
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_should_prevent_directory_traversal_attacks
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robinboening-fleximage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 6
|
10
|
+
version: 1.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ahmed Adam
|
14
14
|
- Alex Wayne
|
15
15
|
- Andrew White
|
16
|
+
- Duccio
|
17
|
+
- Heiner Wohner
|
16
18
|
- JJ Buckley
|
17
19
|
- Jason Lee
|
18
20
|
- Joshua Abbott
|
@@ -23,13 +25,18 @@ authors:
|
|
23
25
|
- Martin Vielsmaier
|
24
26
|
- "Robin B\xC3\xB6ning"
|
25
27
|
- Squeegy
|
28
|
+
- Thomas von Deyen
|
26
29
|
- Vannoy
|
30
|
+
- Wolfgang Klinger
|
31
|
+
- "Wolfgang K\xC3\xB6lbl"
|
32
|
+
- josei
|
27
33
|
- ralph
|
28
34
|
autorequire:
|
29
35
|
bindir: bin
|
30
36
|
cert_chain: []
|
31
37
|
|
32
|
-
date: 2011-05-29 00:00:00
|
38
|
+
date: 2011-05-29 00:00:00 +02:00
|
39
|
+
default_executable:
|
33
40
|
dependencies:
|
34
41
|
- !ruby/object:Gem::Dependency
|
35
42
|
name: rmagick
|
@@ -65,14 +72,14 @@ dependencies:
|
|
65
72
|
requirement: &id003 !ruby/object:Gem::Requirement
|
66
73
|
none: false
|
67
74
|
requirements:
|
68
|
-
- - "
|
75
|
+
- - ">="
|
69
76
|
- !ruby/object:Gem::Version
|
70
|
-
hash:
|
77
|
+
hash: 7
|
71
78
|
segments:
|
72
|
-
-
|
73
|
-
-
|
74
|
-
-
|
75
|
-
version:
|
79
|
+
- 3
|
80
|
+
- 0
|
81
|
+
- 0
|
82
|
+
version: 3.0.0
|
76
83
|
type: :development
|
77
84
|
version_requirements: *id003
|
78
85
|
description: |
|
@@ -93,7 +100,6 @@ files:
|
|
93
100
|
- Rakefile
|
94
101
|
- VERSION
|
95
102
|
- autotest.rb
|
96
|
-
- fleximage.gemspec
|
97
103
|
- init.rb
|
98
104
|
- lib/dsl_accessor.rb
|
99
105
|
- lib/fleximage.rb
|
@@ -113,9 +119,11 @@ files:
|
|
113
119
|
- lib/fleximage/operator/text.rb
|
114
120
|
- lib/fleximage/operator/trim.rb
|
115
121
|
- lib/fleximage/operator/unsharp_mask.rb
|
122
|
+
- lib/fleximage/rails3_view.rb
|
116
123
|
- lib/fleximage/rmagick_image_patch.rb
|
117
124
|
- lib/fleximage/view.rb
|
118
|
-
- tasks/fleximage_tasks.rake
|
125
|
+
- lib/tasks/fleximage_tasks.rake
|
126
|
+
- robinboening-fleximage.gemspec
|
119
127
|
- test/fixtures/100x1.jpg
|
120
128
|
- test/fixtures/100x100.jpg
|
121
129
|
- test/fixtures/1x1.jpg
|
@@ -221,6 +229,7 @@ files:
|
|
221
229
|
- test/unit/require_image_option_test.rb
|
222
230
|
- test/unit/temp_image_test.rb
|
223
231
|
- test/unit/use_creation_date_based_directories_option_test.rb
|
232
|
+
has_rdoc: true
|
224
233
|
homepage: http://github.com/robinboening/fleximage
|
225
234
|
licenses: []
|
226
235
|
|
@@ -250,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
259
|
requirements: []
|
251
260
|
|
252
261
|
rubyforge_project:
|
253
|
-
rubygems_version: 1.
|
262
|
+
rubygems_version: 1.5.0
|
254
263
|
signing_key:
|
255
264
|
specification_version: 3
|
256
265
|
summary: Rails plugin for uploading images as resources, with support for resizing, text stamping, and other special effects.
|