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
@@ -1,23 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- module HerokuRailsImages
5
-
6
- def self.apply_configuration(app, bucket_name)
7
- app.configure_with(RMagickImages)
8
- app.configure_with(RailsDefaults) do |c|
9
- # Use S3 for production
10
- if ::Rails.env == 'production'
11
- c.datastore = Dragonfly::DataStorage::S3DataStore.new
12
- c.datastore.configure do |d|
13
- d.bucket_name = bucket_name
14
- d.access_key_id = ENV['S3_KEY'] || raise("ENV variable 'S3_KEY' needs to be set - use\n\theroku config:add S3_KEY=XXXXXXXXX")
15
- d.secret_access_key = ENV['S3_SECRET'] || raise("ENV variable 'S3_SECRET' needs to be set - use\n\theroku config:add S3_SECRET=XXXXXXXXX")
16
- end
17
- end
18
- end
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,69 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- # RMagickImages is a saved configuration for Dragonfly apps, which does the following:
5
- # - registers an rmagick analyser
6
- # - registers an rmagick processor
7
- # - registers an rmagick encoder
8
- # - adds parameter shortcuts like '280x140!', etc.
9
- # Look at the source code for apply_configuration to see exactly how it configures the app.
10
- module RMagickImages
11
-
12
- def self.apply_configuration(app)
13
- app.configure do |c|
14
- c.register_analyser(Analysis::FileCommandAnalyser)
15
- c.register_analyser(Analysis::RMagickAnalyser)
16
- c.register_processor(Processing::RMagickProcessor)
17
- c.register_encoder(Encoding::RMagickEncoder)
18
- c.parameters.configure do |p|
19
- p.default_format = :jpg
20
- # Standard resizing like '30x40!', etc.
21
- p.add_shortcut(Symbol) do |format|
22
- {:format => format}
23
- end
24
- p.add_shortcut(/^\d*x\d*[><%^!]?$|^\d+@$/) do |geometry, match_data|
25
- {
26
- :processing_method => :resize,
27
- :processing_options => {:geometry => geometry}
28
- }
29
- end
30
- # Cropped resizing like '20x50#ne'
31
- p.add_shortcut(/^(\d+)x(\d+)#(\w{1,2})?/) do |geometry, match_data|
32
- {
33
- :processing_method => :resize_and_crop,
34
- :processing_options => {:width => match_data[1], :height => match_data[2], :gravity => match_data[3]}
35
- }
36
- end
37
- # Cropping like '30x30+10+10ne'
38
- p.add_shortcut(/^(\d+)x(\d+)([+-]\d+)([+-]\d+)(\w{1,2})?/) do |geometry, match_data|
39
- {
40
- :processing_method => :crop,
41
- :processing_options => {
42
- :width => match_data[1],
43
- :height => match_data[2],
44
- :x => match_data[3],
45
- :y => match_data[4],
46
- :gravity => match_data[5]
47
- }
48
- }
49
- end
50
- p.add_shortcut(/^\d*x/, Symbol) do |geometry, format|
51
- p.hash_from_shortcut(geometry).merge(:format => format)
52
- end
53
- p.add_shortcut(:rotate, Numeric) do |_, amount|
54
- {
55
- :processing_method => :rotate,
56
- :processing_options => {:amount => amount, :background_colour => '#0000'}
57
- }
58
- end
59
- p.add_shortcut(:rotate, Numeric, Symbol) do |a, b, format|
60
- p.hash_from_shortcut(a,b).merge(:format => format)
61
- end
62
- end
63
- end
64
-
65
- end
66
-
67
- end
68
- end
69
- end
@@ -1,25 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- module RMagickText
5
-
6
- def self.apply_configuration(app)
7
- app.configure do |c|
8
- c.datastore = DataStorage::TransparentDataStore.new
9
- c.register_analyser(Analysis::FileCommandAnalyser)
10
- c.register_processor(Processing::RMagickTextProcessor)
11
- c.register_encoder(Encoding::RMagickEncoder)
12
- c.parameters.add_shortcut :text, Hash do |_, options|
13
- {
14
- :processing_method => :text,
15
- :processing_options => options,
16
- :format => :png
17
- }
18
- end
19
- end
20
-
21
- end
22
-
23
- end
24
- end
25
- end
@@ -1,13 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- module RailsImages
5
-
6
- def self.apply_configuration(app)
7
- app.configure_with(RMagickImages)
8
- app.configure_with(RailsDefaults)
9
- end
10
-
11
- end
12
- end
13
- end
@@ -1,21 +0,0 @@
1
- module Dragonfly
2
- module DataStorage
3
- class Base
4
-
5
- include BelongsToApp
6
-
7
- def store(temp_object)
8
- raise NotImplementedError
9
- end
10
-
11
- def retrieve(uid)
12
- raise NotImplementedError
13
- end
14
-
15
- def destroy(uid)
16
- raise NotImplementedError
17
- end
18
-
19
- end
20
- end
21
- end
@@ -1,23 +0,0 @@
1
- require "base64"
2
-
3
- module Dragonfly
4
- module DataStorage
5
-
6
- class Base64DataStore < Base
7
-
8
- def store(temp_object)
9
- Base64.encode64(temp_object.data)
10
- end
11
-
12
- def retrieve(uid)
13
- Base64.decode64(uid)
14
- end
15
-
16
- def destroy(uid)
17
- # Nothing to destroy!
18
- end
19
-
20
- end
21
-
22
- end
23
- end
@@ -1,21 +0,0 @@
1
- module Dragonfly
2
- module DataStorage
3
-
4
- class TransparentDataStore < Base
5
-
6
- def store(temp_object)
7
- temp_object.data
8
- end
9
-
10
- def retrieve(uid)
11
- uid
12
- end
13
-
14
- def destroy(uid)
15
- # Nothing to destroy!
16
- end
17
-
18
- end
19
-
20
- end
21
- end
@@ -1,14 +0,0 @@
1
- module Dragonfly
2
- module Delegatable
3
-
4
- def delegatable_methods
5
- if @delegatable_methods
6
- @delegatable_methods
7
- else
8
- ancestors = self.class.ancestors
9
- @delegatable_methods = ancestors[0...ancestors.index(Delegatable)].map{|i| i.instance_methods(false) }.flatten
10
- end
11
- end
12
-
13
- end
14
- end
@@ -1,62 +0,0 @@
1
- module Dragonfly
2
- module Delegator
3
-
4
- include BelongsToApp
5
-
6
- # This gets raised if no delegated objects are able to handle
7
- # the method call, even though they respond to that method.
8
- class UnableToHandle < StandardError; end
9
-
10
- def register(klass, *args, &block)
11
- object = klass.new(*args)
12
- object.configure(&block) if block
13
- object.app = self.app if app_set? && object.is_a?(BelongsToApp)
14
- registered_objects << object
15
- object
16
- end
17
-
18
- def unregister(klass)
19
- registered_objects.delete_if{|obj| obj.is_a?(klass) }
20
- end
21
-
22
- def unregister_all
23
- self.registered_objects = []
24
- end
25
-
26
- def registered_objects
27
- @registered_objects ||= []
28
- end
29
-
30
- def delegate(meth, *args)
31
- registered_objects.reverse.each do |object|
32
- catch :unable_to_handle do
33
- return object.send(meth, *args) if object.respond_to?(meth)
34
- end
35
- end
36
- # If the code gets here, then none of the registered objects were able to handle the method call
37
- raise UnableToHandle, "None of the objects registered with #{self} were able to deal with the method call " +
38
- "#{meth}(#{args.map{|a| a.inspect[0..100]}.join(',')}). You need to register one that can."
39
- end
40
-
41
- def delegatable_methods
42
- registered_objects.map{|a| a.delegatable_methods }.flatten.uniq
43
- end
44
-
45
- def has_delegatable_method?(method)
46
- delegatable_methods.include?(method.to_method_name)
47
- end
48
-
49
- private
50
-
51
- attr_writer :registered_objects
52
-
53
- def method_missing(meth, *args)
54
- if has_delegatable_method?(meth)
55
- delegate(meth, *args)
56
- else
57
- super
58
- end
59
- end
60
-
61
- end
62
- end
@@ -1,9 +0,0 @@
1
- module Dragonfly
2
- class EncoderList
3
- include Delegator
4
-
5
- def initialize(app)
6
- @app = app
7
- end
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- module Dragonfly
2
- module Encoding
3
- class Base
4
-
5
- include BelongsToApp
6
- include Delegatable
7
-
8
- def encode(*args)
9
- throw :unable_to_handle
10
- end
11
-
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Dragonfly
2
- module Encoding
3
-
4
- class TransparentEncoder < Base
5
-
6
- # Does nothing
7
- def encode(temp_object, format, encoding={})
8
- temp_object
9
- end
10
-
11
- end
12
-
13
- end
14
- end
@@ -1,120 +0,0 @@
1
- module Dragonfly
2
-
3
- # An ExtendedTempObject is just a TempObject that belongs to a Dragonfly App.
4
- #
5
- # Because of this, it can make use of the app's registered processors, encoders and analysers
6
- #
7
- # Analysis methods can be accessed on the object itself, e.g. for a registered analysis method 'width', we have
8
- # temp_object.width # ===> 280
9
- #
10
- # Processing methods can be accessed using 'process', e.g. for a registered process method 'resize', we have
11
- # temp_object.process(:resize, {:some => 'option'}) # ===> processed ExtendedTempObject
12
- #
13
- # Similarly, encoding with the method 'encode' delegates to the app's registered encoders
14
- # temp_object.encode(:png, {:some => 'option'}) # ===> encoded ExtendedTempObject
15
- #
16
- # We can use bang methods to operate on the temp_object itself, rather than return a new one:
17
- # temp_object.process!(:resize, {:some => 'option'})
18
- # temp_object.encode!(:png, {:some => 'option'})
19
- #
20
- # You can make use of the app's registered parameter shortcuts (for processing and encoding in one go) using 'transform', e.g.
21
- # temp_object.transform('300x200', :gif) # ===> return a new processed and encoded ExtendedTempObject
22
- # temp_object.transform!('300x200', :gif) # ===> operate on self
23
- class ExtendedTempObject < TempObject
24
-
25
- include BelongsToApp
26
-
27
- def initialize(obj, app)
28
- super(obj)
29
- self.app = app
30
- @cache = {}
31
- end
32
-
33
- def process(processing_method, *args)
34
- self.class.new(processor.send(processing_method, self, *args), app)
35
- end
36
-
37
- def process!(processing_method, *args)
38
- modify_self!(processor.send(processing_method, self, *args))
39
- end
40
-
41
- def encode(*args)
42
- self.class.new(encoder.encode(self, *args), app)
43
- end
44
-
45
- def encode!(*args)
46
- modify_self!(encoder.encode(self, *args))
47
- end
48
-
49
- def transform(*args)
50
- args.any? ? dup.transform!(*args) : self
51
- end
52
-
53
- def transform!(*args)
54
- parameters = parameters_class.from_args(*args)
55
- process!(parameters.processing_method, parameters.processing_options) unless parameters.processing_method.nil?
56
- encode!(parameters.format, parameters.encoding) unless parameters.format.nil?
57
- self
58
- end
59
-
60
- # Modify methods, public_methods and respond_to?, because method_missing
61
- # allows methods from the analyser
62
-
63
- def methods(*args)
64
- (super + analyser.delegatable_methods).uniq
65
- end
66
-
67
- def public_methods(*args)
68
- (super + analyser.delegatable_methods).uniq
69
- end
70
-
71
- def respond_to?(method)
72
- super || analyser.has_delegatable_method?(method)
73
- end
74
-
75
- private
76
-
77
- attr_reader :cache
78
-
79
- def flush_cache!
80
- @cache = {}
81
- end
82
-
83
- def reset!
84
- super
85
- flush_cache!
86
- end
87
-
88
- def method_missing(method, *args, &block)
89
- if analyser.has_delegatable_method?(method)
90
- # Define the method on the instance so we don't use method_missing next time
91
- class << self; self; end.class_eval do
92
- define_method method do
93
- cache[method] ||= analyser.delegate(method, self)
94
- end
95
- end
96
- # Now that it's defined (for next time)
97
- send(method)
98
- else
99
- super
100
- end
101
- end
102
-
103
- def analyser
104
- app.analysers
105
- end
106
-
107
- def processor
108
- app.processors
109
- end
110
-
111
- def encoder
112
- app.encoders
113
- end
114
-
115
- def parameters_class
116
- app.parameters_class
117
- end
118
-
119
- end
120
- end