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.
- data/.rspec +1 -0
- data/.yardopts +24 -0
- data/Gemfile +30 -0
- data/History.md +323 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/config.ru +14 -0
- data/docs.watchr +1 -0
- data/dragonfly.gemspec +297 -0
- data/extra_docs/Analysers.md +66 -0
- data/extra_docs/Caching.md +23 -0
- data/extra_docs/Configuration.md +124 -0
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +153 -0
- data/extra_docs/Encoding.md +67 -0
- data/extra_docs/GeneralUsage.md +121 -0
- data/extra_docs/Generators.md +60 -0
- data/extra_docs/Heroku.md +50 -0
- data/extra_docs/ImageMagick.md +125 -0
- data/extra_docs/Index.md +33 -0
- data/extra_docs/MimeTypes.md +40 -0
- data/extra_docs/Models.md +272 -0
- data/extra_docs/Mongo.md +45 -0
- data/extra_docs/Processing.md +77 -0
- data/extra_docs/Rack.md +52 -0
- data/extra_docs/Rails2.md +57 -0
- data/extra_docs/Rails3.md +62 -0
- data/extra_docs/Sinatra.md +25 -0
- data/extra_docs/URLs.md +169 -0
- data/features/images.feature +47 -0
- data/features/no_processing.feature +14 -0
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +66 -0
- data/features/steps/rails_steps.rb +28 -0
- data/features/support/env.rb +13 -0
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/show.html.erb +6 -0
- data/fixtures/rails_3.0.5/files/config/initializers/dragonfly.rb +4 -0
- data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/image_steps.rb +25 -0
- data/fixtures/rails_3.0.5/files/features/support/paths.rb +17 -0
- data/fixtures/rails_3.0.5/files/features/text_images.feature +7 -0
- data/fixtures/rails_3.0.5/template.rb +20 -0
- data/irbrc.rb +18 -0
- data/lib/dragonfly.rb +55 -0
- data/lib/dragonfly/active_model_extensions.rb +13 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +250 -0
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +148 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +95 -0
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_model_extensions/validations.rb +41 -0
- data/lib/dragonfly/analyser.rb +58 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
- data/lib/dragonfly/analysis/image_magick_analyser.rb +6 -0
- data/lib/dragonfly/app.rb +172 -0
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/image_magick.rb +6 -0
- data/lib/dragonfly/config/rails.rb +20 -0
- data/lib/dragonfly/configurable.rb +207 -0
- data/lib/dragonfly/core_ext/array.rb +7 -0
- data/lib/dragonfly/core_ext/hash.rb +7 -0
- data/lib/dragonfly/core_ext/object.rb +12 -0
- data/lib/dragonfly/core_ext/string.rb +9 -0
- data/lib/dragonfly/core_ext/symbol.rb +9 -0
- data/lib/dragonfly/data_storage.rb +9 -0
- data/lib/dragonfly/data_storage/couch_data_store.rb +64 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +141 -0
- data/lib/dragonfly/data_storage/mongo_data_store.rb +86 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +145 -0
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/image_magick_encoder.rb +6 -0
- data/lib/dragonfly/function_manager.rb +71 -0
- data/lib/dragonfly/generation/image_magick_generator.rb +6 -0
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
- data/lib/dragonfly/image_magick/analyser.rb +51 -0
- data/lib/dragonfly/image_magick/config.rb +41 -0
- data/lib/dragonfly/image_magick/encoder.rb +57 -0
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +99 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +4 -0
- data/lib/dragonfly/job.rb +451 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +15 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +20 -0
- data/lib/dragonfly/processing/image_magick_processor.rb +6 -0
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/rails/images.rb +27 -0
- data/lib/dragonfly/response.rb +97 -0
- data/lib/dragonfly/routed_endpoint.rb +40 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/server.rb +113 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/temp_object.rb +175 -0
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/sample.docx +0 -0
- data/samples/taj.jpg +0 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +1426 -0
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +91 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +48 -0
- data/spec/dragonfly/app_spec.rb +135 -0
- data/spec/dragonfly/configurable_spec.rb +461 -0
- data/spec/dragonfly/core_ext/array_spec.rb +19 -0
- data/spec/dragonfly/core_ext/hash_spec.rb +19 -0
- data/spec/dragonfly/core_ext/string_spec.rb +17 -0
- data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +76 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +296 -0
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +57 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +258 -0
- data/spec/dragonfly/data_storage/shared_data_store_examples.rb +77 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/hash_with_css_style_keys_spec.rb +24 -0
- data/spec/dragonfly/image_magick/analyser_spec.rb +64 -0
- data/spec/dragonfly/image_magick/encoder_spec.rb +41 -0
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/image_magick/processor_spec.rb +233 -0
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +37 -0
- data/spec/dragonfly/job_definitions_spec.rb +35 -0
- data/spec/dragonfly/job_endpoint_spec.rb +173 -0
- data/spec/dragonfly/job_spec.rb +1046 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +47 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/server_spec.rb +278 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/temp_object_spec.rb +306 -0
- data/spec/dragonfly/url_mapper_spec.rb +126 -0
- data/spec/functional/deprecations_spec.rb +51 -0
- data/spec/functional/image_magick_app_spec.rb +27 -0
- data/spec/functional/model_urls_spec.rb +85 -0
- data/spec/functional/remote_on_the_fly_spec.rb +51 -0
- data/spec/functional/to_response_spec.rb +31 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/argument_matchers.rb +19 -0
- data/spec/support/image_matchers.rb +47 -0
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +38 -0
- data/yard/setup.rb +15 -0
- data/yard/templates/default/fulldoc/html/css/common.css +107 -0
- data/yard/templates/default/layout/html/layout.erb +89 -0
- data/yard/templates/default/module/html/configuration_summary.erb +31 -0
- data/yard/templates/default/module/setup.rb +17 -0
- 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
|
data/extra_docs/Couch.md
ADDED
@@ -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.
|