dragonfly 0.8.6 → 0.9.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.

Files changed (155) hide show
  1. data/{.specopts → .rspec} +0 -1
  2. data/.yardopts +6 -2
  3. data/Gemfile +14 -13
  4. data/History.md +47 -9
  5. data/README.md +25 -5
  6. data/Rakefile +37 -79
  7. data/VERSION +1 -1
  8. data/dragonfly.gemspec +140 -89
  9. data/extra_docs/Analysers.md +8 -48
  10. data/extra_docs/Configuration.md +40 -25
  11. data/extra_docs/Couch.md +49 -0
  12. data/extra_docs/DataStorage.md +94 -24
  13. data/extra_docs/Encoding.md +6 -35
  14. data/extra_docs/ExampleUseCases.md +113 -0
  15. data/extra_docs/GeneralUsage.md +7 -23
  16. data/extra_docs/Generators.md +15 -49
  17. data/extra_docs/Heroku.md +7 -8
  18. data/extra_docs/ImageMagick.md +126 -0
  19. data/extra_docs/MimeTypes.md +3 -3
  20. data/extra_docs/Models.md +163 -0
  21. data/extra_docs/Mongo.md +1 -4
  22. data/extra_docs/Processing.md +7 -60
  23. data/extra_docs/Rails2.md +3 -1
  24. data/extra_docs/Rails3.md +2 -10
  25. data/extra_docs/ServingRemotely.md +83 -0
  26. data/extra_docs/Sinatra.md +3 -3
  27. data/extra_docs/URLs.md +60 -33
  28. data/features/rails_3.0.5.feature +8 -0
  29. data/features/steps/rails_steps.rb +7 -18
  30. data/features/support/env.rb +10 -37
  31. data/features/support/setup.rb +32 -0
  32. data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
  33. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  34. data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
  35. data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
  36. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  37. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  38. data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
  39. data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
  40. data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
  41. data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
  42. data/irbrc.rb +2 -1
  43. data/lib/dragonfly.rb +7 -0
  44. data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
  45. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
  46. data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
  47. data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
  48. data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
  49. data/lib/dragonfly/analyser.rb +0 -1
  50. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  51. data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
  52. data/lib/dragonfly/app.rb +64 -55
  53. data/lib/dragonfly/config/heroku.rb +1 -1
  54. data/lib/dragonfly/config/image_magick.rb +2 -37
  55. data/lib/dragonfly/config/rails.rb +5 -2
  56. data/lib/dragonfly/configurable.rb +115 -35
  57. data/lib/dragonfly/core_ext/object.rb +1 -1
  58. data/lib/dragonfly/core_ext/string.rb +1 -1
  59. data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
  60. data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
  61. data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
  62. data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
  63. data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
  64. data/lib/dragonfly/function_manager.rb +4 -2
  65. data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
  66. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  67. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  68. data/lib/dragonfly/image_magick/config.rb +44 -0
  69. data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
  70. data/lib/dragonfly/image_magick/generator.rb +145 -0
  71. data/lib/dragonfly/image_magick/processor.rb +104 -0
  72. data/lib/dragonfly/image_magick/utils.rb +72 -0
  73. data/lib/dragonfly/image_magick_utils.rb +2 -79
  74. data/lib/dragonfly/job.rb +152 -90
  75. data/lib/dragonfly/middleware.rb +5 -19
  76. data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
  77. data/lib/dragonfly/rails/images.rb +15 -10
  78. data/lib/dragonfly/response.rb +26 -12
  79. data/lib/dragonfly/serializer.rb +1 -4
  80. data/lib/dragonfly/server.rb +103 -0
  81. data/lib/dragonfly/temp_object.rb +56 -101
  82. data/lib/dragonfly/url_mapper.rb +78 -0
  83. data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
  84. data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
  85. data/spec/dragonfly/analyser_spec.rb +1 -1
  86. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
  87. data/spec/dragonfly/app_spec.rb +35 -180
  88. data/spec/dragonfly/configurable_spec.rb +259 -18
  89. data/spec/dragonfly/core_ext/string_spec.rb +2 -2
  90. data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
  91. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
  92. data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
  93. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
  94. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
  95. data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
  96. data/spec/dragonfly/function_manager_spec.rb +2 -2
  97. data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
  98. data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
  99. data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
  100. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  101. data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
  102. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  103. data/spec/dragonfly/job_builder_spec.rb +1 -1
  104. data/spec/dragonfly/job_definitions_spec.rb +1 -1
  105. data/spec/dragonfly/job_endpoint_spec.rb +26 -3
  106. data/spec/dragonfly/job_spec.rb +426 -208
  107. data/spec/dragonfly/loggable_spec.rb +2 -2
  108. data/spec/dragonfly/middleware_spec.rb +5 -26
  109. data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
  110. data/spec/dragonfly/serializer_spec.rb +1 -14
  111. data/spec/dragonfly/server_spec.rb +261 -0
  112. data/spec/dragonfly/simple_cache_spec.rb +1 -1
  113. data/spec/dragonfly/temp_object_spec.rb +84 -130
  114. data/spec/dragonfly/url_mapper_spec.rb +130 -0
  115. data/spec/functional/deprecations_spec.rb +51 -0
  116. data/spec/functional/image_magick_app_spec.rb +27 -0
  117. data/spec/functional/model_urls_spec.rb +85 -0
  118. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  119. data/spec/functional/to_response_spec.rb +31 -0
  120. data/spec/spec_helper.rb +12 -22
  121. data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
  122. data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
  123. data/spec/support/simple_matchers.rb +53 -0
  124. data/yard/handlers/configurable_attr_handler.rb +2 -2
  125. data/yard/templates/default/fulldoc/html/css/common.css +12 -10
  126. data/yard/templates/default/layout/html/layout.erb +6 -0
  127. metadata +267 -308
  128. data/Gemfile.rails.2.3.5 +0 -20
  129. data/features/3.0.3.feature +0 -8
  130. data/features/rails_2.3.5.feature +0 -7
  131. data/fixtures/files/app/models/album.rb +0 -3
  132. data/fixtures/files/app/views/albums/new.html.erb +0 -4
  133. data/fixtures/files/features/manage_album_images.feature +0 -12
  134. data/fixtures/rails_2.3.5/template.rb +0 -10
  135. data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
  136. data/lib/dragonfly/config/r_magick.rb +0 -46
  137. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
  138. data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
  139. data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
  140. data/lib/dragonfly/r_magick_utils.rb +0 -48
  141. data/lib/dragonfly/simple_endpoint.rb +0 -76
  142. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
  143. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
  144. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
  145. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
  146. data/spec/dragonfly/config/r_magick_spec.rb +0 -29
  147. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
  148. data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
  149. data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
  150. data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
  151. data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
  152. data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
  153. data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
  154. data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
  155. data/spec/simple_matchers.rb +0 -44
