dragonfly 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (155) hide show
  1. data/{.specopts → .rspec} +0 -1
  2. data/.yardopts +6 -2
  3. data/Gemfile +14 -13
  4. data/History.md +47 -9
  5. data/README.md +25 -5
  6. data/Rakefile +37 -79
  7. data/VERSION +1 -1
  8. data/dragonfly.gemspec +140 -89
  9. data/extra_docs/Analysers.md +8 -48
  10. data/extra_docs/Configuration.md +40 -25
  11. data/extra_docs/Couch.md +49 -0
  12. data/extra_docs/DataStorage.md +94 -24
  13. data/extra_docs/Encoding.md +6 -35
  14. data/extra_docs/ExampleUseCases.md +113 -0
  15. data/extra_docs/GeneralUsage.md +7 -23
  16. data/extra_docs/Generators.md +15 -49
  17. data/extra_docs/Heroku.md +7 -8
  18. data/extra_docs/ImageMagick.md +126 -0
  19. data/extra_docs/MimeTypes.md +3 -3
  20. data/extra_docs/Models.md +163 -0
  21. data/extra_docs/Mongo.md +1 -4
  22. data/extra_docs/Processing.md +7 -60
  23. data/extra_docs/Rails2.md +3 -1
  24. data/extra_docs/Rails3.md +2 -10
  25. data/extra_docs/ServingRemotely.md +83 -0
  26. data/extra_docs/Sinatra.md +3 -3
  27. data/extra_docs/URLs.md +60 -33
  28. data/features/rails_3.0.5.feature +8 -0
  29. data/features/steps/rails_steps.rb +7 -18
  30. data/features/support/env.rb +10 -37
  31. data/features/support/setup.rb +32 -0
  32. data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
  33. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  34. data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
  35. data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
  36. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  37. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  38. data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
  39. data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
  40. data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
  41. data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
  42. data/irbrc.rb +2 -1
  43. data/lib/dragonfly.rb +7 -0
  44. data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
  45. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
  46. data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
  47. data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
  48. data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
  49. data/lib/dragonfly/analyser.rb +0 -1
  50. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  51. data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
  52. data/lib/dragonfly/app.rb +64 -55
  53. data/lib/dragonfly/config/heroku.rb +1 -1
  54. data/lib/dragonfly/config/image_magick.rb +2 -37
  55. data/lib/dragonfly/config/rails.rb +5 -2
  56. data/lib/dragonfly/configurable.rb +115 -35
  57. data/lib/dragonfly/core_ext/object.rb +1 -1
  58. data/lib/dragonfly/core_ext/string.rb +1 -1
  59. data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
  60. data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
  61. data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
  62. data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
  63. data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
  64. data/lib/dragonfly/function_manager.rb +4 -2
  65. data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
  66. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  67. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  68. data/lib/dragonfly/image_magick/config.rb +44 -0
  69. data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
  70. data/lib/dragonfly/image_magick/generator.rb +145 -0
  71. data/lib/dragonfly/image_magick/processor.rb +104 -0
  72. data/lib/dragonfly/image_magick/utils.rb +72 -0
  73. data/lib/dragonfly/image_magick_utils.rb +2 -79
  74. data/lib/dragonfly/job.rb +152 -90
  75. data/lib/dragonfly/middleware.rb +5 -19
  76. data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
  77. data/lib/dragonfly/rails/images.rb +15 -10
  78. data/lib/dragonfly/response.rb +26 -12
  79. data/lib/dragonfly/serializer.rb +1 -4
  80. data/lib/dragonfly/server.rb +103 -0
  81. data/lib/dragonfly/temp_object.rb +56 -101
  82. data/lib/dragonfly/url_mapper.rb +78 -0
  83. data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
  84. data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
  85. data/spec/dragonfly/analyser_spec.rb +1 -1
  86. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
  87. data/spec/dragonfly/app_spec.rb +35 -180
  88. data/spec/dragonfly/configurable_spec.rb +259 -18
  89. data/spec/dragonfly/core_ext/string_spec.rb +2 -2
  90. data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
  91. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
  92. data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
  93. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
  94. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
  95. data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
  96. data/spec/dragonfly/function_manager_spec.rb +2 -2
  97. data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
  98. data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
  99. data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
  100. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  101. data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
  102. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  103. data/spec/dragonfly/job_builder_spec.rb +1 -1
  104. data/spec/dragonfly/job_definitions_spec.rb +1 -1
  105. data/spec/dragonfly/job_endpoint_spec.rb +26 -3
  106. data/spec/dragonfly/job_spec.rb +426 -208
  107. data/spec/dragonfly/loggable_spec.rb +2 -2
  108. data/spec/dragonfly/middleware_spec.rb +5 -26
  109. data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
  110. data/spec/dragonfly/serializer_spec.rb +1 -14
  111. data/spec/dragonfly/server_spec.rb +261 -0
  112. data/spec/dragonfly/simple_cache_spec.rb +1 -1
  113. data/spec/dragonfly/temp_object_spec.rb +84 -130
  114. data/spec/dragonfly/url_mapper_spec.rb +130 -0
  115. data/spec/functional/deprecations_spec.rb +51 -0
  116. data/spec/functional/image_magick_app_spec.rb +27 -0
  117. data/spec/functional/model_urls_spec.rb +85 -0
  118. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  119. data/spec/functional/to_response_spec.rb +31 -0
  120. data/spec/spec_helper.rb +12 -22
  121. data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
  122. data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
  123. data/spec/support/simple_matchers.rb +53 -0
  124. data/yard/handlers/configurable_attr_handler.rb +2 -2
  125. data/yard/templates/default/fulldoc/html/css/common.css +12 -10
  126. data/yard/templates/default/layout/html/layout.erb +6 -0
  127. metadata +267 -308
  128. data/Gemfile.rails.2.3.5 +0 -20
  129. data/features/3.0.3.feature +0 -8
  130. data/features/rails_2.3.5.feature +0 -7
  131. data/fixtures/files/app/models/album.rb +0 -3
  132. data/fixtures/files/app/views/albums/new.html.erb +0 -4
  133. data/fixtures/files/features/manage_album_images.feature +0 -12
  134. data/fixtures/rails_2.3.5/template.rb +0 -10
  135. data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
  136. data/lib/dragonfly/config/r_magick.rb +0 -46
  137. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
  138. data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
  139. data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
  140. data/lib/dragonfly/r_magick_utils.rb +0 -48
  141. data/lib/dragonfly/simple_endpoint.rb +0 -76
  142. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
  143. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
  144. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
  145. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
  146. data/spec/dragonfly/config/r_magick_spec.rb +0 -29
  147. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
  148. data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
  149. data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
  150. data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
  151. data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
  152. data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
  153. data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
  154. data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
  155. data/spec/simple_matchers.rb +0 -44
