oahu-dragonfly 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/.rspec +1 -0
  2. data/.yardopts +24 -0
  3. data/Gemfile +30 -0
  4. data/History.md +323 -0
  5. data/LICENSE +20 -0
  6. data/README.md +88 -0
  7. data/Rakefile +50 -0
  8. data/VERSION +1 -0
  9. data/config.ru +14 -0
  10. data/docs.watchr +1 -0
  11. data/dragonfly.gemspec +297 -0
  12. data/extra_docs/Analysers.md +66 -0
  13. data/extra_docs/Caching.md +23 -0
  14. data/extra_docs/Configuration.md +124 -0
  15. data/extra_docs/Couch.md +49 -0
  16. data/extra_docs/DataStorage.md +153 -0
  17. data/extra_docs/Encoding.md +67 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +60 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/ImageMagick.md +125 -0
  22. data/extra_docs/Index.md +33 -0
  23. data/extra_docs/MimeTypes.md +40 -0
  24. data/extra_docs/Models.md +272 -0
  25. data/extra_docs/Mongo.md +45 -0
  26. data/extra_docs/Processing.md +77 -0
  27. data/extra_docs/Rack.md +52 -0
  28. data/extra_docs/Rails2.md +57 -0
  29. data/extra_docs/Rails3.md +62 -0
  30. data/extra_docs/Sinatra.md +25 -0
  31. data/extra_docs/URLs.md +169 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_3.0.5.feature +8 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +28 -0
  38. data/features/support/env.rb +13 -0
  39. data/features/support/setup.rb +32 -0
  40. data/fixtures/rails_3.0.5/files/app/models/album.rb +7 -0
  41. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  42. data/fixtures/rails_3.0.5/files/app/views/albums/show.html.erb +6 -0
  43. data/fixtures/rails_3.0.5/files/config/initializers/dragonfly.rb +4 -0
  44. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  45. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  46. data/fixtures/rails_3.0.5/files/features/step_definitions/image_steps.rb +25 -0
  47. data/fixtures/rails_3.0.5/files/features/support/paths.rb +17 -0
  48. data/fixtures/rails_3.0.5/files/features/text_images.feature +7 -0
  49. data/fixtures/rails_3.0.5/template.rb +20 -0
  50. data/irbrc.rb +18 -0
  51. data/lib/dragonfly.rb +55 -0
  52. data/lib/dragonfly/active_model_extensions.rb +13 -0
  53. data/lib/dragonfly/active_model_extensions/attachment.rb +250 -0
  54. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +148 -0
  55. data/lib/dragonfly/active_model_extensions/class_methods.rb +95 -0
  56. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  57. data/lib/dragonfly/active_model_extensions/validations.rb +41 -0
  58. data/lib/dragonfly/analyser.rb +58 -0
  59. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  60. data/lib/dragonfly/analysis/image_magick_analyser.rb +6 -0
  61. data/lib/dragonfly/app.rb +172 -0
  62. data/lib/dragonfly/config/heroku.rb +19 -0
  63. data/lib/dragonfly/config/image_magick.rb +6 -0
  64. data/lib/dragonfly/config/rails.rb +20 -0
  65. data/lib/dragonfly/configurable.rb +207 -0
  66. data/lib/dragonfly/core_ext/array.rb +7 -0
  67. data/lib/dragonfly/core_ext/hash.rb +7 -0
  68. data/lib/dragonfly/core_ext/object.rb +12 -0
  69. data/lib/dragonfly/core_ext/string.rb +9 -0
  70. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  71. data/lib/dragonfly/data_storage.rb +9 -0
  72. data/lib/dragonfly/data_storage/couch_data_store.rb +64 -0
  73. data/lib/dragonfly/data_storage/file_data_store.rb +141 -0
  74. data/lib/dragonfly/data_storage/mongo_data_store.rb +86 -0
  75. data/lib/dragonfly/data_storage/s3data_store.rb +145 -0
  76. data/lib/dragonfly/encoder.rb +13 -0
  77. data/lib/dragonfly/encoding/image_magick_encoder.rb +6 -0
  78. data/lib/dragonfly/function_manager.rb +71 -0
  79. data/lib/dragonfly/generation/image_magick_generator.rb +6 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  82. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  83. data/lib/dragonfly/image_magick/config.rb +41 -0
  84. data/lib/dragonfly/image_magick/encoder.rb +57 -0
  85. data/lib/dragonfly/image_magick/generator.rb +145 -0
  86. data/lib/dragonfly/image_magick/processor.rb +99 -0
  87. data/lib/dragonfly/image_magick/utils.rb +72 -0
  88. data/lib/dragonfly/image_magick_utils.rb +4 -0
  89. data/lib/dragonfly/job.rb +451 -0
  90. data/lib/dragonfly/job_builder.rb +39 -0
  91. data/lib/dragonfly/job_definitions.rb +26 -0
  92. data/lib/dragonfly/job_endpoint.rb +15 -0
  93. data/lib/dragonfly/loggable.rb +28 -0
  94. data/lib/dragonfly/middleware.rb +20 -0
  95. data/lib/dragonfly/processing/image_magick_processor.rb +6 -0
  96. data/lib/dragonfly/processor.rb +9 -0
  97. data/lib/dragonfly/rails/images.rb +27 -0
  98. data/lib/dragonfly/response.rb +97 -0
  99. data/lib/dragonfly/routed_endpoint.rb +40 -0
  100. data/lib/dragonfly/serializer.rb +32 -0
  101. data/lib/dragonfly/server.rb +113 -0
  102. data/lib/dragonfly/simple_cache.rb +23 -0
  103. data/lib/dragonfly/temp_object.rb +175 -0
  104. data/lib/dragonfly/url_mapper.rb +78 -0
  105. data/samples/beach.png +0 -0
  106. data/samples/egg.png +0 -0
  107. data/samples/round.gif +0 -0
  108. data/samples/sample.docx +0 -0
  109. data/samples/taj.jpg +0 -0
  110. data/spec/dragonfly/active_model_extensions/model_spec.rb +1426 -0
  111. data/spec/dragonfly/active_model_extensions/spec_helper.rb +91 -0
  112. data/spec/dragonfly/analyser_spec.rb +123 -0
  113. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +48 -0
  114. data/spec/dragonfly/app_spec.rb +135 -0
  115. data/spec/dragonfly/configurable_spec.rb +461 -0
  116. data/spec/dragonfly/core_ext/array_spec.rb +19 -0
  117. data/spec/dragonfly/core_ext/hash_spec.rb +19 -0
  118. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  119. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  120. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +76 -0
  121. data/spec/dragonfly/data_storage/file_data_store_spec.rb +296 -0
  122. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +57 -0
  123. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +258 -0
  124. data/spec/dragonfly/data_storage/shared_data_store_examples.rb +77 -0
  125. data/spec/dragonfly/function_manager_spec.rb +154 -0
  126. data/spec/dragonfly/hash_with_css_style_keys_spec.rb +24 -0
  127. data/spec/dragonfly/image_magick/analyser_spec.rb +64 -0
  128. data/spec/dragonfly/image_magick/encoder_spec.rb +41 -0
  129. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  130. data/spec/dragonfly/image_magick/processor_spec.rb +233 -0
  131. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +173 -0
  135. data/spec/dragonfly/job_spec.rb +1046 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +47 -0
  138. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  139. data/spec/dragonfly/serializer_spec.rb +61 -0
  140. data/spec/dragonfly/server_spec.rb +278 -0
  141. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  142. data/spec/dragonfly/temp_object_spec.rb +306 -0
  143. data/spec/dragonfly/url_mapper_spec.rb +126 -0
  144. data/spec/functional/deprecations_spec.rb +51 -0
  145. data/spec/functional/image_magick_app_spec.rb +27 -0
  146. data/spec/functional/model_urls_spec.rb +85 -0
  147. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  148. data/spec/functional/to_response_spec.rb +31 -0
  149. data/spec/spec_helper.rb +51 -0
  150. data/spec/support/argument_matchers.rb +19 -0
  151. data/spec/support/image_matchers.rb +47 -0
  152. data/spec/support/simple_matchers.rb +53 -0
  153. data/yard/handlers/configurable_attr_handler.rb +38 -0
  154. data/yard/setup.rb +15 -0
  155. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  156. data/yard/templates/default/layout/html/layout.erb +89 -0
  157. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  158. data/yard/templates/default/module/setup.rb +17 -0
  159. metadata +544 -0
