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.

Files changed (157) hide show
  1. data/.gitignore +2 -0
  2. data/.specopts +2 -0
  3. data/.yardopts +11 -5
  4. data/Gemfile +22 -0
  5. data/Gemfile.rails.2.3.5 +13 -0
  6. data/History.md +49 -0
  7. data/README.md +18 -28
  8. data/Rakefile +24 -36
  9. data/VERSION +1 -1
  10. data/config.ru +4 -1
  11. data/dragonfly.gemspec +85 -99
  12. data/extra_docs/Analysers.md +66 -30
  13. data/extra_docs/Caching.md +22 -0
  14. data/extra_docs/Configuration.md +116 -0
  15. data/extra_docs/DataStorage.md +114 -14
  16. data/extra_docs/Encoding.md +62 -37
  17. data/extra_docs/GeneralUsage.md +118 -0
  18. data/extra_docs/Generators.md +92 -0
  19. data/extra_docs/Heroku.md +51 -0
  20. data/extra_docs/Index.md +8 -9
  21. data/extra_docs/MimeTypes.md +18 -17
  22. data/extra_docs/Models.md +251 -0
  23. data/extra_docs/Processing.md +94 -70
  24. data/extra_docs/Rack.md +53 -0
  25. data/extra_docs/Rails2.md +44 -0
  26. data/extra_docs/Rails3.md +51 -0
  27. data/extra_docs/Sinatra.md +21 -0
  28. data/extra_docs/URLs.md +114 -0
  29. data/features/images.feature +6 -7
  30. data/features/no_processing.feature +0 -6
  31. data/features/rails_2.3.5.feature +1 -1
  32. data/features/rails_3.0.0.rc.feature +8 -0
  33. data/features/steps/dragonfly_steps.rb +14 -12
  34. data/features/steps/rails_steps.rb +20 -9
  35. data/features/support/env.rb +10 -11
  36. data/fixtures/files/app/views/albums/new.html.erb +4 -4
  37. data/fixtures/files/app/views/albums/show.html.erb +1 -1
  38. data/fixtures/files/features/manage_album_images.feature +1 -1
  39. data/fixtures/files/features/step_definitions/{album_steps.rb → image_steps.rb} +4 -3
  40. data/fixtures/files/features/support/paths.rb +2 -0
  41. data/fixtures/files/features/text_images.feature +7 -0
  42. data/fixtures/rails_3.0.0.rc/template.rb +21 -0
  43. data/irbrc.rb +2 -1
  44. data/lib/dragonfly.rb +4 -16
  45. data/lib/dragonfly/{active_record_extensions.rb → active_model_extensions.rb} +1 -1
  46. data/lib/dragonfly/active_model_extensions/attachment.rb +146 -0
  47. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/class_methods.rb +5 -6
  48. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/instance_methods.rb +1 -1
  49. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/validations.rb +5 -9
  50. data/lib/dragonfly/analyser.rb +59 -0
  51. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  52. data/lib/dragonfly/analysis/r_magick_analyser.rb +46 -31
  53. data/lib/dragonfly/app.rb +138 -173
  54. data/lib/dragonfly/config/heroku.rb +19 -0
  55. data/lib/dragonfly/config/r_magick.rb +37 -0
  56. data/lib/dragonfly/config/{rails_defaults.rb → rails.rb} +6 -7
  57. data/lib/dragonfly/configurable.rb +30 -27
  58. data/lib/dragonfly/core_ext/object.rb +1 -1
  59. data/lib/dragonfly/data_storage/file_data_store.rb +59 -26
  60. data/lib/dragonfly/data_storage/mongo_data_store.rb +65 -0
  61. data/lib/dragonfly/data_storage/s3data_store.rb +31 -12
  62. data/lib/dragonfly/encoder.rb +13 -0
  63. data/lib/dragonfly/encoding/r_magick_encoder.rb +10 -19
  64. data/lib/dragonfly/endpoint.rb +43 -0
  65. data/lib/dragonfly/function_manager.rb +65 -0
  66. data/lib/dragonfly/{processing/r_magick_text_processor.rb → generation/r_magick_generator.rb} +25 -11
  67. data/lib/dragonfly/generator.rb +9 -0
  68. data/lib/dragonfly/job.rb +290 -0
  69. data/lib/dragonfly/job_builder.rb +39 -0
  70. data/lib/dragonfly/job_definitions.rb +26 -0
  71. data/lib/dragonfly/job_endpoint.rb +17 -0
  72. data/lib/dragonfly/loggable.rb +28 -0
  73. data/lib/dragonfly/middleware.rb +21 -14
  74. data/lib/dragonfly/processing/r_magick_processor.rb +71 -48
  75. data/lib/dragonfly/processor.rb +9 -0
  76. data/lib/dragonfly/r_magick_utils.rb +24 -0
  77. data/lib/dragonfly/rails/images.rb +10 -7
  78. data/lib/dragonfly/routed_endpoint.rb +42 -0
  79. data/lib/dragonfly/serializer.rb +32 -0
  80. data/lib/dragonfly/simple_cache.rb +23 -0
  81. data/lib/dragonfly/simple_endpoint.rb +64 -0
  82. data/lib/dragonfly/temp_object.rb +77 -45
  83. data/spec/argument_matchers.rb +7 -17
  84. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  85. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  86. data/spec/dragonfly/{active_record_extensions → active_model_extensions}/model_spec.rb +282 -244
  87. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  88. data/spec/dragonfly/analyser_spec.rb +123 -0
  89. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +2 -2
  90. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +10 -1
  91. data/spec/dragonfly/app_spec.rb +175 -69
  92. data/spec/dragonfly/configurable_spec.rb +14 -0
  93. data/spec/dragonfly/data_storage/data_store_spec.rb +36 -9
  94. data/spec/dragonfly/data_storage/file_data_store_spec.rb +61 -38
  95. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +18 -0
  96. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +34 -39
  97. data/spec/dragonfly/deprecation_spec.rb +20 -0
  98. data/spec/dragonfly/function_manager_spec.rb +154 -0
  99. data/spec/dragonfly/generation/r_magick_generator_spec.rb +119 -0
  100. data/spec/dragonfly/job_builder_spec.rb +37 -0
  101. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  102. data/spec/dragonfly/job_endpoint_spec.rb +66 -0
  103. data/spec/dragonfly/job_spec.rb +605 -0
  104. data/spec/dragonfly/loggable_spec.rb +80 -0
  105. data/spec/dragonfly/middleware_spec.rb +37 -17
  106. data/spec/dragonfly/processing/r_magick_processor_spec.rb +182 -166
  107. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  108. data/spec/dragonfly/serializer_spec.rb +61 -0
  109. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  110. data/spec/dragonfly/simple_endpoint_spec.rb +78 -0
  111. data/spec/dragonfly/temp_object_spec.rb +154 -119
  112. data/spec/simple_matchers.rb +22 -0
  113. data/spec/spec_helper.rb +28 -4
  114. data/yard/templates/default/layout/html/layout.erb +18 -11
  115. metadata +89 -190
  116. data/config.rb +0 -5
  117. data/extra_docs/ActiveRecord.md +0 -196
  118. data/extra_docs/ExampleUseCases.md +0 -189
  119. data/extra_docs/GettingStarted.md +0 -114
  120. data/extra_docs/Shortcuts.md +0 -118
  121. data/extra_docs/UsingWithRails.md +0 -81
  122. data/features/rails_3.0.0.beta3.feature +0 -7
  123. data/fixtures/rails_3.0.0.beta3/template.rb +0 -16
  124. data/lib/dragonfly/active_record_extensions/attachment.rb +0 -170
  125. data/lib/dragonfly/analyser_list.rb +0 -9
  126. data/lib/dragonfly/analysis/base.rb +0 -10
  127. data/lib/dragonfly/belongs_to_app.rb +0 -24
  128. data/lib/dragonfly/config/heroku_rails_images.rb +0 -23
  129. data/lib/dragonfly/config/r_magick_images.rb +0 -69
  130. data/lib/dragonfly/config/r_magick_text.rb +0 -25
  131. data/lib/dragonfly/config/rails_images.rb +0 -13
  132. data/lib/dragonfly/data_storage/base.rb +0 -21
  133. data/lib/dragonfly/data_storage/base64_data_store.rb +0 -23
  134. data/lib/dragonfly/data_storage/transparent_data_store.rb +0 -21
  135. data/lib/dragonfly/delegatable.rb +0 -14
  136. data/lib/dragonfly/delegator.rb +0 -62
  137. data/lib/dragonfly/encoder_list.rb +0 -9
  138. data/lib/dragonfly/encoding/base.rb +0 -14
  139. data/lib/dragonfly/encoding/transparent_encoder.rb +0 -14
  140. data/lib/dragonfly/extended_temp_object.rb +0 -120
  141. data/lib/dragonfly/parameters.rb +0 -163
  142. data/lib/dragonfly/processing/base.rb +0 -10
  143. data/lib/dragonfly/processor_list.rb +0 -9
  144. data/lib/dragonfly/url_handler.rb +0 -147
  145. data/spec/dragonfly/active_record_extensions/attachment_spec.rb +0 -8
  146. data/spec/dragonfly/active_record_extensions/migration.rb +0 -42
  147. data/spec/dragonfly/active_record_extensions/models.rb +0 -6
  148. data/spec/dragonfly/active_record_extensions/spec_helper.rb +0 -24
  149. data/spec/dragonfly/belongs_to_app_spec.rb +0 -55
  150. data/spec/dragonfly/delegatable_spec.rb +0 -32
  151. data/spec/dragonfly/delegator_spec.rb +0 -145
  152. data/spec/dragonfly/extended_temp_object_spec.rb +0 -71
  153. data/spec/dragonfly/parameters_spec.rb +0 -298
  154. data/spec/dragonfly/processing/r_magick_text_processor_spec.rb +0 -84
  155. data/spec/dragonfly/url_handler_spec.rb +0 -247
  156. data/spec/dragonfly_spec.rb +0 -16
  157. data/spec/ginger_scenarios.rb +0 -13
