dragonfly 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- data/.gitignore +2 -0
- data/.specopts +2 -0
- data/.yardopts +11 -5
- data/Gemfile +22 -0
- data/Gemfile.rails.2.3.5 +13 -0
- data/History.md +49 -0
- data/README.md +18 -28
- data/Rakefile +24 -36
- data/VERSION +1 -1
- data/config.ru +4 -1
- data/dragonfly.gemspec +85 -99
- data/extra_docs/Analysers.md +66 -30
- data/extra_docs/Caching.md +22 -0
- data/extra_docs/Configuration.md +116 -0
- data/extra_docs/DataStorage.md +114 -14
- data/extra_docs/Encoding.md +62 -37
- data/extra_docs/GeneralUsage.md +118 -0
- data/extra_docs/Generators.md +92 -0
- data/extra_docs/Heroku.md +51 -0
- data/extra_docs/Index.md +8 -9
- data/extra_docs/MimeTypes.md +18 -17
- data/extra_docs/Models.md +251 -0
- data/extra_docs/Processing.md +94 -70
- data/extra_docs/Rack.md +53 -0
- data/extra_docs/Rails2.md +44 -0
- data/extra_docs/Rails3.md +51 -0
- data/extra_docs/Sinatra.md +21 -0
- data/extra_docs/URLs.md +114 -0
- data/features/images.feature +6 -7
- data/features/no_processing.feature +0 -6
- data/features/rails_2.3.5.feature +1 -1
- data/features/rails_3.0.0.rc.feature +8 -0
- data/features/steps/dragonfly_steps.rb +14 -12
- data/features/steps/rails_steps.rb +20 -9
- data/features/support/env.rb +10 -11
- data/fixtures/files/app/views/albums/new.html.erb +4 -4
- data/fixtures/files/app/views/albums/show.html.erb +1 -1
- data/fixtures/files/features/manage_album_images.feature +1 -1
- data/fixtures/files/features/step_definitions/{album_steps.rb → image_steps.rb} +4 -3
- data/fixtures/files/features/support/paths.rb +2 -0
- data/fixtures/files/features/text_images.feature +7 -0
- data/fixtures/rails_3.0.0.rc/template.rb +21 -0
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +4 -16
- data/lib/dragonfly/{active_record_extensions.rb → active_model_extensions.rb} +1 -1
- data/lib/dragonfly/active_model_extensions/attachment.rb +146 -0
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/class_methods.rb +5 -6
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/instance_methods.rb +1 -1
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/validations.rb +5 -9
- data/lib/dragonfly/analyser.rb +59 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/r_magick_analyser.rb +46 -31
- data/lib/dragonfly/app.rb +138 -173
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/r_magick.rb +37 -0
- data/lib/dragonfly/config/{rails_defaults.rb → rails.rb} +6 -7
- data/lib/dragonfly/configurable.rb +30 -27
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/data_storage/file_data_store.rb +59 -26
- data/lib/dragonfly/data_storage/mongo_data_store.rb +65 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +31 -12
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/r_magick_encoder.rb +10 -19
- data/lib/dragonfly/endpoint.rb +43 -0
- data/lib/dragonfly/function_manager.rb +65 -0
- data/lib/dragonfly/{processing/r_magick_text_processor.rb → generation/r_magick_generator.rb} +25 -11
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/job.rb +290 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +17 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +21 -14
- data/lib/dragonfly/processing/r_magick_processor.rb +71 -48
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/r_magick_utils.rb +24 -0
- data/lib/dragonfly/rails/images.rb +10 -7
- data/lib/dragonfly/routed_endpoint.rb +42 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/simple_endpoint.rb +64 -0
- data/lib/dragonfly/temp_object.rb +77 -45
- data/spec/argument_matchers.rb +7 -17
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
- data/spec/dragonfly/{active_record_extensions → active_model_extensions}/model_spec.rb +282 -244
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +2 -2
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +10 -1
- data/spec/dragonfly/app_spec.rb +175 -69
- data/spec/dragonfly/configurable_spec.rb +14 -0
- data/spec/dragonfly/data_storage/data_store_spec.rb +36 -9
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +61 -38
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +18 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +34 -39
- data/spec/dragonfly/deprecation_spec.rb +20 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +119 -0
- data/spec/dragonfly/job_builder_spec.rb +37 -0
- data/spec/dragonfly/job_definitions_spec.rb +35 -0
- data/spec/dragonfly/job_endpoint_spec.rb +66 -0
- data/spec/dragonfly/job_spec.rb +605 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +37 -17
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +182 -166
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/simple_endpoint_spec.rb +78 -0
- data/spec/dragonfly/temp_object_spec.rb +154 -119
- data/spec/simple_matchers.rb +22 -0
- data/spec/spec_helper.rb +28 -4
- data/yard/templates/default/layout/html/layout.erb +18 -11
- metadata +89 -190
- data/config.rb +0 -5
- data/extra_docs/ActiveRecord.md +0 -196
- data/extra_docs/ExampleUseCases.md +0 -189
- data/extra_docs/GettingStarted.md +0 -114
- data/extra_docs/Shortcuts.md +0 -118
- data/extra_docs/UsingWithRails.md +0 -81
- data/features/rails_3.0.0.beta3.feature +0 -7
- data/fixtures/rails_3.0.0.beta3/template.rb +0 -16
- data/lib/dragonfly/active_record_extensions/attachment.rb +0 -170
- data/lib/dragonfly/analyser_list.rb +0 -9
- data/lib/dragonfly/analysis/base.rb +0 -10
- data/lib/dragonfly/belongs_to_app.rb +0 -24
- data/lib/dragonfly/config/heroku_rails_images.rb +0 -23
- data/lib/dragonfly/config/r_magick_images.rb +0 -69
- data/lib/dragonfly/config/r_magick_text.rb +0 -25
- data/lib/dragonfly/config/rails_images.rb +0 -13
- data/lib/dragonfly/data_storage/base.rb +0 -21
- data/lib/dragonfly/data_storage/base64_data_store.rb +0 -23
- data/lib/dragonfly/data_storage/transparent_data_store.rb +0 -21
- data/lib/dragonfly/delegatable.rb +0 -14
- data/lib/dragonfly/delegator.rb +0 -62
- data/lib/dragonfly/encoder_list.rb +0 -9
- data/lib/dragonfly/encoding/base.rb +0 -14
- data/lib/dragonfly/encoding/transparent_encoder.rb +0 -14
- data/lib/dragonfly/extended_temp_object.rb +0 -120
- data/lib/dragonfly/parameters.rb +0 -163
- data/lib/dragonfly/processing/base.rb +0 -10
- data/lib/dragonfly/processor_list.rb +0 -9
- data/lib/dragonfly/url_handler.rb +0 -147
- data/spec/dragonfly/active_record_extensions/attachment_spec.rb +0 -8
- data/spec/dragonfly/active_record_extensions/migration.rb +0 -42
- data/spec/dragonfly/active_record_extensions/models.rb +0 -6
- data/spec/dragonfly/active_record_extensions/spec_helper.rb +0 -24
- data/spec/dragonfly/belongs_to_app_spec.rb +0 -55
- data/spec/dragonfly/delegatable_spec.rb +0 -32
- data/spec/dragonfly/delegator_spec.rb +0 -145
- data/spec/dragonfly/extended_temp_object_spec.rb +0 -71
- data/spec/dragonfly/parameters_spec.rb +0 -298
- data/spec/dragonfly/processing/r_magick_text_processor_spec.rb +0 -84
- data/spec/dragonfly/url_handler_spec.rb +0 -247
- data/spec/dragonfly_spec.rb +0 -16
- data/spec/ginger_scenarios.rb +0 -13
data/extra_docs/Processing.md
CHANGED
@@ -1,98 +1,122 @@
|
|
1
1
|
Processing
|
2
2
|
==========
|
3
3
|
|
4
|
-
|
5
|
-
For example, resizing an image is classed as processing, whereas converting it from 'png' to 'jpeg' is classed as encoding.
|
4
|
+
Changing data in some way, e.g. resizing an image, comes under the banner of Processing.
|
6
5
|
|
7
|
-
|
6
|
+
You can register as many processors as you like.
|
8
7
|
|
9
|
-
Let's say we have a
|
8
|
+
Let's say we have a Dragonfly app
|
10
9
|
|
11
|
-
app = Dragonfly
|
10
|
+
app = Dragonfly[:images]
|
12
11
|
|
13
|
-
|
12
|
+
and an image object (actually a {Dragonfly::Job Job} object)...
|
14
13
|
|
15
|
-
|
14
|
+
image = app.fetch('some/uid')
|
16
15
|
|
17
|
-
|
18
|
-
For example, registering the {Dragonfly::Processing::RMagickProcessor rmagick processor}
|
16
|
+
...OR a Dragonfly model accessor...
|
19
17
|
|
20
|
-
|
18
|
+
image = @album.cover_image
|
21
19
|
|
22
|
-
|
20
|
+
We can process it using any processing methods that have been registered with the processor.
|
23
21
|
|
24
|
-
|
25
|
-
|
22
|
+
RMagickProcessor
|
23
|
+
----------------
|
24
|
+
The {Dragonfly::Processing::RMagickProcessor RMagickProcessor} is registered by default by
|
25
|
+
the {Dragonfly::Config::RMagick RMagick configuration} used by 'dragonfly/rails/images'.
|
26
26
|
|
27
|
-
|
27
|
+
If not already registered:
|
28
28
|
|
29
|
-
|
30
|
-
-----------------
|
29
|
+
app.processor.register(Dragonfly::Processing::RMagickProcessor)
|
31
30
|
|
32
|
-
|
33
|
-
Each method takes the temp_object, and the (optional) processing options hash as its argument.
|
31
|
+
gives us these methods:
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
def black_and_white(temp_object, opts={})
|
38
|
-
# use temp_object.data, temp_object.path, etc...
|
39
|
-
# ...process and return a String, File, Tempfile or TempObject
|
40
|
-
end
|
33
|
+
image.process(:thumb, '400x300#') # see below
|
41
34
|
|
42
|
-
|
35
|
+
image.process(:crop, :width => 40, :height => 50, :x => 20, :y => 30)
|
36
|
+
image.process(:crop, :width => 40, :height => 50, :gravity => 'ne')
|
43
37
|
|
44
|
-
|
38
|
+
image.process(:flip) # flips it vertically
|
39
|
+
image.process(:flop) # flips it horizontally
|
45
40
|
|
46
|
-
|
47
|
-
app.register_processor(MyProcessor)
|
41
|
+
image.process(:greyscale, :depth => 128) # default depth 256
|
48
42
|
|
49
|
-
|
43
|
+
image.process(:resize, '40x40')
|
44
|
+
image.process(:resize_and_crop, :width => 40, :height=> 50, :gravity => 'ne')
|
50
45
|
|
51
|
-
|
46
|
+
image.process(:rotate, 45, :background_colour => 'transparent') # default bg black
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
image.process(:vignette) # options :x, :y, :radius, :sigma
|
49
|
+
|
50
|
+
The method `thumb` takes a geometry string and calls `resize`, `resize_and_crop` or `crop` accordingly.
|
51
|
+
|
52
|
+
image.process(:thumb, '400x300') # calls resize
|
53
|
+
|
54
|
+
Below are some examples of geometry strings:
|
55
|
+
|
56
|
+
'400x300' # resize, maintain aspect ratio
|
57
|
+
'400x300!' # force resize, don't maintain aspect ratio
|
58
|
+
'400x' # resize width, maintain aspect ratio
|
59
|
+
'x300' # resize height, maintain aspect ratio
|
60
|
+
'400x300>' # resize only if the image is larger than this
|
61
|
+
'400x300<' # resize only if the image is smaller than this
|
62
|
+
'50x50%' # resize width and height to 50%
|
63
|
+
'400x300^' # resize width, height to minimum 400,300, maintain aspect ratio
|
64
|
+
'2000@' # resize so max area in pixels is 2000
|
65
|
+
'400x300#' # resize, crop if necessary to maintain aspect ratio (centre gravity)
|
66
|
+
'400x300#ne' # as above, north-east gravity
|
67
|
+
'400x300se' # crop, with south-east gravity
|
68
|
+
'400x300+50+100' # crop from the point 50,100 with width, height 400,300
|
69
|
+
|
70
|
+
Lazy evaluation
|
71
|
+
---------------
|
72
|
+
|
73
|
+
new_image = image.process(:some_method)
|
74
|
+
|
75
|
+
doesn't actually do anything until you call something on the returned {Dragonfly::Job Job} object, like `url`, `data`, etc.
|
76
|
+
|
77
|
+
Bang method
|
78
|
+
-----------
|
79
|
+
|
80
|
+
image.process!(:some_method)
|
81
|
+
|
82
|
+
modifies the image object itself, rather than returning a new object.
|
56
83
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
:processing_options => {:size => '30x30'},
|
67
|
-
:format => :png
|
68
|
-
)
|
69
|
-
|
70
|
-
or if using an activerecord model,
|
71
|
-
|
72
|
-
my_model.preview_image.url('some_uid',
|
73
|
-
:processing_method => :black_and_white,
|
74
|
-
:processing_options => {:size => '30x30'},
|
75
|
-
:format => :png
|
76
|
-
)
|
77
|
-
|
78
|
-
However, this could soon get tedious if using more than once, so the best thing is to register a shortcut for it.
|
79
|
-
So in your configuration of the Dragonfly app (or in an initializer if using 'dragonfly/rails/images') you
|
80
|
-
could do something like:
|
81
|
-
|
82
|
-
app.parameters.add_shortcut(/^bw-(\d*x\d*)$/) do |string, match_data|
|
83
|
-
{
|
84
|
-
:processing_method => :black_and_white,
|
85
|
-
:processing_options => {:size => match_data[1]},
|
86
|
-
:format => :png
|
87
|
-
}
|
84
|
+
Custom Processors
|
85
|
+
-----------------
|
86
|
+
|
87
|
+
To register a single custom processor:
|
88
|
+
|
89
|
+
app.processor.add :watermark do |temp_object, *args|
|
90
|
+
# use temp_object.data, temp_object.path, temp_object.file, etc.
|
91
|
+
SomeLibrary.add_watermark(temp_object.data, 'some/watermark/file.png')
|
92
|
+
# return a String, File or Tempfile
|
88
93
|
end
|
89
|
-
|
90
|
-
Now you can get urls by using the shortcut:
|
91
94
|
|
92
|
-
|
95
|
+
new_image = image.process(:watermark)
|
96
|
+
|
97
|
+
You can create a class like the RMagick one above, in which case all public methods will be counted as processing methods.
|
98
|
+
Each method takes the temp_object as its argument, plus any other args.
|
99
|
+
|
100
|
+
class MyProcessor
|
101
|
+
|
102
|
+
def coolify(temp_object, opts={})
|
103
|
+
SomeLib.coolify(temp_object.data, opts)
|
104
|
+
end
|
105
|
+
|
106
|
+
def uglify(temp_object, ugliness)
|
107
|
+
`uglify -i #{temp_object.path} -u #{ugliness}`
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def my_helper_method
|
113
|
+
# do stuff
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
93
117
|
|
94
|
-
|
118
|
+
app.processor.register(MyProcessor)
|
95
119
|
|
96
|
-
|
120
|
+
new_image = image.coolify(:some => :args)
|
97
121
|
|
98
|
-
|
122
|
+
new_image = image.uglify(:loads)
|
data/extra_docs/Rack.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
Rack
|
2
|
+
====
|
3
|
+
For more info about using Rack applications, see the docs at {http://rack.rubyforge.org/}
|
4
|
+
|
5
|
+
Basic usage involves storing data (e.g. images),
|
6
|
+
then serving it in some form.
|
7
|
+
|
8
|
+
A basic rackup file `config.ru`:
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'dragonfly'
|
12
|
+
|
13
|
+
Dragonfly[:my_app_name].configure do |c|
|
14
|
+
# ... configuration here
|
15
|
+
end
|
16
|
+
|
17
|
+
run Dragonfly:App[:my_app_name]
|
18
|
+
|
19
|
+
See {file:Configuration} for more details.
|
20
|
+
|
21
|
+
The basic flow is instantiate an app -> configure it -> run it.
|
22
|
+
|
23
|
+
Example: Using to serve resized images
|
24
|
+
--------------------------------------
|
25
|
+
|
26
|
+
`config.ru`:
|
27
|
+
|
28
|
+
require 'rubygems'
|
29
|
+
require 'dragonfly'
|
30
|
+
|
31
|
+
app = Dragonfly[:images]
|
32
|
+
app.configure_with(:rmagick)
|
33
|
+
|
34
|
+
run app
|
35
|
+
|
36
|
+
This enables the app to use all the RMagick goodies provided by Dragonfly (see {file:Configuration}).
|
37
|
+
By default the {Dragonfly::DataStorage::FileDataStore file data store} is used.
|
38
|
+
|
39
|
+
In the console:
|
40
|
+
|
41
|
+
app = Dragonfly[:images]
|
42
|
+
|
43
|
+
# Store
|
44
|
+
uid = app.store(File.new('path/to/image.png')) # ===> unique uid
|
45
|
+
|
46
|
+
# Get the url for a thumbnail
|
47
|
+
url = app.fetch(uid).thumb('400x300').url # ===> "/media/BAhbBlsHOgZmIg9hc..."
|
48
|
+
|
49
|
+
Now when we visit the url `/media/BAhbBlsHOgZmIg9hc...` in the browser, we get a resized image!
|
50
|
+
|
51
|
+
Mounting in Rack
|
52
|
+
----------------
|
53
|
+
See {file:URLs}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Using With Rails 2.3
|
2
|
+
====================
|
3
|
+
|
4
|
+
Setting up the quick way
|
5
|
+
------------------------
|
6
|
+
config/initializers/dragonfly.rb:
|
7
|
+
|
8
|
+
require 'dragonfly/rails/images'
|
9
|
+
|
10
|
+
Setting up the more explicit way
|
11
|
+
--------------------------------
|
12
|
+
You can do the above explicitly.
|
13
|
+
|
14
|
+
config/initializers/dragonfly.rb:
|
15
|
+
|
16
|
+
require 'dragonfly'
|
17
|
+
|
18
|
+
app = Dragonfly[:images]
|
19
|
+
app.configure_with(:rmagick)
|
20
|
+
app.configure_with(:rails)
|
21
|
+
|
22
|
+
app.define_macro(ActiveRecord::Base, :image_accessor)
|
23
|
+
|
24
|
+
environment.rb:
|
25
|
+
|
26
|
+
config.middleware.insert 0, 'Dragonfly::Middleware', :images, '/media'
|
27
|
+
config.middleware.insert 0, 'Rack::Cache', {
|
28
|
+
:verbose => true,
|
29
|
+
:metastore => "file:#{Rails.root}/tmp/dragonfly/cache/meta",
|
30
|
+
:entitystore => "file:#{Rails.root}/tmp/dragonfly/cache/body"
|
31
|
+
}
|
32
|
+
|
33
|
+
Gems
|
34
|
+
----
|
35
|
+
environment.rb
|
36
|
+
|
37
|
+
config.gem 'dragonfly', '~>0.7.0'
|
38
|
+
config.gem 'rmagick', :lib => 'RMagick'
|
39
|
+
config.gem 'rack-cache', :lib => 'rack/cache'
|
40
|
+
|
41
|
+
Use it!
|
42
|
+
-------
|
43
|
+
|
44
|
+
To see what you can do with the model accessors, see {file:Models}.
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Using With Rails 3
|
2
|
+
==================
|
3
|
+
|
4
|
+
Setting up the quick way
|
5
|
+
------------------------
|
6
|
+
config/initializers/dragonfly.rb:
|
7
|
+
|
8
|
+
require 'dragonfly/rails/images'
|
9
|
+
|
10
|
+
Setting up the more explicit way
|
11
|
+
--------------------------------
|
12
|
+
You can do the above explicitly.
|
13
|
+
|
14
|
+
config/initializers/dragonfly.rb:
|
15
|
+
|
16
|
+
require 'dragonfly'
|
17
|
+
|
18
|
+
app = Dragonfly[:images]
|
19
|
+
app.configure_with(:rmagick)
|
20
|
+
app.configure_with(:rails)
|
21
|
+
|
22
|
+
app.define_macro(ActiveRecord::Base, :image_accessor)
|
23
|
+
|
24
|
+
application.rb:
|
25
|
+
|
26
|
+
config.middleware.insert 0, 'Dragonfly::Middleware', :images, '/media'
|
27
|
+
config.middleware.insert 0, 'Rack::Cache', {
|
28
|
+
:verbose => true,
|
29
|
+
:metastore => "file:#{Rails.root}/tmp/dragonfly/cache/meta",
|
30
|
+
:entitystore => "file:#{Rails.root}/tmp/dragonfly/cache/body"
|
31
|
+
}
|
32
|
+
|
33
|
+
Gemfile
|
34
|
+
-------
|
35
|
+
|
36
|
+
gem 'dragonfly', '~>0.7.0'
|
37
|
+
gem 'rmagick', :require => 'RMagick'
|
38
|
+
gem 'rack-cache', :require => 'rack/cache'
|
39
|
+
|
40
|
+
Use it!
|
41
|
+
-------
|
42
|
+
|
43
|
+
To see what you can do with the model accessors, see {file:Models}.
|
44
|
+
|
45
|
+
Mounting in routes.rb
|
46
|
+
---------------------
|
47
|
+
Instead of mounting as a middleware, you could skip that bit and mount directly in the routes.rb file:
|
48
|
+
|
49
|
+
match '/media(/:dragonfly)', :to => Dragonfly[:images]
|
50
|
+
|
51
|
+
Make sure the the path prefix matches the Dragonfly app's configured url_path_prefix (which is /media by default for Rails).
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Sinatra
|
2
|
+
=======
|
3
|
+
You can use {Dragonfly::Job Job}'s `to_response` method like so:
|
4
|
+
|
5
|
+
get '/images/:size.:format' do |size, format|
|
6
|
+
app.fetch_file('~/some/image.png').thumb(size).encode(format).to_response
|
7
|
+
end
|
8
|
+
|
9
|
+
NOTE: uids from the datastore currently have slashes and dots in them so may cause problems when using ':uid' as
|
10
|
+
a path segment.
|
11
|
+
|
12
|
+
or you can mount as a middleware, like in rails:
|
13
|
+
|
14
|
+
Dragonfly[:images].configure_with(:rmagick) do |c|
|
15
|
+
c.url_path_prefix = '/media'
|
16
|
+
end
|
17
|
+
|
18
|
+
use Dragonfly::Middleware, :images, '/media'
|
19
|
+
|
20
|
+
get '/' #... do
|
21
|
+
# ...
|
data/extra_docs/URLs.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
URLs
|
2
|
+
====
|
3
|
+
|
4
|
+
We can get urls for any kind of job:
|
5
|
+
|
6
|
+
app = Dragonfly[:images]
|
7
|
+
|
8
|
+
app.fetch('my_uid').process(:flip).url # "/BAhbBlsH..."
|
9
|
+
app.generate(:text, 'hello').thumb('500x302').gif.url # "/BAhbCFsHOgZ..."
|
10
|
+
|
11
|
+
Path prefix
|
12
|
+
-----------
|
13
|
+
If the app is mounted with a path prefix (such as when using in Rails), then we need to add this prefix
|
14
|
+
to the urls:
|
15
|
+
|
16
|
+
app.url_path_prefix = '/media'
|
17
|
+
|
18
|
+
(or done in a configuration block).
|
19
|
+
|
20
|
+
app.fetch('my_uid').url # "/media/BAhbBlsH..."
|
21
|
+
|
22
|
+
This is done for you when using {file:Configuration Rails defaults}.
|
23
|
+
|
24
|
+
You can override it using
|
25
|
+
|
26
|
+
app.fetch('my_uid').url(:path_prefix => '/images') # "/images/BAhbBlsH..."
|
27
|
+
|
28
|
+
Host
|
29
|
+
----
|
30
|
+
You can also set a host for the urls
|
31
|
+
|
32
|
+
app.url_host = 'http://some.host'
|
33
|
+
app.fetch('my_uid').url # "http://some.host/BAhb..."
|
34
|
+
|
35
|
+
app.fetch('my_uid').url(:host => 'http://localhost:80') # "http://localhost:80/BAh..."
|
36
|
+
|
37
|
+
Routed Endpoints
|
38
|
+
----------------
|
39
|
+
You can also use a number of Rack-based routers and create Dragonfly endpoints.
|
40
|
+
|
41
|
+
If we have an app set up for using RMagick:
|
42
|
+
|
43
|
+
app = Dragonfly[:images].configure_with(:rmagick)
|
44
|
+
|
45
|
+
Then to get the url '/text/hello' to display the text "hello"...
|
46
|
+
|
47
|
+
Rails 3 (routes.rb):
|
48
|
+
|
49
|
+
match '/text/:text' => app.endpoint{|params, app|
|
50
|
+
app.generate(:text, params[:text])
|
51
|
+
}
|
52
|
+
|
53
|
+
{http://github.com/josh/rack-mount Rack-Mount}:
|
54
|
+
|
55
|
+
Routes = Rack::Mount::RouteSet.new do |set|
|
56
|
+
|
57
|
+
set.add_route app.endpoint{|params, a| a.generate(:text, params[:text]) },
|
58
|
+
:path_info => %r{/text/(?:<text>.+)}
|
59
|
+
|
60
|
+
# ...
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
{http://github.com/joshbuddy/usher Usher}:
|
65
|
+
|
66
|
+
routes = Usher::Interface.for(:rack) do
|
67
|
+
add('/text/:text').to app.endpoint{|params, app|
|
68
|
+
app.generate(:text, params[:text])
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
{http://github.com/joshbuddy/http_router HTTP Router}:
|
73
|
+
|
74
|
+
r = HttpRouter.new
|
75
|
+
r.add('/text/:text').to app.endpoint{|params, app|
|
76
|
+
app.generate(:text, params[:text])
|
77
|
+
}
|
78
|
+
|
79
|
+
In each case the url will need to be generated by the router of choice, or manually.
|
80
|
+
|
81
|
+
Simple Endpoints
|
82
|
+
----------------
|
83
|
+
{Dragonfly::Job Job} objects can also be turned straight into Rack endpoints using `to_app`, e.g. in Rails 3:
|
84
|
+
|
85
|
+
match '/beach' => app.fetch_file('~/some/image.png').thumb('100x100#').jpg.to_app
|
86
|
+
|
87
|
+
|
88
|
+
Denial-of-service attacks
|
89
|
+
-------------------------
|
90
|
+
Although the standard urls are fairly cryptic, a malicious person who knows the Dragonfly source code could potentially
|
91
|
+
work out how to generate urls to spam your server with heavy requests, e.g. resize to 100000 by 100000 pixels.
|
92
|
+
|
93
|
+
Therefore the app can be protected by requiring the presence of a "DOS-protection" SHA in the urls:
|
94
|
+
|
95
|
+
app.configure do |c|
|
96
|
+
c.protect_from_dos_attacks = true
|
97
|
+
c.secret = 'You should supply some random secret here'
|
98
|
+
end
|
99
|
+
|
100
|
+
Then the standard generated urls will have a SHA query parameter attached:
|
101
|
+
|
102
|
+
app.fetch('my_uid').url # "/BAhbBlsHOgZmIghzZGY?s=df76ba27"
|
103
|
+
|
104
|
+
Any requests without the correct SHA parameter result in a 400 (bad parameters) error response.
|
105
|
+
|
106
|
+
You can also validate for a correct SHA using routed endpoints:
|
107
|
+
|
108
|
+
match '/text/:text' => app.endpoint{|params, app|
|
109
|
+
app.generate(:text, params[:text]).validate_sha!(params[:sha])
|
110
|
+
}
|
111
|
+
|
112
|
+
... where obviously you need to pass in a 'sha' parameter to the url, which can be found using
|
113
|
+
|
114
|
+
app.generate(:text, 'some text').sha
|