dragonfly 0.9.15 → 1.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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -8
  3. data/.travis.yml +11 -0
  4. data/Gemfile +1 -0
  5. data/History.md +52 -2
  6. data/LICENSE +1 -1
  7. data/README.md +38 -95
  8. data/dev/grid.jpg +0 -0
  9. data/dev/irbrc.rb +27 -0
  10. data/dev/rails_template.rb +38 -0
  11. data/dev/test.ru +56 -0
  12. data/dev/test_rails +19 -0
  13. data/dragonfly.gemspec +3 -21
  14. data/lib/dragonfly.rb +45 -44
  15. data/lib/dragonfly/app.rb +175 -96
  16. data/lib/dragonfly/configurable.rb +71 -170
  17. data/lib/dragonfly/content.rb +211 -0
  18. data/lib/dragonfly/core_ext/object.rb +1 -6
  19. data/lib/dragonfly/file_data_store.rb +197 -0
  20. data/lib/dragonfly/image_magick/analysers/image_properties.rb +23 -0
  21. data/lib/dragonfly/image_magick/generators/convert.rb +19 -0
  22. data/lib/dragonfly/image_magick/generators/plain.rb +26 -0
  23. data/lib/dragonfly/image_magick/generators/plasma.rb +25 -0
  24. data/lib/dragonfly/image_magick/generators/text.rb +127 -0
  25. data/lib/dragonfly/image_magick/plugin.rb +83 -0
  26. data/lib/dragonfly/image_magick/processors/convert.rb +29 -0
  27. data/lib/dragonfly/image_magick/processors/encode.rb +18 -0
  28. data/lib/dragonfly/image_magick/processors/thumb.rb +76 -0
  29. data/lib/dragonfly/job.rb +118 -134
  30. data/lib/dragonfly/job_endpoint.rb +2 -0
  31. data/lib/dragonfly/memory_data_store.rb +34 -0
  32. data/lib/dragonfly/middleware.rb +5 -3
  33. data/lib/dragonfly/{active_model_extensions.rb → model.rb} +5 -3
  34. data/lib/dragonfly/{active_model_extensions → model}/attachment.rb +40 -35
  35. data/lib/dragonfly/{active_model_extensions → model}/attachment_class_methods.rb +36 -40
  36. data/lib/dragonfly/model/class_methods.rb +109 -0
  37. data/lib/dragonfly/{active_model_extensions → model}/instance_methods.rb +2 -2
  38. data/lib/dragonfly/{active_model_extensions → model}/validations.rb +17 -12
  39. data/lib/dragonfly/railtie.rb +8 -6
  40. data/lib/dragonfly/register.rb +27 -0
  41. data/lib/dragonfly/response.rb +47 -52
  42. data/lib/dragonfly/routed_endpoint.rb +4 -0
  43. data/lib/dragonfly/serializer.rb +15 -5
  44. data/lib/dragonfly/server.rb +56 -29
  45. data/lib/dragonfly/shell.rb +12 -23
  46. data/lib/dragonfly/spec/data_store_examples.rb +64 -0
  47. data/lib/dragonfly/temp_object.rb +32 -47
  48. data/lib/dragonfly/url_attributes.rb +19 -22
  49. data/lib/dragonfly/url_mapper.rb +3 -0
  50. data/lib/dragonfly/utils.rb +12 -0
  51. data/lib/dragonfly/version.rb +1 -1
  52. data/lib/dragonfly/whitelist.rb +19 -0
  53. data/lib/rails/generators/dragonfly/USAGE +8 -0
  54. data/lib/rails/generators/dragonfly/dragonfly_generator.rb +24 -0
  55. data/lib/rails/generators/dragonfly/templates/initializer.rb.erb +27 -0
  56. data/samples/gif.gif +0 -0
  57. data/spec/dragonfly/app_spec.rb +270 -64
  58. data/spec/dragonfly/configurable_spec.rb +142 -418
  59. data/spec/dragonfly/content_spec.rb +353 -0
  60. data/spec/dragonfly/cookie_monster_spec.rb +2 -1
  61. data/spec/dragonfly/file_data_store_spec.rb +301 -0
  62. data/spec/dragonfly/image_magick/analysers/image_properties_spec.rb +20 -0
  63. data/spec/dragonfly/image_magick/generators/convert_spec.rb +19 -0
  64. data/spec/dragonfly/image_magick/generators/plain_spec.rb +50 -0
  65. data/spec/dragonfly/image_magick/generators/plasma_spec.rb +32 -0
  66. data/spec/dragonfly/image_magick/generators/text_spec.rb +77 -0
  67. data/spec/dragonfly/image_magick/plugin_spec.rb +131 -0
  68. data/spec/dragonfly/image_magick/processors/convert_spec.rb +56 -0
  69. data/spec/dragonfly/image_magick/processors/thumb_spec.rb +173 -0
  70. data/spec/dragonfly/job_endpoint_spec.rb +30 -73
  71. data/spec/dragonfly/job_spec.rb +280 -608
  72. data/spec/dragonfly/memory_data_store_spec.rb +20 -0
  73. data/spec/dragonfly/middleware_spec.rb +47 -27
  74. data/spec/dragonfly/{active_model_extensions → model}/model_spec.rb +331 -555
  75. data/spec/dragonfly/model/validations_spec.rb +196 -0
  76. data/spec/dragonfly/register_spec.rb +35 -0
  77. data/spec/dragonfly/routed_endpoint_spec.rb +6 -6
  78. data/spec/dragonfly/serializer_spec.rb +13 -15
  79. data/spec/dragonfly/server_spec.rb +122 -46
  80. data/spec/dragonfly/shell_spec.rb +43 -24
  81. data/spec/dragonfly/temp_object_spec.rb +69 -94
  82. data/spec/dragonfly/url_attributes_spec.rb +49 -0
  83. data/spec/dragonfly/utils_spec.rb +32 -0
  84. data/spec/dragonfly/whitelist_spec.rb +30 -0
  85. data/spec/dragonfly_spec.rb +43 -0
  86. data/spec/fixtures/deprecated_stored_content/eggs.bonus +1 -0
  87. data/spec/fixtures/deprecated_stored_content/eggs.bonus.meta +1 -0
  88. data/spec/functional/configuration_spec.rb +19 -0
  89. data/spec/functional/model_urls_spec.rb +43 -41
  90. data/spec/functional/remote_on_the_fly_spec.rb +14 -16
  91. data/spec/functional/shell_commands_spec.rb +24 -14
  92. data/spec/functional/to_response_spec.rb +10 -10
  93. data/spec/functional/urls_spec.rb +5 -3
  94. data/spec/spec_helper.rb +23 -28
  95. data/spec/support/argument_matchers.rb +7 -8
  96. data/spec/support/image_matchers.rb +14 -36
  97. data/spec/support/model_helpers.rb +97 -0
  98. data/spec/support/simple_matchers.rb +12 -0
  99. metadata +92 -393
  100. data/.yardopts +0 -29
  101. data/Rakefile +0 -36
  102. data/config.ru +0 -14
  103. data/docs.watchr +0 -1
  104. data/extra_docs/Analysers.md +0 -68
  105. data/extra_docs/Caching.md +0 -23
  106. data/extra_docs/Configuration.md +0 -149
  107. data/extra_docs/Couch.md +0 -49
  108. data/extra_docs/DataStorage.md +0 -226
  109. data/extra_docs/Encoding.md +0 -67
  110. data/extra_docs/ExampleUseCases.md +0 -116
  111. data/extra_docs/GeneralUsage.md +0 -105
  112. data/extra_docs/Generators.md +0 -68
  113. data/extra_docs/Heroku.md +0 -50
  114. data/extra_docs/ImageMagick.md +0 -136
  115. data/extra_docs/Index.md +0 -33
  116. data/extra_docs/MimeTypes.md +0 -40
  117. data/extra_docs/Models.md +0 -441
  118. data/extra_docs/Mongo.md +0 -42
  119. data/extra_docs/Processing.md +0 -77
  120. data/extra_docs/Rack.md +0 -52
  121. data/extra_docs/Rails2.md +0 -57
  122. data/extra_docs/Rails3.md +0 -56
  123. data/extra_docs/ServingRemotely.md +0 -104
  124. data/extra_docs/Sinatra.md +0 -25
  125. data/extra_docs/URLs.md +0 -203
  126. data/features/images.feature +0 -47
  127. data/features/no_processing.feature +0 -14
  128. data/features/rails.feature +0 -8
  129. data/features/steps/common_steps.rb +0 -8
  130. data/features/steps/dragonfly_steps.rb +0 -66
  131. data/features/steps/rails_steps.rb +0 -40
  132. data/features/support/env.rb +0 -13
  133. data/features/support/setup.rb +0 -41
  134. data/fixtures/rails/files/app/models/album.rb +0 -6
  135. data/fixtures/rails/files/app/views/albums/new.html.erb +0 -7
  136. data/fixtures/rails/files/app/views/albums/show.html.erb +0 -6
  137. data/fixtures/rails/files/config/initializers/dragonfly.rb +0 -4
  138. data/fixtures/rails/files/features/manage_album_images.feature +0 -38
  139. data/fixtures/rails/files/features/step_definitions/helper_steps.rb +0 -7
  140. data/fixtures/rails/files/features/step_definitions/image_steps.rb +0 -25
  141. data/fixtures/rails/files/features/step_definitions/web_steps.rb +0 -189
  142. data/fixtures/rails/files/features/support/paths.rb +0 -17
  143. data/fixtures/rails/files/features/text_images.feature +0 -7
  144. data/fixtures/rails/template.rb +0 -20
  145. data/irbrc.rb +0 -19
  146. data/lib/dragonfly/active_model_extensions/class_methods.rb +0 -98
  147. data/lib/dragonfly/analyser.rb +0 -58
  148. data/lib/dragonfly/analysis/file_command_analyser.rb +0 -33
  149. data/lib/dragonfly/analysis/image_magick_analyser.rb +0 -6
  150. data/lib/dragonfly/config/heroku.rb +0 -26
  151. data/lib/dragonfly/config/image_magick.rb +0 -6
  152. data/lib/dragonfly/config/rails.rb +0 -20
  153. data/lib/dragonfly/data_storage.rb +0 -11
  154. data/lib/dragonfly/data_storage/couch_data_store.rb +0 -83
  155. data/lib/dragonfly/data_storage/file_data_store.rb +0 -144
  156. data/lib/dragonfly/data_storage/mongo_data_store.rb +0 -96
  157. data/lib/dragonfly/data_storage/s3data_store.rb +0 -168
  158. data/lib/dragonfly/encoder.rb +0 -13
  159. data/lib/dragonfly/encoding/image_magick_encoder.rb +0 -6
  160. data/lib/dragonfly/function_manager.rb +0 -67
  161. data/lib/dragonfly/generation/image_magick_generator.rb +0 -6
  162. data/lib/dragonfly/generator.rb +0 -9
  163. data/lib/dragonfly/image_magick/analyser.rb +0 -53
  164. data/lib/dragonfly/image_magick/config.rb +0 -44
  165. data/lib/dragonfly/image_magick/encoder.rb +0 -57
  166. data/lib/dragonfly/image_magick/generator.rb +0 -147
  167. data/lib/dragonfly/image_magick/processor.rb +0 -114
  168. data/lib/dragonfly/image_magick/utils.rb +0 -46
  169. data/lib/dragonfly/image_magick_utils.rb +0 -4
  170. data/lib/dragonfly/job_builder.rb +0 -39
  171. data/lib/dragonfly/job_definitions.rb +0 -30
  172. data/lib/dragonfly/loggable.rb +0 -28
  173. data/lib/dragonfly/processing/image_magick_processor.rb +0 -6
  174. data/lib/dragonfly/processor.rb +0 -9
  175. data/lib/dragonfly/rails/images.rb +0 -32
  176. data/lib/dragonfly/simple_cache.rb +0 -23
  177. data/spec/dragonfly/active_model_extensions/spec_helper.rb +0 -95
  178. data/spec/dragonfly/analyser_spec.rb +0 -123
  179. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +0 -49
  180. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +0 -84
  181. data/spec/dragonfly/data_storage/file_data_store_spec.rb +0 -308
  182. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +0 -81
  183. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +0 -277
  184. data/spec/dragonfly/data_storage/shared_data_store_examples.rb +0 -77
  185. data/spec/dragonfly/function_manager_spec.rb +0 -154
  186. data/spec/dragonfly/image_magick/analyser_spec.rb +0 -73
  187. data/spec/dragonfly/image_magick/encoder_spec.rb +0 -46
  188. data/spec/dragonfly/image_magick/generator_spec.rb +0 -178
  189. data/spec/dragonfly/image_magick/processor_spec.rb +0 -293
  190. data/spec/dragonfly/job_builder_spec.rb +0 -37
  191. data/spec/dragonfly/job_definitions_spec.rb +0 -57
  192. data/spec/dragonfly/loggable_spec.rb +0 -80
  193. data/spec/dragonfly/simple_cache_spec.rb +0 -27
  194. data/spec/dragonfly/url_attributes.rb +0 -47
  195. data/spec/functional/deprecations_spec.rb +0 -51
  196. data/spec/functional/image_magick_app_spec.rb +0 -27
  197. data/spec/test_imagemagick.ru +0 -49
  198. data/yard/handlers/configurable_attr_handler.rb +0 -38
  199. data/yard/setup.rb +0 -15
  200. data/yard/templates/default/fulldoc/html/css/common.css +0 -109
  201. data/yard/templates/default/layout/html/layout.erb +0 -93
  202. data/yard/templates/default/module/html/configuration_summary.erb +0 -31
  203. data/yard/templates/default/module/setup.rb +0 -17