@@ -39,10 +39,9 @@ Feature: champion uses dragonfly to process images
39
39
  And the image should have format 'png'
40
40
 
41
41
  Scenario: use a parameters shortcut
42
- # Note that this scenario makes use of the configured default format
43
- When I go to the url for "beach.png", with shortcut '100x150!'
44
- Then the response should be OK
45
- And the response should have mime-type 'image/jpeg'
46
- And the image should have width '100'
47
- And the image should have height '150'
48
- And the image should have format 'jpeg'
42
+ When I go to the url for "beach.png", with shortcut '100x150!'
43
+ Then the response should be OK
44
+ And the response should have mime-type 'image/png'
45
+ And the image should have width '100'
46
+ And the image should have height '150'
47
+ And the image should have format 'png'
@@ -12,9 +12,3 @@ Feature: winner uses dragonfly to serve different kinds of files
12
12
  Then the response should be OK
13
13
  And the response should have mime-type 'application/zip'
14
14
  And the response should have the same content as the file "sample.docx"
15
-
16
- Scenario: Go to url for original, with extension
17
- Given a stored file "sample.docx"
18
- When I go to the url for "sample.docx", with format 'docx'
19
- Then the response should be OK
20
- And the response should have mime-type 'application/zip'
@@ -4,4 +4,4 @@ Feature: champion uses dragonfly in his Rails 2.3.5 application
4
4
 
