fog-dragonfly 0.8.1

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.
Files changed (155) hide show
  1. data/.specopts +2 -0
  2. data/.yardopts +23 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.rails.2.3.5 +14 -0
  5. data/History.md +266 -0
  6. data/LICENSE +20 -0
  7. data/README.md +88 -0
  8. data/Rakefile +92 -0
  9. data/VERSION +1 -0
  10. data/config.ru +13 -0
  11. data/docs.watchr +1 -0
  12. data/dragonfly.gemspec +293 -0
  13. data/extra_docs/Analysers.md +108 -0
  14. data/extra_docs/Caching.md +23 -0
  15. data/extra_docs/Configuration.md +138 -0
  16. data/extra_docs/DataStorage.md +136 -0
  17. data/extra_docs/Encoding.md +96 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +102 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/Index.md +36 -0
  22. data/extra_docs/MimeTypes.md +40 -0
  23. data/extra_docs/Models.md +266 -0
  24. data/extra_docs/Mongo.md +45 -0
  25. data/extra_docs/Processing.md +130 -0
  26. data/extra_docs/Rack.md +52 -0
  27. data/extra_docs/Rails2.md +55 -0
  28. data/extra_docs/Rails3.md +62 -0
  29. data/extra_docs/Sinatra.md +25 -0
  30. data/extra_docs/URLs.md +169 -0
  31. data/features/3.0.3.feature +8 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_2.3.5.feature +7 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +39 -0
  38. data/features/support/env.rb +40 -0
  39. data/fixtures/files/app/models/album.rb +3 -0
  40. data/fixtures/files/app/views/albums/new.html.erb +4 -0
  41. data/fixtures/files/app/views/albums/show.html.erb +4 -0
  42. data/fixtures/files/config/initializers/dragonfly.rb +4 -0
  43. data/fixtures/files/features/manage_album_images.feature +12 -0
  44. data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
  45. data/fixtures/files/features/support/paths.rb +15 -0
  46. data/fixtures/files/features/text_images.feature +7 -0
  47. data/fixtures/rails_2.3.5/template.rb +10 -0
  48. data/fixtures/rails_3.0.3/template.rb +20 -0
  49. data/irbrc.rb +17 -0
  50. data/lib/dragonfly.rb +45 -0
  51. data/lib/dragonfly/active_model_extensions.rb +13 -0
  52. data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
  53. data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
  54. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  55. data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
  56. data/lib/dragonfly/analyser.rb +59 -0
  57. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  58. data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
  59. data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
  60. data/lib/dragonfly/app.rb +182 -0
  61. data/lib/dragonfly/config/heroku.rb +19 -0
  62. data/lib/dragonfly/config/image_magick.rb +41 -0
  63. data/lib/dragonfly/config/r_magick.rb +46 -0
  64. data/lib/dragonfly/config/rails.rb +17 -0
  65. data/lib/dragonfly/configurable.rb +119 -0
  66. data/lib/dragonfly/core_ext/object.rb +8 -0
  67. data/lib/dragonfly/core_ext/string.rb +9 -0
  68. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  69. data/lib/dragonfly/data_storage.rb +9 -0
  70. data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
  71. data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
  72. data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
  73. data/lib/dragonfly/encoder.rb +13 -0
  74. data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
  75. data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
  76. data/lib/dragonfly/function_manager.rb +69 -0
  77. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
  78. data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
  79. data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/image_magick_utils.rb +81 -0
  82. data/lib/dragonfly/job.rb +371 -0
  83. data/lib/dragonfly/job_builder.rb +39 -0
  84. data/lib/dragonfly/job_definitions.rb +26 -0
  85. data/lib/dragonfly/job_endpoint.rb +15 -0
  86. data/lib/dragonfly/loggable.rb +28 -0
  87. data/lib/dragonfly/middleware.rb +34 -0
  88. data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
  89. data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
  90. data/lib/dragonfly/processor.rb +9 -0
  91. data/lib/dragonfly/r_magick_utils.rb +48 -0
  92. data/lib/dragonfly/rails/images.rb +22 -0
  93. data/lib/dragonfly/response.rb +82 -0
  94. data/lib/dragonfly/routed_endpoint.rb +40 -0
  95. data/lib/dragonfly/serializer.rb +32 -0
  96. data/lib/dragonfly/simple_cache.rb +23 -0
  97. data/lib/dragonfly/simple_endpoint.rb +63 -0
  98. data/lib/dragonfly/temp_object.rb +220 -0
  99. data/samples/beach.png +0 -0
  100. data/samples/egg.png +0 -0
  101. data/samples/round.gif +0 -0
  102. data/samples/sample.docx +0 -0
  103. data/samples/taj.jpg +0 -0
  104. data/spec/argument_matchers.rb +19 -0
  105. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  106. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  107. data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
  108. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  109. data/spec/dragonfly/analyser_spec.rb +123 -0
  110. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
  111. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
  112. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
  113. data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
  114. data/spec/dragonfly/app_spec.rb +280 -0
  115. data/spec/dragonfly/config/r_magick_spec.rb +25 -0
  116. data/spec/dragonfly/configurable_spec.rb +220 -0
  117. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  118. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  119. data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
  120. data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
  121. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
  122. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
  123. data/spec/dragonfly/deprecation_spec.rb +20 -0
  124. data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
  125. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
  126. data/spec/dragonfly/function_manager_spec.rb +154 -0
  127. data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
  128. data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
  129. data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
  130. data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
  131. data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +120 -0
  135. data/spec/dragonfly/job_spec.rb +773 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +68 -0
  138. data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
  139. data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
  140. data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
  141. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  142. data/spec/dragonfly/serializer_spec.rb +61 -0
  143. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  144. data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
  145. data/spec/dragonfly/temp_object_spec.rb +352 -0
  146. data/spec/image_matchers.rb +47 -0
  147. data/spec/simple_matchers.rb +44 -0
  148. data/spec/spec_helper.rb +58 -0
  149. data/yard/handlers/configurable_attr_handler.rb +38 -0
  150. data/yard/setup.rb +15 -0
  151. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  152. data/yard/templates/default/layout/html/layout.erb +87 -0
  153. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  154. data/yard/templates/default/module/setup.rb +17 -0
  155. metadata +550 -0
