dragonfly 1.1.3 → 1.3.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.

data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  Dragonfly
2
2
  ===========
3
+
4
+ [![Build Status](https://travis-ci.org/markevans/dragonfly.svg?branch=master)](https://travis-ci.org/markevans/dragonfly)
5
+
3
6
  Hello!!
4
7
  Dragonfly is a highly customizable ruby gem for handling images and other attachments and is already in use on thousands of websites.
5
8
 
@@ -10,7 +13,7 @@ class User < ActiveRecord::Base # model
10
13
  end
11
14
  ```
12
15
  ```erb
13
- <%= image_tag @user.photo.thumb('300x200#').url # view %>
16
+ <%= image_tag @user.photo.thumb('300x200#').url if @user.photo_stored? # view %>
14
17
  ```
15
18
 
16
19
  ... or generate text images on-demand in Sinatra ...
@@ -44,7 +47,7 @@ Installation
44
47
 
45
48
  or in your Gemfile
46
49
  ```ruby
47
- gem 'dragonfly', '~> 1.1.3'
50
+ gem 'dragonfly', '~> 1.2.2'
48
51
  ```
49
52
 
50
53
  Require with
@@ -1,40 +1,42 @@
1
- gem 'dragonfly', :path => File.expand_path('../..', __FILE__)
2
- generate "dragonfly"
3
- generate "scaffold", "photo image_uid:string image_name:string"
4
- rake "db:migrate"
5
- route %(
6
- get "text/:text" => Dragonfly.app.endpoint { |params, app|
7
- app.generate(:text, params[:text])
8
- }
9
- )
10
- route "root :to => 'photos#index'"
11
- run "rm -rf public/index.html"
1
+ after_bundle do
2
+ gem 'dragonfly', :path => File.expand_path('../..', __FILE__)
3
+ generate "dragonfly"
4
+ generate "scaffold", "photo image_uid:string image_name:string"
5
+ rake "db:migrate"
6
+ route %(
7
+ get "text/:text" => Dragonfly.app.endpoint { |params, app|
8
+ app.generate(:text, params[:text])
9
+ }
10
+ )
11
+ route "root :to => 'photos#index'"
12
+ run "rm -rf public/index.html"
12
13
 
13
- possible_base_classes = ['ActiveRecord::Base', 'ApplicationRecord']
14
- possible_base_classes.each do |base_class|
15
- inject_into_file 'app/models/photo.rb', :after => "class Photo < #{base_class}\n" do
16
- %(
17
- attr_accessible :image rescue nil
18
- dragonfly_accessor :image
19
- )
14
+ possible_base_classes = ['ActiveRecord::Base', 'ApplicationRecord']
15
+ possible_base_classes.each do |base_class|
16
+ inject_into_file 'app/models/photo.rb', :after => "class Photo < #{base_class}\n" do
17
+ %(
18
+ attr_accessible :image rescue nil
19
+ dragonfly_accessor :image
20
+ )
21
+ end
20
22
  end
21
- end
22
23
 
23
- gsub_file 'app/views/photos/_form.html.erb', /^.*:image_.*$/, ''
24
+ gsub_file 'app/views/photos/_form.html.erb', /^.*:image_.*$/, ''
24
25
 
25
- inject_into_file 'app/views/photos/_form.html.erb', :before => %(<div class="actions">\n) do
26
- %(
27
- <div class="field">
28
- <%= f.label :image %><br>
29
- <%= f.file_field :image %>
30
- </div>
26
+ inject_into_file 'app/views/photos/_form.html.erb', :before => %(<div class="actions">\n) do
27
+ %(
28
+ <div class="field">
29
+ <%= form.label :image %><br>
30
+ <%= form.file_field :image %>
31
+ </div>
31
32
 
32
- <%= image_tag @photo.image.thumb('100x100').url if @photo.image_uid %>
33
- )
34
- end
33
+ <%= image_tag @photo.image.thumb('100x100').url if @photo.image_stored? %>
34
+ )
35
+ end
35
36
 
36
- gsub_file "app/controllers/photos_controller.rb", "permit(", "permit(:image, "
37
+ gsub_file "app/controllers/photos_controller.rb", "permit(", "permit(:image, "
37
38
 
38
- append_file 'app/views/photos/show.html.erb', %(
39
- <%= image_tag @photo.image.thumb('300x300').url if @photo.image_uid? %>
40
- )
39
+ append_file 'app/views/photos/show.html.erb', %(
40
+ <%= image_tag @photo.image.thumb('300x300').url if @photo.image_stored? %>
41
+ )
42
+ end
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'dragonfly/version'
4
+ require "dragonfly/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "dragonfly"
@@ -13,33 +13,27 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "http://github.com/markevans/dragonfly"
14
14
  spec.license = "MIT"
15
15
  spec.files = `git ls-files`.split($/)
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
  spec.extra_rdoc_files = [
20
20
  "LICENSE",
21
- "README.md"
21
+ "README.md",
22
22
  ]
23
23
 
24
- # Rack 2.0 only works with ruby >= 2.2.2
25
- if RUBY_VERSION < "2.2.2"
26
- rack_version = "~> 1.3"
27
- activemodel_version = "~> 4.2"
28
- else
29
- rack_version = ">= 1.3"
30
- activemodel_version = nil
31
- end
32
-
33
24
  # Runtime dependencies
34
- spec.add_runtime_dependency("rack", rack_version)
25
+ spec.add_runtime_dependency("rack", ">= 1.3")
35
26
  spec.add_runtime_dependency("multi_json", "~> 1.0")
36
27
  spec.add_runtime_dependency("addressable", "~> 2.3")
37
28
 
38
29
  # Development dependencies
39
30
  spec.add_development_dependency("rspec", "~> 2.5")
40
31
  spec.add_development_dependency("webmock")
41
- spec.add_development_dependency("activemodel", activemodel_version)
32
+ spec.add_development_dependency("activemodel")
42
33
  if RUBY_PLATFORM == "java"
43
34
  spec.add_development_dependency("jruby-openssl")
35
+ else
36
+ spec.add_development_dependency("activerecord")
37
+ spec.add_development_dependency("sqlite3")
44
38
  end
45
39
  end
@@ -33,12 +33,14 @@ module Dragonfly
33
33
 
34
34
  # Logging
35
35
  def logger
36
- @logger ||= Logger.new('dragonfly.log')
36
+ @logger = Logger.new('dragonfly.log') unless instance_variable_defined?(:@logger)
37
+ @logger
37
38
  end
38
39
  attr_writer :logger
39
40
 
40
41
  [:debug, :warn, :info].each do |method|
41
42
  define_method method do |message|
43
+ return unless logger
42
44
  logger.send(method, "DRAGONFLY: #{message}")
43
45
  end
44
46
  end
@@ -137,7 +137,7 @@ module Dragonfly
137
137
  # # ===> "beach.jpg: image/jpeg"
138
138
  def shell_eval(opts={})
139
139
  should_escape = opts[:escape] != false
140
- command = yield(should_escape ? shell.quote(path) : path)
140
+ command = yield(should_escape ? shell.escape(path) : path)
141
141
  run command, :escape => should_escape
142
142
  end
143
143
 
@@ -152,7 +152,7 @@ module Dragonfly
152
152
  ext = opts[:ext] || self.ext
153
153
  should_escape = opts[:escape] != false
154
154
  tempfile = Utils.new_tempfile(ext)
155
- new_path = should_escape ? shell.quote(tempfile.path) : tempfile.path
155
+ new_path = should_escape ? shell.escape(tempfile.path) : tempfile.path
156
156
  command = yield(new_path)
157
157
  run(command, :escape => should_escape)
158
158
  update(tempfile)
@@ -169,8 +169,8 @@ module Dragonfly
169
169
  ext = opts[:ext] || self.ext
170
170
  should_escape = opts[:escape] != false
171
171
  tempfile = Utils.new_tempfile(ext)
172
- old_path = should_escape ? shell.quote(path) : path
173
- new_path = should_escape ? shell.quote(tempfile.path) : tempfile.path
172
+ old_path = should_escape ? shell.escape(path) : path
173
+ new_path = should_escape ? shell.escape(tempfile.path) : tempfile.path
174
174
  command = yield(old_path, new_path)
175
175
  run(command, :escape => should_escape)
176
176
  update(tempfile)
@@ -80,7 +80,7 @@ module Dragonfly
80
80
  end
81
81
 
82
82
  def update_from_data_uri
83
- mime_type, b64_data = uri.scan(/\Adata:([^;]+);base64,(.*)$/)[0]
83
+ mime_type, b64_data = uri.scan(/\Adata:([^;]+);base64,(.*)\Z/m)[0]
84
84
  if mime_type && b64_data
85
85
  data = Base64.decode64(b64_data)
86
86
  ext = app.ext_for(mime_type)
@@ -91,7 +91,7 @@ module Dragonfly
91
91
  end
92
92
 
93
93
  def parse_url(url)
94
- URI.parse(url)
94
+ URI.parse(url.to_s)
95
95
  rescue URI::InvalidURIError
96
96
  begin
97
97
  encoded_uri = Addressable::URI.parse(url).normalize.to_s
@@ -30,7 +30,12 @@ module Dragonfly
30
30
 
31
31
  # Add callbacks
32
32
  before_save :save_dragonfly_attachments if respond_to?(:before_save)
33
- before_destroy :destroy_dragonfly_attachments if respond_to?(:before_destroy)
33
+ case
34
+ when respond_to?(:after_commit)
35
+ after_commit :destroy_dragonfly_attachments, on: :destroy
36
+ when respond_to?(:after_destroy)
37
+ after_destroy :destroy_dragonfly_attachments
38
+ end
34
39
 
35
40
  # Register the new attribute
36
41
  dragonfly_attachment_classes << new_dragonfly_attachment_class(attribute, app, config_block)
@@ -86,7 +91,7 @@ module Dragonfly
86
91
  unless Utils.blank?(string)
87
92
  begin
88
93
  dragonfly_attachments[attribute].retained_attrs = Serializer.json_b64_decode(string)
89
- rescue Serializer::BadString => e
94
+ rescue Serializer::BadString
90
95
  Dragonfly.warn("couldn't update attachment with serialized retained_#{attribute} string #{string.inspect}")
91
96
  end
92
97
  end
@@ -24,9 +24,9 @@ module Dragonfly
24
24
  Dragonfly.warn("can't handle return value from routed endpoint: #{value.inspect}")
25
25
  plain_response(500, "Server Error")
26
26
  end
27
- rescue Job::NoSHAGiven => e
27
+ rescue Job::NoSHAGiven
28
28
  plain_response(400, "You need to give a SHA parameter")
29
- rescue Job::IncorrectSHA => e
29
+ rescue Job::IncorrectSHA
30
30
  plain_response(400, "The SHA parameter you gave is incorrect")
31
31
  end
32
32
 
@@ -28,11 +28,11 @@ module Dragonfly
28
28
  attr_reader :url_format, :fetch_file_whitelist, :fetch_url_whitelist
29
29
 
30
30
  def add_to_fetch_file_whitelist(patterns)
31
- fetch_file_whitelist.push *patterns
31
+ fetch_file_whitelist.push(*patterns)
32
32
  end
33
33
 
34
34
  def add_to_fetch_url_whitelist(patterns)
35
- fetch_url_whitelist.push *patterns
35
+ fetch_url_whitelist.push(*patterns)
36
36
  end
37
37
 
38
38
  def url_format=(url_format)
@@ -15,14 +15,11 @@ module Dragonfly
15
15
  end
16
16
 
17
17
  def escape_args(args)
18
- args.shellsplit.map do |arg|
19
- quote arg.gsub(/\\?'/, %q('\\\\''))
20
- end.join(' ')
18
+ args.shellsplit.map{|arg| escape(arg) }.join(' ')
21
19
  end
22
20
 
23
- def quote(string)
24
- q = Dragonfly.running_on_windows? ? '"' : "'"
25
- q + string + q
21
+ def escape(string)
22
+ Shellwords.escape(string)
26
23
  end
27
24
 
28
25
  private
@@ -36,22 +33,31 @@ module Dragonfly
36
33
  def run_command(command)
37
34
  result = `#{command}`
38
35
  status = $?
39
- raise CommandFailed, "Command failed (#{command}) with exit status #{status.exitstatus}" unless status.success?
36
+ raise_command_failed!(command, status.exitstatus) unless status.success?
40
37
  result
38
+ rescue Errno::ENOENT => e
39
+ raise_command_failed!(command, nil, e.message)
41
40
  end
42
41
 
43
42
  else
44
43
 
45
44
  def run_command(command)
46
- Open3.popen3 command do |stdin, stdout, stderr, wait_thread|
47
- stdin.close_write # make sure it doesn't hang
48
- status = wait_thread.value
49
- raise CommandFailed, "Command failed (#{command}) with exit status #{status.exitstatus} and stderr #{stderr.read}" unless status.success?
50
- stdout.read
51
- end
45
+ stdout_str, stderr_str, status = Open3.capture3(command)
46
+ raise_command_failed!(command, status.exitstatus, stderr_str) unless status.success?
47
+ stdout_str
48
+ rescue Errno::ENOENT => e
49
+ raise_command_failed!(command, nil, e.message)
52
50
  end
53
51
 
54
52
  end
55
53
 
54
+ def raise_command_failed!(command, status=nil, error=nil)
55
+ raise CommandFailed, [
56
+ "Command failed: #{command}",
57
+ ("exit status: #{status}" if status),
58
+ ("error: #{error}" if error),
59
+ ].join(', ')
60
+ end
61
+
56
62
  end
57
63
  end
@@ -24,7 +24,7 @@ module Dragonfly
24
24
 
25
25
  def initialize(url_format)
26
26
  @url_format = url_format
27
- raise BadUrlFormat, "bad url format #{url_format}" if url_format[/[\w_]:[\w_]/]
27
+ raise BadUrlFormat, "bad url format #{url_format}" if url_format[/\w:\w/]
28
28
  init_segments
29
29
  init_url_regexp
30
30
  end
@@ -43,7 +43,7 @@ module Dragonfly
43
43
  end
44
44
 
45
45
  def params_in_url
46
- @params_in_url ||= url_format.scan(/\:[\w_]+/).map{|f| f.tr(':','') }
46
+ @params_in_url ||= url_format.scan(/\:\w+/).map{|f| f.tr(':','') }
47
47
  end
48
48
 
49
49
  def url_for(params)
@@ -51,7 +51,7 @@ module Dragonfly
51
51
  url = url_format.dup
52
52
  segments.each do |seg|
53
53
  value = params[seg.param]
54
- value ? url.sub!(/:[\w_]+/, Utils.uri_escape_segment(value.to_s)) : url.sub!(/.:[\w_]+/, '')
54
+ value ? url.sub!(/:\w+/, Utils.uri_escape_segment(value.to_s)) : url.sub!(/.:\w+/, '')
55
55
  params.delete(seg.param)
56
56
  end
57
57
  url << "?#{Rack::Utils.build_query(params)}" if params.any?
@@ -62,7 +62,7 @@ module Dragonfly
62
62
 
63
63
  def init_segments
64
64
  @segments = []
65
- url_format.scan(/([^\w_]):([\w_]+)/).each do |seperator, param|
65
+ url_format.scan(/([^\w]):(\w+)/).each do |seperator, param|
66
66
  segments << Segment.new(
67
67
  param,
68
68
  seperator,
@@ -73,7 +73,7 @@ module Dragonfly
73
73
 
74
74
  def init_url_regexp
75
75
  i = -1
76
- regexp_string = url_format.gsub(/[^\w_]:[\w_]+/) do
76
+ regexp_string = url_format.gsub(/[^\w]:\w+/) do
77
77
  i += 1
78
78
  segments[i].regexp_string
79
79
  end
@@ -38,7 +38,7 @@ module Dragonfly
38
38
  end
39
39
 
40
40
  def uri_unescape(string)
41
- URI.unescape(string)
41
+ URI::DEFAULT_PARSER.unescape(string)
42
42
  end
43
43
 
44
44
  end
@@ -1,3 +1,3 @@
1
1
  module Dragonfly
2
- VERSION = '1.1.3'
2
+ VERSION = "1.3.0"
3
3
  end
@@ -20,7 +20,7 @@ Dragonfly.logger = Rails.logger
20
20
  Rails.application.middleware.use Dragonfly::Middleware
21
21
 
22
22
  # Add model functionality
23
- if defined?(ActiveRecord::Base)
24
- ActiveRecord::Base.extend Dragonfly::Model
25
- ActiveRecord::Base.extend Dragonfly::Model::Validations
23
+ ActiveSupport.on_load(:active_record) do
24
+ extend Dragonfly::Model
25
+ extend Dragonfly::Model::Validations
26
26
  end
@@ -232,7 +232,7 @@ describe Dragonfly::Content do
232
232
  path = p
233
233
  "cat #{path}"
234
234
  end.should == "big\nstuff"
235
- path.should == app.shell.quote(content.path)
235
+ path.should == app.shell.escape(content.path)
236
236
  end
237
237
 
238
238
  it "allows evaluating without escaping" do
@@ -253,8 +253,8 @@ describe Dragonfly::Content do
253
253
  new_path = n
254
254
  "cp #{o} #{n}"
255
255
  end.should == content
256
- old_path.should == app.shell.quote(original_path)
257
- new_path.should == app.shell.quote(content.path)
256
+ old_path.should == app.shell.escape(original_path)
257
+ new_path.should == app.shell.escape(content.path)
258
258
  content.data.should == "big\nstuff"
259
259
  end
260
260
 
@@ -7,7 +7,7 @@ describe Dragonfly::CookieMonster do
7
7
  def app(extra_env={})
8
8
  Rack::Builder.new do
9
9
  use Dragonfly::CookieMonster
10
- run proc{|env| env.merge!(extra_env); [200, {"Set-Cookie" => "blah", "Something" => "else"}, ["body here"]] }
10
+ run proc{|env| env.merge!(extra_env); [200, {"Set-Cookie" => "blah=thing", "Something" => "else"}, ["body here"]] }
11
11
  end
12
12
  end
13
13
 
@@ -15,7 +15,7 @@ describe Dragonfly::CookieMonster do
15
15
  response = Rack::MockRequest.new(app).get('')
16
16
  response.status.should == 200
17
17
  response.body.should == "body here"
18
- response.headers["Set-Cookie"].should == "blah"
18
+ response.headers["Set-Cookie"].should == "blah=thing"
19
19
  response.headers["Something"].should == "else"
20
20
  end
21
21
 
@@ -61,7 +61,7 @@ describe "a configured imagemagick app" do
61
61
 
62
62
  it "should return false for pdfs" do
63
63
  image.encode('pdf').image?.should be_falsey
64
- end
64
+ end unless ENV['SKIP_FLAKY_TESTS']
65
65
  end
66
66
 
67
67
  describe "processors that change the url" do