@@ -12,6 +12,8 @@ module Dragonfly
12
12
  configurable_attr :database, 'dragonfly'
13
13
  configurable_attr :username
14
14
  configurable_attr :password
15
+ configurable_attr :connection
16
+ configurable_attr :db
15
17
 
16
18
  # Mongo gem deprecated ObjectID in favour of ObjectId
17
19
  OBJECT_ID = defined?(BSON::ObjectId) ? BSON::ObjectId : BSON::ObjectID
@@ -23,12 +25,14 @@ module Dragonfly
23
25
  self.database = opts[:database] if opts[:database]
24
26
  self.username = opts[:username]
25
27
  self.password = opts[:password]
28
+ self.connection = opts[:connection]
29
+ self.db = opts[:db]
26
30
  end
27
31
 
28
32
  def store(temp_object, opts={})
29
33
  ensure_authenticated!
30
34
  temp_object.file do |f|
31
- mongo_id = grid.put(f, :metadata => marshal_encode(temp_object.attributes))
35
+ mongo_id = grid.put(f, :metadata => marshal_encode(opts[:meta] || {}))
32
36
  mongo_id.to_s
33
37
  end
34
38
  end
@@ -36,11 +40,11 @@ module Dragonfly
36
40
  def retrieve(uid)
37
41
  ensure_authenticated!
38
42
  grid_io = grid.get(bson_id(uid))