@@ -1,17 +0,0 @@
1
- module NavigationHelpers
2
- def path_to(page_name)
3
- case page_name
4
- when "the new album page"
5
- '/albums/new'
6
- when /^the page for album "(.+)"$/
7
- album_path(Album.find_by_name($1))
8
- when /^the image for text "(.+)", size "(.+)"$/
9
- "/text/#{$1}/#{$2}"
10
- else
11
- raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
12
- "Now, go and add a mapping in #{__FILE__}"
13
- end
14
- end
15
- end
16
-
17
- World(NavigationHelpers)
@@ -1,7 +0,0 @@
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
@@ -1,20 +0,0 @@
1
- gem 'rack-cache', :require => 'rack/cache'
2
-
3
- gem 'capybara'
4
- gem 'cucumber-rails'
5
- gem 'cucumber', '0.8.5'
6
-
7
- generate 'cucumber:install'
8
-
9
- generate 'scaffold albums cover_image_uid:string name:string'
10
- rake 'db:migrate'
11
-
12
- # Copy over all files from the template dir
13
- files_dir = File.expand_path(File.dirname(__FILE__) + '/files')
14
- run "cp -r #{files_dir}/** ."
15
-
16
- route <<ROUTES
17
- match '/text/:text/:size' => Dragonfly[:images].endpoint{|params, app|
18
- app.generate(:text, params[:text]).thumb(params[:size])
19
- }
20
- ROUTES
data/irbrc.rb DELETED
@@ -1,19 +0,0 @@
1
- require "rubygems"
2
- require "bundler/setup"
3
- $:.unshift(File.expand_path('../lib', __FILE__))
4
- require 'dragonfly'
5
- include Dragonfly::Serializer
6
- APP = Dragonfly[:images].configure_with(:imagemagick)
7
-
8
- # available_uids = `find #{APP.datastore.root_path} ! -type d`.split("\n").map do |file|
9
- # file.sub("#{APP.datastore.root_path}/", '')
10
- # end
11
-
12
- puts "Loaded stuff from dragonfly irbrc"
13
- # puts "\nAvailable uids:\n"
14
- # puts available_uids
15
- puts "\nAvailable sample images:\n"
16
- puts Dir['samples/*']
17
- puts "\nAvailable constants:\n"
18
- puts "APP"
19
- puts
@@ -1,98 +0,0 @@
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 activemodel class body
11
- define_method macro_name do |attribute, &config_block|
12
-
13
- # Add callbacks
14
- before_save :save_dragonfly_attachments
15
- before_destroy :destroy_dragonfly_attachments
16
-
17
- # Register the new attribute
18
- dragonfly_attachment_classes << new_dragonfly_attachment_class(attribute, app, config_block)
19
-
20
- # Define the setter for the attribute
21
- define_method "#{attribute}=" do |value|
22
- dragonfly_attachments[attribute].assign(value)
23
- end
24
-
25
- # Define the getter for the attribute
26
- define_method attribute do
27
- dragonfly_attachments[attribute].to_value
28
- end
29
-
30
- # Define the URL setter
31
- define_method "#{attribute}_url=" do |url|
32
- unless url.blank?
33
- dragonfly_attachments[attribute].assign(app.fetch_url(url))
34
- end
35
- end
36
-
37
- # Define the URL getter
38
- define_method "#{attribute}_url" do
39
- nil
40
- end
41
-
42
- # Define the remove setter
43
- define_method "remove_#{attribute}=" do |value|
44
- unless [0, "0", false, "false", "", nil].include?(value)
45
- dragonfly_attachments[attribute].assign(nil)
46
- instance_variable_set("@remove_#{attribute}", true)
47
- end
48
- end
49
-
50
- # Define the remove getter
51
- attr_reader "remove_#{attribute}"
52
-
53
- # Define the retained setter
54
- define_method "retained_#{attribute}=" do |string|
55
- unless string.blank?
56
- begin
57
- dragonfly_attachments[attribute].retained_attrs = Serializer.json_decode(string, :symbolize_keys => true)
58
- rescue Serializer::BadString => e
59
- app.log.warn("*** WARNING ***: couldn't update attachment with serialized retained_#{attribute} string #{string.inspect}")
60
- end
61
- end
62
- dragonfly_attachments[attribute].should_retain = true
63
- dragonfly_attachments[attribute].retain!
64
- string
65
- end
66
-
67
- # Define the retained getter
68
- define_method "retained_#{attribute}" do
69
- attrs = dragonfly_attachments[attribute].retained_attrs
70
- Serializer.json_encode(attrs) if attrs
71
- end
72
-
73
- end
74
-
75
- end
76
- app
77
- end
78
-
79
- def dragonfly_attachment_classes
80
- @dragonfly_attachment_classes ||= begin
81
- parent_class = ancestors.select{|a| a.is_a?(Class) }[1]
82
- if parent_class.respond_to?(:dragonfly_attachment_classes)
83
- parent_class.dragonfly_attachment_classes.map do |klass|
84
- new_dragonfly_attachment_class(klass.attribute, klass.app, klass.config_block)
85
- end
86
- else
87
- []
88
- end
89
- end
90
- end
91
-
92
- def new_dragonfly_attachment_class(attribute, app, config_block)
93
- Class.new(Attachment).init(self, attribute, app, config_block)
94
- end
95
-
96
- end
97
- end
98
- end
@@ -1,58 +0,0 @@
1
- module Dragonfly
2
- class Analyser < FunctionManager
3
-
4
- configurable_attr :enable_cache, true
5
- configurable_attr :cache_size, 100
6
-
7
- def initialize
8
- super
9
- analyser = self
10
- @analysis_methods = Module.new do
11
-
12
- define_method :analyser do
13
- analyser
14
- end
15
-
16
- end
17
- @analysis_method_names = []
18
- end
19
-
20
- attr_reader :analysis_methods, :analysis_method_names
21
-
22
- def analyse(temp_object, method, *args)
23
- if enable_cache
24
- key = [temp_object.unique_id, method, *args]
25
- cache[key] ||= call_last(method, temp_object, *args)
26
- else
27
- call_last(method, temp_object, *args)
28
- end
29
- rescue NotDefined, UnableToHandle => e
30
- log.warn(e.message)
31
- nil
32
- end
33
-
34
- # Each time a function is registered with the analyser,
35
- # add a method to the analysis_methods module.
36
- # Expects the object that is extended to define 'analyse(method, *args)'
37
- def add(name, *args, &block)
38
- analysis_methods.module_eval %(
39
- def #{name}(*args)
40
- analyse(:#{name}, *args)
41
- end
42
- )
43
- analysis_method_names << name.to_sym
44
- super
45
- end
46
-
47
- def clear_cache!
48
- @cache = nil
49
- end
50
-
51
- private
52
-
53
- def cache
54
- @cache ||= SimpleCache.new(cache_size)
55
- end
56
-
57
- end
58
- end
@@ -1,33 +0,0 @@
1
- module Dragonfly
2
- module Analysis
3
-
4
- class FileCommandAnalyser
5
-
6
- include Shell
7
- include Configurable
8
-
9
- configurable_attr :file_command, "file"
10
- configurable_attr :use_filesystem, true
11
- configurable_attr :num_bytes_to_check, 255
12
-
13
- def mime_type(temp_object)
14
- content_type = if use_filesystem
15
- `#{file_command} -b --mime #{quote temp_object.path}`
16
- else
17
- IO.popen("#{file_command} -b --mime -", 'r+') do |io|
18
- if num_bytes_to_check
19
- io.write temp_object.data[0, num_bytes_to_check]
20
- else
21
- io.write temp_object.data
22
- end
23
- io.close_write
24
- io.read
25
- end
26
- end.split(';').first
27
- content_type.strip if content_type
28
- end
29
-
30
- end
31
-
32
- end
33
- end
@@ -1,6 +0,0 @@
1
- module Dragonfly
2
- module Analysis
3
- puts "WARNING: Dragonfly::Analysis::ImageMagickAnalyser is DEPRECATED and will soon be removed. Please use Dragonfly::ImageMagick::Analyser instead."
4
- ImageMagickAnalyser = ImageMagick::Analyser
5
- end
6
- end
@@ -1,26 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- module Heroku
5
-
6
- def self.apply_configuration(app, bucket_name)
7
- app.log.warn("""HEROKU CONFIGURATION IS NOW DEPRECATED - you should configure with the S3 Datastore directly, e.g.
8
- c.datastore = Dragonfly::DataStorage::S3DataStore.new(
9
- :bucket_name => '#{bucket_name}',
10
- :access_key_id => 'XXX',
11
- :secret_access_key => 'XXX'
12
- )
13
- """)
14
- app.configure do |c|
15
- c.datastore = DataStorage::S3DataStore.new
16
- c.datastore.configure do |d|
17
- d.bucket_name = bucket_name
18
- d.access_key_id = ENV['S3_KEY'] || raise("ENV variable 'S3_KEY' needs to be set - use\n\theroku config:add S3_KEY=XXXXXXXXX")
19
- d.secret_access_key = ENV['S3_SECRET'] || raise("ENV variable 'S3_SECRET' needs to be set - use\n\theroku config:add S3_SECRET=XXXXXXXXX")
20
- end
21
- end
22
- end
23
-
24
- end
25
- end
26
- end
@@ -1,6 +0,0 @@
1
- module Dragonfly
2
- module Config
3
- puts "WARNING: Dragonfly::Config::ImageMagick is DEPRECATED and will soon be removed. Please use Dragonfly::ImageMagick::Config instead."
4
- ImageMagick = Dragonfly::ImageMagick::Config
5
- end
6
- end
@@ -1,20 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- module Rails
5
-
6
- def self.apply_configuration(app)
7
- app.configure do |c|
8
- c.log = ::Rails.logger
9
- if c.datastore.is_a?(DataStorage::FileDataStore)
10
- c.datastore.root_path = ::Rails.root.join('public/system/dragonfly', ::Rails.env).to_s
11
- c.datastore.server_root = ::Rails.root.join('public').to_s
12
- end
13
- c.url_format = '/media/:job/:basename.:format'
14
- c.analyser.register(Analysis::FileCommandAnalyser)
15
- end
16
- end
17
-
18
- end
19
- end
20
- end
@@ -1,11 +0,0 @@
1
- module Dragonfly
2
- module DataStorage
3
-
4
- # Exceptions
5
- class BadUID < RuntimeError; end
6
- class DataNotFound < RuntimeError; end
7
- class UnableToStore < RuntimeError; end
8
- class DestroyError < RuntimeError; end
9
-
10
- end
11
- end
@@ -1,83 +0,0 @@
1
- require 'couchrest'
2
-
3
- module Dragonfly
4
- module DataStorage
5
- class CouchDataStore
6
-
7
- include Configurable
8
- include Serializer
9
-
10
- configurable_attr :host, 'localhost'
11
- configurable_attr :port, '5984'
12
- configurable_attr :database, 'dragonfly'
13
- configurable_attr :username
14
- configurable_attr :password
15
-
16
- def initialize(opts={})
17
- self.host = opts[:host] if opts[:host]
18
- self.port = opts[:port] if opts[:port]
19
- self.database = opts[:database] if opts[:database]
20
- self.username = opts[:username]
21
- self.password = opts[:password]
22
- end
23
-
24
- def store(temp_object, opts={})
25
- name = temp_object.name || 'file'
26
- content_type = opts[:content_type] || opts[:mime_type] || 'application/octet-stream'
27
-
28
- temp_object.file do |f|
29
- doc = CouchRest::Document.new(:meta => marshal_encode(temp_object.meta))
30
- response = db.save_doc(doc)
31
- doc.put_attachment(name, f.dup, :content_type => content_type)
32
- form_uid(response['id'], name)
33
- end
34
- rescue RuntimeError => e
35
- raise UnableToStore, "#{e} - #{temp_object.inspect}"
36
- end
37
-
38
- def retrieve(uid)
39
- doc_id, attachment = parse_uid(uid)
40
- doc = db.get(doc_id)
41
- [doc.fetch_attachment(attachment), marshal_decode(doc['meta'])]
42
- rescue RestClient::ResourceNotFound => e
43
- raise DataNotFound, "#{e} - #{uid}"
44
- end
45
-
46
- def destroy(uid)
47
- doc_id, attachment = parse_uid(uid)
48
- doc = db.get(doc_id)
49
- db.delete_doc(doc)
50
- rescue RestClient::ResourceNotFound => e
51
- raise DataNotFound, "#{e} - #{uid}"
52
- end
53
-
54
- def db
55
- @db ||= begin
56
- url = "http://#{auth}#{host}:#{port}"
57
- CouchRest.new(url).database!(database)
58
- end
59
- end
60
-
61
- def url_for(uid, opts={})
62
- doc_id, attachment = parse_uid(uid)
63
- "http://#{host}:#{port}/#{database}/#{doc_id}/#{attachment}"
64
- end
65
-
66
- private
67
-
68
- def auth
69
- username.blank? ? nil : "#{username}:#{password}@"
70
- end
71
-
72
- def form_uid(doc_id, attachment)
73
- "#{doc_id}/#{attachment}"
74
- end
75
-
76
- def parse_uid(uid)
77
- doc_id, attachment = uid.split('/')
78
- [doc_id, (attachment || 'file')]
79
- end
80
-
81
- end
82
- end
83
- end
@@ -1,144 +0,0 @@
1
- require 'pathname'
2
-
3
- module Dragonfly
4
- module DataStorage
5
-
6
- class FileDataStore
7
-
8
- # Exceptions
9
- class UnableToFormUrl < RuntimeError; end
10
-
11
- include Configurable
12
-
13
- configurable_attr :root_path, '/var/tmp/dragonfly'
14
- configurable_attr :server_root
15
- configurable_attr :store_meta, true
16
-
17
- def store(temp_object, opts={})
18
- relative_path = if opts[:path]
19
- opts[:path]
20
- else
21
- filename = temp_object.name || 'file'
22
- relative_path = relative_path_for(filename)
23
- end
24
-
25
- begin
26
- path = absolute(relative_path)
27
- until !File.exist?(path)
28
- path = disambiguate(path)
29
- end
30
- temp_object.to_file(path).close
31
- store_meta_data(path, temp_object.meta) if store_meta
32
- rescue Errno::EACCES => e
33
- raise UnableToStore, e.message
34
- end
35
-
36
- relative(path)
37
- end
38
-
39
- def retrieve(relative_path)
40
- validate_uid!(relative_path)
41
- path = absolute(relative_path)
42
- pathname = Pathname.new(path)
43
- raise DataNotFound, "couldn't find file #{path}" unless pathname.exist?
44
- [
45
- pathname,
46
- (store_meta ? retrieve_meta_data(path) : {})
47
- ]
48
- end
49
-
50
- def destroy(relative_path)
51
- validate_uid!(relative_path)
52
- path = absolute(relative_path)
53
- FileUtils.rm path
54
- FileUtils.rm_f meta_data_path(path)
55
- FileUtils.rm_f deprecated_meta_data_path(path)
56
- purge_empty_directories(relative_path)
57
- rescue Errno::ENOENT => e
58
- raise DataNotFound, e.message
59
- end
60
-
61
- def url_for(relative_path, opts={})
62
- if server_root.nil?
63
- raise NotConfigured, "you need to configure server_root for #{self.class.name} in order to form urls"
64
- else
65
- _, __, path = absolute(relative_path).partition(server_root)
66
- if path.empty?
67
- raise UnableToFormUrl, "couldn't form url for uid #{relative_path.inspect} with root_path #{root_path.inspect} and server_root #{server_root.inspect}"
68
- else
69
- path
70
- end
71
- end
72
- end
73
-
74
- def disambiguate(path)
75
- dirname = File.dirname(path)
76
- basename = File.basename(path, '.*')
77
- extname = File.extname(path)
78
- "#{dirname}/#{basename}_#{(Time.now.usec*10 + rand(100)).to_s(32)}#{extname}"
79
- end
80
-
81
- private
82
-
83
- def absolute(relative_path)
84
- relative_path.to_s == '.' ? root_path : File.join(root_path, relative_path)
85
- end
86
-
87
- def relative(absolute_path)
88
- absolute_path[/^#{Regexp.escape root_path}\/?(.*)$/, 1]
89
- end
90
-
91
- def directory_empty?(path)
92
- Dir.entries(path) == ['.','..']
93
- end
94
-
95
- def root_path?(dir)
96
- root_path == dir
97
- end
98
-
99
- def meta_data_path(data_path)
100
- "#{data_path}.meta"
101
- end
102
-
103
- def deprecated_meta_data_path(data_path)
104
- "#{data_path}.extra"
105
- end
106
-
107
- def relative_path_for(filename)
108
- time = Time.now
109
- msec = time.usec / 1000
110
- "#{time.strftime '%Y/%m/%d/%H_%M_%S'}_#{msec}_#{filename.gsub(/[^\w.]+/,'_')}"
111
- end
112
-
113
- def store_meta_data(data_path, meta)
114
- File.open(meta_data_path(data_path), 'wb') do |f|
115
- f.write Marshal.dump(meta)
116
- end
117
- end
118
-
119
- def retrieve_meta_data(data_path)
120
- path = meta_data_path(data_path)
121
- if File.exist?(path)
122
- File.open(path,'rb'){|f| Marshal.load(f.read) }
123
- else
124
- deprecated_path = deprecated_meta_data_path(data_path)
125
- File.exist?(deprecated_path) ? File.open(deprecated_path,'rb'){|f| Marshal.load(f.read) } : {}
126
- end
127
- end
128
-
129
- def purge_empty_directories(path)
130
- containing_directory = Pathname.new(path).dirname
131
- containing_directory.ascend do |relative_dir|
132
- dir = absolute(relative_dir)
133
- FileUtils.rmdir dir if directory_empty?(dir) && !root_path?(dir)
134
- end
135
- end
136
-
137
- def validate_uid!(uid)
138
- raise BadUID, "tried to retrieve uid #{uid.inspect}" if uid.blank? || uid['../']
139
- end
140
-
141
- end
142
-
143
- end
144
- end