oahu-dragonfly 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,124 @@
1
+ Configuration
2
+ =============
3
+
4
+ Given a Dragonfly app
5
+
6
+ app = Dragonfly[:app_name]
7
+
8
+ Configuration can either be done like so...
9
+
10
+ app.configure do |c|
11
+ c.url_path_prefix = '/media'
12
+ # ...
13
+ end
14
+
15
+ ...or directly like so...
16
+
17
+ app.url_path_prefix = '/media'
18
+
19
+ The defaults should be fairly sensible, but you can tweak a number of things if you wish.
20
+ Here is an example of an app with all attributes configured:
21
+
22
+ app.configure do |c|
23
+ c.datastore = SomeCustomDataStore.new :egg => 'head' # defaults to FileDataStore
24
+
25
+ c.cache_duration = 3600*24*365*2 # defaults to 1 year # (1 year)
26
+ c.fallback_mime_type = 'something/mental' # defaults to application/octet-stream
27
+ c.log = Logger.new($stdout) # defaults to Logger.new('/var/tmp/dragonfly.log')
28
+ c.trust_file_extensions = false # defaults to true
29
+
30
+ c.url_path_prefix = '/images' # defaults to nil
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
+
34
+ c.content_filename = proc{|job, request| # defaults to the original name, with modified ext if encoded
35
+ "file.#{job.ext}"
36
+ }
37
+ c.content_disposition = :attachment # defaults to nil (use the browser default)
38
+
39
+ c.protect_from_dos_attacks = true # defaults to false - adds a SHA parameter on the end of urls
40
+ c.secret = 'This is my secret yeh!!' # should set this if concerned about DOS attacks
41
+
42
+ c.analyser.register(MyAnalyser) # See 'Analysers' for more details
43
+ c.processor.register(MyProcessor, :type => :fig) # See 'Processing' for more details
44
+ c.encoder.register(MyEncoder) do |e| # See 'Encoding' for more details
45
+ e.some_value = 'geg'
46
+ end
47
+ c.generator.register(MyGenerator) # See 'Generators' for more details
48
+
49
+ c.register_mime_type(:egg, 'fried/egg') # See 'MimeTypes' for more details
50
+
51
+ c.job :black_and_white do |size| # Job shortcut - lets you do image.black_and_white('30x30')
52
+ process :greyscale
53
+ process :thumb, size
54
+ encode :gif
55
+ end
56
+ end
57
+
58
+ Where is configuration done?
59
+ ----------------------------
60
+ In Rails, it should be done in an initializer, e.g. 'config/initializers/dragonfly.rb'.
61
+ Otherwise it should be done anywhere where general setup is done, early on.
62
+
63
+ Saved configurations
64
+ ====================
65
+ Saved configurations are useful if you often configure the app the same way.
66
+ There are a number that are provided with Dragonfly:
67
+
68
+ ImageMagick
69
+ -----------
70
+
71
+ app.configure_with(:imagemagick)
72
+
73
+ The {Dragonfly::ImageMagick::Config ImageMagick configuration} registers the app with the {Dragonfly::ImageMagick::Analyser ImageMagick Analyser}, {Dragonfly::ImageMagick::Processor ImageMagick Processor},
74
+ {Dragonfly::ImageMagick::Encoder ImageMagick Encoder} and {Dragonfly::ImageMagick::Generator ImageMagick Generator}, and adds the 'job shortcuts'
75
+ `thumb`, `jpg`, `png`, `gif` and `convert`.
76
+
77
+ The file 'dragonfly/rails/images' does this for you.
78
+
79
+ The processor, analyser, encoder and generator pass data around using tempfiles.
80
+
81
+ Rails
82
+ -----
83
+
84
+ app.configure_with(:rails)
85
+
86
+ 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
87
+ registers the {Dragonfly::Analysis::FileCommandAnalyser FileCommandAnalyser} for helping with mime_type validations.
88
+
89
+ The file 'dragonfly/rails/images' does this for you.
90
+
91
+ Heroku
92
+ ------
93
+
94
+ app.configure_with(:heroku, 's3_bucket_name')
95
+
96
+ The {Dragonfly::Config::Heroku Heroku configuration} configures it to use the {Dragonfly::DataStorage::S3DataStore}, using Heroku's config attributes.
97
+ See {file:Heroku} for more info.
98
+
99
+ Custom Saved Configuration
100
+ --------------------------
101
+ You can create your own saved configuration with any object that responds to 'apply_configuration':
102
+
103
+ module MyConfiguration
104
+
105
+ def self.apply_configuration(app, *args)
106
+ app.configure do |c|
107
+ c.url_path_prefix = '/hello/beans'
108
+ c.processor.register(MyProcessor)
109
+ # ...
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ Then to configure:
116
+
117
+ app.configure_with(MyConfiguration, :any_other => :args) # other args get passed through to apply_configuration
118
+
119
+ You can also carry on configuring by passing a block
120
+
121
+ app.configure_with(MyConfiguration) do |c|
122
+ c.any_extra = :config_here
123
+ # ...
124
+ end
@@ -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.
@@ -0,0 +1,153 @@
1
+ Data Storage
2
+ ============
3
+
4
+ Each dragonfly app has a key-value datastore to store the content (originals only).
5
+
6
+ Lets say we have an app
7
+
8
+ app = Dragonfly[:my_app_name]
9
+
10
+ Then we can store data like so:
11
+
12
+ uid = app.store('SOME CONTENT') # Can pass in a String, File or Tempfile
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)
15
+
16
+ uid = app.store('SOME CONTENT',
17
+ :meta => {:time => Time.now},
18
+ :name => 'great_content.txt',
19
+ :format => :txt
20
+ )
21
+
22
+ We can get content with
23
+
24
+ content = app.fetch(uid)
25
+ content.data # "SOME CONTENT"
26
+
27
+ We can also get the extra saved attributes
28
+
29
+ content.meta # {:time => Sat Aug 14 12:04:13 +0100 2010}
30
+ content.name # 'great_content.txt'
31
+ content.format # :txt
32
+
33
+ We can destroy it with
34
+
35
+ app.destroy(uid)
36
+
37
+ You can create your own datastore, or use one of the provided ones as outlined below.
38
+
39
+ File datastore
40
+ --------------
41
+ The {Dragonfly::DataStorage::FileDataStore FileDataStore} stores data on the local filesystem.
42
+
43
+ It is used by default.
44
+
45
+ If for whatever reason you need to configure it again:
46
+
47
+ # shouldn't need this - it is the default
48
+ app.datastore = Dragonfly::DataStorage::FileDataStore.new
49
+
50
+ app.datastore.configure do |d|
51
+ d.root_path = '/my/custom/path' # defaults to /var/tmp/dragonfly
52
+ end
53
+
54
+
55
+ S3 datastore
56
+ ------------
57
+ To configure with the {Dragonfly::DataStorage::S3DataStore S3DataStore}:
58
+
59
+ app.datastore = Dragonfly::DataStorage::S3DataStore.new
60
+
61
+ app.datastore.configure do |d|
62
+ c.bucket_name = 'my_bucket'
63
+ c.access_key_id = 'salfjasd34u23'
64
+ c.secret_access_key = '8u2u3rhkhfo23...'
65
+ end
66
+
67
+ You can also pass these options to `S3DataStore.new` as an options hash.
68
+
69
+
70
+ Mongo datastore
71
+ ---------------
72
+ To configure with the {Dragonfly::DataStorage::MongoDataStore MongoDataStore}:
73
+
74
+ app.datastore = Dragonfly::DataStorage::MongoDataStore.new
75
+
76
+ It won't normally need configuring, but if you wish to:
77
+
78
+ app.datastore.configure do |d|
79
+ c.host = 'http://egg.heads:5000' # defaults to localhost
80
+ c.port = '27018' # defaults to mongo default (27017)
81
+ c.database = 'my_database' # defaults to 'dragonfly'
82
+ c.username = 'some_user' # only needed if mongo is running in auth mode
83
+ c.password = 'some_password' # only needed if mongo is running in auth mode
84
+ end
85
+
86
+ You can also pass these options to `MongoDataStore.new` as an options hash.
87
+
88
+ Couch datastore
89
+ ---------------
90
+ To configure with the {Dragonfly::DataStorage::CouchDataStore CouchDataStore}:
91
+
92
+ app.datastore = Dragonfly::DataStorage::CouchDataStore.new
93
+
94
+ To configure:
95
+
96
+ app.datastore.configure do |d|
97
+ c.host = 'localhost' # defaults to localhost
98
+ c.port = '5984' # defaults to couchdb default (5984)
99
+ c.database = 'dragonfly' # defaults to 'dragonfly'
100
+ c.username = '' # not needed if couchdb is in 'admin party' mode
101
+ c.password = '' # not needed if couchdb is in 'admin party' mode
102
+ end
103
+
104
+ You can also pass these options to `CouchDataStore.new` as an options hash.
105
+
106
+ Custom datastore
107
+ ----------------
108
+ Data stores are key-value in nature, and need to implement 3 methods: `store`, `retrieve` and `destroy`.
109
+
110
+ class MyDataStore
111
+
112
+ def store(temp_object, opts={})
113
+ # ... use temp_object.data, temp_object.file, temp_object.path, etc. ...
114
+ # store and return the uid
115
+ 'return_some_unique_uid'
116
+ end
117
+
118
+ def retrieve(uid)
119
+ # return an array containing
120
+ [
121
+ content, # either a File, String or Tempfile
122
+ extra_data # Hash with optional keys :meta, :name, :format
123
+ ]
124
+ end
125
+
126
+ def destroy(uid)
127
+ # find the content and destroy
128
+ end
129
+
130
+ end
131
+
132
+ You can now configure the app to use your datastore:
133
+
134
+ Dragonfly[:my_app_name].datastore = MyDataStore.new
135
+
136
+ Notice that `store` takes a second `opts` argument.
137
+ Any options other than `meta`, `name` and `format` get passed through to here, so calling
138
+
139
+ uid = app.store('SOME CONTENT',
140
+ :name => 'great_content.txt',
141
+ :some_other => :option
142
+ )
143
+
144
+ will be split inside `store` like so:
145
+
146
+ def store(temp_object, opts={})
147
+ temp_object.data # "SOME CONTENT"
148
+ temp_object.name # 'great_content.txt'
149
+ opts # {:some_other => :option}
150
+ # ...
151
+ end
152
+
153
+ # ...
@@ -0,0 +1,67 @@
1
+ Encoding
2
+ ========
3
+ Registered encoders change the format of data, e.g. a jpeg image to a png image.
4
+
5
+ You can register as many encoders 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 encode it to any format registered with the encoder.
20
+
21
+ Lazy evaluation
22
+ ---------------
23
+
24
+ gif_image = image.encode(:gif)
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.encode!(:gif)
32
+
33
+ modifies the image object itself, rather than returning a new object.
34
+
35
+ ImageMagick Encoder
36
+ -------------------
37
+ See {file:ImageMagick}.
38
+
39
+ Custom Encoders
40
+ ---------------
41
+
42
+ To register a custom encoder, for e.g. pdf format:
43
+
44
+ app.encoder.add do |temp_object, format|
45
+ throw :unable_to_handle unless format == :pdf
46
+ # use temp_object.data, temp_object.path, temp_object.file, etc.
47
+ SomeLibrary.convert_to_pdf(temp_object.data)
48
+ # return a String, Pathname, File or Tempfile
49
+ end
50
+
51
+ pdf_image = image.encode(:pdf)
52
+
53
+ If `:unable_to_handle` is thrown, the next most recently registered encoder is used, and so on.
54
+
55
+ Alternatively you can create a class like the ImageMagick one above, which implements the method `encode`, and register this.
56
+
57
+ class MyEncoder
58
+
59
+ def encode(temp_object, format, *args)
60
+ SomeLib.encode(temp_object.data, format, *args)
61
+ end
62
+
63
+ end
64
+
65
+ app.encoder.register(MyEncoder)
66
+
67
+ pdf_image = image.encode(:pdf, :some => :args)
@@ -0,0 +1,121 @@
1
+ General Usage
2
+ =============
3
+
4
+ You can have multiple dragonfly apps, each with their own configuration.
5
+ Each app has a name, and is referred to by that name.
6
+
7
+ Dragonfly[:images] # ===> Creates an app called 'images'
8
+ Dragonfly[:images] # ===> Refers to the already created app 'images'
9
+
10
+ app = Dragonfly[:images]
11
+
12
+ Getting/generating content
13
+ --------------------------
14
+ Three methods can be used to get content:
15
+
16
+ app.fetch('some_uid') # Fetch from datastore (default filesystem)
17
+
18
+ app.fetch_file('~/path/to/file.png') # Fetch from a local file
19
+
20
+ app.generate(:plasma, 400, 300) # Generates using a method from the configured
21
+ # generator (in this case a plasma image)
22
+
23
+ These all return {Dragonfly::Job Job} objects. These objects are lazy - they don't do any fetching/generating until
24
+ some other method is called on them.
25
+
26
+ Using the content
27
+ -----------------
28
+ Once we have a {Dragonfly::Job Job} object:
29
+
30
+ image = app.fetch('some_uid')
31
+
32
+ We can get the data a number of ways...
33
+
34
+ image.data # => "\377???JFIF\000\..."
35
+ image.to_file('out.png') # writes to file 'out.png' and returns a readable file object
36
+ image.tempfile # => #<File:/var/folders/st/strHv74sH044JPabSiODz... a closed Tempfile object
37
+ image.file # => #<File:/var/folders/st/strHv74sH044JPabSiODz... a readable (open) File object
38
+ image.file do |f| # Yields an open file object, returns the return value of
39
+ data = f.read(256) # the block, and closes the file object
40
+ end
41
+ image.path # => '/var/folders/st/strHv74sH044JPabSiODz...' i.e. the path of the tempfile
42
+ image.size # => 134507 (size in bytes)
43
+
44
+ We can get its url...
45
+
46
+ image.url # => "/media/BAhbBlsHOgZmIg9hc..."
47
+
48
+ We can analyse it (see {file:Analysers} for more info) ...
49
+
50
+ image.width # => 280
51
+
52
+ We can process it (see {file:Processing} for more info) ...
53
+
54
+ new_image = image.process(:thumb, '40x30') # returns another 'Job' object
55
+
56
+ We can encode it (see {file:Encoding} for more info) ...
57
+
58
+ new_image = image.encode(:gif) # returns another 'Job' object
59
+
60
+ Chaining
61
+ --------
62
+ Because the methods
63
+
64
+ - `fetch`
65
+
66
+ - `fetch_file`
67
+
68
+ - `generate`
69
+
70
+ - `process`
71
+
72
+ - `encode`
73
+
74
+ all return {Dragonfly::Job Job} objects, we can chain them as much as we want...
75
+
76
+ image = app.fetch('some_uid').process(:greyscale).process(:thumb, '40x20#').encode(:gif)
77
+
78
+ ... and because they're lazy, we don't actually do any processing/encoding until either `apply` is called
79
+
80
+ image.apply # actually 'does' the processing and returns self
81
+
82
+ ... or a method is called like `data`, `to_file`, etc.
83
+
84
+ This means we can cheaply generate urls for processed data without doing any fetching or processing:
85
+
86
+ url = app.fetch('some_uid').process(:thumb, '40x20#').encode(:gif).url
87
+
88
+ and then visit that url in a browser to get the actual processed image.
89
+
90
+ Shortcuts
91
+ ---------
92
+ Commonly used processing/encoding steps can be shortened, so instead of
93
+
94
+ app.fetch('some_uid').process(:greyscale).process(:thumb, '40x20#').encode(:jpg)
95
+
96
+ we could use something like
97
+
98
+ app.fetch('some_uid').grey('40x20#')
99
+
100
+ This does exactly the same, returning a {Dragonfly::Job Job} object.
101
+
102
+ To define this shortcut:
103
+
104
+ app.configure do |c|
105
+ c.job :grey do |size|
106
+ process :greyscale
107
+ process :thumb, size
108
+ encode :jpg
109
+ end
110
+ # ...
111
+ end
112
+
113
+ The {Dragonfly::ImageMagick::Config ImageMagick} configuration comes with the pre-defined shortcuts:
114
+
115
+ image.thumb('40x30') # same as image.process(:thumb, '40x30')
116
+ image.jpg # same as image.encode(:jpg)
117
+ image.png # same as image.encode(:png)
118
+ image.gif # same as image.encode(:gif)
119
+ image.convert('-scale 30x30') # same as image.process(:convert, '-scale 30x30')
120
+
121
+ `thumb` and `convert` can optionally take a format (e.g. :gif) as the second argument.