39
- extra = marshal_decode(grid_io.metadata)
40
- extra[:meta].merge!(:stored_at => grid_io.upload_date)
43
+ meta = marshal_decode(grid_io.metadata)
44
+ meta.merge!(:stored_at => grid_io.upload_date)
41
45
  [
42
46
  grid_io.read,
43
- extra
47
+ meta
44
48
  ]
45
49
  rescue Mongo::GridFileNotFound, INVALID_OBJECT_ID => e
46
50
  raise DataNotFound, "#{e} - #{uid}"
@@ -1,4 +1,4 @@
1
- require 'aws/s3'
1
+ require 'fog'
2
2
 
3
3
  module Dragonfly
4
4
  module DataStorage
@@ -6,88 +6,132 @@ module Dragonfly
6
6
  class S3DataStore
7
7
 
8
8
  include Configurable
9
- include AWS::S3
10
9
  include Serializer
11
10
 
12
11
  configurable_attr :bucket_name
13
12
  configurable_attr :access_key_id
14
13
  configurable_attr :secret_access_key
15
14
  configurable_attr :use_filesystem, true
15
+ configurable_attr :region
16
+ configurable_attr :storage_headers, {'x-amz-acl' => 'public-read'}
17
+
18
+ REGIONS = {
19
+ 'us-east-1' => 's3.amazonaws.com', #default
20
+ 'eu-west-1' => 's3-eu-west-1.amazonaws.com',
21
+ 'ap-southeast-1' => 's3-ap-southeast-1.amazonaws.com',
22
+ 'us-west-1' => 's3-us-west-1.amazonaws.com'
23
+ }
16
24
 
17
25
  def initialize(opts={})
18
26
  self.bucket_name = opts[:bucket_name]
19
27
  self.access_key_id = opts[:access_key_id]
20
28
  self.secret_access_key = opts[:secret_access_key]
21
- end
22
-
23
- def connect!
24
- AWS::S3::Base.establish_connection!(
25
- :access_key_id => access_key_id,
26
- :secret_access_key => secret_access_key
27
- )
28
- end
29
-
30
- def create_bucket!
31
- Bucket.create(bucket_name) unless bucket_names.include?(bucket_name)
29
+ self.region = opts[:region]
32
30
  end
33
31
 
34
32
  def store(temp_object, opts={})
35
- uid = opts[:path] || generate_uid(temp_object.name || 'file')
36
- ensure_initialized
37
- extra_data = temp_object.attributes
33
+ ensure_configured
34
+ ensure_bucket_initialized
35
+
36
+ meta = opts[:meta] || {}
37
+ headers = opts[:headers] || {}
38
+ uid = opts[:path] || generate_uid(meta[:name] || temp_object.original_filename || 'file')
39
+
38
40
  if use_filesystem
39
41
  temp_object.file do |f|
40
- S3Object.store(uid, f, bucket_name, s3_metadata_for(extra_data))
42
+ storage.put_object(bucket_name, uid, f, full_storage_headers(headers, meta))
41
43
  end
42
44
  else
43
- S3Object.store(uid, temp_object.data, bucket_name, s3_metadata_for(extra_data))
45
+ storage.put_object(bucket_name, uid, temp_object.data, full_storage_headers(headers, meta))
44
46
  end
47
+
45
48
  uid
46
49
  end
47
50
 
48
51
  def retrieve(uid)
49
- ensure_initialized
50
- s3_object = S3Object.find(uid, bucket_name)
52
+ ensure_configured
53
+ response = storage.get_object(bucket_name, uid)
51
54
  [
52
- s3_object.value,
53
- parse_s3_metadata(s3_object.metadata)
55
+ response.body,
56
+ parse_s3_metadata(response.headers)
54
57
  ]
55
- rescue AWS::S3::NoSuchKey => e
58
+ rescue Excon::Errors::NotFound => e
56
59
  raise DataNotFound, "#{e} - #{uid}"
57
60
  end
58
61
 
59
62
  def destroy(uid)
60
- ensure_initialized
61
- S3Object.delete(uid, bucket_name)
62
- rescue AWS::S3::NoSuchKey => e
63
+ storage.delete_object(bucket_name, uid)
64
+ rescue Excon::Errors::NotFound => e
63
65
  raise DataNotFound, "#{e} - #{uid}"
