kt-paperclip 6.2.0 → 6.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. data/.github/ISSUE_TEMPLATE/custom.md +10 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.hound.yml +364 -357
  7. data/.rubocop.yml +2 -0
  8. data/.travis.yml +7 -9
  9. data/Gemfile +3 -2
  10. data/README.md +38 -17
  11. data/lib/kt-paperclip.rb +1 -0
  12. data/lib/paperclip.rb +2 -1
  13. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +2 -2
  14. data/lib/paperclip/io_adapters/uri_adapter.rb +13 -3
  15. data/lib/paperclip/schema.rb +2 -2
  16. data/lib/paperclip/storage/s3.rb +2 -2
  17. data/lib/paperclip/url_generator.rb +8 -1
  18. data/lib/paperclip/validators.rb +4 -4
  19. data/lib/paperclip/validators/attachment_content_type_validator.rb +8 -1
  20. data/lib/paperclip/validators/attachment_file_name_validator.rb +8 -1
  21. data/lib/paperclip/validators/attachment_size_validator.rb +17 -1
  22. data/lib/paperclip/version.rb +1 -1
  23. data/paperclip.gemspec +3 -3
  24. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +20 -15
  25. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +13 -3
  26. data/spec/paperclip/storage/s3_spec.rb +54 -3
  27. data/spec/paperclip/url_generator_spec.rb +10 -0
  28. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +88 -0
  29. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +90 -0
  30. data/spec/paperclip/validators/attachment_size_validator_spec.rb +90 -0
  31. data/spec/support/fixtures/aws_s3.yml +13 -0
  32. data/spec/support/model_reconstruction.rb +1 -1
  33. metadata +14 -9
  34. data/.github/issue_template.md +0 -3
@@ -1 +1,3 @@
1
+ require:
2
+ - rubocop-rails
1
3
  inherit_from: .hound.yml
@@ -1,12 +1,12 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1
5
4
  - 2.2
6
5
  - 2.3
7
6
  - 2.4
8
7
  - 2.5
9
8
  - 2.6
9
+ - 2.7
10
10
 
11
11
  script: "bundle exec rake clean spec cucumber"
12
12
 
@@ -29,19 +29,17 @@ gemfile:
29
29
  matrix:
30
30
  fast_finish: true
31
31
  exclude:
32
- - gemfile: gemfiles/5.0.gemfile
33
- rvm: 2.1
34
- - gemfile: gemfiles/5.1.gemfile
35
- rvm: 2.1
36
- - gemfile: gemfiles/5.2.gemfile
37
- rvm: 2.1
38
32
  - gemfile: gemfiles/5.2.gemfile
39
33
  rvm: 2.2
40
- - gemfile: gemfiles/6.0.gemfile
41
- rvm: 2.1
42
34
  - gemfile: gemfiles/6.0.gemfile
43
35
  rvm: 2.2
44
36
  - gemfile: gemfiles/6.0.gemfile
45
37
  rvm: 2.3
46
38
  - gemfile: gemfiles/6.0.gemfile
47
39
  rvm: 2.4
40
+ - gemfile: gemfiles/4.2.gemfile
41
+ rvm: 2.7
42
+ - gemfile: gemfiles/5.0.gemfile
43
+ rvm: 2.7
44
+ - gemfile: gemfiles/5.1.gemfile
45
+ rvm: 2.7
data/Gemfile CHANGED
@@ -8,11 +8,12 @@ gem "pry"
8
8
  # Prevents bundler from taking a long-time to resolve
9
9
  group :development, :test do
10
10
  gem "activerecord-import"
11
- gem 'bootsnap', require: false
11
+ gem "bootsnap", require: false
12
12
  gem "builder"
13
- gem 'listen', '~> 3.0.8'
13
+ gem "listen", "~> 3.0.8"
14
14
  gem "mime-types"
15
15
  gem "rspec"
16
16
  gem "rubocop", require: false