5
5
  Scenario: Set up dragonfly using the provided initializer
6
6
  Given a Rails 2.3.5 application set up for using dragonfly
7
- Then the cucumber features in my Rails 2.3.5 app should pass
7
+ Then the manage_album_images cucumber features in my Rails 2.3.5 app should pass
@@ -0,0 +1,8 @@
1
+ Feature: champion uses dragonfly in his Rails 3.0.0.rc application
2
+ In order to be a champion
3
+ A user uses dragonfly in his Rails 3.0.0.rc application
4
+
5
+ Scenario: Set up dragonfly using initializer
6
+ Given a Rails 3.0.0.rc application set up for using dragonfly
7
+ Then the manage_album_images cucumber features in my Rails 3.0.0.rc app should pass
8
+ And the text_images cucumber features in my Rails 3.0.0.rc app should pass
@@ -1,5 +1,7 @@
1
+ require 'tempfile'
2
+
1
3
  Given /^we are using the app for (\w+)$/ do |app_name|
2
- $app = Dragonfly::App[app_name.to_sym]
4
+ $app = Dragonfly[app_name.to_sym]
3
5
  end
4
6
 
5
7
  Given /^a stored file "(.+?)"$/ do |name|
@@ -16,23 +18,23 @@ Given /^a stored image "(.+?)" with dimensions (\d+)x(\d+)$/ do |name, width, he
16
18
  end