64
66
  end
65
67
 
68
+ def url_for(uid, opts={})
69
+ if opts && opts[:expires]
70
+ storage.get_object_url(bucket_name, uid, opts[:expires])
71
+ else
72
+ "http://#{bucket_name}.s3.amazonaws.com/#{uid}"
73
+ end
74
+ end
75
+
76
+ def domain
77
+ REGIONS[get_region]
78
+ end
79
+
80
+ def storage
81
+ @storage ||= Fog::Storage.new(
82
+ :provider => 'AWS',
83
+ :aws_access_key_id => access_key_id,
84
+ :aws_secret_access_key => secret_access_key,
85
+ :region => region
86
+ )
87
+ end
88
+
89
+ def bucket_exists?
90
+ storage.get_bucket_location(bucket_name)
91
+ true
92
+ rescue Excon::Errors::NotFound => e
93
+ false
94
+ end
95
+
66
96
  private
67
97
 
68
- def bucket_names
69
- Service.buckets.map{|bucket| bucket.name }
98
+ def ensure_configured
99
+ unless @configured
100
+ [:bucket_name, :access_key_id, :secret_access_key].each do |attr|
101
+ raise NotConfigured, "You need to configure #{self.class.name} with #{attr}" if send(attr).nil?
102
+ end
103
+ @configured = true
104
+ end
70
105
  end
71
106
 
72
- def ensure_initialized
73
- unless @initialized
74
- connect!
75
- create_bucket!
76
- @initialized = true
107
+ def ensure_bucket_initialized
108
+ unless @bucket_initialized
109
+ storage.put_bucket(bucket_name, 'LocationConstraint' => region) unless bucket_exists?
110
+ @bucket_initialized = true
77
111
  end
78
112
  end
79
113
 
114
+ def get_region
115
+ reg = region || 'us-east-1'
116
+ raise "Invalid region #{reg} - should be one of #{valid_regions.join(', ')}" unless valid_regions.include?(reg)
117
+ reg
118
+ end
119
+
80
120
  def generate_uid(name)
81
121
  "#{Time.now.strftime '%Y/%m/%d/%H/%M/%S'}/#{rand(1000)}/#{name.gsub(/[^\w.]+/, '_')}"
82
122
  end
83
123
 
84
- def s3_metadata_for(extra_data)
85
- {'x-amz-meta-extra' => marshal_encode(extra_data)}
124
+ def full_storage_headers(headers, meta)
125
+ {'x-amz-meta-extra' => marshal_encode(meta)}.merge(storage_headers).merge(headers)
126
+ end
127
+
128
+ def parse_s3_metadata(headers)
129
+ encoded_meta = headers['x-amz-meta-extra']
130
+ (marshal_decode(encoded_meta) if encoded_meta) || {}
86
131
  end
87
132
 
88
- def parse_s3_metadata(metadata)
89
- extra_data = metadata['x-amz-meta-extra']
90
- marshal_decode(extra_data) if extra_data
133
+ def valid_regions
134
+ REGIONS.keys
91
135
  end
92
136
 
93
137
  end
@@ -1,57 +1,6 @@
1
1
  module Dragonfly
2
2
  module Encoding
3
- class ImageMagickEncoder
4
-
5
- include Configurable
6
- include ImageMagickUtils
7
-
8
- configurable_attr :supported_formats, [
9
- :ai,
10
- :bmp,
11
- :eps,
12
- :gif,
13
- :gif87,
14
- :ico,
15
- :j2c,
16
- :jp2,
17
- :jpeg,
18
- :jpg,
19
- :pbm,
20
- :pcd,
21
- :pct,
22
- :pcx,
23
- :pdf,
24
- :pict,
25
- :pjpeg,
26
- :png,
27
- :png24,
28
- :png32,
29
- :png8,
30
- :pnm,
31
- :ppm,
32
- :ps,
33
- :psd,
34
- :ras,
35
- :tga,
36
- :tiff,
37
- :wbmp,
38
- :xbm,
39
- :xpm,
40
- :xwd
41
- ]
42
-
43
- def encode(temp_object, format, args='')
44
- format = format.to_s.downcase
45
- throw :unable_to_handle unless supported_formats.include?(format.to_sym)
46
- details = identify(temp_object)
47
-
48
- if details[:format] == format.to_sym && args.empty?
49
- temp_object
50
- else
51
- convert(temp_object, args, format)
52
- end
53
- end
54
-
55
- end
3
+ puts "WARNING: Dragonfly::Encoding::ImageMagickEncoder is DEPRECATED and will soon be removed. Please use Dragonfly::ImageMagick::Encoder instead."
4
+ ImageMagickEncoder = ImageMagick::Encoder
56
5
  end
