dragonfly 0.9.12 → 0.9.13

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.

@@ -6,34 +6,34 @@ module Dragonfly
6
6
 
7
7
  def register_dragonfly_app(macro_name, app)
8
8
  (class << self; self; end).class_eval do
9
-
9
+
10
10
  # Defines e.g. 'image_accessor' for any activemodel class body
11
11
  define_method macro_name do |attribute, &config_block|
12
12
 
13
13
  # Add callbacks
14
14
  before_save :save_dragonfly_attachments
15
15
  before_destroy :destroy_dragonfly_attachments
16
-
16
+
17
17
  # Register the new attribute
18
18
  dragonfly_attachment_classes << new_dragonfly_attachment_class(attribute, app, config_block)
19
-
19
+
20
20
  # Define the setter for the attribute
21
21
  define_method "#{attribute}=" do |value|
22
22
  dragonfly_attachments[attribute].assign(value)
23
23
  end
24
-
24
+
25
25
  # Define the getter for the attribute
26
26
  define_method attribute do
27
27
  dragonfly_attachments[attribute].to_value
28
28
  end
29
-
29
+
30
30
  # Define the URL setter
31
31
  define_method "#{attribute}_url=" do |url|
32
32
  unless url.blank?
33
33
  dragonfly_attachments[attribute].assign(app.fetch_url(url))
34
34
  end
35
35
  end
36
-
36
+
37
37
  # Define the URL getter
38
38
  define_method "#{attribute}_url" do
39
39
  nil
@@ -54,28 +54,28 @@ module Dragonfly
54
54
  define_method "retained_#{attribute}=" do |string|
55
55
  unless string.blank?
56
56
  begin
57
- dragonfly_attachments[attribute].retained_attrs = Serializer.marshal_decode(string)
57
+ dragonfly_attachments[attribute].retained_attrs = Serializer.json_decode(string, :symbolize_keys => true)
58
58
  rescue Serializer::BadString => e
59
- app.log.warn("*** WARNING ***: couldn't update attachment with serialized retained_#{attribute} string #{string.inspect}")
59
+ app.log.warn("*** WARNING ***: couldn't update attachment with serialized retained_#{attribute} string #{string.inspect}")
60
60
  end
61
61
  end
62
62
  dragonfly_attachments[attribute].should_retain = true
63
63
  dragonfly_attachments[attribute].retain!
64
64
  string
65
65
  end
66
-
66
+
67
67
  # Define the retained getter
68
68
  define_method "retained_#{attribute}" do
69
69
  attrs = dragonfly_attachments[attribute].retained_attrs
70
- Serializer.marshal_encode(attrs) if attrs
70
+ Serializer.json_encode(attrs) if attrs
71
71
  end
72
-
72
+
73
73
  end
74
-
74
+
75
75
  end
76
76
  app
77
77
  end
78
-
78
+
79
79
  def dragonfly_attachment_classes
80
80
  @dragonfly_attachment_classes ||= begin
81
81
  parent_class = ancestors.select{|a| a.is_a?(Class) }[1]
@@ -88,11 +88,11 @@ module Dragonfly
88
88
  end
89
89
  end
90
90
  end
91
-
91
+
92
92
  def new_dragonfly_attachment_class(attribute, app, config_block)
93
93
  Class.new(Attachment).init(self, attribute, app, config_block)
94
94
  end
95
-
95
+
96
96
  end
97
97
  end
98
98
  end
@@ -40,6 +40,8 @@ module Dragonfly
40
40
  include Utils
41
41
 
42
42
  def plain(width, height, colour, opts={})
43
+ opts = Dragonfly::Utils.symbolize_keys(opts)
44
+
43
45
  format = opts[:format] || 'png'
44
46
  [
45
47
  convert(nil, "-size #{width}x#{height} xc:#{colour}", format),
@@ -13,25 +13,27 @@ module Dragonfly
13
13
  's' => 'South',
14
14
  'se' => 'SouthEast'
15
15
  }
16
-
16
+
17
17
  # Geometry string patterns
18
18
  RESIZE_GEOMETRY = /^\d*x\d*[><%^!]?$|^\d+@$/ # e.g. '300x200!'
19
19
  CROPPED_RESIZE_GEOMETRY = /^(\d+)x(\d+)#(\w{1,2})?$/ # e.g. '20x50#ne'
20
20
  CROP_GEOMETRY = /^(\d+)x(\d+)([+-]\d+)?([+-]\d+)?(\w{1,2})?$/ # e.g. '30x30+10+10'