17
19
 
18
20
  When /^I go to the url for "(.+?)"$/ do |name|
19
- make_request name
21
+ uid = TEMP_FILES[name]
22
+ make_request $app.fetch(uid)
20
23
  end
21
24
 
22
- When /^I go to the url for "(.+?)", with format '([^']+?)'$/ do |name, ext|
23
- make_request name, :format => ext
25
+ When /^I go to the url for "(.+?)", with format '([^']+?)'$/ do |name, format|
26
+ uid = TEMP_FILES[name]
27
+ make_request $app.fetch(uid).encode(format)
24
28
  end
25
29
 
26
- When /^I go to the url for "(.+?)", with format '(.+?)' and resize geometry '(.+?)'$/ do |name, ext, geometry|
27
- make_request(name,
28
- :format => ext,
29
- :processing_method => :resize,
30
- :processing_options => {:geometry => geometry}
31
- )
30
+ When /^I go to the url for "(.+?)", with format '(.+?)' and resize geometry '(.+?)'$/ do |name, format, geometry|
31
+ uid = TEMP_FILES[name]
32
+ make_request $app.fetch(uid).process(:resize, geometry).encode(format)
32
33
  end
33
34
 
34
- When /^I go to the url for "(.+?)", with shortcut '([^']+?)'$/ do |name, arg1|
35
- make_request name, arg1
35
+ When /^I go to the url for "(.+?)", with shortcut '([^']+?)'$/ do |name, geometry|
36
+ uid = TEMP_FILES[name]
37
+ make_request $app.fetch(uid).thumb(geometry)
36
38
  end
37
39
 
38
40
  Then "the response should be OK" do
@@ -1,5 +1,9 @@
1
1
  RAILS_APP_NAME = 'tmp_app'
2
- FIXTURES_PATH = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
2
+ FIXTURES_PATH = ROOT_PATH + "/fixtures"
3
+ GEMFILES = {
4
+ '2.3.5' => ROOT_PATH + '/Gemfile.rails.2.3.5',
5
+ '3.0.0.rc' => ROOT_PATH + '/Gemfile',
6
+ }
3
7
 
4
8
  def fixture_path(version)
5
9
  "#{FIXTURES_PATH}/rails_#{version}"
@@ -11,18 +15,25 @@ end
11
15
 
12
16
  ##############################################################################
13
17
 
14
- Given /^a Rails (.+) application set up for using dragonfly$/ do |version|
15
- raise "Problem setting up Rails app" unless `
16
- cd #{fixture_path(version)} &&
17
- rm -rf #{RAILS_APP_NAME} &&
18
- rails _#{version}_ #{RAILS_APP_NAME} -m template.rb`
18
+ {
19
+ '2.3.5' => "BUNDLE_GEMFILE=#{GEMFILES['2.3.5']} rails #{RAILS_APP_NAME} -m template.rb",
20
+ '3.0.0.rc' => "BUNDLE_GEMFILE=#{GEMFILES['3.0.0.rc']} bundle exec rails new #{RAILS_APP_NAME} -m template.rb"
21
+ }.each do |version, rails_command|
22
+
23
+ Given /^a Rails #{version} application set up for using dragonfly$/ do
24
+ raise "Problem setting up Rails app" unless `
25
+ cd #{fixture_path(version)} &&
26
+ rm -rf #{RAILS_APP_NAME} &&
27
+ #{rails_command}`
28
+ end
29
+
19
30
  end
20
31
 
21
- Then /^the cucumber features in my Rails (.+) app should pass$/ do |version|
32
+ Then /^the (.+) cucumber features in my Rails (.+) app should pass$/ do |filename, version|
22
33
  puts "\n*** RUNNING FEATURES IN THE RAILS APP... ***\n"
23
34
  path = File.join(fixture_path(version), RAILS_APP_NAME)
24
- `cd #{path} && RAILS_ENV=cucumber rake db:migrate`
25
- features_passed = system "cd #{path} && cucumber features"
35
+ `cd #{path} && BUNDLE_GEMFILE=#{GEMFILES[version]} RAILS_ENV=cucumber rake db:migrate`
36
+ features_passed = system "cd #{path} && BUNDLE_GEMFILE=#{GEMFILES[version]} cucumber features/#{filename}.feature"
26
37
  puts "\n*** FINISHED RUNNING FEATURES IN THE RAILS APP ***\n"