57
6
  end
@@ -6,6 +6,7 @@ module Dragonfly
6
6
  class UnableToHandle < NotImplementedError; end
7
7
 
8
8
  include Loggable
9
+ include Configurable
9
10
 
10
11
  def initialize
11
12
  @functions = {}
@@ -23,6 +24,7 @@ module Dragonfly
23
24
  obj = klass.new(*args)
24
25
  obj.configure(&block) if block
25
26
  obj.use_same_log_as(self) if obj.is_a?(Loggable)
27
+ obj.use_as_fallback_config(self) if obj.is_a?(Configurable)
26
28
  methods_to_add(obj).each do |meth|
27
29
  add meth.to_sym, obj.method(meth)
28
30
  end
@@ -58,8 +60,8 @@ module Dragonfly
58
60
  def methods_to_add(obj)
59
61
  if obj.is_a?(Configurable)
60
62
  obj.public_methods(false) -
61
- obj.configuration_methods.map{|meth| meth.to_method_name} -
62
- [:configuration_methods.to_method_name]
63
+ obj.config_methods.map{|meth| meth.to_method_name} -
64
+ [:configured_class.to_method_name] # Hacky - there must be a better way...
63
65
  else
64
66
  obj.public_methods(false)
65
67
  end
@@ -1,140 +1,6 @@
1
1
  module Dragonfly
2
2
  module Generation