@@ -17,13 +17,10 @@ In config/initializers/dragonfly.rb:
17
17
 
18
18
  app = Dragonfly[:images]
19
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
20
  # Configure to use ImageMagick, Rails defaults, and the Mongo data store
24
21
  app.configure_with(:imagemagick)
25
22
  app.configure_with(:rails) do |c|
26
- c.datastore = Dragonfly::DataStorage::MongoDataStore.new :database => db
23
+ c.datastore = Dragonfly::DataStorage::MongoDataStore.new :db => Mongoid.database
27
24
  end
28
25
 
29
26
  # Allow all mongoid models to use the macro 'image_accessor'
@@ -1,7 +1,6 @@
1
1
  Processing
2
2
  ==========
3
-
4
- Changing data in some way, e.g. resizing an image, comes under the banner of Processing.
3
+ Registered processors allow you to modify data, e.g. resizing an image.
5
4
 
6
5
  You can register as many processors as you like.
7
6
 
@@ -19,62 +18,6 @@ and an image object (actually a {Dragonfly::Job Job} object)...
19
18
 
20
19
  We can process it using any processing methods that have been registered with the processor.
21
20
 
22
- ImageMagickProcessor
23
- --------------------
24
- The {Dragonfly::Processing::ImageMagickProcessor ImageMagickProcessor} is registered by default by
25
- the {Dragonfly::Config::ImageMagick ImageMagick configuration} used by 'dragonfly/rails/images'.
26
-
27
- If not already registered:
28
-
29
- app.processor.register(Dragonfly::Processing::ImageMagickProcessor)
30
-
31
- gives us these methods:
32
-
33
- image.process(:thumb, '400x300#') # see below
34
-
35
- image.process(:crop, :width => 40, :height => 50, :x => 20, :y => 30)
36
- image.process(:crop, :width => 40, :height => 50, :gravity => 'ne')
37
-
38
- image.process(:flip) # flips it vertically
39
- image.process(:flop) # flips it horizontally
40
-
41
- image.process(:greyscale, :depth => 128) # default depth 256
42
-
43
- image.process(:resize, '40x40')
44
- image.process(:resize_and_crop, :width => 40, :height=> 50, :gravity => 'ne')
45
-
46
- image.process(:rotate, 45, :background_colour => 'transparent') # default bg black
47
-
48
- The method `thumb` takes a geometry string and calls `resize`, `resize_and_crop` or `crop` accordingly.
49
-
50
- image.process(:thumb, '400x300') # calls resize
51
-
52
- Below are some examples of geometry strings:
53
-
54
- '400x300' # resize, maintain aspect ratio
55
- '400x300!' # force resize, don't maintain aspect ratio
56
- '400x' # resize width, maintain aspect ratio
57
- 'x300' # resize height, maintain aspect ratio
58
- '400x300>' # resize only if the image is larger than this
59
- '400x300<' # resize only if the image is smaller than this
60
- '50x50%' # resize width and height to 50%
61
- '400x300^' # resize width, height to minimum 400,300, maintain aspect ratio
62
- '2000@' # resize so max area in pixels is 2000
63
- '400x300#' # resize, crop if necessary to maintain aspect ratio (centre gravity)
64
- '400x300#ne' # as above, north-east gravity
65
- '400x300se' # crop, with south-east gravity
66
- '400x300+50+100' # crop from the point 50,100 with width, height 400,300
67
-
68
- RMagickProcessor
69
- ----------------
70
- The {Dragonfly::Processing::RMagickProcessor RMagickProcessor} uses the {http://rmagick.rubyforge.org RMagick} library and provides the methods
71
- `thumb`, `crop`, `flip`, `flop`, `greyscale`, `resize`, `resize_and_crop` and `rotate` like the ImageMagickProcessor above.
72
-
73
- You can tell it not to use the file system when registering it
74
-
75
- app.processor.register(Dragonfly::Processing::RMagickProcessor){|p| p.use_filesystem = false }
76
-
77
-
78
21
  Lazy evaluation
79
22
  ---------------
80
23
 
@@ -89,6 +32,10 @@ Bang method
89
32
 
90
33
  modifies the image object itself, rather than returning a new object.
91
34
 
35
+ ImageMagick Processor
36
+ ---------------------
37
+ See {file:ImageMagick}.
38
+
92
39
  Custom Processors
93
40
  -----------------
94
41
 
@@ -97,12 +44,12 @@ To register a single custom processor:
97
44
  app.processor.add :watermark do |temp_object, *args|
98
45
  # use temp_object.data, temp_object.path, temp_object.file, etc.
99
46
  SomeLibrary.add_watermark(temp_object.data, 'some/watermark/file.png')
100
- # return a String, File or Tempfile
47
+ # return a String, Pathname, File or Tempfile
101
48
  end
102
49
 
103
50
  new_image = image.process(:watermark)
104
51
 
105
- You can create a class like the RMagick one above, in which case all public methods will be counted as processing methods.
52
+ You can create a class like the ImageMagick one above, in which case all public methods will be counted as processing methods.
106
53
  Each method takes the temp_object as its argument, plus any other args.
107
54
 
108
55
  class MyProcessor
@@ -1,6 +1,8 @@
1
1
  Using With Rails 2.3
2
2
  ====================
3
3
 
4
+ **NOTE: RAILS 2.3 IS NOT SUPPORTED IN NEW VERSIONS OF DRAGONFLY SO PLEASE USE VERSION 0.8.4**
5
+
4
6
  Setting up the quick way
5
7
  ------------------------
6
8
  config/initializers/dragonfly.rb:
@@ -34,7 +36,7 @@ Gems
34
36
  ----
35
37
  environment.rb
36
38
 
37
- config.gem 'dragonfly', '~>0.8.6'
39
+ config.gem 'dragonfly', '0.8.4'
38
40
  config.gem 'rack-cache', :lib => 'rack/cache'
39
41
 
40
42
  Capistrano
@@ -23,7 +23,7 @@ config/initializers/dragonfly.rb:
23
23
 
24
24
  application.rb:
25
25
 
26
- config.middleware.insert_after 'Rack::Lock', 'Dragonfly::Middleware', :images, '/media'
26
+ config.middleware.insert 0, 'Dragonfly::Middleware', :images
27
27
  config.middleware.insert_before 'Dragonfly::Middleware', 'Rack::Cache', {
28
28
  :verbose => true,
29
29
  :metastore => "file:#{Rails.root}/tmp/dragonfly/cache/meta",
@@ -33,7 +33,7 @@ application.rb:
33
33
  Gemfile
34
34
  -------
35
35
 
36
- gem 'dragonfly', '~>0.8.6'
36
+ gem 'dragonfly', '~>0.9.0'
37
37
  gem 'rack-cache', :require => 'rack/cache'
38
38
 
39
39
  Capistrano
@@ -52,11 +52,3 @@ Use it!
52
52
  -------
53
53
 
54
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,83 @@
1
+ Serving Content Remotely
2
+ ========================
3
+
4
+ Dragonfly stores original versions of content in a datastore which could be the {file:DataStorage#File\_datastore filesystem},
5
+ {file:DataStorage#S3\_datastore S3}, etc., but when it comes to serving it, or serving a processed version
6
+ (e.g. an image thumbnail), it fetches it and serves locally from the {Dragonfly::Server dragonfly server}.
7
+
8
+ For most cases, this is the way to go - you have control over it and you can {file:Caching cache it using HTTP caching}.
9
+
10
+ However, if for whatever reason you must serve content from the datastore directly, e.g. for lightening the load on your server, Dragonfly
11
+ provides a number of ways of doing this.
12
+
13
+ Serving Original Content
14
+ ------------------------
15
+ The {file:DataStorage#File\_datastore FileDataStore}, {file:DataStorage#S3\_datastore S3DataStore} and
16
+ {file:DataStorage#Couch\_datastore CouchDataStore} allow for serving data directly, so given a Dragonfly app
17
+
18
+ app = Dragonfly[:my_app]
19
+
20
+ and the uid for some stored content
21
+
22
+ uid = app.store(Pathname.new('some/file.jpg'))
23
+
24
+ we can get the remote url using
25
+
26
+ app.remote_url_for(uid) # e.g. http://my-bucket.s3.amazonaws.com/2011/04/01/03/03/05/243/file.jpg
27
+
28
+ or from a model attachment:
29
+
30
+ my_model.attachment.remote_url # http://my-bucket.s....
31
+
32
+ Serving Processed Content
33
+ -------------------------
34
+ Serving processed versions of content such as thumbnails remotely is a bit more tricky as we need to upload the thumbnail
35
+ to the datastore in the on-the-fly manner.
36
+
37
+ Dragonfly provides a way of doing this using `define_url` and `before_serve` methods.
38
+
39
+ The details of keeping track of/expiring these thumbnails is up to you.
40
+
41
+ Below is an example using an ActiveRecord 'Thumb' table to keep track of image thumbnails.
42
+ It has two string columns; 'job' and 'uid'.
43
+
44
+ app.configure do |c|
45
+
46
+ c.server.before_serve do |job, env|
47
+ # Before serving, the first time it is requested...
48
+ # store the thumbnail in the datastore
49
+ uid = job.store
50
+
51
+ # Keep track of its uid
52
+ Thumb.create!(
53
+ :uid => uid,
54
+ :job => job.serialize # 'BAhbBls...' - holds all the job info
55
+ ) # e.g. fetch 'some_uid' then resize to '40x40'
56
+ end
57
+
58
+ # Override the .url method...
59
+ c.define_url do |app, job, opts|
60
+ thumb = Thumb.find_by_job(job.serialize)
61
+ # If (fetch 'some_uid' then resize to '40x40') has been stored already..
62
+ if thumb
63
+ app.datastore.url_for(thumb.uid)
64
+ # ...otherwise serve from the Dragonfly server as per usual
65
+ else
66
+ app.server.url_for(job)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ This would give
73
+
74
+ app.fetch('some_uid').thumb('40x40').url # normal Dragonfly url e.g. /media/BAhbBls...
75
+
76
+ then from the second time onwards
77
+
78
+ app.fetch('some_uid').thumb('40x40').url # http://my-bucket.s3.amazonaws.com/2011...
79
+
80
+ The above is just an example - there are a number of things you could do with `before_serve` and `define_url` -
81
+ you could use e.g. Redis or some key-value store to keep track of thumbnails.
82
+ You'd also probably want a way of expiring the thumbnails or destroying them when the original is destroyed, but this
83
+ is left up to you as it's outside of the scope of Dragonfly.
@@ -10,16 +10,16 @@ You can use {Dragonfly::Job Job}'s `to_response` method like so:
10
10
 
11
11
  `to_response` returns a rack-style response array with status, headers and body.
12
12
 
13
- NOTE: uids from the datastore currently have slashes and dots in them so may cause problems when using ':uid' as
13
+ NOTE: uids from the datastore may have slashes and dots in them so make sure you escape url-escape them when using ':uid' as
14
14
  a path segment.
15
15
 
16
16
  or you can mount as a middleware, like in rails:
17
17
 
18
18
  Dragonfly[:images].configure_with(:imagemagick) do |c|
19
- c.url_path_prefix = '/media'
19
+ c.url_format = '/media/:job'
20
20
  end
21
21
 
22
- use Dragonfly::Middleware, :images, '/media'
22
+ use Dragonfly::Middleware, :images
23
23
 
24
24
  get '/' #... do
25
25
  # ...
@@ -8,53 +8,61 @@ We can get urls for any kind of job:
8
8
  app.fetch('my_uid').process(:flip).url # "/BAhbBlsH..."
9
9
  app.generate(:text, 'hello').thumb('500x302').gif.url # "/BAhbCFsHOgZ..."
10
10
 
11
- Path prefix
11
+ Path format
12
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:
13
+ The format of the standard urls can be configured using `url_format`:
15
14
 
16
- app.url_path_prefix = '/media'
15
+ app.configure do |c|
16
+ c.url_format = '/:job'
17
+ end
17
18
 
18
- (or done in a configuration block).
19
+ (or call `app.server.url_format=` directly).
19
20
 
20
- app.fetch('my_uid').url # "/media/BAhbBlsH..."
21
+ `url_format = '/:job/:basename.:format'`:
21
22
 
22
- This is done for you when using {file:Configuration Rails defaults}.
23
+ media = app.fetch('my_uid')
24
+ media.url # "/BAhbBlsHOgZmSSIJbWlsawY6BkVU"
25
+ media.name = 'milk.txt'
26
+ media.url # "/BAhbBlsHOgZmSSIJbWlsawY6BkVU/milk.txt"
27
+ media.encode(:pdf).url # "/BAhbB1sHOgZ...RbBzoGZToIcGRm/milk.pdf"
28
+ media.url(:format => 'bang') # "/BAhbBlsHOgZmSSIJbWlsawY6BkVU/milk.bang"
29
+ media.url(:some => 'thing') # "/BAhbBlsHOgZmSSIJbWlsawY6BkVU/milk.txt?some=thing"
23
30
 
24
- You can override it using
31
+ `url_format = '/some-prefix/:job'`:
25
32
 
26
- app.fetch('my_uid').url(:path_prefix => '/images') # "/images/BAhbBlsH..."
33
+ media = app.fetch('my_uid')
34
+ media.url # "/some-prefix/BAhbBlsHOgZmSSIJbWlsawY6BkVU"
27
35
 
28
- Host
29
- ----
30
- You can also set a host for the urls
36
+ `url_format = '/blah'`:
31
37
 
32
- app.url_host = 'http://some.host'
33
- app.fetch('my_uid').url # "http://some.host/BAhb..."
38
+ media = app.fetch('my_uid')
39
+ media.url # "/blah?job=BAhbBlsHOgZmSSIJbWlsawY6BkVU"
34
40
 
35
- app.fetch('my_uid').url(:host => 'http://localhost:80') # "http://localhost:80/BAh..."
41
+ When using {file:Models}, any {file:Models#_Magic__Attributes magic attributes} will be used in url generation, e.g.
36
42
 
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).
43
+ app.server.url_format = '/frogs/:job/:basename-:width.:format'
40
44
 
41
- Note that this has no effect on the response.
45
+ with
42
46
 
43
- app.url_suffix = '.jpg'
44
- app.fetch('some/uid').url # "...b21lL3VpZA.jpg"
47
+ class Frog
48
+ image_accessor :face # columns face_uid, face_name and face_width
49
+ end
45
50
 
46
- You can also pass it a block, that yields the {Dragonfly::Job Job}, for example:
51
+ gives
47
52
 
48
- app.url_suffix = proc{|job|
49
- "/#{job.uid_basename}#{job.encoded_extname || job.uid_extname}"
50
- }
53
+ frog = Frog.new :face => Pathname.new('froggie.jpg') # image with width 400
54
+
55
+ frog.face.url # "/frogs/BAhbBlsHOgZmSSIIc2RmBjoGRVQ/froggie-400.jpg"
51
56
 
52
- app.fetch('2007/painting.pdf').url # "...eS5ib2R5/painting.pdf"
53
- app.fetch('2007/painting.pdf').encode(:png).url # "...gZlOgbmc/painting.png"
57
+ Host
58
+ ----
59
+ You can also set a host for the urls
54
60
 
55
- And you can override it:
61
+ app.configure{|c| c.url_host = 'http://some.host' } # or directly on app.server
62
+
63
+ app.fetch('my_uid').url # "http://some.host/BAhb..."
56
64
 
57
- app.fetch('some/uid').url(:suffix => '/yellowbelly') # "...b21lL3VpZA/yellowbelly"
65
+ app.fetch('my_uid').url(:host => 'http://localhost:80') # "http://localhost:80/BAh..."
58
66
 
59
67
  Content-Disposition
60
68
  -------------------
@@ -79,7 +87,7 @@ Downloaded filename
79
87
  To specify the filename the browser uses for 'Save As' dialogues:
80
88
 
81
89
  app.content_filename = proc{|job, request|
82
- "#{job.basename}_#{job.process_steps.first.name}.#{job.encoded_format || job.ext}"
90
+ "#{job.basename}_#{job.process_steps.first.name}.#{job.format}"
83
91
  }
84
92
 
85
93
  This will for example give the following filenames for the following jobs:
@@ -101,7 +109,7 @@ Then to get the url '/text/hello' to display the text "hello"...
101
109
 
102
110
  Rails 3 (routes.rb):
103
111
 
104
- match '/text/:text' => app.endpoint{|params, app|
112
+ match '/text/:text' => app.endpoint { |params, app|
105
113
  app.generate(:text, params[:text])
106
114
  }
107
115
 
@@ -119,7 +127,7 @@ Rails 3 (routes.rb):
119
127
  {http://github.com/joshbuddy/usher Usher}:
120
128
 
121
129
  routes = Usher::Interface.for(:rack) do
122
- add('/text/:text').to app.endpoint{|params, app|
130
+ add('/text/:text').to app.endpoint { |params, app|
123
131
  app.generate(:text, params[:text])
124
132
  }
125
133
  end
@@ -127,7 +135,7 @@ Rails 3 (routes.rb):
127
135
  {http://github.com/joshbuddy/http_router HTTP Router}:
128
136
 
129
137
  r = HttpRouter.new
130
- r.add('/text/:text').to app.endpoint{|params, app|
138
+ r.add('/text/:text').to app.endpoint { |params, app|
131
139
  app.generate(:text, params[:text])
132
140
  }
133
141
 
@@ -167,3 +175,22 @@ You can also validate for a correct SHA using routed endpoints:
167
175
  ... where obviously you need to pass in a 'sha' parameter to the url, which can be found using
168
176
 
169
177
  app.generate(:text, 'some text').sha
178
+
179
+ Overriding responses
180
+ --------------------
181
+ You can override/add headers using `response_headers`:
182
+
183
+ app.configure do |c|
184
+ c.response_headers['X-Something'] = 'Custom header' # set directly..
185
+ c.response_headers['summink'] = proc{|job, request| # ...or via a callback
186
+ job.image? ? 'image yo' : 'not an image'
187
+ }
188
+ end
189
+
190
+ You can intercept the response from the dragonfly server by throwing `:halt` with a Rack response array from inside the `before_serve` callback:
191
+
192
+ app.configure do |c|
193
+ c.server.before_serve do |job, env|
194
+ throw :halt, [200, {'Content-type' => 'text/plain'}, ['hello']]
195
+ end
196
+ end
@@ -0,0 +1,8 @@
1
+ Feature: champion uses dragonfly in his Rails 3.0.5 application
2
+ In order to be a champion
3
+ A user uses dragonfly in his Rails 3.0.5 application
4
+
5
+ Scenario: Set up dragonfly using initializer
6
+ Given a Rails 3.0.5 application set up for using dragonfly
7
+ Then the manage_album_images cucumber features in my Rails 3.0.5 app should pass
8
+ And the text_images cucumber features in my Rails 3.0.5 app should pass
@@ -1,9 +1,5 @@
1
1
  RAILS_APP_NAME = 'tmp_app'
2
2
  FIXTURES_PATH = ROOT_PATH + "/fixtures"
3
- GEMFILES = {
4
- '2.3.5' => ROOT_PATH + '/Gemfile.rails.2.3.5',
5
- '3.0.3' => ROOT_PATH + '/Gemfile',
6
- }
7
3
 
8
4
  def fixture_path(version)
9
5
  "#{FIXTURES_PATH}/rails_#{version}"
@@ -15,25 +11,18 @@ end
15
11
 
16
12
  ##############################################################################
17
13
 
18
- {
19
- '2.3.5' => "BUNDLE_GEMFILE=#{GEMFILES['2.3.5']} rails #{RAILS_APP_NAME} -m template.rb",
20
- '3.0.3' => "BUNDLE_GEMFILE=#{GEMFILES['3.0.3']} bundle exec rails new #{RAILS_APP_NAME} -m template.rb"
21
- }.each do |version, rails_command|
22
-
23
- Given /^a Rails #{version} application set up for using dragonfly$/ do
24
- raise "Problem setting up Rails app" unless `
25
- cd #{fixture_path(version)} &&
26
- rm -rf #{RAILS_APP_NAME} &&
27
- #{rails_command}`
28
- end
29
-
14
+ Given "a Rails 3.0.5 application set up for using dragonfly" do
15
+ raise "Problem setting up Rails app" unless `
16
+ cd #{fixture_path('3.0.5')} &&
17
+ rm -rf #{RAILS_APP_NAME} &&
18
+ bundle exec rails new #{RAILS_APP_NAME} -m template.rb`
30
19
  end
31
20
 
32
21
  Then /^the (.+) cucumber features in my Rails (.+) app should pass$/ do |filename, version|
33
22
  puts "\n*** RUNNING FEATURES IN THE RAILS APP... ***\n"
34
23
  path = File.join(fixture_path(version), RAILS_APP_NAME)
35
- `cd #{path} && BUNDLE_GEMFILE=#{GEMFILES[version]} RAILS_ENV=cucumber rake db:migrate`
36
- features_passed = system "cd #{path} && BUNDLE_GEMFILE=#{GEMFILES[version]} cucumber features/#{filename}.feature"
24
+ `cd #{path} && RAILS_ENV=cucumber rake db:migrate`
25
+ features_passed = system "cd #{path} && cucumber features/#{filename}.feature"
37
26
  puts "\n*** FINISHED RUNNING FEATURES IN THE RAILS APP ***\n"
38
27
  raise "Features failed" unless features_passed
39
28
  end