27
38
  raise "Features failed" unless features_passed
28
39
  end
@@ -4,18 +4,14 @@ require 'spec/expectations'
4
4
  require 'test/unit/assertions'
5
5
  require File.dirname(__FILE__) + '/../../spec/image_matchers.rb'
6
6
 
7
- # A hack as system calls weren't using my path
8
- extra_paths = %w(/opt/local/bin)
9
- ENV['PATH'] ||= ''
10
- ENV['PATH'] += ':' + extra_paths.join(':')
7
+ ROOT_PATH = File.expand_path(File.dirname(__FILE__) + "/../..")
11
8
 
12
9
  # A hash of <name for reference> => <dragonfly uid> pairs
13
10
  TEMP_FILES = {}
14
11
 
15
- Dragonfly::App[:images].configure_with(Dragonfly::Config::RMagickImages)
16
- Dragonfly::App[:files].configure do |c|
17
- c.register_analyser(Dragonfly::Analysis::FileCommandAnalyser)
18
- c.register_encoder(Dragonfly::Encoding::TransparentEncoder)
12
+ Dragonfly[:images].configure_with(:rmagick)
13
+ Dragonfly[:files].configure do |c|
14
+ c.analyser.register(Dragonfly::Analysis::FileCommandAnalyser)
19
15
  end
20
16
 
21
17
  SAMPLE_IMAGE_PATH = File.dirname(__FILE__)+'/../../samples/beach.png'
@@ -28,12 +24,15 @@ Before do
28
24
  end
29
25
  end
30
26
 
27
+ AfterStep do |scenario|
28
+ FileUtils.rm_f("#{ROOT_PATH}/Gemfile.lock")
29
+ end
30
+
31
31
  module MyHelpers
32
32
 
33
- def make_request(name, *args)
33
+ def make_request(job)
34
34
  request = Rack::MockRequest.new($app)
35
- url = $app.url_for(TEMP_FILES[name], *args)
36
- @response = request.get(url)
35
+ @response = request.get(job.url)
37
36
  end
38
37
 
39
38
  end
@@ -1,4 +1,4 @@
1
- <% form_for @album, :html => {:multipart => true} do |f| %>
2
- <%= f.file_field :cover_image %>
3
- <%= f.submit 'Create' %>
4
- <% end %>
1
+ <form action="/albums" enctype="multipart/form-data" method="post">
2
+ <input name="album[cover_image]" type="file" />
3
+ <input type="submit" value="Create" />
4
+ </form>
@@ -1,4 +1,4 @@
1
1
  <%= flash[:notice] %>
2
2
  Look at this cover image!
3
- <%= image_tag @album.cover_image.url('200x100!') %>
3
+ <%= image_tag @album.cover_image.thumb('200x100!').url %>
4
4
  <%= link_to 'Index', albums_path %>
@@ -9,4 +9,4 @@ Feature: champion adds cover images to his albums
9
9
  Then I should see "successfully created"
10
10
  And I should see "Look at this cover image!"
11
11
  When I look at the generated beach image
12
- And I should see a JPEG image of size 200x100
12
+ And I should see a PNG image of size 200x100
@@ -1,14 +1,15 @@
1
1
  When /^I look at the generated (.+) image$/ do |image_name|
2
- page.body =~ /src="(.+?#{image_name}.+?)"/
2
+ page.body =~ %r{src="(/media[^"]+?)"}
3
3
  url = $1
4
4
  visit(url)
5
5
  end
6
6
 
7
7
  Then /^I should see a (.+) image of size (.+)$/ do |format, size|
8
8
  tempfile = Tempfile.new('wicked')
9
+ page.body.force_encoding('UTF-8').encode! if page.body.respond_to?(:force_encoding) # For some reason need this on Ruby 1.9.2
9
10
  tempfile.write page.body
10
11
  tempfile.close
11
12
  output = `identify #{tempfile.path}`.split(' ')
12
- output[1].should == 'JPEG'
13
- output[2].should == '200x100'
13
+ output[1].should == format
14
+ output[2].should == size
14
15
  end
@@ -3,6 +3,8 @@ module NavigationHelpers
3
3
  case page_name
4
4
  when "the new album page"
5
5
  '/albums/new'