@@ -0,0 +1,45 @@
1
+ Mongo
2
+ =====
3
+ Dragonfly can be used with any ActiveModel-compatible model, therefore libraries like [Mongoid](http://mongoid.org) work out of the box.
4
+
5
+ Furthermore, Mongo DB has support for storing blob-like objects directly in the database (using MongoDB 'GridFS'),
6
+ so you can make use of this with the supplied {Dragonfly::DataStorage::MongoDataStore MongoDataStore}.
7
+
8
+ For more info about ActiveModel, see {file:Models}.
9
+
10
+ For more info about using the Mongo data store, see {file:DataStorage}.
11
+
12
+ Example setup in Rails, using Mongoid
13
+ -------------------------------------
14
+ In config/initializers/dragonfly.rb:
15
+
16
+ require 'dragonfly'
17
+
18
+ app = Dragonfly[:images]
19
+
20
+ # Get database name from config/mongoid.yml
21
+ db = YAML.load_file(Rails.root.join('config/mongoid.yml'))[Rails.env]['database']
22
+
23
+ # Configure to use ImageMagick, Rails defaults, and the Mongo data store
24
+ app.configure_with(:imagemagick)
25
+ app.configure_with(:rails) do |c|
26
+ c.datastore = Dragonfly::DataStorage::MongoDataStore.new :database => db
27
+ end
28
+
29
+ # Allow all mongoid models to use the macro 'image_accessor'
30
+ app.define_macro_on_include(Mongoid::Document, :image_accessor)
31
+
32
+ # ... any other setup, see Rails docs
33
+
34
+ Then in models:
35
+
36
+ class Album
37
+ include Mongoid::Document
38
+
39
+ field :cover_image_uid
40
+ image_accessor :cover_image
41
+
42
+ # ...
43
+ end
44
+
45
+ See {file:Models} for more info.
@@ -0,0 +1,77 @@
1
+ Processing
2
+ ==========
3
+ Registered processors allow you to modify data, e.g. resizing an image.
4
+
5
+ You can register as many processors as you like.
6
+
7
+ Let's say we have a Dragonfly app
8
+
9
+ app = Dragonfly[:images]
10
+
11
+ and an image object (actually a {Dragonfly::Job Job} object)...
12
+
13
+ image = app.fetch('some/uid')
14
+
15
+ ...OR a Dragonfly model accessor...
16
+
17
+ image = @album.cover_image
18
+
19
+ We can process it using any processing methods that have been registered with the processor.
20
+
21
+ Lazy evaluation
22
+ ---------------
23
+
24
+ new_image = image.process(:some_method)
25
+
26
+ doesn't actually do anything until you call something on the returned {Dragonfly::Job Job} object, like `url`, `data`, etc.
27
+
28
+ Bang method
29
+ -----------
30
+
31
+ image.process!(:some_method)
32
+
33
+ modifies the image object itself, rather than returning a new object.
34
+
35
+ ImageMagick Processor
36
+ ---------------------
37
+ See {file:ImageMagick}.
38
+
39
+ Custom Processors
40
+ -----------------
41
+
42
+ To register a single custom processor:
43
+
44
+ app.processor.add :watermark do |temp_object, *args|
45
+ # use temp_object.data, temp_object.path, temp_object.file, etc.
46
+ SomeLibrary.add_watermark(temp_object.data, 'some/watermark/file.png')
47
+ # return a String, Pathname, File or Tempfile
48
+ end
49
+
50
+ new_image = image.process(:watermark)
51
+
52
+ You can create a class like the ImageMagick one above, in which case all public methods will be counted as processing methods.
53
+ Each method takes the temp_object as its argument, plus any other args.
54
+
55
+ class MyProcessor
56
+
57
+ def coolify(temp_object, opts={})
58
+ SomeLib.coolify(temp_object.data, opts)
59
+ end
60
+
61
+ def uglify(temp_object, ugliness)
62
+ `uglify -i #{temp_object.path} -u #{ugliness}`
63
+ end
64
+
65
+ private
66
+
67
+ def my_helper_method
68
+ # do stuff
69
+ end
70
+
71
+ end
72
+
73
+ app.processor.register(MyProcessor)
74
+
75
+ new_image = image.coolify(:some => :args)
76
+
77
+ new_image = image.uglify(:loads)
@@ -0,0 +1,52 @@
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].configure_with(:imagemagick)
32
+
33
+ run app
34
+
35
+ This enables the app to use all the ImageMagick goodies provided by Dragonfly (see {file:Configuration}).
36
+ By default the {Dragonfly::DataStorage::FileDataStore file data store} is used.
37
+
38
+ In the console:
39
+
40
+ app = Dragonfly[:images]
41
+
42
+ # Store
43
+ uid = app.store(File.new('path/to/image.png')) # ===> unique uid
44
+
45
+ # Get the url for a thumbnail
46
+ url = app.fetch(uid).thumb('400x300').url # ===> "/media/BAhbBlsHOgZmIg9hc..."
47
+
48
+ Now when we visit the url `/media/BAhbBlsHOgZmIg9hc...` in the browser, we get a resized image!
49
+
50
+ Mounting in Rack
51
+ ----------------
52
+ See {file:URLs}
@@ -0,0 +1,57 @@
1
+ Using With Rails 2.3
2
+ ====================
3
+
4
+ **NOTE: RAILS 2.3 IS NOT SUPPORTED IN NEW VERSIONS OF DRAGONFLY SO PLEASE USE VERSION 0.8.2**
5
+
6
+ Setting up the quick way
7
+ ------------------------
8
+ config/initializers/dragonfly.rb:
9
+
10
+ require 'dragonfly/rails/images'
11
+
12
+ Setting up the more explicit way
13
+ --------------------------------
14
+ You can do the above explicitly.
15
+
16
+ config/initializers/dragonfly.rb:
17
+
18
+ require 'dragonfly'
19
+
20
+ app = Dragonfly[:images]
21
+ app.configure_with(:imagemagick)
22
+ app.configure_with(:rails)
23
+
24
+ app.define_macro(ActiveRecord::Base, :image_accessor)
25
+
26
+ environment.rb:
27
+
28
+ config.middleware.insert_after 'Rack::Lock', 'Dragonfly::Middleware', :images, '/media'
29
+ config.middleware.insert_before 'Dragonfly::Middleware', 'Rack::Cache', {
30
+ :verbose => true,
31
+ :metastore => "file:#{Rails.root}/tmp/dragonfly/cache/meta",
32
+ :entitystore => "file:#{Rails.root}/tmp/dragonfly/cache/body"
33
+ }
34
+
35
+ Gems
36
+ ----
37
+ environment.rb
38
+
39
+ config.gem 'dragonfly', '0.8.2'
40
+ config.gem 'rack-cache', :lib => 'rack/cache'
41
+
42
+ Capistrano
43
+ ----------
44
+ If using Capistrano with the above, you probably will want to keep the cache between deploys, so in deploy.rb:
45
+
46
+ namespace :dragonfly do
47
+ desc "Symlink the Rack::Cache files"
48
+ task :symlink, :roles => [:app] do
49
+ run "mkdir -p #{shared_path}/tmp/dragonfly && ln -nfs #{shared_path}/tmp/dragonfly #{release_path}/tmp/dragonfly"
50
+ end
51
+ end
52
+ after 'deploy:update_code', 'dragonfly:symlink'
53
+
54
+ Use it!
55
+ -------
56
+
57
+ To see what you can do with the model accessors, see {file:Models}.
@@ -0,0 +1,62 @@
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(:imagemagick)
20
+ app.configure_with(:rails)
21
+
22
+ app.define_macro(ActiveRecord::Base, :image_accessor)
23
+
24
+ application.rb:
25
+
26
+ config.middleware.insert_after 'Rack::Lock', 'Dragonfly::Middleware', :images
27
+ config.middleware.insert_before 'Dragonfly::Middleware', '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.8.2'
37
+ gem 'rack-cache', :require => 'rack/cache'
38
+
39
+ Capistrano
40
+ ----------
41
+ If using Capistrano with the above, you probably will want to keep the cache between deploys, so in deploy.rb:
42
+
43
+ namespace :dragonfly do
44
+ desc "Symlink the Rack::Cache files"
45
+ task :symlink, :roles => [:app] do
46
+ run "mkdir -p #{shared_path}/tmp/dragonfly && ln -nfs #{shared_path}/tmp/dragonfly #{release_path}/tmp/dragonfly"
47
+ end
48
+ end
49
+ after 'deploy:update_code', 'dragonfly:symlink'
50
+
51
+ Use it!
52
+ -------
53
+
54
+ To see what you can do with the model accessors, see {file:Models}.
55
+
56
+ Mounting in routes.rb
57
+ ---------------------
58
+ Instead of mounting as a middleware, you could skip that bit and mount directly in the routes.rb file:
59
+
60
+ match '/media/*:dragonfly', :to => Dragonfly[:images]
61
+
62
+ 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,25 @@
1
+ Sinatra
2
+ =======
3
+ You can use {Dragonfly::Job Job}'s `to_response` method like so:
4
+
5
+ app = Dragonfly[:images].configure_with(:imagemagick)
6
+
7
+ get '/images/:size.:format' do |size, format|
8
+ app.fetch_file('~/some/image.png').thumb(size).encode(format).to_response(env)
9
+ end
10
+
11
+ `to_response` returns a rack-style response array with status, headers and body.
12
+
13
+ NOTE: uids from the datastore currently have slashes and dots in them so may cause problems when using ':uid' as
14
+ a path segment.
15
+
16
+ or you can mount as a middleware, like in rails:
17
+
18
+ Dragonfly[:images].configure_with(:imagemagick) do |c|
19
+ c.url_path_prefix = '/media'
20
+ end
21
+
22
+ use Dragonfly::Middleware, :images
23
+
24
+ get '/' #... do
25
+ # ...
@@ -0,0 +1,169 @@
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
+ Suffix
38
+ ------
39
+ You can set a suffix for the urls (for example if some other component behaves badly with urls that have no file extension).
40
+
41
+ Note that this has no effect on the response.
42
+
43
+ app.url_suffix = '.jpg'
44
+ app.fetch('some/uid').url # "...b21lL3VpZA.jpg"
45
+
46
+ You can also pass it a block, that yields the {Dragonfly::Job Job}, for example:
47
+
48
+ app.url_suffix = proc{|job|
49
+ "/#{job.uid_basename}#{job.encoded_extname || job.uid_extname}"
50
+ }
51
+
52
+ app.fetch('2007/painting.pdf').url # "...eS5ib2R5/painting.pdf"
53
+ app.fetch('2007/painting.pdf').encode(:png).url # "...gZlOgbmc/painting.png"
54
+
55
+ And you can override it:
56
+
57
+ app.fetch('some/uid').url(:suffix => '/yellowbelly') # "...b21lL3VpZA/yellowbelly"
58
+
59
+ Content-Disposition
60
+ -------------------
61
+ You can manually set the content-disposition of the response:
62
+
63
+ app.content_disposition = :attachment # should be :inline or :attachment (or :hidden)
64
+
65
+ `:attachment` tells the browser to download it, `:inline` tells it to display in-browser if possible.
66
+
67
+ You can also use a block:
68
+
69
+ app.content_disposition = proc{|job, request|
70
+ if job.format == :jpg || request['d'] == 'inline' # request is a Rack::Request object
71
+ :inline
72
+ else
73
+ :attachment
74
+ end
75
+ }
76
+
77
+ Downloaded filename
78
+ -------------------
79
+ To specify the filename the browser uses for 'Save As' dialogues:
80
+
81
+ app.content_filename = proc{|job, request|
82
+ "#{job.basename}_#{job.process_steps.first.name}.#{job.encoded_format || job.ext}"
83
+ }
84
+
85
+ This will for example give the following filenames for the following jobs:
86
+
87
+ app.fetch('some/tree.png').process(:greyscale) # -> 'tree_greyscale.png'
88
+ app.fetch('some/tree.png').process(:greyscale).gif # -> 'tree_greyscale.gif'
89
+
90
+ By default the original filename is used, with a modified extension if it's been encoded.
91
+
92
+ Routed Endpoints
93
+ ----------------
94
+ You can also use a number of Rack-based routers and create Dragonfly endpoints.
95
+
96
+ If we have an app set up for using ImageMagick:
97
+
98
+ app = Dragonfly[:images].configure_with(:imagemagick)
99
+
100
+ Then to get the url '/text/hello' to display the text "hello"...
101
+
102
+ Rails 3 (routes.rb):
103
+
104
+ match '/text/:text' => app.endpoint{|params, app|
105
+ app.generate(:text, params[:text])
106
+ }
107
+
108
+ {http://github.com/josh/rack-mount Rack-Mount}:
109
+
110
+ Routes = Rack::Mount::RouteSet.new do |set|
111
+
112
+ set.add_route app.endpoint{|params, a| a.generate(:text, params[:text]) },
113
+ :path_info => %r{/text/(?:<text>.+)}
114
+
115
+ # ...
116
+
117
+ end
118
+
119
+ {http://github.com/joshbuddy/usher Usher}:
120
+
121
+ routes = Usher::Interface.for(:rack) do
122
+ add('/text/:text').to app.endpoint{|params, app|
123
+ app.generate(:text, params[:text])
124
+ }
125
+ end
126
+
127
+ {http://github.com/joshbuddy/http_router HTTP Router}:
128
+
129
+ r = HttpRouter.new
130
+ r.add('/text/:text').to app.endpoint{|params, app|
131
+ app.generate(:text, params[:text])
132
+ }
133
+
134
+ In each case the url will need to be generated by the router of choice, or manually.
135
+
136
+ Simple Endpoints
137
+ ----------------
138
+ {Dragonfly::Job Job} objects can also be turned straight into Rack endpoints using `to_app`, e.g. in Rails 3:
139
+
140
+ match '/beach' => app.fetch_file('~/some/image.png').thumb('100x100#').jpg.to_app
141
+
142
+
143
+ Denial-of-service attacks
144
+ -------------------------
145
+ Although the standard urls are fairly cryptic, a malicious person who knows the Dragonfly source code could potentially
146
+ work out how to generate urls to spam your server with heavy requests, e.g. resize to 100000 by 100000 pixels.
147
+
148
+ Therefore the app can be protected by requiring the presence of a "DOS-protection" SHA in the urls:
149
+
150
+ app.configure do |c|
151
+ c.protect_from_dos_attacks = true
152
+ c.secret = 'You should supply some random secret here'
153
+ end
154
+
155
+ Then the standard generated urls will have a SHA query parameter attached:
156
+
157
+ app.fetch('my_uid').url # "/BAhbBlsHOgZmIghzZGY?s=df76ba27"
158
+
159
+ Any requests without the correct SHA parameter result in a 400 (bad parameters) error response.
160
+
161
+ You can also validate for a correct SHA using routed endpoints:
162
+
163
+ match '/text/:text' => app.endpoint{|params, app|
164
+ app.generate(:text, params[:text]).validate_sha!(params[:sha])
165
+ }
166
+
167
+ ... where obviously you need to pass in a 'sha' parameter to the url, which can be found using
168
+
169
+ app.generate(:text, 'some text').sha