3
- class ImageMagickGenerator
4
-
5
- FONT_STYLES = {
6
- 'normal' => 'normal',
7
- 'italic' => 'italic',
8
- 'oblique' => 'oblique'
9
- }
10
-
11
- FONT_STRETCHES = {
12
- 'normal' => 'normal',
13
- 'semi-condensed' => 'semi-condensed',
14
- 'condensed' => 'condensed',
15
- 'extra-condensed' => 'extra-condensed',
16
- 'ultra-condensed' => 'ultra-condensed',
17
- 'semi-expanded' => 'semi-expanded',
18
- 'expanded' => 'expanded',
19
- 'extra-expanded' => 'extra-expanded',
20
- 'ultra-expanded' => 'ultra-expanded'
21
- }
22
-
23
- FONT_WEIGHTS = {
24
- 'normal' => 'normal',
25
- 'bold' => 'bold',
26
- 'bolder' => 'bolder',
27
- 'lighter' => 'lighter',
28
- '100' => 100,
29
- '200' => 200,
30
- '300' => 300,
31
- '400' => 400,
32
- '500' => 500,
33
- '600' => 600,
34
- '700' => 700,
35
- '800' => 800,
36
- '900' => 900
37
- }
38
-
39
- include ImageMagickUtils
40
- include Configurable
41
-
42
- def plasma(width, height, format='png')
43
- tempfile = new_tempfile(format)
44
- run "#{convert_command} -size #{width}x#{height} plasma:fractal #{tempfile.path}"
45
- [
46
- tempfile,
47
- {:format => format.to_sym, :name => "plasma.#{format}"}
48
- ]
49
- end
50
-
51
- def text(string, opts={})
52
- opts = HashWithCssStyleKeys[opts]
53
- args = []
54
- format = (opts[:format] || :png)
55
- background = opts[:background_color] || 'none'
56
- font_size = (opts[:font_size] || 12).to_i
57
- escaped_string = "\"#{string.gsub(/"/, '\"')}\""
58
-
59
- # Settings
60
- args.push("-gravity NorthWest")
61
- args.push("-antialias")
62
- args.push("-pointsize #{font_size}")
63
- args.push("-font '#{opts[:font]}'") if opts[:font]
64
- args.push("-family '#{opts[:font_family]}'") if opts[:font_family]
65
- args.push("-fill #{opts[:color]}") if opts[:color]
66
- args.push("-stroke #{opts[:stroke_color]}") if opts[:stroke_color]
67
- args.push("-style #{FONT_STYLES[opts[:font_style]]}") if opts[:font_style]
68
- args.push("-stretch #{FONT_STRETCHES[opts[:font_stretch]]}") if opts[:font_stretch]
69
- args.push("-weight #{FONT_WEIGHTS[opts[:font_weight]]}") if opts[:font_weight]
70
- args.push("-background #{background}")
71
- args.push("label:#{escaped_string}")
72
-
73
- # Padding
74
- pt, pr, pb, pl = parse_padding_string(opts[:padding]) if opts[:padding]
75
- padding_top = (opts[:padding_top] || pt || 0)
76
- padding_right = (opts[:padding_right] || pr || 0)
77
- padding_bottom = (opts[:padding_bottom] || pb || 0)
78
- padding_left = (opts[:padding_left] || pl || 0)
79
-
80
- tempfile = new_tempfile(format)
81
- run "#{convert_command} #{args.join(' ')} #{tempfile.path}"
82
-
83
- if (padding_top || padding_right || padding_bottom || padding_left)
84
- attrs = identify(tempfile)
85
- text_width = attrs[:width].to_i
86
- text_height = attrs[:height].to_i
87
- width = padding_left + text_width + padding_right
88
- height = padding_top + text_height + padding_bottom
89
-
90
- args = args.slice(0, args.length - 2)
91
- args.push("-size #{width}x#{height}")
92
- args.push("xc:#{background}")
93
- args.push("-annotate 0x0+#{padding_left}+#{padding_top} #{escaped_string}")
94
- run "#{convert_command} #{args.join(' ')} #{tempfile.path}"
95
- end
96
-
97
- [
98
- tempfile,
99
- {:format => format, :name => "text.#{format}"}
100
- ]
101
- end
102
-
103
- private
104
-
105
- # Use css-style padding declaration, i.e.
106
- # 10 (all sides)
107
- # 10 5 (top/bottom, left/right)
108
- # 10 5 10 (top, left/right, bottom)
109
- # 10 5 10 5 (top, right, bottom, left)
110
- def parse_padding_string(str)
111
- padding_parts = str.gsub('px','').split(/\s+/).map{|px| px.to_i}
112
- case padding_parts.size
113
- when 1
114
- p = padding_parts.first
115
- [p,p,p,p]
116
- when 2
117
- p,q = padding_parts
118
- [p,q,p,q]
119
- when 3
120
- p,q,r = padding_parts
121
- [p,q,r,q]
122
- when 4
123
- padding_parts
124
- else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
125
- end
126
- end
127
-
128
- def scale_factor_for(font_size)
129
- # Scale approximately to 64 if below
130
- min_size = 64
131
- if font_size < min_size
132
- (min_size.to_f / font_size).ceil
133
- else
134
- 1
135
- end.to_f
136
- end
137
-
138
- end
3
+ puts "WARNING: Dragonfly::Generation::ImageMagickGenerator is DEPRECATED and will soon be removed. Please use Dragonfly::ImageMagick::Generator instead."
4
+ ImageMagickGenerator = ImageMagick::Generator
139
5
  end
140
6
  end
@@ -0,0 +1,21 @@
1
+ module Dragonfly
2
+
3
+ # HashWithCssStyleKeys is solely for being able to access a hash
4
+ # which has css-style keys (e.g. 'font-size') with the underscore
5
+ # symbol version
6
+ # @example
7
+ # opts = {'font-size' => '23px', :color => 'white'}
8
+ # opts = HashWithCssStyleKeys[opts]
9
+ # opts[:font_size] # ===> '23px'
10
+ # opts[:color] # ===> 'white'
11
+ class HashWithCssStyleKeys < Hash
12
+ def [](key)
13
+ super || (
14
+ str_key = key.to_s
15
+ css_key = str_key.gsub('_','-')
16
+ super(str_key) || super(css_key) || super(css_key.to_sym)
17
+ )
18
+ end
19
+ end
20
+
21
+ end