6
+ when /^the image for text "(.+)", size "(.+)"$/
7
+ "/text/#{$1}/#{$2}"
6
8
  else
7
9
  raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
8
10
  "Now, go and add a mapping in #{__FILE__}"
@@ -0,0 +1,7 @@
1
+ Feature: champion adds text images to his app
2
+ In order to be a champion
3
+ A user adds text images to his app
4
+
5
+ Scenario: View text image
6
+ When I go to the image for text "Hello", size "300x150!"
7
+ Then I should see a PNG image of size 300x150
@@ -0,0 +1,21 @@
1
+ gem 'rack-cache', :require => 'rack/cache'
2
+ gem 'rmagick', '2.12.2', :require => 'RMagick'
3
+
4
+ gem 'capybara'
5
+ gem 'cucumber-rails'
6
+ gem 'cucumber', '0.8.5'
7
+
8
+ generate 'cucumber:install'
9
+
10
+ generate 'scaffold albums cover_image_uid:string'
11
+ rake 'db:migrate'
12
+
13
+ # Copy over all files from the template dir
14
+ files_dir = File.expand_path(File.dirname(__FILE__) + '/../files')
15
+ run "cp -r #{files_dir}/** ."
16
+
17
+ route <<ROUTES
18
+ match '/text/:text/:size' => Dragonfly[:images].endpoint{|params, app|
19
+ app.generate(:text, params[:text]).thumb(params[:size])
20
+ }
21
+ ROUTES
data/irbrc.rb CHANGED
@@ -1,4 +1,5 @@
1
- require File.dirname(__FILE__) + '/config'
1
+ require File.dirname(__FILE__) + '/lib/dragonfly'
2
+ APP = Dragonfly[:images].configure_with(:rmagick)
2
3
 
3
4
  available_uids = `find #{APP.datastore.root_path} ! -type d`.split("\n").map do |file|
4
5
  file.sub("#{APP.datastore.root_path}/", '')
data/lib/dragonfly.rb CHANGED
@@ -1,4 +1,4 @@
1
- # AUTOLOAD EVERYTHING IN THE IMAGETASTIC DIRECTORY TREE
1
+ # AUTOLOAD EVERYTHING IN THE DRAGONFLY DIRECTORY TREE
2
2
 
3
3
  # The convention is that dirs are modules
4
4
  # so declare them here and autoload any modules/classes inside them
@@ -17,6 +17,7 @@ def autoload_files_in_dir(path, namespace)
17
17
  eval("module #{namespace}; end")
18
18
  # Autoload modules/classes in that module
19
19
  Dir.glob("#{path}/*.rb").each do |file|
20
+ file = File.expand_path(file)
20
21
  sub_const_name = camelize( File.basename(file, '.rb') )
21
22
  eval("#{namespace}.autoload('#{sub_const_name}', '#{file}')")
22
23
  end
@@ -36,21 +37,8 @@ require File.dirname(__FILE__) + '/dragonfly/core_ext/symbol'
36
37
  module Dragonfly
37
38
  class << self
38
39
 
39
- def const_missing(const)
40
- case const
41
- when :RMagickConfiguration
42
- puts "WARNING: RMagickConfiguration is deprecated and will be removed in future "+
43
- "versions of Dragonfly. Please change to Dragonfly::Config::RMagickImages"
44
- const_set(:RMagickConfiguration, Config::RMagickImages)
45
- else
46
- super
47
- end
48
- end
49
-
50
- def active_record_macro(prefix, app)
51
- already_extended = (class << ActiveRecord::Base; self; end).included_modules.include?(ActiveRecordExtensions)
52
- ActiveRecord::Base.extend(ActiveRecordExtensions) unless already_extended
53
- ActiveRecord::Base.register_dragonfly_app(prefix, app)
40
+ def [](*args)
41
+ App[*args]
54
42
  end
55
43
 
56
44
  end
@@ -1,6 +1,6 @@
1
1
  module Dragonfly
2
2
 
3
- module ActiveRecordExtensions
3
+ module ActiveModelExtensions
4
4
 
5
5
  def self.extended(klass)
6
6
  unless klass.include?(InstanceMethods)