17
+ gem "rubocop-rails"
17
18
  gem "sprockets", "3.7.2"
18
19
  end
data/README.md CHANGED
@@ -10,12 +10,11 @@ Please feel free to contribute Issues and pull requests.
10
10
  ## Documentation valid for `master` branch
11
11
 
12
12
  Please check the documentation for the paperclip version you are using:
13
- https://github.com/kreeti/paperclip/releases
13
+ https://github.com/kreeti/kt-paperclip/releases
14
14
 
15
15
  ---
16
16
 
17
- [![Build Status](https://secure.travis-ci.org/kreeti/paperclip.svg?branch=master)](http://travis-ci.org/kreeti/paperclip)
18
- [![Dependency Status](https://gemnasium.com/kreeti/paperclip.svg?travis)](https://gemnasium.com/kreeti/paperclip)
17
+ [![Build Status](https://travis-ci.com/kreeti/kt-paperclip.svg?branch=master)](https://travis-ci.com/kreeti/kt-paperclip)
19
18
  [![Code Climate](https://codeclimate.com/github/kreeti/paperclip.svg)](https://codeclimate.com/github/kreeti/paperclip)
20
19
  [![Inline docs](http://inch-ci.org/github/kreeti/paperclip.svg)](http://inch-ci.org/github/kreeti/paperclip)
21
20
  [![Security](https://hakiri.io/github/kreeti/paperclip/master.svg)](https://hakiri.io/github/kreeti/paperclip/master)
@@ -79,10 +78,10 @@ packages). Attached files are saved to the filesystem and referenced in the
79
78
  browser by an easily understandable specification, which has sensible and
80
79
  useful defaults.
81
80
 
82
- See the documentation for `has_attached_file` in [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/paperclip/Paperclip/ClassMethods) for
81
+ See the documentation for `has_attached_file` in [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/kt-paperclip/Paperclip/ClassMethods) for
83
82
  more detailed options.
84
83
 
85
- The complete [RDoc](http://www.rubydoc.info/gems/paperclip) is online.
84
+ The complete [RDoc](http://www.rubydoc.info/gems/kt-paperclip) is online.
86
85
 
87
86
  ---
88
87
 
@@ -91,7 +90,7 @@ Requirements
91
90
 
92
91
  ### Ruby and Rails
93
92
 
94
- Paperclip now requires Ruby version **>= 2.1** and Rails version **>= 4.2**
93
+ Paperclip now requires Ruby version **>= 2.2** and Rails version **>= 4.2**
95
94
  (only if you're going to use Paperclip with Ruby on Rails).
96
95
 
97
96
  ### Image Processor
@@ -172,13 +171,13 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
172
171
  Include the gem in your Gemfile:
173
172
 
174
173
  ```ruby
175
- gem "kt-paperclip", "~> 6.0.0"
174
+ gem "kt-paperclip", "~> 6.3"
176
175
  ```
177
176
 
178
177
  Or, if you want to get the latest, you can get master from the main paperclip repository:
179
178
 
180
179
  ```ruby
181
- gem "paperclip", git: "git://github.com/kreeti/paperclip.git"
180
+ gem "kt-paperclip", git: "git://github.com/kreeti/kt-paperclip.git"
182
181
  ```
183
182
 
184
183
  If you're trying to use features that don't seem to be in the latest released gem, but are
@@ -310,7 +309,7 @@ You'll need to add `<attachment>_content_type` in case you want to use content t
310
309
  validation.
311
310
 
312
311
  More information about the options passed to `has_attached_file` is available in the
313
- documentation of [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
312
+ documentation of [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/kt-paperclip/Paperclip/ClassMethods).
314
313
 
315
314
  Validations
316
315
  -----------
@@ -342,7 +341,7 @@ Example Usage:
342
341
  validates_attachment_presence :avatar
343
342
  ```
344
343
 
345
- Lastly, you can also define multiple validations on a single attachment using `validates_attachment`:
344
+ You can also define multiple validations on a single attachment using `validates_attachment`:
346
345
 
347
346
  ```ruby
348
347
  validates_attachment :avatar, presence: true,
@@ -411,6 +410,28 @@ validates_attachment :avatar,
411
410
  `Paperclip::ContentTypeDetector` will attempt to match a file's extension to an
412
411
  inferred content_type, regardless of the actual contents of the file.
413
412
 
413
+ ### Duplicate error messages
414
+
415
+ By default Paperclip will copy validation errors from the attribute to the base
416
+ of your model. Depending on how you display your validation errors, this can lead
417
+ to confusing duplicate errors (one on the attribute and another referring to the
418
+ base model).
419
+
420
+ You can override this behaviour with the `add_validation_errors_to` option. By
421
+ default this is set to `:both` but can be set to either `:attribute` or `:base`.
422
+
423
+ * `:both` creates errors on both the attribute and base model.
424
+ * `:attribute` only creates an error on the attribute of the model.
425
+ * `:base` only creates an error on the base model.
426
+
427
+ You can set this option globally:
428
+
429
+ `Paperclip.options[:add_validation_errors_to] = :attribute`
430
+
431
+ or pass it in to an individual validation declaration:
432
+
433
+ `validates_attachment :document, content_type: { content_type: "application/pdf" }, add_validation_errors_to: :attribute`
434
+
414
435
  ---
415
436
 
416
437
  Internationalization (I18n)
@@ -606,7 +627,7 @@ gem 'aws-sdk-s3'
606
627
 
607
628
  And then you can specify using S3 from `has_attached_file`.
608
629
  You can find more information about configuring and using S3 storage in
609
- [the `Paperclip::Storage::S3` documentation](http://www.rubydoc.info/gems/paperclip/Paperclip/Storage/S3).
630
+ [the `Paperclip::Storage::S3` documentation](http://www.rubydoc.info/gems/kt-paperclip/Paperclip/Storage/S3).
610
631
 
611
632
  Files on the local filesystem (and in the Rails app's public directory) will be
612
633
  available to the internet at large. If you require access control, it's
@@ -689,7 +710,7 @@ Custom Attachment Processors
689
710
  You can write your own custom attachment processors to carry out tasks like
690
711
  adding watermarks, compressing images, or encrypting files. Custom processors
691
712
  must be defined within the `Paperclip` module, inherit from
692
- `Paperclip::Processor` (see [`lib/paperclip/processor.rb`](https://github.com/kreeti/paperclip/blob/master/lib/paperclip/processor.rb)),
713
+ `Paperclip::Processor` (see [`lib/paperclip/processor.rb`](https://github.com/kreeti/kt-paperclip/blob/master/lib/paperclip/processor.rb)),
693
714
  and implement a `make` method that returns a `File`. All files in your Rails
694
715
  app's `lib/paperclip` and `lib/paperclip_processors` directories will be
695
716
  automatically loaded by Paperclip. Processors are specified using the
@@ -892,7 +913,7 @@ Your::Application.configure do
892
913
  end
893
914
  ```
894
915
 
895
- More information in the [rdocs](http://www.rubydoc.info/github/thoughtbot/paperclip/Paperclip.options)
916
+ More information in the [rdocs](https://www.rubydoc.info/gems/kt-paperclip/Paperclip.options)
896
917
 
897
918
  ---
898
919
 
@@ -976,7 +997,7 @@ Testing
976
997
  -------
977
998
 
978
999
  Paperclip provides rspec-compatible matchers for testing attachments. See the
979
- documentation on [Paperclip::Shoulda::Matchers](http://www.rubydoc.info/gems/paperclip/Paperclip/Shoulda/Matchers)
1000
+ documentation on [Paperclip::Shoulda::Matchers](http://www.rubydoc.info/gems/kt-paperclip/Paperclip/Shoulda/Matchers)
980
1001
  for more information.
981
1002
 
982
1003
  **Parallel Tests**
@@ -1036,15 +1057,15 @@ If you'd like to contribute a feature or bugfix: Thanks! To make sure your
1036
1057
  fix/feature has a high chance of being included, please read the following
1037
1058
  guidelines:
1038
1059
 
1039
- 1. Post a [pull request](https://github.com/kreeti/paperclip/compare/).
1060
+ 1. Post a [pull request](https://github.com/kreeti/kt-paperclip/compare/).
1040
1061
  2. Make sure there are tests! We will not accept any patch that is not tested.
1041
1062
  It's a rare time when explicit tests aren't needed. If you have questions
1042
1063
  about writing tests for paperclip, please open a
1043
- [GitHub issue](https://github.com/kreeti/paperclip/issues/new).
1064
+ [GitHub issue](https://github.com/kreeti/kt-paperclip/issues/new).
1044
1065
 
1045
1066
  Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md) for more details on contributing and running test.
1046
1067
 
1047
- Thank you to all [the contributors](https://github.com/kreeti/paperclip/graphs/contributors)!
1068
+ Thank you to all [the contributors](https://github.com/kreeti/kt-paperclip/graphs/contributors)!
1048
1069
 
1049
1070
  License
1050
1071
  -------
@@ -0,0 +1 @@
1
+ require "paperclip"
@@ -98,7 +98,8 @@ module Paperclip
98
98
  swallow_stderr: true,
99
99
  use_exif_orientation: true,
100
100
  whiny: true,
101
- is_windows: Gem.win_platform?
101
+ is_windows: Gem.win_platform?,
102
+ add_validation_errors_to: :both
102
103
  }
103
104
  end
104
105
 
@@ -9,8 +9,8 @@ module Paperclip
9
9
  REGEXP = /\Ahttps?:\/\//.freeze
10
10
 
11
11
  def initialize(target, options = {})
12
- escaped = URI.escape(target)
13
- super(URI(target == URI.unescape(target) ? escaped : target), options)
12
+ escaped = Paperclip::UrlGenerator.escape(target)
13
+ super(URI(target == Paperclip::UrlGenerator.unescape(target) ? escaped : target), options)
14
14
  end
15
15
  end
16
16
  end
@@ -50,10 +50,20 @@ module Paperclip
50
50
  "index.html"
51
51
  end
52
52
 
53
- def download_content
54
- options = { read_timeout: Paperclip.options[:read_timeout] }.compact
53
+ if RUBY_VERSION < '2.5'
54
+ def download_content
55
+ options = { read_timeout: Paperclip.options[:read_timeout] }.compact
55
56
 
56
- open(@target, **options)
57
+ # rubocop:disable Security/Open
58
+ open(@target, options)
59
+ # rubocop:enable Security/Open
60
+ end
61
+ else
62
+ def download_content
63
+ options = { read_timeout: Paperclip.options[:read_timeout] }.compact
64
+
65
+ URI.open(@target, options)
66
+ end
57
67
  end
58
68
 
59
69
  def copy_to_tempfile(src)
@@ -26,7 +26,7 @@ module Paperclip
26
26
  attachment_names.each do |attachment_name|
27
27
  COLUMNS.each_pair do |column_name, column_type|
28
28
  column_options = options.merge(options[column_name.to_sym] || {})
29
- add_column(table_name, "#{attachment_name}_#{column_name}", column_type, column_options)
29
+ add_column(table_name, "#{attachment_name}_#{column_name}", column_type, **column_options)
30
30
  end
31
31
  end
32
32
  end
@@ -55,7 +55,7 @@ module Paperclip
55
55
  attachment_names.each do |attachment_name|
56
56
  COLUMNS.each_pair do |column_name, column_type|
57
57
  column_options = options.merge(options[column_name.to_sym] || {})
58
- column("#{attachment_name}_#{column_name}", column_type, column_options)
58
+ column("#{attachment_name}_#{column_name}", column_type, **column_options)
59
59
  end
60
60
  end
61
61
  end
@@ -427,9 +427,9 @@ module Paperclip
427
427
  def find_credentials(creds)
428
428
  case creds
429
429
  when File
430
- YAML::safe_load(ERB.new(File.read(creds.path)).result)
430
+ YAML::safe_load(ERB.new(File.read(creds.path)).result, [], [], true)
431
431
  when String, Pathname
432
- YAML::safe_load(ERB.new(File.read(creds)).result)
432
+ YAML::safe_load(ERB.new(File.read(creds)).result, [], [], true)
433
433
  when Hash
434
434
  creds
435
435
  when NilClass
@@ -3,6 +3,13 @@ require "active_support/core_ext/module/delegation"
3
3
 
4
4
  module Paperclip
5
5
  class UrlGenerator
6
+ class << self
7
+ def encoder
8
+ @encoder ||= URI::RFC2396_Parser.new
9
+ end
10
+ delegate :escape, :unescape, to: :encoder
11
+ end
12
+
6
13
  def initialize(attachment)
7
14
  @attachment = attachment
8
15
  end
@@ -65,7 +72,7 @@ module Paperclip
65
72
  if url.respond_to?(:escape)
66
73
  url.escape
67
74
  else
68
- URI.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
75
+ self.class.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
69
76
  end
70
77
  end
71
78
 
@@ -20,10 +20,10 @@ module Paperclip
20
20
  ::Paperclip::REQUIRED_VALIDATORS = [AttachmentFileNameValidator, AttachmentContentTypeValidator, AttachmentFileTypeIgnoranceValidator].freeze
21
21
 
22
22
  module ClassMethods
23
- # This method is a shortcut to validator classes that is in
24
- # "Attachment...Validator" format. It is almost the same thing as the
25
- # +validates+ method that shipped with Rails, but this is customized to
26
- # be using with attachment validators. This is helpful when you're using
23
+ # This method is a shortcut to the validator classes that are in
24
+ # "Attachment...Validator" format. It is almost the same as the
25
+ # +validates+ method that ships with Rails, but is customized for
26
+ # use with attachment validators. This is helpful when you're using
27
27
  # multiple attachment validators on a single attachment.
28
28
  #
29
29
  # Example of using the validator:
@@ -3,6 +3,9 @@ module Paperclip
3
3
  class AttachmentContentTypeValidator < ActiveModel::EachValidator
4
4
  def initialize(options)
5
5
  options[:allow_nil] = true unless options.key?(:allow_nil)
6
+ unless options.key?(:add_validation_errors_to)
7
+ options[:add_validation_errors_to] = Paperclip.options[:add_validation_errors_to]
8
+ end
6
9
  super
7
10
  end
8
11
 
@@ -20,10 +23,14 @@ module Paperclip
20
23
  validate_whitelist(record, attribute, value)
21
24
  validate_blacklist(record, attribute, value)
22
25
 
23
- if record.errors.include? attribute
26
+ if record.errors.include?(attribute) &&
27
+ [:both, :base].include?(options[:add_validation_errors_to])
28
+
24
29
  record.errors[attribute].each do |error|
25
30
  record.errors.add base_attribute, error
26
31
  end
32
+
33
+ record.errors.delete(attribute) if options[:add_validation_errors_to] == :base
27
34
  end
28
35
  end
29
36
 
@@ -3,6 +3,9 @@ module Paperclip
3
3
  class AttachmentFileNameValidator < ActiveModel::EachValidator
4
4
  def initialize(options)
5
5
  options[:allow_nil] = true unless options.key?(:allow_nil)
6
+ unless options.key?(:add_validation_errors_to)
7
+ options[:add_validation_errors_to] = Paperclip.options[:add_validation_errors_to]
8
+ end
6
9
  super
7
10
  end
8
11
 
@@ -20,10 +23,14 @@ module Paperclip
20
23
  validate_whitelist(record, attribute, value)
21
24
  validate_blacklist(record, attribute, value)
22
25
 
23
- if record.errors.include? attribute
26
+ if record.errors.include?(attribute) &&
27
+ [:both, :base].include?(options[:add_validation_errors_to])
28
+
24
29
  record.errors[attribute].each do |error|
25
30
  record.errors.add base_attribute, error
26
31
  end
32
+
33
+ record.errors.delete(attribute) if options[:add_validation_errors_to] == :base
27
34
  end
28
35
  end
29
36
 
@@ -17,6 +17,18 @@ module Paperclip
17
17
  def validate_each(record, attr_name, value)
18
18
  base_attr_name = attr_name
19
19
  attr_name = "#{attr_name}_file_size".to_sym
20
+
21
+ error_attrs = []
22
+ case options[:add_validation_errors_to]
23
+ when :base
24
+ error_attrs << base_attr_name
25
+ when :attribute
26
+ error_attrs << attr_name
27
+ else
28
+ error_attrs << base_attr_name
29
+ error_attrs << attr_name
30
+ end
31
+
20
32
  value = record.send(:read_attribute_for_validation, attr_name)
21
33
 
22
34
  unless value.blank?
@@ -26,7 +38,7 @@ module Paperclip
26
38
 
27
39
  unless value.send(CHECKS[option], option_value)
28
40
  error_message_key = options[:in] ? :in_between : option
29
- [attr_name, base_attr_name].each do |error_attr_name|
41
+ error_attrs.each do |error_attr_name|
30
42
  record.errors.add(error_attr_name, error_message_key, filtered_options(value).merge(
31
43
  min: min_value_in_human_size(record),
32
44
  max: max_value_in_human_size(record),
@@ -56,6 +68,10 @@ module Paperclip
56
68
  options[:greater_than_or_equal_to] = range
57
69
  end
58
70
  end
71
+
72
+ unless options.key?(:add_validation_errors_to)
73
+ options[:add_validation_errors_to] = Paperclip.options[:add_validation_errors_to]
74
+ end
59
75
  end
60
76
 
61
77
  def extract_option_value(option, option_value)
@@ -1,3 +1,3 @@
1
1
  module Paperclip
2
- VERSION = "6.2.0" unless defined?(Paperclip::VERSION)
2
+ VERSION = "6.4.1" unless defined?(Paperclip::VERSION)
3
3
  end
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.author = "Surendra Singhi"
9
9
  s.email = ["ssinghi@kreeti.com"]
10
- s.homepage = "https://github.com/kreeti/paperclip"
10
+ s.homepage = "https://github.com/kreeti/kt-paperclip"
11
11
  s.summary = "File attachments as attributes for ActiveRecord"
12
12
  s.description = "Easy upload management for ActiveRecord"
13
13
  s.license = "MIT"
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.post_install_message = File.read("UPGRADING") if File.exist?("UPGRADING")
21
21
 
22
22
  s.requirements << "ImageMagick"
23
- s.required_ruby_version = ">= 2.1.0"
23
+ s.required_ruby_version = ">= 2.2.0"
24
24
 
25
25
  s.add_dependency("activemodel", ">= 4.2.0")
26
26
  s.add_dependency("activesupport", ">= 4.2.0")
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_development_dependency("aws-sdk-s3")
35
35
  s.add_development_dependency("bundler")
36
36
  s.add_development_dependency("capybara")
37
- s.add_development_dependency("cucumber-expressions", "4.0.3") # TODO: investigate failures on 4.0.4
37
+ s.add_development_dependency("cucumber-expressions")
38
38
  s.add_development_dependency("cucumber-rails")
39
39
  s.add_development_dependency("fakeweb")
40
40
  s.add_development_dependency("fog-aws")