@@ -0,0 +1,45 @@
1
+ module Dragonfly
2
+ module ActiveModelExtensions
3
+ module ClassMethods
4
+
5
+ include Validations
6
+
7
+ def register_dragonfly_app(macro_name, app)
8
+ (class << self; self; end).class_eval do
9
+
10
+ # Defines e.g. 'image_accessor' for any activerecord class body
11
+ define_method macro_name do |attribute|
12
+
13
+ # Prior to activerecord 3, adding before callbacks more than once does add it more than once
14
+ before_save :save_attachments unless respond_to?(:before_save_callback_chain) && before_save_callback_chain.find(:save_attachments)
15
+ before_destroy :destroy_attachments unless respond_to?(:before_destroy_callback_chain) && before_destroy_callback_chain.find(:destroy_attachments)
16
+
17
+ # Register the new attribute
18
+ dragonfly_apps_for_attributes[attribute] = app
19
+
20
+ # Define the setter for the attribute
21
+ define_method "#{attribute}=" do |value|
22
+ attachments[attribute].assign(value)
23
+ end
24
+
25
+ # Define the getter for the attribute
26
+ define_method attribute do
27
+ attachments[attribute].to_value
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ app
34
+ end
35
+
36
+ def dragonfly_apps_for_attributes
37
+ @dragonfly_apps_for_attributes ||= begin
38
+ parent_class = ancestors.select{|a| a.is_a?(Class) }[1]
39
+ parent_class.respond_to?(:dragonfly_apps_for_attributes) ? parent_class.dragonfly_apps_for_attributes.dup : {}
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ module Dragonfly
2
+ module ActiveModelExtensions
3
+ module InstanceMethods
4
+
5
+ def attachments
6
+ @attachments ||= self.class.dragonfly_apps_for_attributes.inject({}) do |hash, (attribute, app)|
7
+ hash[attribute] = Attachment.new(app, self, attribute)
8
+ hash
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def save_attachments
15
+ attachments.each do |attribute, attachment|
16
+ attachment.save!
17
+ end
18
+ end
19
+
20
+ def destroy_attachments
21
+ attachments.each do |attribute, attachment|
22
+ attachment.destroy!
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ module Dragonfly
2
+ module ActiveModelExtensions
3
+ module Validations
4
+
5
+ private
6
+
7
+ def validates_property(property_name, opts)
8
+ attrs = opts[:of] or raise ArgumentError, "you need to provide the attribute which has the property, using :of => <attribute_name>"
9
+ attrs = [attrs].flatten #(make sure it's an array)
10
+
11
+ raise ArgumentError, "you must provide either :in => [<value1>, <value2>..] or :as => <value>" unless opts[:in] || opts[:as]
12
+ allowed_values = opts[:in] || [opts[:as]]
13
+
14
+ args = attrs + [opts]
15
+ validates_each(*args) do |record, attr, attachment|
16
+ if attachment
17
+ property = attachment.send(property_name)
18
+ record.errors.add(attr,
19
+ opts[:message] ||
20
+ "#{property_name.to_s.humanize.downcase} is incorrect. It needs to be #{expected_values_string(allowed_values)}, but was '#{property}'"
21
+ ) unless allowed_values.include?(property)
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ def expected_values_string(allowed_values)
28
+ if allowed_values.is_a?(Range)
29
+ "between #{allowed_values.first} and #{allowed_values.last}"
30
+ else
31
+ allowed_values.length > 1 ? "one of '#{allowed_values.join('\', \'')}'" : "'#{allowed_values.first.to_s}'"
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ module Dragonfly
2
+ class Analyser < FunctionManager
3
+
4
+ include Configurable
5
+ configurable_attr :enable_cache, true
6
+ configurable_attr :cache_size, 100
7
+
8
+ def initialize
9
+ super
10
+ analyser = self
11
+ @analysis_methods = Module.new do
12
+
13
+ define_method :analyser do
14
+ analyser
15
+ end
16
+
17
+ end
18
+ @analysis_method_names = []
19
+ end
20
+
21
+ attr_reader :analysis_methods, :analysis_method_names
22
+
23
+ def analyse(temp_object, method, *args)
24
+ if enable_cache
25
+ key = [temp_object.object_id, method, *args]
26
+ cache[key] ||= call_last(method, temp_object, *args)
27
+ else
28
+ call_last(method, temp_object, *args)
29
+ end
30
+ rescue NotDefined, UnableToHandle => e
31
+ log.warn(e.message)
32
+ nil
33
+ end
34
+
35
+ # Each time a function is registered with the analyser,
36
+ # add a method to the analysis_methods module.
37
+ # Expects the object that is extended to define 'analyse(method, *args)'
38
+ def add(name, *args, &block)
39
+ analysis_methods.module_eval %(
40
+ def #{name}(*args)
41
+ analyse(:#{name}, *args)
42
+ end
43
+ )
44
+ analysis_method_names << name.to_sym
45
+ super
46
+ end
47
+
48
+ def clear_cache!
49
+ @cache = nil
50
+ end
51
+
52
+ private
53
+
54
+ def cache
55
+ @cache ||= SimpleCache.new(cache_size)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,32 @@
1
+ module Dragonfly
2
+ module Analysis
3
+
4
+ class FileCommandAnalyser
5
+
6
+ include Configurable
7
+
8
+ configurable_attr :file_command, "file"
9
+ configurable_attr :use_filesystem, false
10
+ configurable_attr :num_bytes_to_check, 255
11
+
12
+ def mime_type(temp_object)
13
+ content_type = if use_filesystem
14
+ `#{file_command} -b --mime '#{temp_object.path}'`
15
+ else
16
+ IO.popen("#{file_command} -b --mime -", 'r+') do |io|
17
+ if num_bytes_to_check
18
+ io.write temp_object.data[0, num_bytes_to_check]
19
+ else
20
+ io.write temp_object.data
21
+ end
22
+ io.close_write
23
+ io.read
24
+ end
25
+ end.split(';').first
26
+ content_type.strip if content_type
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,47 @@
1
+ module Dragonfly
2
+ module Analysis
3
+ class ImageMagickAnalyser
4
+
5
+ include ImageMagickUtils
6
+ include Configurable
7
+
8
+ def width(temp_object)
9
+ identify(temp_object)[:width]
10
+ end
11
+
12
+ def height(temp_object)
13
+ identify(temp_object)[:height]
14
+ end
15
+
16
+ def aspect_ratio(temp_object)
17
+ attrs = identify(temp_object)
18
+ attrs[:width].to_f / attrs[:height]
19
+ end
20
+
21
+ def portrait?(temp_object)
22
+ attrs = identify(temp_object)
23
+ attrs[:width] <= attrs[:height]
24
+ end
25
+
26
+ def landscape?(temp_object)
27
+ attrs = identify(temp_object)
28
+ attrs[:width] >= attrs[:height]
29
+ end
30
+
31
+ def depth(temp_object)
32
+ identify(temp_object)[:depth]
33
+ end
34
+
35
+ def number_of_colours(temp_object)
36
+ details = raw_identify(temp_object, '-verbose -unique')
37
+ details[/Colors: (\d+)/, 1].to_i
38
+ end
39
+ alias number_of_colors number_of_colours
40
+
41
+ def format(temp_object)
42
+ identify(temp_object)[:format]
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,63 @@
1
+ require 'RMagick'
2
+
3
+ module Dragonfly
4
+ module Analysis
5
+ class RMagickAnalyser
6
+
7
+ include RMagickUtils
8
+ include Configurable
9
+
10
+ configurable_attr :use_filesystem, true
11
+
12
+ def width(temp_object)
13
+ ping_rmagick_image(temp_object) do |image|
14
+ image.columns
15
+ end
16
+ end
17
+
18
+ def height(temp_object)
19
+ ping_rmagick_image(temp_object) do |image|
20
+ image.rows
21
+ end
22
+ end
23
+
24
+ def aspect_ratio(temp_object)
25
+ ping_rmagick_image(temp_object) do |image|
26
+ image.columns.to_f / image.rows
27
+ end
28
+ end
29
+
30
+ def portrait?(temp_object)
31
+ ping_rmagick_image(temp_object) do |image|
32
+ image.columns <= image.rows
33
+ end
34
+ end
35
+
36
+ def landscape?(temp_object)
37
+ ping_rmagick_image(temp_object) do |image|
38
+ image.columns >= image.rows
39
+ end
40
+ end
41
+
42
+ def depth(temp_object)
43
+ rmagick_image(temp_object) do |image|
44
+ image.depth
45
+ end
46
+ end
47
+
48
+ def number_of_colours(temp_object)
49
+ rmagick_image(temp_object) do |image|
50
+ image.number_colors
51
+ end
52
+ end
53
+ alias number_of_colors number_of_colours
54
+
55
+ def format(temp_object)
56
+ ping_rmagick_image(temp_object) do |image|
57
+ image.format.downcase.to_sym
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,182 @@
1
+ require 'logger'
2
+ require 'forwardable'
3
+ require 'rack'
4
+
5
+ module Dragonfly
6
+ class App
7
+
8
+ class << self
9
+
10
+ private :new # Hide 'new' - need to use 'instance'
11
+
12
+ def instance(name)
13
+ apps[name] ||= new
14
+ end
15
+
16
+ alias [] instance
17
+
18
+ private
19
+
20
+ def apps
21
+ @apps ||= {}
22
+ end
23
+
24
+ end
25
+
26
+ def initialize
27
+ @analyser, @processor, @encoder, @generator = Analyser.new, Processor.new, Encoder.new, Generator.new
28
+ @analyser.use_same_log_as(self)
29
+ @processor.use_same_log_as(self)
30
+ @encoder.use_same_log_as(self)
31
+ @generator.use_same_log_as(self)
32
+ @job_definitions = JobDefinitions.new
33
+ @server = Dragonfly::SimpleEndpoint.new(self)
34
+ end
35
+
36
+ include Configurable
37
+
38
+ extend Forwardable
39
+ def_delegator :datastore, :destroy
40
+ def_delegators :new_job, :fetch, :generate, :fetch_file
41
+ def_delegator :server, :call
42
+
43
+ configurable_attr :datastore do DataStorage::FileDataStore.new end
44
+ configurable_attr :cache_duration, 3600*24*365 # (1 year)
45
+ configurable_attr :fallback_mime_type, 'application/octet-stream'
46
+ configurable_attr :url_path_prefix
47
+ configurable_attr :url_host
48
+ configurable_attr :url_suffix
49
+ configurable_attr :protect_from_dos_attacks, false
50
+ configurable_attr :secret, 'secret yo'
51
+ configurable_attr :log do Logger.new('/var/tmp/dragonfly.log') end
52
+ configurable_attr :infer_mime_type_from_file_ext, true
53
+ configurable_attr :content_disposition
54
+ configurable_attr :content_filename, Response::DEFAULT_FILENAME
55
+
56
+ attr_reader :analyser
57
+ attr_reader :processor
58
+ attr_reader :encoder
59
+ attr_reader :generator
60
+ attr_reader :server
61
+
62
+ configuration_method :analyser
63
+ configuration_method :processor
64
+ configuration_method :encoder
65
+ configuration_method :generator
66
+
67
+ attr_accessor :job_definitions
68
+
69
+ SAVED_CONFIGS = {
70
+ :imagemagick => 'ImageMagick',
71
+ :image_magick => 'ImageMagick',
72
+ :rmagick => 'RMagick',
73
+ :r_magick => 'RMagick',
74
+ :rails => 'Rails',
75
+ :heroku => 'Heroku'
76
+ }
77
+
78
+ def configurer_for(symbol)
79
+ class_name = SAVED_CONFIGS[symbol]
80
+ if class_name.nil?
81
+ raise ArgumentError, "#{symbol.inspect} is not a known configuration - try one of #{SAVED_CONFIGS.keys.join(', ')}"
82
+ end
83
+ Config.const_get(class_name)
84
+ end
85
+
86
+ def new_job(content=nil, opts={})
87
+ content ? Job.new(self, TempObject.new(content, opts)) : Job.new(self)
88
+ end
89
+
90
+ def endpoint(job=nil, &block)
91
+ block ? RoutedEndpoint.new(self, &block) : JobEndpoint.new(job)
92
+ end
93
+
94
+ def job(name, &block)
95
+ job_definitions.add(name, &block)
96
+ end
97
+ configuration_method :job
98
+
99
+ def store(object, opts={})
100
+ temp_object = object.is_a?(TempObject) ? object : TempObject.new(object)
101
+ temp_object.extract_attributes_from(opts)
102
+ datastore.store(temp_object, opts)
103
+ end
104
+
105
+ def register_mime_type(format, mime_type)
106
+ registered_mime_types[file_ext_string(format)] = mime_type
107
+ end
108
+ configuration_method :register_mime_type
109
+
110
+ def registered_mime_types
111
+ @registered_mime_types ||= Rack::Mime::MIME_TYPES.dup
112
+ end
113
+
114
+ def mime_type_for(format)
115
+ registered_mime_types[file_ext_string(format)]
116
+ end
117
+
118
+ def resolve_mime_type(temp_object)
119
+ mime_type_for(temp_object.format) ||
120
+ (mime_type_for(temp_object.ext) if infer_mime_type_from_file_ext) ||
121
+ analyser.analyse(temp_object, :mime_type) ||
122
+ mime_type_for(analyser.analyse(temp_object, :format)) ||
123
+ fallback_mime_type
124
+ end
125
+
126
+ def mount_path
127
+ url_path_prefix.blank? ? '/' : url_path_prefix
128
+ end
129
+
130
+ def url_for(job, *args)
131
+ if (args.length == 1 && args.first.kind_of?(Hash)) || args.empty?
132
+ opts = args.first ? args.first.dup : {}
133
+ host = opts.delete(:host) || url_host
134
+ suffix = opts.delete(:suffix) || url_suffix
135
+ suffix = suffix.call(job) if suffix.respond_to?(:call)
136
+ path_prefix = opts.delete(:path_prefix) || url_path_prefix
137
+ path = "#{host}#{path_prefix}#{job.to_path}#{suffix}"
138
+ query = opts
139
+ query.merge!(server.required_params_for(job)) if protect_from_dos_attacks
140
+ path << "?#{Rack::Utils.build_query(query)}" if query.any?
141
+ path
142
+ else
143
+ # Deprecation stuff - will be removed!!!
144
+ case args[0]
145
+ when /^(\d+)?x(\d+)?/
146
+ log.warn("DEPRECATED USE OF url_for and will be removed in the future - please use thumb(#{args.map{|a|a.inspect}.join(', ')}).url")
147
+ args[1] ? job.thumb(args[0], args[1]).url : job.thumb(args[0]).url
148
+ when :gif, :png, :jpg, :jpeg
149
+ log.warn("DEPRECATED USE OF url_for and will be removed in the future - please use encode(#{args.first.inspect}).url")
150
+ job.encode(args[0]).url
151
+ else
152
+ raise "DEPRECATED USE OF url_for - will be removed in future versions - please consult the docs"
153
+ end
154
+ end
155
+ end
156
+
157
+ def define_macro(mod, macro_name)
158
+ already_extended = (class << mod; self; end).included_modules.include?(ActiveModelExtensions)
159
+ mod.extend(ActiveModelExtensions) unless already_extended
160
+ mod.register_dragonfly_app(macro_name, self)
161
+ end
162
+
163
+ def define_macro_on_include(mod, macro_name)
164
+ app = self
165
+ (class << mod; self; end).class_eval do
166
+ alias included_without_dragonfly included
167
+ define_method :included_with_dragonfly do |mod|
168
+ included_without_dragonfly(mod)
169
+ app.define_macro(mod, macro_name)
170
+ end
171
+ alias included included_with_dragonfly
172
+ end
173
+ end
174
+
175
+ private
176
+
177
+ def file_ext_string(format)
178
+ '.' + format.to_s.downcase.sub(/^.*\./,'')
179
+ end
180
+
181
+ end
182
+ end