dragonfly 0.6.2 → 0.7.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.
- data/.gitignore +2 -0
- data/.specopts +2 -0
- data/.yardopts +11 -5
- data/Gemfile +22 -0
- data/Gemfile.rails.2.3.5 +13 -0
- data/History.md +49 -0
- data/README.md +18 -28
- data/Rakefile +24 -36
- data/VERSION +1 -1
- data/config.ru +4 -1
- data/dragonfly.gemspec +85 -99
- data/extra_docs/Analysers.md +66 -30
- data/extra_docs/Caching.md +22 -0
- data/extra_docs/Configuration.md +116 -0
- data/extra_docs/DataStorage.md +114 -14
- data/extra_docs/Encoding.md +62 -37
- data/extra_docs/GeneralUsage.md +118 -0
- data/extra_docs/Generators.md +92 -0
- data/extra_docs/Heroku.md +51 -0
- data/extra_docs/Index.md +8 -9
- data/extra_docs/MimeTypes.md +18 -17
- data/extra_docs/Models.md +251 -0
- data/extra_docs/Processing.md +94 -70
- data/extra_docs/Rack.md +53 -0
- data/extra_docs/Rails2.md +44 -0
- data/extra_docs/Rails3.md +51 -0
- data/extra_docs/Sinatra.md +21 -0
- data/extra_docs/URLs.md +114 -0
- data/features/images.feature +6 -7
- data/features/no_processing.feature +0 -6
- data/features/rails_2.3.5.feature +1 -1
- data/features/rails_3.0.0.rc.feature +8 -0
- data/features/steps/dragonfly_steps.rb +14 -12
- data/features/steps/rails_steps.rb +20 -9
- data/features/support/env.rb +10 -11
- data/fixtures/files/app/views/albums/new.html.erb +4 -4
- data/fixtures/files/app/views/albums/show.html.erb +1 -1
- data/fixtures/files/features/manage_album_images.feature +1 -1
- data/fixtures/files/features/step_definitions/{album_steps.rb → image_steps.rb} +4 -3
- data/fixtures/files/features/support/paths.rb +2 -0
- data/fixtures/files/features/text_images.feature +7 -0
- data/fixtures/rails_3.0.0.rc/template.rb +21 -0
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +4 -16
- data/lib/dragonfly/{active_record_extensions.rb → active_model_extensions.rb} +1 -1
- data/lib/dragonfly/active_model_extensions/attachment.rb +146 -0
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/class_methods.rb +5 -6
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/instance_methods.rb +1 -1
- data/lib/dragonfly/{active_record_extensions → active_model_extensions}/validations.rb +5 -9
- data/lib/dragonfly/analyser.rb +59 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/r_magick_analyser.rb +46 -31
- data/lib/dragonfly/app.rb +138 -173
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/r_magick.rb +37 -0
- data/lib/dragonfly/config/{rails_defaults.rb → rails.rb} +6 -7
- data/lib/dragonfly/configurable.rb +30 -27
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/data_storage/file_data_store.rb +59 -26
- data/lib/dragonfly/data_storage/mongo_data_store.rb +65 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +31 -12
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/r_magick_encoder.rb +10 -19
- data/lib/dragonfly/endpoint.rb +43 -0
- data/lib/dragonfly/function_manager.rb +65 -0
- data/lib/dragonfly/{processing/r_magick_text_processor.rb → generation/r_magick_generator.rb} +25 -11
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/job.rb +290 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +17 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +21 -14
- data/lib/dragonfly/processing/r_magick_processor.rb +71 -48
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/r_magick_utils.rb +24 -0
- data/lib/dragonfly/rails/images.rb +10 -7
- data/lib/dragonfly/routed_endpoint.rb +42 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/simple_endpoint.rb +64 -0
- data/lib/dragonfly/temp_object.rb +77 -45
- data/spec/argument_matchers.rb +7 -17
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
- data/spec/dragonfly/{active_record_extensions → active_model_extensions}/model_spec.rb +282 -244
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +2 -2
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +10 -1
- data/spec/dragonfly/app_spec.rb +175 -69
- data/spec/dragonfly/configurable_spec.rb +14 -0
- data/spec/dragonfly/data_storage/data_store_spec.rb +36 -9
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +61 -38
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +18 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +34 -39
- data/spec/dragonfly/deprecation_spec.rb +20 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +119 -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 +66 -0
- data/spec/dragonfly/job_spec.rb +605 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +37 -17
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +182 -166
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/simple_endpoint_spec.rb +78 -0
- data/spec/dragonfly/temp_object_spec.rb +154 -119
- data/spec/simple_matchers.rb +22 -0
- data/spec/spec_helper.rb +28 -4
- data/yard/templates/default/layout/html/layout.erb +18 -11
- metadata +89 -190
- data/config.rb +0 -5
- data/extra_docs/ActiveRecord.md +0 -196
- data/extra_docs/ExampleUseCases.md +0 -189
- data/extra_docs/GettingStarted.md +0 -114
- data/extra_docs/Shortcuts.md +0 -118
- data/extra_docs/UsingWithRails.md +0 -81
- data/features/rails_3.0.0.beta3.feature +0 -7
- data/fixtures/rails_3.0.0.beta3/template.rb +0 -16
- data/lib/dragonfly/active_record_extensions/attachment.rb +0 -170
- data/lib/dragonfly/analyser_list.rb +0 -9
- data/lib/dragonfly/analysis/base.rb +0 -10
- data/lib/dragonfly/belongs_to_app.rb +0 -24
- data/lib/dragonfly/config/heroku_rails_images.rb +0 -23
- data/lib/dragonfly/config/r_magick_images.rb +0 -69
- data/lib/dragonfly/config/r_magick_text.rb +0 -25
- data/lib/dragonfly/config/rails_images.rb +0 -13
- data/lib/dragonfly/data_storage/base.rb +0 -21
- data/lib/dragonfly/data_storage/base64_data_store.rb +0 -23
- data/lib/dragonfly/data_storage/transparent_data_store.rb +0 -21
- data/lib/dragonfly/delegatable.rb +0 -14
- data/lib/dragonfly/delegator.rb +0 -62
- data/lib/dragonfly/encoder_list.rb +0 -9
- data/lib/dragonfly/encoding/base.rb +0 -14
- data/lib/dragonfly/encoding/transparent_encoder.rb +0 -14
- data/lib/dragonfly/extended_temp_object.rb +0 -120
- data/lib/dragonfly/parameters.rb +0 -163
- data/lib/dragonfly/processing/base.rb +0 -10
- data/lib/dragonfly/processor_list.rb +0 -9
- data/lib/dragonfly/url_handler.rb +0 -147
- data/spec/dragonfly/active_record_extensions/attachment_spec.rb +0 -8
- data/spec/dragonfly/active_record_extensions/migration.rb +0 -42
- data/spec/dragonfly/active_record_extensions/models.rb +0 -6
- data/spec/dragonfly/active_record_extensions/spec_helper.rb +0 -24
- data/spec/dragonfly/belongs_to_app_spec.rb +0 -55
- data/spec/dragonfly/delegatable_spec.rb +0 -32
- data/spec/dragonfly/delegator_spec.rb +0 -145
- data/spec/dragonfly/extended_temp_object_spec.rb +0 -71
- data/spec/dragonfly/parameters_spec.rb +0 -298
- data/spec/dragonfly/processing/r_magick_text_processor_spec.rb +0 -84
- data/spec/dragonfly/url_handler_spec.rb +0 -247
- data/spec/dragonfly_spec.rb +0 -16
- data/spec/ginger_scenarios.rb +0 -13
data/extra_docs/Shortcuts.md
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
Shortcuts
|
2
|
-
=========
|
3
|
-
|
4
|
-
When you call {Dragonfly::App#fetch fetch}, {Dragonfly::ExtendedTempObject#transform transform},
|
5
|
-
{Dragonfly::UrlHandler#url_for url_for}, (or {Dragonfly::ActiveRecordExtensions::Attachment#url url} on an ActiveRecord attachment), you can specify all the job parameters
|
6
|
-
necessary to fetch the appropriate content.
|
7
|
-
|
8
|
-
The parameters are the following:
|
9
|
-
|
10
|
-
- `:uid` - the uid used by the datastore to retrieve the data (was returned when stored)
|
11
|
-
- `:processing_method` - the method used to do the processing
|
12
|
-
- `:processing_options` - options hash passed to the processing method
|
13
|
-
- `:format` - the format to encode the data with, e.g. 'png'
|
14
|
-
- `:encoding` - an options hash passed to the encoder for other options, e.g. bitrate, etc.
|
15
|
-
|
16
|
-
Say we have an app configured with the {Dragonfly::Config::RMagickImages RMagickImages}
|
17
|
-
|
18
|
-
app = Dragonfly::App[:my_app]
|
19
|
-
app.configure_with(Dragonfly::Config::RMagickImages)
|
20
|
-
|
21
|
-
we can call things like
|
22
|
-
|
23
|
-
app.fetch 'some_uid',
|
24
|
-
:processing_method => :resize_and_crop,
|
25
|
-
:processing_options => {:width => 100, :height => 50, :gravity => 'ne'},
|
26
|
-
:format => :jpg,
|
27
|
-
:encoding => {:some => 'option'} # => gets a processed and encoded temp_object
|
28
|
-
|
29
|
-
app.url_for 'some_uid',
|
30
|
-
:processing_method => :resize_and_crop,
|
31
|
-
:processing_options => {:width => 100, :height => 50, :gravity => 'ne'},
|
32
|
-
:format => :jpg,
|
33
|
-
:encoding => {:some => 'option'} # => "/images/some_uid.tif?m=resize_and_crop&o[width]=...."
|
34
|
-
|
35
|
-
YIKES!!!!!
|
36
|
-
|
37
|
-
That's an awful lot of code every time, especially if we reuse the same parameters over and over.
|
38
|
-
That's why for the arguments after the uid, you can register {Dragonfly::Parameters parameter shortcuts}.
|
39
|
-
|
40
|
-
Simple shortcuts
|
41
|
-
----------------
|
42
|
-
If we were to use the parameters in the example above a number of times, we could register a simple named shortcut, say 'thumb', using a symbol.
|
43
|
-
|
44
|
-
app.parameters.add_shortcut(:thumb,
|
45
|
-
:processing_method => :resize_and_crop,
|
46
|
-
:processing_options => {:width => 100, :height => 50, :gravity => 'ne'},
|
47
|
-
:format => :jpg,
|
48
|
-
:encoding => {:some => 'option'}
|
49
|
-
)
|
50
|
-
|
51
|
-
We can now use this named shortcut, `:thumb`, in place of the parameters elsewhere
|
52
|
-
|
53
|
-
app.fetch 'some_uid', :thumb # => gets a processed and encoded temp_object as before
|
54
|
-
app.url_for 'some_uid', :thumb # => "/images/some_uid.tif?m=resize_and_crop&o[width]=....", as before
|
55
|
-
|
56
|
-
Complex shortcuts
|
57
|
-
-----------------
|
58
|
-
Rather than create a new named shortcut for every different set of parameters, we can make life easier by defining shortcuts
|
59
|
-
which match a set of arguments, then form parameters from them.
|
60
|
-
|
61
|
-
For example, take the shortcut
|
62
|
-
|
63
|
-
app.parameters.add_shortcut(/\d+x\d+/, Symbol) do |geometry, format|
|
64
|
-
{
|
65
|
-
:processing_method => :my_resize_method,
|
66
|
-
:processing_options => {:geometry => geometry},
|
67
|
-
:format => format
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
It will match where there are two arguments, a string matching `/\d+x\d+/` and a symbol, and convert to a hash of job parameters.
|
72
|
-
Note that the matching arguments are yielded to the block.
|
73
|
-
So, for example,
|
74
|
-
|
75
|
-
app.url_for('some_uid', '100x50', :jpg)
|
76
|
-
|
77
|
-
generates the same url as if we'd used
|
78
|
-
|
79
|
-
app.url_for 'some_uid',
|
80
|
-
:processing_method => :my_resize_method,
|
81
|
-
:processing_options => {:geometry => 100},
|
82
|
-
:format => :jpg
|
83
|
-
|
84
|
-
The following examples would not match
|
85
|
-
|
86
|
-
app.url_for('some_uid', '100xg50', :jpg) # '100xg50' doesn't match /\d+x\d+/
|
87
|
-
app.url_for('some_uid', '100x50', 'jpg') # 'jpg' is not a Symbol
|
88
|
-
app.url_for('some_uid', '100x50') # not enough arguments
|
89
|
-
app.url_for('some_uid', '100x50', :jpg, 4) # too many arguments
|
90
|
-
|
91
|
-
The arguments are matched using the `===` operator (as used in `case` statements), which is why, for example, `:jpg` matches `Symbol`.
|
92
|
-
|
93
|
-
Regexp shortcuts
|
94
|
-
----------------
|
95
|
-
If we register a complex shortcut as a single regexp, then the match data is also yielded, for convenience.
|
96
|
-
|
97
|
-
app.parameters.add_shortcut(/(\d+)x(\d+)/) do |geometry, match_data|
|
98
|
-
{
|
99
|
-
:processing_method => :my_resize_method,
|
100
|
-
:processing_options => {:width => match_data[1], :height => match_data[2]}
|
101
|
-
}
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
Default parameters
|
106
|
-
------------------
|
107
|
-
If we've configured a default parameter, e.g.
|
108
|
-
|
109
|
-
app.parameters.default_format = :jpg
|
110
|
-
|
111
|
-
then this will be used in these methods whenever that parameter is not given, such as in the example above.
|
112
|
-
|
113
|
-
Avoiding processing/encoding
|
114
|
-
----------------------------
|
115
|
-
If `:processing_method` is set to nil, then no processing takes place when methods like {Dragonfly::App#fetch fetch}, {Dragonfly::ExtendedTempObject#transform transform},
|
116
|
-
{Dragonfly::UrlHandler#url_for url_for}, and {Dragonfly::ActiveRecordExtensions::Attachment#url url} are called.
|
117
|
-
|
118
|
-
Similarly, if `:format` is set to nil, then no encoding takes place.
|
@@ -1,81 +0,0 @@
|
|
1
|
-
Using With Rails
|
2
|
-
================
|
3
|
-
|
4
|
-
Dragonfly works with both Rails 2.3 and Rails 3.
|
5
|
-
|
6
|
-
The main way to use Dragonfly with Rails is as a {Dragonfly::Middleware middleware}.
|
7
|
-
|
8
|
-
1. Setting up
|
9
|
-
------------------
|
10
|
-
|
11
|
-
The quick way
|
12
|
-
-------------
|
13
|
-
There is a ready-made file which sets up Dragonfly for image processing for your rails app.
|
14
|
-
If image resizing, etc. is all you want to do, then put this in an initializer, e.g config/initializers/dragonfly.rb:
|
15
|
-
|
16
|
-
require 'dragonfly/rails/images'
|
17
|
-
|
18
|
-
This file initializes a dragonfly app, configures it to use rmagick processing, encoding, etc.,
|
19
|
-
registers the app so that you can use ActiveRecord accessors, and inserts it into the Rails middleware stack.
|
20
|
-
|
21
|
-
The more explicit way
|
22
|
-
---------------------
|
23
|
-
You can do the above explicitly.
|
24
|
-
|
25
|
-
config/initializers/dragonfly.rb:
|
26
|
-
|
27
|
-
require 'dragonfly'
|
28
|
-
|
29
|
-
app = Dragonfly::App[:images]
|
30
|
-
app.configure_with(Dragonfly::Config::RailsImages)
|
31
|
-
|
32
|
-
# Define the method 'image_accessor' in ActiveRecord models
|
33
|
-
Dragonfly.active_record_macro(:image, app)
|
34
|
-
|
35
|
-
environment.rb (application.rb in Rails 3):
|
36
|
-
|
37
|
-
config.middleware.insert_after 'Rack::Lock', 'Dragonfly::Middleware', :images
|
38
|
-
config.middleware.insert_before 'Dragonfly::Middleware', 'Rack::Cache', {
|
39
|
-
:verbose => true,
|
40
|
-
:metastore => "file:#{Rails.root}/tmp/dragonfly/cache/meta",
|
41
|
-
:entitystore => "file:#{Rails.root}/tmp/dragonfly/cache/body"
|
42
|
-
}
|
43
|
-
|
44
|
-
2. Gem dependencies
|
45
|
-
-------------------
|
46
|
-
|
47
|
-
Tell Rails about the gem dependencies in the usual way:
|
48
|
-
|
49
|
-
For Rails 2.3 add this to config/environment.rb:
|
50
|
-
|
51
|
-
config.gem 'rmagick', :lib => 'RMagick' # only if used
|
52
|
-
config.gem 'rack-cache', :lib => 'rack/cache' # only if used
|
53
|
-
config.gem 'dragonfly'
|
54
|
-
|
55
|
-
For Rails 3 add it to the Gemfile, e.g.:
|
56
|
-
|
57
|
-
gem 'rmagick', :require => 'RMagick' # only if used
|
58
|
-
gem 'rack-cache', :require => 'rack/cache' # only if used
|
59
|
-
gem 'dragonfly'
|
60
|
-
|
61
|
-
You only need the lines above for {http://tomayko.com/src/rack-cache/ rack-cache} and
|
62
|
-
{http://rmagick.rubyforge.org/ rmagick} if you've used the file 'dragonfly/rails/images', or manually used them yourself.
|
63
|
-
|
64
|
-
3. Use it!
|
65
|
-
----------
|
66
|
-
|
67
|
-
Now that you have a parasitic Dragonfly app living inside your Rails app, you can upload media to your models, display/play around with them, etc.
|
68
|
-
|
69
|
-
To see what you can do with the active record accessors, see {file:ActiveRecord}.
|
70
|
-
|
71
|
-
For more info about general Dragonfly setup, including avoiding denial-of-service attacks, see {file:GettingStarted}.
|
72
|
-
|
73
|
-
Extra Config
|
74
|
-
------------
|
75
|
-
There are one or two config options you may commonly want to tweak.
|
76
|
-
In this case, add something like the following to your initializer:
|
77
|
-
|
78
|
-
Dragonfly::App[:images].configure do |c|
|
79
|
-
c.url_handler.path_prefix = '/attachments' # configures where the Dragonfly app is served from - default '/media'
|
80
|
-
c.url_handler.secret = 'PUT A SECRET HERE!!' # for protecting from Denial-Of-Service attacks
|
81
|
-
end
|
@@ -1,7 +0,0 @@
|
|
1
|
-
Feature: champion uses dragonfly in his Rails 3.0.0.beta3 application
|
2
|
-
In order to be a champion
|
3
|
-
A user uses dragonfly in his Rails 3.0.0.beta3 application
|
4
|
-
|
5
|
-
Scenario: Set up dragonfly using initializer
|
6
|
-
Given a Rails 3.0.0.beta3 application set up for using dragonfly
|
7
|
-
Then the cucumber features in my Rails 3.0.0.beta3 app should pass
|
@@ -1,16 +0,0 @@
|
|
1
|
-
gem 'rack-cache', :require => 'rack/cache'
|
2
|
-
gem 'rmagick', :require => 'RMagick'
|
3
|
-
|
4
|
-
gem 'capybara'
|
5
|
-
gem 'cucumber-rails'
|
6
|
-
gem 'cucumber', '0.7.2'
|
7
|
-
gem 'rspec-rails', '2.0.0.beta.8'
|
8
|
-
|
9
|
-
generate 'cucumber:skeleton'
|
10
|
-
|
11
|
-
generate 'scaffold albums cover_image_uid:string'
|
12
|
-
rake 'db:migrate'
|
13
|
-
|
14
|
-
# Copy over all files from the template dir
|
15
|
-
files_dir = File.expand_path(File.dirname(__FILE__) + '/../../files')
|
16
|
-
run "cp -r #{files_dir}/** ."
|
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
|
-
module Dragonfly
|
4
|
-
module ActiveRecordExtensions
|
5
|
-
|
6
|
-
class PendingUID; def to_s; 'PENDING'; end; end
|
7
|
-
|
8
|
-
class Attachment
|
9
|
-
|
10
|
-
extend Forwardable
|
11
|
-
def_delegators :temp_object,
|
12
|
-
:data, :to_file, :file, :tempfile, :path, :process, :process!, :encode, :encode!, :transform, :transform!
|
13
|
-
|
14
|
-
def initialize(app, parent_model, attribute_name)
|
15
|
-
@app, @parent_model, @attribute_name = app, parent_model, attribute_name
|
16
|
-
end
|
17
|
-
|
18
|
-
def assign(value)
|
19
|
-
if value.nil?
|
20
|
-
self.temp_object = nil
|
21
|
-
self.uid = nil
|
22
|
-
reset_magic_attributes
|
23
|
-
else
|
24
|
-
self.temp_object = app.create_object(value)
|
25
|
-
self.uid = PendingUID.new
|
26
|
-
set_magic_attributes
|
27
|
-
end
|
28
|
-
value
|
29
|
-
end
|
30
|
-
|
31
|
-
def destroy!
|
32
|
-
app.datastore.destroy(previous_uid) if previous_uid
|
33
|
-
rescue DataStorage::DataNotFound => e
|
34
|
-
app.log.warn("*** WARNING ***: tried to destroy data with uid #{previous_uid}, but got error: #{e}")
|
35
|
-
end
|
36
|
-
|
37
|
-
def fetch(*args)
|
38
|
-
app.fetch(uid, *args)
|
39
|
-
end
|
40
|
-
|
41
|
-
def save!
|
42
|
-
destroy! if uid_changed?
|
43
|
-
self.uid = app.datastore.store(temp_object) if has_data_to_store?
|
44
|
-
end
|
45
|
-
|
46
|
-
def temp_object
|
47
|
-
if @temp_object
|
48
|
-
@temp_object
|
49
|
-
elsif been_persisted?
|
50
|
-
@temp_object = fetch
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_value
|
55
|
-
self if been_assigned?
|
56
|
-
end
|
57
|
-
|
58
|
-
def url(*args)
|
59
|
-
unless uid.nil? || uid.is_a?(PendingUID)
|
60
|
-
app.url_for(uid, *args)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def methods(*args)
|
65
|
-
(super + methods_to_delegate_to_temp_object).uniq
|
66
|
-
end
|
67
|
-
|
68
|
-
def public_methods(*args)
|
69
|
-
(super + methods_to_delegate_to_temp_object).uniq
|
70
|
-
end
|
71
|
-
|
72
|
-
def respond_to?(method)
|
73
|
-
super || methods_to_delegate_to_temp_object.include?(method.to_method_name)
|
74
|
-
end
|
75
|
-
|
76
|
-
def ext
|
77
|
-
has_magic_attribute_for?(:ext) ? magic_attribute_for(:ext) : temp_object.ext
|
78
|
-
end
|
79
|
-
|
80
|
-
def name
|
81
|
-
has_magic_attribute_for?(:name) ? magic_attribute_for(:name) : temp_object.name
|
82
|
-
end
|
83
|
-
|
84
|
-
def size
|
85
|
-
has_magic_attribute_for?(:size) ? magic_attribute_for(:size) : temp_object.size
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def been_assigned?
|
91
|
-
uid
|
92
|
-
end
|
93
|
-
|
94
|
-
def been_persisted?
|
95
|
-
uid && !uid.is_a?(PendingUID)
|
96
|
-
end
|
97
|
-
|
98
|
-
def has_data_to_store?
|
99
|
-
uid.is_a?(PendingUID)
|
100
|
-
end
|
101
|
-
|
102
|
-
def uid_changed?
|
103
|
-
parent_model.send("#{attribute_name}_uid_changed?")
|
104
|
-
end
|
105
|
-
|
106
|
-
def uid=(uid)
|
107
|
-
parent_model.send("#{attribute_name}_uid=", uid)
|
108
|
-
end
|
109
|
-
|
110
|
-
def uid
|
111
|
-
parent_model.send("#{attribute_name}_uid")
|
112
|
-
end
|
113
|
-
|
114
|
-
def previous_uid
|
115
|
-
parent_model.send("#{attribute_name}_uid_was")
|
116
|
-
end
|
117
|
-
|
118
|
-
attr_reader :app, :parent_model, :attribute_name
|
119
|
-
|
120
|
-
attr_writer :temp_object
|
121
|
-
|
122
|
-
def analyser
|
123
|
-
app.analysers
|
124
|
-
end
|
125
|
-
|
126
|
-
def methods_to_delegate_to_temp_object
|
127
|
-
analyser.delegatable_methods
|
128
|
-
end
|
129
|
-
|
130
|
-
def can_delegate_to_temp_object?(meth)
|
131
|
-
methods_to_delegate_to_temp_object.include?(meth.to_method_name)
|
132
|
-
end
|
133
|
-
|
134
|
-
def magic_attributes
|
135
|
-
parent_model.class.column_names.select { |name|
|
136
|
-
name =~ /^#{attribute_name}_(.+)$/ &&
|
137
|
-
(can_delegate_to_temp_object?($1) || %w(size ext name).include?($1))
|
138
|
-
}
|
139
|
-
end
|
140
|
-
|
141
|
-
def set_magic_attributes
|
142
|
-
magic_attributes.each do |attribute|
|
143
|
-
method = attribute.sub("#{attribute_name}_", '')
|
144
|
-
parent_model.send("#{attribute}=", temp_object.send(method))
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def reset_magic_attributes
|
149
|
-
magic_attributes.each{|attribute| parent_model.send("#{attribute}=", nil) }
|
150
|
-
end
|
151
|
-
|
152
|
-
def has_magic_attribute_for?(property)
|
153
|
-
magic_attributes.include?("#{attribute_name}_#{property}")
|
154
|
-
end
|
155
|
-
|
156
|
-
def magic_attribute_for(property)
|
157
|
-
parent_model.send("#{attribute_name}_#{property}")
|
158
|
-
end
|
159
|
-
|
160
|
-
def method_missing(meth, *args, &block)
|
161
|
-
if can_delegate_to_temp_object?(meth)
|
162
|
-
has_magic_attribute_for?(meth) ? magic_attribute_for(meth) : temp_object.send(meth, *args, &block)
|
163
|
-
else
|
164
|
-
super
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
module Dragonfly
|
4
|
-
module BelongsToApp
|
5
|
-
|
6
|
-
# Exceptions
|
7
|
-
class NotConfigured < RuntimeError; end
|
8
|
-
|
9
|
-
attr_writer :app
|
10
|
-
|
11
|
-
def app
|
12
|
-
@app || raise(NotConfigured, "#{self.inspect} has no app set")
|
13
|
-
end
|
14
|
-
|
15
|
-
def app_set?
|
16
|
-
!!@app
|
17
|
-
end
|
18
|
-
|
19
|
-
def log
|
20
|
-
app_set? ? app.log : (@log ||= Logger.new(STDOUT))
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|