21
21
  THUMB_GEOMETRY = Regexp.union RESIZE_GEOMETRY, CROPPED_RESIZE_GEOMETRY, CROP_GEOMETRY
22
-
22
+
23
23
  include Configurable
24
24
  include Utils
25
-
25
+
26
26
  def resize(temp_object, geometry)
27
27
  convert(temp_object, "-resize #{geometry}")
28
28
  end
29
-
29
+
30
30
  def auto_orient(temp_object)
31
31
  convert(temp_object, "-auto-orient")
32
32
  end
33
33
 
34
34
  def crop(temp_object, opts={})
35
+ opts = Dragonfly::Utils.symbolize_keys(opts)
36
+
35
37
  width = opts[:width]
36
38
  height = opts[:height]
37
39
  gravity = GRAVITIES[opts[:gravity]]
@@ -41,24 +43,26 @@ module Dragonfly
41
43
  y = '+' + y unless y[/^[+-]/]
42
44
  repage = opts[:repage] == false ? '' : '+repage'
43
45
  resize = opts[:resize]
44
-
46
+
45
47
  convert(temp_object, "#{"-resize #{resize} " if resize}#{"-gravity #{gravity} " if gravity}-crop #{width}x#{height}#{x}#{y} #{repage}")
46
48
  end
47
-
49
+
48
50
  def flip(temp_object)
49
51
  convert(temp_object, "-flip")
50
52
  end
51
-
53
+
52
54
  def flop(temp_object)
53
55
  convert(temp_object, "-flop")
54
56
  end
55
-
57
+
56
58
  def greyscale(temp_object)
57
59
  convert(temp_object, "-colorspace Gray")
58
60
  end
59
61
  alias grayscale greyscale
60
-
62
+
61
63
  def resize_and_crop(temp_object, opts={})
64
+ opts = Dragonfly::Utils.symbolize_keys(opts)
65
+
62
66
  if !opts[:width] && !opts[:height]
63
67
  return temp_object
64
68
  elsif !opts[:width] || !opts[:height]
@@ -72,37 +76,39 @@ module Dragonfly
72
76
  opts[:resize] = "#{opts[:width]}x#{opts[:height]}^^"
73
77
  crop(temp_object, opts)
74
78
  end
75
-
79
+
76
80
  def rotate(temp_object, amount, opts={})
81
+ opts = Dragonfly::Utils.symbolize_keys(opts)
82
+
77
83
  convert(temp_object, "-rotate #{amount}#{opts[:qualifier]}")
78
84
  end
79
85
 
80
86
  def strip(temp_object)
81
87
  convert(temp_object, "-strip")
82
- end
83
-
88
+ end
89
+
84
90
  def thumb(temp_object, geometry)
85
91
  case geometry
86
92
  when RESIZE_GEOMETRY
87
93
  resize(temp_object, geometry)
88
94
  when CROPPED_RESIZE_GEOMETRY
89
- resize_and_crop(temp_object, :width => $1, :height => $2, :gravity => $3)
95
+ resize_and_crop(temp_object, 'width' => $1, 'height' => $2, 'gravity' => $3)
90
96
  when CROP_GEOMETRY
91
97
  crop(temp_object,
92
- :width => $1,
93
- :height => $2,
94
- :x => $3,
95
- :y => $4,
96
- :gravity => $5
98
+ 'width' => $1,
99
+ 'height' => $2,
100
+ 'x' => $3,
101
+ 'y' => $4,
102
+ 'gravity' => $5
97
103
  )
98
104
  else raise ArgumentError, "Didn't recognise the geometry string #{geometry}"
99
105
  end
100
106
  end
101
-
107
+
102
108
  def convert(temp_object, args='', format=nil)
103
109
  format ? [super, {:format => format.to_sym}] : super
104
110
  end
105
-
111
+
106
112
  end
107
113
  end
108
114
  end
data/lib/dragonfly/job.rb CHANGED
@@ -35,9 +35,9 @@ module Dragonfly
35
35
  def step_name
36
36
  @step_name ||= basename.gsub(/[A-Z]/){ "_#{$&.downcase}" }.sub('_','').to_sym
37
37
  end
38
- # Dragonfly::Job::Fetch -> :f
38
+ # Dragonfly::Job::Fetch -> 'f'
39
39
  def abbreviation
40
- @abbreviation ||= basename.scan(/[A-Z]/).join.downcase.to_sym
40
+ @abbreviation ||= basename.scan(/[A-Z]/).join.downcase
41
41
  end
42
42
  end
43
43
 
@@ -69,7 +69,7 @@ module Dragonfly
69
69
 
70
70
  class Process < Step
71
71
  def name
72
- args.first
72
+ args.first.to_sym
73
73
  end
74
74
  def arguments
75
75
  args[1..-1]
@@ -86,7 +86,7 @@ module Dragonfly
86
86
  job.url_attrs[:format] = format
87
87
  end
88
88
  def format
89
- args.first
89
+ args.first.to_sym
90
90
  end
91
91
  def arguments
92
92
  args[1..-1]
@@ -99,8 +99,14 @@ module Dragonfly
99
99
  end
100
100
 
101
101
  class Generate < Step
102
+ def name
103
+ args.first.to_sym
104
+ end
105
+ def arguments
106
+ args[1..-1]
107
+ end
102
108
  def apply
103
- content, meta = job.app.generator.generate(*args)
109
+ content, meta = job.app.generator.generate(name, *arguments)
104
110
  job.update(content, meta)
105
111
  end
106
112
  end
@@ -166,7 +172,7 @@ module Dragonfly
166
172
  end
167
173
 
168
174
  def deserialize(string, app)
169
- from_a(Serializer.marshal_decode(string), app)
175
+ from_a(Serializer.json_decode(string), app)
170
176
  end
171
177
 
172
178
  def step_abbreviations
@@ -187,20 +193,20 @@ module Dragonfly
187
193
  # If we had traits/classboxes in ruby maybe this wouldn't be needed
188
194
  # Think of it as like a normal instance method but with a css-like !important after it
189
195
  module OverrideInstanceMethods
190
-
196
+
191
197
  def format
192
198
  apply
193
199
  meta[:format] || (ext.to_sym if ext && app.trust_file_extensions) || analyse(:format)
194
200
  end
195
-
201
+
196
202
  def mime_type
197
203
  app.mime_type_for(format) || analyse(:mime_type) || app.fallback_mime_type
198
204
  end
199
-
205
+
200
206
  def to_s
201
207
  super.sub(/#<Class:\w+>/, 'Extended Dragonfly::Job')
202
208
  end
203
-
209
+
204
210
  end
205
211
 
206
212
  def initialize(app, content=nil, meta={}, url_attrs={})
@@ -280,7 +286,7 @@ module Dragonfly
280
286
  end
281
287
 
282
288
  def serialize
283
- Serializer.marshal_encode(to_a)
289
+ Serializer.json_encode(to_a)
284
290
  end
285
291
 
286
292
  def unique_signature
@@ -311,7 +317,7 @@ module Dragonfly
311
317
  def url_attrs=(hash)
312
318
  @url_attrs = UrlAttributes[hash]
313
319
  end
314
-
320
+
315
321
  attr_reader :url_attrs
316
322
 
317
323
  def b64_data
@@ -380,7 +386,7 @@ module Dragonfly
380
386
  def inspect
381
387
  "<Dragonfly::Job app=#{app.name.inspect}, steps=#{steps.inspect}, temp_object=#{temp_object.inspect}, steps applied:#{applied_steps.length}/#{steps.length} >"
382
388
  end
383
-
389
+
384
390
  def update(content, new_meta)
385
391
  if new_meta
386
392
  new_meta.merge!(new_meta.delete(:meta)) if new_meta[:meta] # legacy data etc. may have nested meta hash - deprecate gracefully here
@@ -388,12 +394,12 @@ module Dragonfly
388
394
  old_meta = temp_object ? temp_object.meta : {}
389
395
  self.temp_object = TempObject.new(content, old_meta.merge(new_meta || {}))
390
396
  end
391
-
397
+
392
398
  def close
393
399
  previous_temp_objects.each{|temp_object| temp_object.close }
394
400
  temp_object.close if temp_object
395
401
  end
396
-
402
+
397
403
  protected
398
404
 
399
405
  attr_writer :steps
@@ -405,20 +411,20 @@ module Dragonfly
405
411
  apply
406
412
  temp_object || raise(NoContent, "Job has not been initialized with content. Need to fetch first?")
407
413
  end
408
-
414
+
409
415
  def attributes_for_url
410
416
  attrs = url_attrs.slice(*server.params_in_url)
411
417
  attrs[:format] = (attrs[:format] || (url_attrs.ext if app.trust_file_extensions)).to_s if server.params_in_url.include?('format')
412
418
  attrs.delete_if{|k, v| v.blank? }
413
419
  attrs
414
420
  end
415
-
421
+
416
422
  attr_reader :previous_temp_objects
417
423
 
418
424
  def last_step_of_type(type)
419
425
  steps.select{|s| s.is_a?(type) }.last
420
426
  end
421
-
427
+
422
428
  def opts_for_store
423
429
  {:mime_type => mime_type}
424
430
  end
@@ -9,7 +9,7 @@ module Dragonfly
9
9
  end
10
10
 
11
11
  def call(env)
12
- params = symbolize_keys_of Rack::Request.new(env).params
12
+ params = Utils.symbolize_keys Rack::Request.new(env).params
13
13
  job = @block.call(params.merge(routing_params(env)), @app)
14
14
  Response.new(job, env).to_response
15
15
  rescue Job::NoSHAGiven => e
@@ -33,12 +33,5 @@ module Dragonfly
33
33
  raise(NoRoutingParams, "couldn't find any routing parameters in env #{env.inspect}")
34
34
  end
35
35
 
36
- def symbolize_keys_of(hash)
37
- hash.inject({}) do |h, (key, value)|
38
- h[(key.to_sym rescue key) || key] = value
39
- h
40
- end
41
- end
42
-
43
36
  end
44
37
  end
@@ -1,32 +1,43 @@
1
1
  # encoding: utf-8
2
2
  require 'base64'
3
+ require 'multi_json'
3
4
 
4
5
  module Dragonfly
5
6
  module Serializer
6
-
7
+
7
8
  # Exceptions
8
9
  class BadString < RuntimeError; end
9
-
10
+
10
11
  extend self # So we can do Serializer.b64_encode, etc.
11
-
12
+
12
13
  def b64_encode(string)
13
- Base64.encode64(string).tr("\n=",'').tr('/','~')
14
+ Base64.encode64(string).tr("\n=",'')
14
15
  end
15
-
16
+
16
17
  def b64_decode(string)
17
18
  padding_length = string.length % 4
18
- Base64.decode64(string.tr('~','/') + '=' * padding_length)
19
+ Base64.decode64(string + '=' * padding_length)
19
20
  end
20
-
21
+
21
22
  def marshal_encode(object)
22
23
  b64_encode(Marshal.dump(object))
23
24
  end
24
-
25
+
25
26
  def marshal_decode(string)
26
27
  Marshal.load(b64_decode(string))
27
28
  rescue TypeError, ArgumentError => e
28
29
  raise BadString, "couldn't decode #{string} - got #{e}"
29
30
  end
30
-
31
+
32
+ def json_encode(object)
33
+ b64_encode(MultiJson.encode(object))
34
+ end
35
+
36
+ def json_decode(string, opts={})
37
+ MultiJson.decode(b64_decode(string), :symbolize_keys => opts[:symbolize_keys])
38
+ rescue MultiJson::DecodeError => e
39
+ raise BadString, "couldn't decode #{string} - got #{e}"
40
+ end
41
+
31
42
  end
32
43
  end
@@ -6,7 +6,7 @@ module Dragonfly
6
6
 
7
7
  include Loggable
8
8
  include Configurable
9
-
9
+
10
10
  configurable_attr :allow_fetch_file, false
11
11
  configurable_attr :allow_fetch_url, false
12
12
  configurable_attr :dragonfly_url, '/dragonfly'
@@ -16,18 +16,18 @@ module Dragonfly
16
16
 
17
17
  extend Forwardable
18
18
  def_delegator :url_mapper, :params_in_url
19
-
19
+
20
20
  def initialize(app)
21
21
  @app = app
22
22
  use_same_log_as(app)
23
23
  use_as_fallback_config(app)
24
24
  end
25
-
25
+
26
26
  def before_serve(&block)
27
27
  self.before_serve_callback = block
28
28
  end
29
29
  configuration_method :before_serve
30
-
30
+
31
31
  def call(env)
32
32
  if dragonfly_url == env["PATH_INFO"]
33
33
  dragonfly_response
@@ -68,13 +68,12 @@ module Dragonfly
68
68
  end
69
69
 
70
70
  private
71
-
71
+
72
72
  attr_reader :app
73
73
  attr_accessor :before_serve_callback
74
74
 
75
75
  def url_mapper
76
76
  @url_mapper ||= UrlMapper.new(url_format,
77
- :job => '[\w+~]',
78
77
  :basename => '[^\/]',
79
78
  :name => '[^\/]',
80
79
  :format => '[^\.]'