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
@@ -1,52 +1,10 @@
1
1
  Analysers
2
2
  =========
3
+ Analysers are registered with Dragonfly apps for adding methods to {file:GeneralUsage Job} objects and {file:Models model attachments} such as `width`, `height`, etc.
3
4
 
4
- Analysing data for things like width, mime_type, etc. come under the banner of Analysis.
5
-
6
- You can register as many analysers as you like.
7
-
8
- Let's say we have a Dragonfly app
9
-
10
- app = Dragonfly[:images]
11
-
12
- and an image object (actually a {Dragonfly::Job Job} object)...
13
-
14
- image = app.fetch('some/uid')
15
-
16
- ...OR a Dragonfly model accessor...
17
-
18
- image = @album.cover_image
19
-
20
- We can analyse it using any analysis methods that have been registered with the analyser.
21
-
22
- ImageMagickAnalyser
23
- -------------------
24
- The {Dragonfly::Analysis::ImageMagickAnalyser ImageMagickAnalyser} is registered by default by the
25
- {Dragonfly::Config::ImageMagick ImageMagick configuration} used by 'dragonfly/rails/images'.
26
-
27
- If not already registered:
28
-
29
- app.analyser.register(Dragonfly::Analysis::ImageMagickAnalyser)
30
-
31
- gives us these methods:
32
-
33
- image.width # => 280
34
- image.height # => 355
35
- image.aspect_ratio # => 0.788732394366197
36
- image.portrait? # => true
37
- image.landscape? # => false
38
- image.depth # => 8
39
- image.number_of_colours # => 34703
40
- image.format # => :png
41
-
42
- RMagickAnalyser
43
- -------------------
44
- The {Dragonfly::Analysis::RMagickAnalyser RMagickAnalyser} uses the {http://rmagick.rubyforge.org RMagick} library and provides methods `width`, `height`, `aspect_ratio`,
45
- `portrait?`, `landscape?`, `depth`, `number_of_colours` and `format` like the ImageMagickAnalyser.
46
-
47
- You can tell it not to use the file system when registering it
48
-
49
- app.analyser.register(Dragonfly::Analysis::RMagickAnalyser){|a| a.use_filesystem = false }
5
+ ImageMagick Analyser
6
+ --------------------
7
+ See {file:ImageMagick}.
50
8
 
51
9
  FileCommandAnalyser
52
10
  -------------------
@@ -63,10 +21,12 @@ gives us:
63
21
 
64
22
  image.mime_type # => 'image/png'
65
23
 
66
- It doesn't use the filesystem by default (it operates on in-memory strings), but we can make it do so by using
24
+ You shouldn't need to configure it but if you need to:
67
25
 
68
26
  app.analyser.register(Dragonfly::Analysis::FileCommandAnalyser) do |a|
69
- a.use_filesystem = true
27
+ a.use_filesystem = false # defaults to true
28
+ a.file_command = '/opt/local/bin/file' # defaults to 'file'
29
+ a.num_bytes_to_check = 1024 # defaults to 255 - only applies if not using the filesystem
70
30
  end
71
31
 
72
32
  Custom Analysers
@@ -5,16 +5,16 @@ Given a Dragonfly app
5
5
 
6
6
  app = Dragonfly[:app_name]
7
7
 
8
- Configuration can either be done like so...
8
+ Configuration can either be done using a block...
9
9
 
10
10
  app.configure do |c|
11
- c.url_path_prefix = '/media'
11
+ c.url_format = '/media/:job'
12
12
  # ...
13
13
  end
14
14
 
15
- ...or directly like so...
15
+ ...or directly...
16
16
 
17
- app.url_path_prefix = '/media'
17
+ app.url_format = '/media/:job'
18
18
 
19
19
  The defaults should be fairly sensible, but you can tweak a number of things if you wish.
20
20
  Here is an example of an app with all attributes configured:
@@ -25,11 +25,10 @@ Here is an example of an app with all attributes configured:
25
25
  c.cache_duration = 3600*24*365*2 # defaults to 1 year # (1 year)
26
26
  c.fallback_mime_type = 'something/mental' # defaults to application/octet-stream
27
27
  c.log = Logger.new($stdout) # defaults to Logger.new('/var/tmp/dragonfly.log')
28
- c.infer_mime_type_from_file_ext = false # defaults to true
28
+ c.trust_file_extensions = false # defaults to true
29
29
 
30
- c.url_path_prefix = '/images' # defaults to nil
30
+ c.url_format = '/images/:job/:basename.:format' # defaults to '/:job/:basename.:format'
31
31
  c.url_host = 'http://some.domain.com:4000' # defaults to nil
32
- c.url_suffix = '.jpg' # defaults to nil - has no effect other than change the url
33
32
 
34
33
  c.content_filename = proc{|job, request| # defaults to the original name, with modified ext if encoded
35
34
  "file.#{job.ext}"
@@ -53,6 +52,28 @@ Here is an example of an app with all attributes configured:
53
52
  process :thumb, size
54
53
  encode :gif
55
54
  end
55
+
56
+ c.define_url do |app, job, opts| # allows overriding urls - defaults to
57
+ if job.step_types == [:fetch] # app.server.url_for(job, opts)
58
+ app.datastore.url_for(job.uid)
59
+ else
60
+ app.server.url_for(job, opts)
61
+ end
62
+ end
63
+
64
+ c.server.before_serve do |job, env| # allows you to do something before content is served
65
+ # do something
66
+ end
67
+
68
+ c.response_headers['X-Something'] = 'Custom header' # You can set custom response headers
69
+ c.response_headers['summink'] = proc{|job, request| # either directly or via a callback
70
+ job.image? ? 'image yo' : 'not an image'
71
+ }
72
+
73
+ # When using ImageMagick only...
74
+ c.convert_command = "/opt/local/bin/convert" # defaults to "convert"
75
+ c.identify_command = "/opt/local/bin/convert" # defaults to "convert"
76
+ c.log_commands = true # defaults to false
56
77
  end
57
78
 
58
79
  Where is configuration done?
@@ -70,34 +91,19 @@ ImageMagick
70
91
 
71
92
  app.configure_with(:imagemagick)
72
93
 
73
- The {Dragonfly::Config::ImageMagick ImageMagick configuration} registers the app with the {Dragonfly::Analysis::ImageMagickAnalyser ImageMagickAnalyser}, {Dragonfly::Processing::ImageMagickProcessor ImageMagickProcessor},
74
- {Dragonfly::Encoding::ImageMagickEncoder ImageMagickEncoder} and {Dragonfly::Generation::ImageMagickGenerator ImageMagickGenerator}, and adds the 'job shortcuts'
75
- `thumb`, `jpg`, `png`, `gif` and `convert`.
94
+ The {Dragonfly::ImageMagick::Config ImageMagick configuration} registers the app with the {Dragonfly::ImageMagick::Analyser ImageMagick Analyser}, {Dragonfly::ImageMagick::Processor ImageMagick Processor},
95
+ {Dragonfly::ImageMagick::Encoder ImageMagick Encoder} and {Dragonfly::ImageMagick::Generator ImageMagick Generator}, and a number of job shortcuts.
76
96
 
77
97
  The file 'dragonfly/rails/images' does this for you.
78
98
 
79
99
  The processor, analyser, encoder and generator pass data around using tempfiles.
80
100
 
81
- RMagick
82
- -------
83
-
84
- app.configure_with(:rmagick)
85
-
86
- The {Dragonfly::Config::RMagick RMagick configuration} registers the app with the {Dragonfly::Analysis::RMagickAnalyser RMagickAnalyser}, {Dragonfly::Processing::RMagickProcessor RMagickProcessor},
87
- {Dragonfly::Encoding::RMagickEncoder RMagickEncoder} and {Dragonfly::Generation::RMagickGenerator RMagickGenerator}, and adds the 'job shortcuts'
88
- `thumb`, `jpg`, `png` and `gif`.
89
-
90
- By default the processor, analyser, encoder and generator pass data around using tempfiles.
91
- You can make it pass data around using in-memory strings using
92
-
93
- app.configure_with(:rmagick, :use_filesystem => false)
94
-
95
101
  Rails
96
102
  -----
97
103
 
98
104
  app.configure_with(:rails)
99
105
 
100
- The {Dragonfly::Config::Rails Rails configuration} points the log to the Rails logger, configures the file data store root path, sets the url_path_prefix to /media, and
106
+ The {Dragonfly::Config::Rails Rails configuration} points the log to the Rails logger, configures the file data store root path, sets the url path prefix to '/media', and
101
107
  registers the {Dragonfly::Analysis::FileCommandAnalyser FileCommandAnalyser} for helping with mime_type validations.
102
108
 
103
109
  The file 'dragonfly/rails/images' does this for you.
@@ -136,3 +142,12 @@ You can also carry on configuring by passing a block
136
142
  c.any_extra = :config_here
137
143
  # ...
138
144
  end
145
+
146
+ If you wish to be able to use a symbol to represent your configuration (e.g. for a plugin, etc.) you can register it
147
+ globally as a one-off:
148
+
149
+ Dragonfly::App.register_configuration(:myconfig){ My::Saved::Configuration }
150
+
151
+ Then from then on you can configure Dragonfly apps using
152
+
153
+ app.configure_with(:myconfig, :any_other => :args)
@@ -0,0 +1,49 @@
1
+ CouchDB
2
+ =====
3
+ Dragonfly can be used with any ActiveModel-compatible model, and so you can use it with CouchDB using [CouchRest::Model](https://github.com/couchrest/couchrest_model).
4
+
5
+ Since CouchDB allows you to store files directly on documents as attachments, you can also use the supplied {Dragonfly::DataStorage::CouchDataStore CouchDataStore}.
6
+ which allows storing files as attachments directly on documents.
7
+
8
+ For more info about ActiveModel, see {file:Models}.
9
+
10
+ For more info about using the Couch data store, see {file:DataStorage}.
11
+
12
+ Example setup in Rails, using CouchRest::Model
13
+ -------------------------------------
14
+ In config/initializers/dragonfly.rb:
15
+
16
+ require 'dragonfly'
17
+
18
+ app = Dragonfly[:images]
19
+
20
+ # Get database config from config/couchdb.yml
21
+ couch_settings = YAML.load_file(Rails.root.join('config/couchdb.yml'))[Rails.env]
22
+
23
+ # Configure to use ImageMagick, Rails defaults, and the Couch data store
24
+ app.configure_with(:imagemagick)
25
+ app.configure_with(:rails) do |c|
26
+ c.datastore = Dragonfly::DataStorage::CouchDataStore.new(
27
+ :host => couch_settings['host'],
28
+ :port => couch_settings['port'],
29
+ :username => couch_settings['username'],
30
+ :password => couch_settings['password'],
31
+ :database => couch_settings['database']
32
+ )
33
+ end
34
+
35
+ # Allow all CouchRest::Model models to use the macro 'image_accessor'
36
+ app.define_macro(CouchRest::Model::Base, :image_accessor)
37
+
38
+ # ... any other setup, see Rails docs
39
+
40
+ Then in models:
41
+
42
+ class Album < CouchRest::Model::Base
43
+ property :cover_image_uid
44
+ image_accessor :cover_image
45
+
46
+ # ...
47
+ end
48
+
49
+ See {file:Models} for more info.
@@ -1,6 +1,5 @@
1
1
  Data Storage
2
2
  ============
3
-
4
3
  Each dragonfly app has a key-value datastore to store the content (originals only).
5
4
 
6
5
  Lets say we have an app
@@ -9,14 +8,14 @@ Lets say we have an app
9
8
 
10
9
  Then we can store data like so:
11
10
 
12
- uid = app.store('SOME CONTENT') # Can pass in a String, File or Tempfile
11
+ # Can pass in a String, Pathname, File or Tempfile
12
+ uid = app.store('SOME CONTENT')
13
13
 
14
- We can also save metadata at the same time, and give it a name and format (if you pass in a File object the filename is used by default)
14
+ We can also save metadata at the same time, and any other options the configured datastore accepts
15
15
 
16
16
  uid = app.store('SOME CONTENT',
17
- :meta => {:time => Time.now},
18
- :name => 'great_content.txt',
19
- :format => :txt
17
+ :meta => {:time => Time.now, :name => 'content.txt'},
18
+ :some => 'option'
20
19
  )
21
20
 
22
21
  We can get content with
@@ -26,14 +25,27 @@ We can get content with
26
25
 
27
26
  We can also get the extra saved attributes
28
27
 
29
- content.meta # {:time => Sat Aug 14 12:04:13 +0100 2010}
30
- content.name # 'great_content.txt'
31
- content.format # :txt
28
+ content.meta # {:time => Sat Aug 14 12:04:13 +0100 2010, :name => 'content.txt'}
29
+ content.name # 'content.txt'
32
30
 
33
31
  We can destroy it with
34
32
 
35
33
  app.destroy(uid)
36
34
 
35
+ Serving directly from the datastore
36
+ -----------------------------------
37
+ Datastores can optionally serve data directly too, by implementing `url_for`
38
+
39
+ app.datastore.url_for(uid, :some => 'option') # ---> "http://some.url/thing.txt"
40
+
41
+ or (the same)
42
+
43
+ app.remote_url_for(uid, :some => 'option')
44
+
45
+ or
46
+
47
+ my_model.remote_url(:some => 'option')
48
+
37
49
  You can create your own datastore, or use one of the provided ones as outlined below.
38
50
 
39
51
  File datastore
@@ -48,9 +60,22 @@ If for whatever reason you need to configure it again:
48
60
  app.datastore = Dragonfly::DataStorage::FileDataStore.new
49
61
 
50
62
  app.datastore.configure do |d|
51
- d.root_path = '/my/custom/path' # defaults to /var/tmp/dragonfly
63
+ d.root_path = '/filesystem/path/public/place' # defaults to /var/tmp/dragonfly
64
+ d.server_root = '/filesystem/path/public' # filesystem root for serving from - default to nil
65
+ d.store_meta = false # default to true - can be switched off to avoid
66
+ # saving an extra .meta file if meta not needed
52
67
  end
53
68
 
69
+ You can serve directly from the FileDataStore if the `server_root` is set.
70
+
71
+ To customize the storage path (and therefore the uid), use the `:path` option on store
72
+
73
+ app.store("SOME CONTENT", :path => 'some/path.txt')
74
+
75
+ To do this on a per-model basis see {file:Models#Storage_options}.
76
+
77
+ **BEWARE!!!!** you must make sure the path (which will become the uid for the content) is unique and changes each time the content
78
+ is changed, otherwise you could have caching problems, as the generated urls will be the same for the same uid.
54
79
 
55
80
  S3 datastore
56
81
  ------------
@@ -62,10 +87,28 @@ To configure with the {Dragonfly::DataStorage::S3DataStore S3DataStore}:
62
87
  c.bucket_name = 'my_bucket'
63
88
  c.access_key_id = 'salfjasd34u23'
64
89
  c.secret_access_key = '8u2u3rhkhfo23...'
90
+ c.region = 'eu-west-1' # defaults to 'us-east-1'
91
+ c.storage_headers = {'some' => 'thing'} # defaults to {'x-amz-acl' => 'public-read'}
65
92
  end
66
93
 
67
94
  You can also pass these options to `S3DataStore.new` as an options hash.
68
95
 
96
+ You can serve directly from the S3DataStore using e.g.
97
+
98
+ my_model.remote_url
99
+
100
+ or with an expiring url:
101
+
102
+ my_model.remote_url(:expires => 3.days.from_now)
103
+
104
+ Extra options you can use on store are `:path` and `:headers`
105
+
106
+ app.store("SOME CONTENT", :path => 'some/path.txt', :headers => {'x-amz-acl' => 'public-read-write'})
107
+
108
+ To do this on a per-model basis see {file:Models#Storage_options}.
109
+
110
+ **BEWARE!!!!** you must make sure the path (which will become the uid for the content) is unique and changes each time the content
111
+ is changed, otherwise you could have caching problems, as the generated urls will be the same for the same uid.
69
112
 
70
113
  Mongo datastore
71
114
  ---------------
@@ -83,7 +126,32 @@ It won't normally need configuring, but if you wish to:
83
126
  c.password = 'some_password' # only needed if mongo is running in auth mode
84
127
  end
85
128
 
86
- You can also pass these options to `MongoDataStore.new` as an options hash.
129
+ If you already have a mongo database or connection available, you can skip setting these and set `db` or `connection` instead.
130
+
131
+ You can also pass any options to `MongoDataStore.new` as an options hash.
132
+
133
+ You can't serve directly from the mongo datastore.
134
+
135
+ Couch datastore
136
+ ---------------
137
+ To configure with the {Dragonfly::DataStorage::CouchDataStore CouchDataStore}:
138
+
139
+ app.datastore = Dragonfly::DataStorage::CouchDataStore.new
140
+
141
+ To configure:
142
+
143
+ app.datastore.configure do |d|
144
+ c.host = 'localhost' # defaults to localhost
145
+ c.port = '5984' # defaults to couchdb default (5984)
146
+ c.database = 'dragonfly' # defaults to 'dragonfly'
147
+ c.username = '' # not needed if couchdb is in 'admin party' mode
148
+ c.password = '' # not needed if couchdb is in 'admin party' mode
149
+ end
150
+
151
+ You can also pass these options to `CouchDataStore.new` as an options hash.
152
+
153
+ You can serve directly from the couch datastore. You can optionally pass in a `:mime_type` option to `store`
154
+ to tell it what to use for its 'Content-Type' header.
87
155
 
88
156
  Custom datastore
89
157
  ----------------
@@ -93,7 +161,6 @@ Data stores are key-value in nature, and need to implement 3 methods: `store`, `
93
161
 
94
162
  def store(temp_object, opts={})
95
163
  # ... use temp_object.data, temp_object.file, temp_object.path, etc. ...
96
- # ... can also make use of temp_object.name, temp_object.format, temp_object.meta
97
164
  # store and return the uid
98
165
  'return_some_unique_uid'
99
166
  end
@@ -101,9 +168,9 @@ Data stores are key-value in nature, and need to implement 3 methods: `store`, `
101
168
  def retrieve(uid)
102
169
  # return an array containing
103
170
  [
104
- content, # either a File, String or Tempfile
105
- extra_data # Hash with optional keys :meta, :name, :format
106
- ]
171
+ content, # either a File, String or Tempfile
172
+ meta_data # Hash - :name and :format are treated specially,
173
+ ] # e.g. job.name is taken from job.meta[:name]
107
174
  end
108
175
 
109
176
  def destroy(uid)
@@ -117,20 +184,23 @@ You can now configure the app to use your datastore:
117
184
  Dragonfly[:my_app_name].datastore = MyDataStore.new
118
185
 
119
186
  Notice that `store` takes a second `opts` argument.
120
- Any options other than `meta`, `name` and `format` get passed through to here, so calling
187
+ Any options, including `:meta`, get passed here
121
188
 
122
189
  uid = app.store('SOME CONTENT',
123
- :name => 'great_content.txt',
190
+ :meta => {:name => 'great_content.txt'},
124
191
  :some_other => :option
125
192
  )
126
193
 
127
- will be split inside `store` like so:
194
+ # ...
195
+
196
+ You can also optionally serve data directly from the datastore if it implements `url_for`:
197
+
198
+ class MyDataStore
128
199
 
129
- def store(temp_object, opts={})
130
- temp_object.data # "SOME CONTENT"
131
- temp_object.name # 'great_content.txt'
132
- opts # {:some_other => :option}
133
200
  # ...
134
- end
135
201
 
136
- # ...
202
+ def url_for(uid, opts={})
203
+ "http://some.domain/#{uid}"
204
+ end
205
+
206
+ end
@@ -1,8 +1,6 @@
1
1
  Encoding
2
2
  ========
3
-
4
- Changing the format of data, but not changing the data itself,
5
- e.g. converting to gif format, comes under the banner of Encoding.
3
+ Registered encoders change the format of data, e.g. a jpeg image to a png image.
6
4
 
7
5
  You can register as many encoders as you like.
8
6
 
@@ -20,37 +18,6 @@ and an image object (actually a {Dragonfly::Job Job} object)...
20
18
 
21
19
  We can encode it to any format registered with the encoder.
22
20
 
23
- ImageMagickEncoder
24
- ------------------
25
- The {Dragonfly::Encoding::ImageMagickEncoder ImageMagickEncoder} is registered by default by
26
- the {Dragonfly::Config::ImageMagick ImageMagick configuration} used by 'dragonfly/rails/images'.
27
-
28
- If not already registered:
29
-
30
- app.encoder.register(Dragonfly::Encoding::ImageMagickEncoder)
31
-
32
- gives us:
33
-
34
- image.encode(:jpg)
35
- image.encode(:gif)
36
- image.encode(:png)
37
- image.encode(:tiff)
38
-
39
- and various other formats (see {Dragonfly::Encoding::ImageMagickEncoder ImageMagickEncoder}).
40
-
41
- You can also pass additional options to the imagemagick command line:
42
-
43
- image.encode(:jpg, '-quality 10')
44
-
45
- RMagickEncoder
46
- --------------
47
- The {Dragonfly::Encoding::RMagickEncoder RMagickEncoder} uses the {http://rmagick.rubyforge.org RMagick} library to do similar things to the
48
- ImageMagickEncoder above.
49
-
50
- You can tell it not to use the file system when registering it using
51
-
52
- app.encoder.register(Dragonfly::Encoding::RMagickEncoder){|e| e.use_filesystem = false }
53
-
54
21
  Lazy evaluation
55
22
  ---------------
56
23
 
@@ -65,6 +32,10 @@ Bang method
65
32
 
66
33
  modifies the image object itself, rather than returning a new object.
67
34
 
35
+ ImageMagick Encoder
36
+ -------------------
37
+ See {file:ImageMagick}.
38
+
68
39
  Custom Encoders
69
40
  ---------------
70
41
 
@@ -74,7 +45,7 @@ To register a custom encoder, for e.g. pdf format:
74
45
  throw :unable_to_handle unless format == :pdf
75
46
  # use temp_object.data, temp_object.path, temp_object.file, etc.
76
47
  SomeLibrary.convert_to_pdf(temp_object.data)
77
- # return a String, File or Tempfile
48
+ # return a String, Pathname, File or Tempfile
78
49
  end
79
50
 
80
51
  pdf_image = image.encode(:pdf)