@@ -0,0 +1,146 @@
1
+ require 'forwardable'
2
+
3
+ module Dragonfly
4
+ module ActiveModelExtensions
5
+
6
+ class Attachment
7
+
8
+ extend Forwardable
9
+ def_delegators :job,
10
+ :data, :to_file, :file, :tempfile, :path,
11
+ :process, :encode, :analyse,
12
+ :url
13
+
14
+ def initialize(app, parent_model, attribute_name)
15
+ @app, @parent_model, @attribute_name = app, parent_model, attribute_name
16
+ self.extend app.analyser.analysis_methods
17
+ self.extend app.job_definitions
18
+ self.uid = parent_uid
19
+ self.job = app.fetch(uid) if uid
20
+ end
21
+
22
+ def assign(value)
23
+ if value.nil?
24
+ self.job = nil
25
+ reset_magic_attributes
26
+ else
27
+ self.job = case value
28
+ when Job then value.dup
29
+ when self.class then value.job.dup
30
+ else app.new_job(value)
31
+ end
32
+ set_magic_attributes
33
+ end
34
+ set_uid_and_parent_uid(nil)
35
+ value
36
+ end
37
+
38
+ def destroy!
39
+ destroy_previous!
40
+ destroy_content(uid) if uid
41
+ end
42
+
43
+ def save!
44
+ sync_with_parent!
45
+ destroy_previous!
46
+ if job && !uid
47
+ set_uid_and_parent_uid app.store(job.result)
48
+ self.job = job.to_fetched_job(uid)
49
+ end
50
+ end
51
+
52
+ def to_value
53
+ self if job
54
+ end
55
+
56
+ def analyse(meth, *args)
57
+ has_magic_attribute_for?(meth) ? magic_attribute_for(meth) : job.send(meth)
58
+ end
59
+
60
+ [:size, :ext, :name].each do |meth|
61
+ define_method meth do
62
+ analyse(meth)
63
+ end
64
+ end
65
+
66
+ protected
67
+
68
+ attr_reader :job
69
+
70
+ private
71
+
72
+ def destroy_content(uid)
73
+ app.datastore.destroy(uid)
74
+ rescue DataStorage::DataNotFound => e
75
+ app.log.warn("*** WARNING ***: tried to destroy data with uid #{uid}, but got error: #{e}")
76
+ end
77
+
78
+ def destroy_previous!
79
+ if previous_uid
80
+ destroy_content(previous_uid)
81
+ self.previous_uid = nil
82
+ end
83
+ end
84
+
85
+ def sync_with_parent!
86
+ # If the parent uid has been set manually
87
+ if uid != parent_uid
88
+ self.uid = parent_uid
89
+ end
90
+ end
91
+
92
+ def set_uid_and_parent_uid(uid)
93
+ self.uid = uid
94
+ self.parent_uid = uid
95
+ end
96
+
97
+ def parent_uid=(uid)
98
+ parent_model.send("#{attribute_name}_uid=", uid)
99
+ end
100
+
101
+ def parent_uid
102
+ parent_model.send("#{attribute_name}_uid")
103
+ end
104
+
105
+ attr_reader :app, :parent_model, :attribute_name
106
+ attr_writer :job
107
+ attr_accessor :previous_uid
108
+ attr_reader :uid
109
+
110
+ def uid=(uid)
111
+ self.previous_uid = @uid if @uid
112
+ @uid = uid
113
+ end
114
+
115
+ def allowed_magic_attributes
116
+ app.analyser.analysis_method_names + [:size, :ext, :name]
117
+ end
118
+
119
+ def magic_attributes
120
+ parent_model.public_methods.select { |name|
121
+ name.to_s =~ /^#{attribute_name}_(.+)$/ && allowed_magic_attributes.include?($1.to_sym)
122
+ }
123
+ end
124
+
125
+ def set_magic_attributes
126
+ magic_attributes.each do |attribute|
127
+ method = attribute.to_s.sub("#{attribute_name}_", '')
128
+ parent_model.send("#{attribute}=", job.send(method))
129
+ end
130
+ end
131
+
132
+ def reset_magic_attributes
133
+ magic_attributes.each{|attribute| parent_model.send("#{attribute}=", nil) }
134
+ end
135
+
136
+ def has_magic_attribute_for?(property)
137
+ magic_attributes.include?("#{attribute_name}_#{property}".to_method_name)
138
+ end
139
+
140
+ def magic_attribute_for(property)
141
+ parent_model.send("#{attribute_name}_#{property}")
142
+ end
143
+
144
+ end
145
+ end
146
+ end