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.
- data/{.specopts → .rspec} +0 -1
- data/.yardopts +6 -2
- data/Gemfile +14 -13
- data/History.md +47 -9
- data/README.md +25 -5
- data/Rakefile +37 -79
- data/VERSION +1 -1
- data/dragonfly.gemspec +140 -89
- data/extra_docs/Analysers.md +8 -48
- data/extra_docs/Configuration.md +40 -25
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +94 -24
- data/extra_docs/Encoding.md +6 -35
- data/extra_docs/ExampleUseCases.md +113 -0
- data/extra_docs/GeneralUsage.md +7 -23
- data/extra_docs/Generators.md +15 -49
- data/extra_docs/Heroku.md +7 -8
- data/extra_docs/ImageMagick.md +126 -0
- data/extra_docs/MimeTypes.md +3 -3
- data/extra_docs/Models.md +163 -0
- data/extra_docs/Mongo.md +1 -4
- data/extra_docs/Processing.md +7 -60
- data/extra_docs/Rails2.md +3 -1
- data/extra_docs/Rails3.md +2 -10
- data/extra_docs/ServingRemotely.md +83 -0
- data/extra_docs/Sinatra.md +3 -3
- data/extra_docs/URLs.md +60 -33
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/rails_steps.rb +7 -18
- data/features/support/env.rb +10 -37
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -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/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
- data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
- data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +7 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
- data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
- data/lib/dragonfly/analyser.rb +0 -1
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
- data/lib/dragonfly/app.rb +64 -55
- data/lib/dragonfly/config/heroku.rb +1 -1
- data/lib/dragonfly/config/image_magick.rb +2 -37
- data/lib/dragonfly/config/rails.rb +5 -2
- data/lib/dragonfly/configurable.rb +115 -35
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/core_ext/string.rb +1 -1
- data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
- data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
- data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
- data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
- data/lib/dragonfly/function_manager.rb +4 -2
- data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
- 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 +44 -0
- data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +104 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +2 -79
- data/lib/dragonfly/job.rb +152 -90
- data/lib/dragonfly/middleware.rb +5 -19
- data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
- data/lib/dragonfly/rails/images.rb +15 -10
- data/lib/dragonfly/response.rb +26 -12
- data/lib/dragonfly/serializer.rb +1 -4
- data/lib/dragonfly/server.rb +103 -0
- data/lib/dragonfly/temp_object.rb +56 -101
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
- data/spec/dragonfly/analyser_spec.rb +1 -1
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
- data/spec/dragonfly/app_spec.rb +35 -180
- data/spec/dragonfly/configurable_spec.rb +259 -18
- data/spec/dragonfly/core_ext/string_spec.rb +2 -2
- data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
- data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
- data/spec/dragonfly/function_manager_spec.rb +2 -2
- data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
- data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
- data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +1 -1
- data/spec/dragonfly/job_definitions_spec.rb +1 -1
- data/spec/dragonfly/job_endpoint_spec.rb +26 -3
- data/spec/dragonfly/job_spec.rb +426 -208
- data/spec/dragonfly/loggable_spec.rb +2 -2
- data/spec/dragonfly/middleware_spec.rb +5 -26
- data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
- data/spec/dragonfly/serializer_spec.rb +1 -14
- data/spec/dragonfly/server_spec.rb +261 -0
- data/spec/dragonfly/simple_cache_spec.rb +1 -1
- data/spec/dragonfly/temp_object_spec.rb +84 -130
- data/spec/dragonfly/url_mapper_spec.rb +130 -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 +12 -22
- data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
- data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +2 -2
- data/yard/templates/default/fulldoc/html/css/common.css +12 -10
- data/yard/templates/default/layout/html/layout.erb +6 -0
- metadata +267 -308
- data/Gemfile.rails.2.3.5 +0 -20
- data/features/3.0.3.feature +0 -8
- data/features/rails_2.3.5.feature +0 -7
- data/fixtures/files/app/models/album.rb +0 -3
- data/fixtures/files/app/views/albums/new.html.erb +0 -4
- data/fixtures/files/features/manage_album_images.feature +0 -12
- data/fixtures/rails_2.3.5/template.rb +0 -10
- data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
- data/lib/dragonfly/config/r_magick.rb +0 -46
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
- data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
- data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
- data/lib/dragonfly/r_magick_utils.rb +0 -48
- data/lib/dragonfly/simple_endpoint.rb +0 -76
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
- data/spec/dragonfly/config/r_magick_spec.rb +0 -29
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
- data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
- data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
- data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
- data/spec/simple_matchers.rb +0 -44
data/features/support/env.rb
CHANGED
@@ -1,40 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# A hash of <name for reference> => <dragonfly uid> pairs
|
10
|
-
TEMP_FILES = {}
|
11
|
-
|
12
|
-
Dragonfly[:images].configure_with(:imagemagick)
|
13
|
-
Dragonfly[:files].configure do |c|
|
14
|
-
c.analyser.register(Dragonfly::Analysis::FileCommandAnalyser)
|
1
|
+
require 'bundler'
|
2
|
+
begin
|
3
|
+
Bundler.setup(:default, :cucumber)
|
4
|
+
rescue Bundler::BundlerError => e
|
5
|
+
$stderr.puts e.message
|
6
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
exit e.status_code
|
15
8
|
end
|
16
9
|
|
17
|
-
|
18
|
-
|
19
|
-
Before do
|
20
|
-
# Remove temporary images
|
21
|
-
TEMP_FILES.each do |name, uid|
|
22
|
-
$app.datastore.destroy(uid)
|
23
|
-
TEMP_FILES.delete(name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
AfterStep do |scenario|
|
28
|
-
Dir["#{ROOT_PATH}/Gemfile*.lock"].each{|f| FileUtils.rm_f(f) }
|
29
|
-
end
|
30
|
-
|
31
|
-
module MyHelpers
|
32
|
-
|
33
|
-
def make_request(job)
|
34
|
-
request = Rack::MockRequest.new($app)
|
35
|
-
@response = request.get(job.url)
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
11
|
+
require 'dragonfly'
|
39
12
|
|
40
|
-
|
13
|
+
require 'rspec/expectations'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
ROOT_PATH = File.expand_path(File.dirname(__FILE__) + "/../..")
|
2
|
+
|
3
|
+
require ROOT_PATH + '/spec/support/image_matchers.rb'
|
4
|
+
|
5
|
+
# A hash of <name for reference> => <dragonfly uid> pairs
|
6
|
+
TEMP_FILES = {}
|
7
|
+
|
8
|
+
Dragonfly[:images].configure_with(:imagemagick)
|
9
|
+
Dragonfly[:files].configure do |c|
|
10
|
+
c.analyser.register(Dragonfly::Analysis::FileCommandAnalyser)
|
11
|
+
end
|
12
|
+
|
13
|
+
SAMPLE_IMAGE_PATH = ROOT_PATH + '/samples/beach.png'
|
14
|
+
|
15
|
+
Before do
|
16
|
+
# Remove temporary images
|
17
|
+
TEMP_FILES.each do |name, uid|
|
18
|
+
$app.datastore.destroy(uid)
|
19
|
+
TEMP_FILES.delete(name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module MyHelpers
|
24
|
+
|
25
|
+
def make_request(job)
|
26
|
+
request = Rack::MockRequest.new($app)
|
27
|
+
@response = request.get(job.url)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
World(MyHelpers)
|
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Feature: champion adds cover images to his albums
|
2
|
+
In order to be a champion
|
3
|
+
A user adds an image to his album
|
4
|
+
|
5
|
+
Scenario: Add and view image
|
6
|
+
When I go to the new album page
|
7
|
+
And I attach the file "../../../samples/beach.png" to "album[cover_image]"
|
8
|
+
And I press "Create"
|
9
|
+
Then I should see "successfully created"
|
10
|
+
And I should see "Look at this cover image!"
|
11
|
+
When I look at the generated image
|
12
|
+
Then I should see a PNG image of size 200x100
|
13
|
+
|
14
|
+
Scenario: validation fails
|
15
|
+
When I go to the new album page
|
16
|
+
And I attach the file "../../../samples/sample.docx" to "album[cover_image]"
|
17
|
+
And I press "Create"
|
18
|
+
Then I should see "Cover image format is incorrect. It needs to be one of 'jpg', 'png', 'gif', but was 'docx'"
|
19
|
+
|
20
|
+
Scenario: other validation fails
|
21
|
+
When I go to the new album page
|
22
|
+
And I fill in "album[name]" with "too long"
|
23
|
+
And I attach the file "../../../samples/beach.png" to "album[cover_image]"
|
24
|
+
And I press "Create"
|
25
|
+
Then I should see "Name is too long"
|
26
|
+
When I fill in "album[name]" with "short"
|
27
|
+
And I press "Create"
|
28
|
+
Then I should see "successfully created"
|
29
|
+
And I should see "short"
|
30
|
+
And I should see "Look at this cover image!"
|
31
|
+
When I look at the generated image
|
32
|
+
Then I should see a PNG image of size 200x100
|
33
|
+
|
34
|
+
Scenario: view remote image
|
35
|
+
Given an album "good" with attached file "beach.png"
|
36
|
+
When I go to the page for album "good"
|
37
|
+
And I look at the original image
|
38
|
+
Then I should see a PNG image of size 280x355
|
@@ -1,9 +1,19 @@
|
|
1
|
-
|
1
|
+
Given /^an album "(.+)" with attached file "(.+)"$/ do |name, filename|
|
2
|
+
Album.create! :name => name, :cover_image => Rails.root.join('../../../samples', filename)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I look at the generated image$/ do
|
2
6
|
page.body =~ %r{src="(/media[^"]+?)"}
|
3
7
|
url = $1
|
4
8
|
visit(url)
|
5
9
|
end
|
6
10
|
|
11
|
+
When /^I look at the original image$/ do
|
12
|
+
page.body =~ %r{src="(/system[^"]+?)"}
|
13
|
+
url = $1
|
14
|
+
visit(url)
|
15
|
+
end
|
16
|
+
|
7
17
|
Then /^I should see a (.+) image of size (.+)$/ do |format, size|
|
8
18
|
tempfile = Tempfile.new('wicked')
|
9
19
|
page.body.force_encoding('UTF-8').encode! if page.body.respond_to?(:force_encoding) # For some reason need this on Ruby 1.9.2
|
File without changes
|
@@ -6,11 +6,11 @@ gem 'cucumber', '0.8.5'
|
|
6
6
|
|
7
7
|
generate 'cucumber:install'
|
8
8
|
|
9
|
-
generate 'scaffold albums cover_image_uid:string'
|
9
|
+
generate 'scaffold albums cover_image_uid:string name:string'
|
10
10
|
rake 'db:migrate'
|
11
11
|
|
12
12
|
# Copy over all files from the template dir
|
13
|
-
files_dir = File.expand_path(File.dirname(__FILE__) + '
|
13
|
+
files_dir = File.expand_path(File.dirname(__FILE__) + '/files')
|
14
14
|
run "cp -r #{files_dir}/** ."
|
15
15
|
|
16
16
|
route <<ROUTES
|
data/irbrc.rb
CHANGED
@@ -2,6 +2,7 @@ require "rubygems"
|
|
2
2
|
require "bundler/setup"
|
3
3
|
$:.unshift(File.expand_path('../lib', __FILE__))
|
4
4
|
require 'dragonfly'
|
5
|
+
include Dragonfly::Serializer
|
5
6
|
APP = Dragonfly[:images].configure_with(:imagemagick)
|
6
7
|
|
7
8
|
# available_uids = `find #{APP.datastore.root_path} ! -type d`.split("\n").map do |file|
|
@@ -15,4 +16,4 @@ puts "\nAvailable sample images:\n"
|
|
15
16
|
puts Dir['samples/*']
|
16
17
|
puts "\nAvailable constants:\n"
|
17
18
|
puts "APP"
|
18
|
-
puts
|
19
|
+
puts
|
data/lib/dragonfly.rb
CHANGED
@@ -43,5 +43,12 @@ module Dragonfly
|
|
43
43
|
App[*args]
|
44
44
|
end
|
45
45
|
|
46
|
+
# Register saved configurations so we can do e.g.
|
47
|
+
# Dragonfly[:my_app].configure_with(:image_magick)
|
48
|
+
App.register_configuration(:imagemagick){ ImageMagick::Config }
|
49
|
+
App.register_configuration(:image_magick){ ImageMagick::Config }
|
50
|
+
App.register_configuration(:rails){ Config::Rails }
|
51
|
+
App.register_configuration(:heroku){ Config::Heroku }
|
52
|
+
|
46
53
|
end
|
47
54
|
end
|
@@ -1,29 +1,46 @@
|
|
1
1
|
require 'forwardable'
|
2
|
+
require 'dragonfly/active_model_extensions/attachment_class_methods'
|
2
3
|
|
3
4
|
module Dragonfly
|
4
5
|
module ActiveModelExtensions
|
5
6
|
|
6
7
|
class Attachment
|
7
8
|
|
9
|
+
# Exceptions
|
10
|
+
class BadAssignmentKey < RuntimeError; end
|
11
|
+
|
8
12
|
extend Forwardable
|
9
13
|
def_delegators :job,
|
10
14
|
:data, :to_file, :file, :tempfile, :path,
|
11
15
|
:process, :encode, :analyse,
|
12
16
|
:meta, :meta=,
|
17
|
+
:name, :basename, :ext, :size,
|
13
18
|
:url
|
14
19
|
|
15
|
-
def initialize(
|
16
|
-
@
|
17
|
-
self.
|
18
|
-
|
19
|
-
|
20
|
-
self.
|
20
|
+
def initialize(model)
|
21
|
+
@model = model
|
22
|
+
self.uid = model_uid
|
23
|
+
update_from_uid if uid
|
24
|
+
@should_run_callbacks = true
|
25
|
+
self.class.ensure_uses_cached_magic_attributes
|
26
|
+
end
|
27
|
+
|
28
|
+
def app
|
29
|
+
self.class.app
|
30
|
+
end
|
31
|
+
|
32
|
+
def attribute
|
33
|
+
self.class.attribute
|
21
34
|
end
|
22
35
|
|
23
36
|
def assign(value)
|
37
|
+
self.changed = true
|
38
|
+
destroy_retained! if retained?
|
39
|
+
set_uid_and_model_uid(nil)
|
24
40
|
if value.nil?
|
25
41
|
self.job = nil
|
26
42
|
reset_magic_attributes
|
43
|
+
self.class.run_callbacks(:after_unassign, model, self) if should_run_callbacks?
|
27
44
|
else
|
28
45
|
self.job = case value
|
29
46
|
when Job then value.dup
|
@@ -31,44 +48,34 @@ module Dragonfly
|
|
31
48
|
else app.new_job(value)
|
32
49
|
end
|
33
50
|
set_magic_attributes
|
51
|
+
update_meta
|
52
|
+
self.class.run_callbacks(:after_assign, model, self) if should_run_callbacks?
|
53
|
+
retain! if should_retain?
|
34
54
|
end
|
35
|
-
set_uid_and_parent_uid(nil)
|
36
55
|
value
|
37
56
|
end
|
38
57
|
|
58
|
+
def changed?
|
59
|
+
!!@changed
|
60
|
+
end
|
61
|
+
|
39
62
|
def destroy!
|
40
63
|
destroy_previous!
|
41
64
|
destroy_content(uid) if uid
|
42
65
|
end
|
43
66
|
|
44
67
|
def save!
|
45
|
-
|
68
|
+
sync_with_model
|
69
|
+
store_job! if job && !uid
|
46
70
|
destroy_previous!
|
47
|
-
|
48
|
-
|
49
|
-
:meta => {
|
50
|
-
:model_class => parent_model.class.name,
|
51
|
-
:model_attachment => attribute_name
|
52
|
-
}
|
53
|
-
)
|
54
|
-
self.job = job.to_fetched_job(uid)
|
55
|
-
end
|
71
|
+
self.changed = false
|
72
|
+
self.retained = false
|
56
73
|
end
|
57
74
|
|
58
75
|
def to_value
|
59
76
|
self if job
|
60
77
|
end
|
61
78
|
|
62
|
-
def analyse(meth, *args)
|
63
|
-
has_magic_attribute_for?(meth) ? magic_attribute_for(meth) : job.send(meth)
|
64
|
-
end
|
65
|
-
|
66
|
-
[:size, :ext, :name].each do |meth|
|
67
|
-
define_method meth do
|
68
|
-
analyse(meth)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
79
|
def name=(name)
|
73
80
|
job.name = name
|
74
81
|
set_magic_attribute(:name, name) if has_magic_attribute_for?(:name)
|
@@ -84,6 +91,71 @@ module Dragonfly
|
|
84
91
|
assign(encode(*args))
|
85
92
|
self
|
86
93
|
end
|
94
|
+
|
95
|
+
def remote_url(opts={})
|
96
|
+
app.remote_url_for(uid, opts) if uid
|
97
|
+
end
|
98
|
+
|
99
|
+
def apply
|
100
|
+
job.apply
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
attr_writer :should_run_callbacks
|
105
|
+
|
106
|
+
def should_run_callbacks?
|
107
|
+
!!@should_run_callbacks
|
108
|
+
end
|
109
|
+
|
110
|
+
# Retaining for avoiding uploading more than once
|
111
|
+
|
112
|
+
def retain!
|
113
|
+
if changed? && job
|
114
|
+
store_job!
|
115
|
+
self.retained = true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_writer :should_retain
|
120
|
+
|
121
|
+
def should_retain?
|
122
|
+
!!@should_retain
|
123
|
+
end
|
124
|
+
|
125
|
+
def retained?
|
126
|
+
!!@retained
|
127
|
+
end
|
128
|
+
|
129
|
+
def destroy_retained!
|
130
|
+
destroy_content(retained_attrs[:uid])
|
131
|
+
end
|
132
|
+
|
133
|
+
def retained_attrs
|
134
|
+
attribute_keys.inject({}) do |hash, key|
|
135
|
+
hash[key] = send(key)
|
136
|
+
hash
|
137
|
+
end if retained?
|
138
|
+
end
|
139
|
+
|
140
|
+
def retained_attrs=(attrs)
|
141
|
+
if changed? # if already set, ignore and destroy this retained content
|
142
|
+
destroy_content(attrs[:uid])
|
143
|
+
else
|
144
|
+
attrs.each do |key, value|
|
145
|
+
unless attribute_keys.include?(key)
|
146
|
+
raise BadAssignmentKey, "trying to call #{attribute}_#{key} = #{value.inspect} via retained_#{attribute} but this is not allowed!"
|
147
|
+
end
|
148
|
+
model.send("#{attribute}_#{key}=", value)
|
149
|
+
end
|
150
|
+
sync_with_model
|
151
|
+
update_from_uid
|
152
|
+
self.retained = true
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def inspect
|
157
|
+
"<Dragonfly Attachment uid=#{uid.inspect}, app=#{app.inspect}>"
|
158
|
+
end
|
87
159
|
|
88
160
|
protected
|
89
161
|
|
@@ -91,6 +163,18 @@ module Dragonfly
|
|
91
163
|
|
92
164
|
private
|
93
165
|
|
166
|
+
attr_writer :changed, :retained
|
167
|
+
|
168
|
+
def attribute_keys
|
169
|
+
[:uid] + magic_attributes
|
170
|
+
end
|
171
|
+
|
172
|
+
def store_job!
|
173
|
+
opts = self.class.evaluate_storage_opts(model, self)
|
174
|
+
set_uid_and_model_uid job.store(opts)
|
175
|
+
self.job = job.to_fetched_job(uid)
|
176
|
+
end
|
177
|
+
|
94
178
|
def destroy_content(uid)
|
95
179
|
app.datastore.destroy(uid)
|
96
180
|
rescue DataStorage::DataNotFound => e
|
@@ -104,48 +188,52 @@ module Dragonfly
|
|
104
188
|
end
|
105
189
|
end
|
106
190
|
|
107
|
-
def
|
108
|
-
# If the
|
109
|
-
if uid !=
|
110
|
-
self.uid =
|
191
|
+
def sync_with_model
|
192
|
+
# If the model uid has been set manually
|
193
|
+
if uid != model_uid
|
194
|
+
self.uid = model_uid
|
111
195
|
end
|
112
196
|
end
|
113
197
|
|
114
|
-
def
|
198
|
+
def set_uid_and_model_uid(uid)
|
115
199
|
self.uid = uid
|
116
|
-
self.
|
200
|
+
self.model_uid = uid
|
117
201
|
end
|
118
202
|
|
119
|
-
def
|
120
|
-
|
203
|
+
def model_uid=(uid)
|
204
|
+
model.send("#{attribute}_uid=", uid)
|
121
205
|
end
|
122
206
|
|
123
|
-
def
|
124
|
-
|
207
|
+
def model_uid
|
208
|
+
model.send("#{attribute}_uid")
|
125
209
|
end
|
126
210
|
|
127
|
-
attr_reader :
|
211
|
+
attr_reader :model, :uid
|
128
212
|
attr_writer :job
|
129
213
|
attr_accessor :previous_uid
|
130
|
-
attr_reader :uid
|
131
214
|
|
132
215
|
def uid=(uid)
|
133
216
|
self.previous_uid = @uid if @uid
|
134
217
|
@uid = uid
|
135
218
|
end
|
136
219
|
|
137
|
-
def
|
138
|
-
|
220
|
+
def update_meta
|
221
|
+
magic_attributes.each{|property| meta[property] = model.send("#{attribute}_#{property}") }
|
222
|
+
meta[:model_class] = model.class.name
|
223
|
+
meta[:model_attachment] = attribute
|
224
|
+
end
|
225
|
+
|
226
|
+
def update_from_uid
|
227
|
+
self.job = app.fetch(uid)
|
228
|
+
update_meta
|
139
229
|
end
|
140
230
|
|
141
231
|
def magic_attributes
|
142
|
-
|
143
|
-
name.to_s =~ /^#{attribute_name}_(.+)$/ && allowed_magic_attributes.include?($1.to_sym)
|
144
|
-
}.map{|name| name.to_s.sub("#{attribute_name}_", '').to_sym }
|
232
|
+
self.class.magic_attributes
|
145
233
|
end
|
146
234
|
|
147
235
|
def set_magic_attribute(property, value)
|
148
|
-
|
236
|
+
model.send("#{attribute}_#{property}=", value)
|
149
237
|
end
|
150
238
|
|
151
239
|
def set_magic_attributes
|
@@ -161,7 +249,7 @@ module Dragonfly
|
|
161
249
|
end
|
162
250
|
|
163
251
|
def magic_attribute_for(property)
|
164
|
-
|
252
|
+
model.send("#{attribute}_#{property}")
|
165
253
|
end
|
166
254
|
|
167
255
|
end
|