kt-paperclip-vips 1.2.2 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4aa0400c5db1aca28cf71692d749f5693bccfa4ac56d5cbd6599d10060423c3
4
- data.tar.gz: 99c3a302cae0af2f37c24918b6bfbfffca917cde6640fa18e013e6dd934bfc6e
3
+ metadata.gz: 5abb1916de9e20f18378d68ad36d1ad68444d9f4810b2af60a503f061e62173b
4
+ data.tar.gz: '038faff11b80ab241544d7afd510c3fbff8907be56e5abe6c485872fc735a3ab'
5
5
  SHA512:
6
- metadata.gz: aa8aee51bc040cd4a3bcb5ee2d2a90dffde49d602db8def2b42a50a284998cb310d49f2eabf7e109b16c5a8c2444f8a37728074372d581e1d6987ec06a2bc3c1
7
- data.tar.gz: 7a538b91a744206fe7dfa52eb80c8cb9d21085d2bb4fb23ed0f84498d70459149a36f2665a8f8fc27c033a638adc9007c9cd46dc360174508998d1ecc241c7f5
6
+ metadata.gz: 4f189349bf4e1dc8b3a56799ec1a1639c9e47810200aa9818eadb2fc5f8d2c6f1a0df69d27abcb3d129a6a76a70fedf1e91d79f3522fcb120c9ab5261dad63e9
7
+ data.tar.gz: '082eda71b1c8cbcb2b3f99713036e0944cea35c3c88f45fe87e72c6c6b6a4f5063a946ce7fac2edc0cda87b501444c26d518d800c0f180026850189b7b2fe2a1'
data/.rubocop.yml ADDED
@@ -0,0 +1,135 @@
1
+ plugins:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.2
8
+ DisabledByDefault: false
9
+ DisplayCopNames: true
10
+ NewCops: enable
11
+ Exclude:
12
+ - "**/bin/*"
13
+ - "**/config.ru"
14
+ - "**/db/**/*"
15
+ - "**/schema.rb"
16
+ - "**/node_modules/**/*"
17
+ - "**/vendor/**/*"
18
+ - "**/vendor/**/*.txt"
19
+ - "**/test/**/*"
20
+ - "**/tmp/**/*"
21
+
22
+ # Dim down rubocop's annoyance level below:
23
+
24
+ Layout/ArgumentAlignment:
25
+ Enabled: true
26
+ EnforcedStyle: with_fixed_indentation
27
+
28
+ Layout/CaseIndentation:
29
+ Enabled: true
30
+ EnforcedStyle: end
31
+
32
+ Layout/EndAlignment:
33
+ Enabled: true
34
+ EnforcedStyleAlignWith: variable
35
+ AutoCorrect: true
36
+
37
+ Layout/LineLength:
38
+ Exclude:
39
+ - app/views/**/*.rb
40
+ - app/components/**/*.rb
41
+ - lib/generators/**/*.rb
42
+ Max: 125
43
+
44
+ Layout/SpaceInsideBlockBraces:
45
+ Enabled: true
46
+ EnforcedStyleForEmptyBraces: space
47
+
48
+ Layout/SpaceInsideArrayLiteralBrackets:
49
+ EnforcedStyle: no_space
50
+
51
+ Layout/SpaceInsideHashLiteralBraces:
52
+ Enabled: true
53
+ EnforcedStyle: space
54
+ EnforcedStyleForEmptyBraces: no_space
55
+
56
+ Lint/MissingSuper:
57
+ Enabled: false
58
+
59
+ Metrics:
60
+ Enabled: false
61
+
62
+ Naming/FileName:
63
+ Exclude:
64
+ - lib/paperclip-vips.rb
65
+
66
+ RSpec/ExampleLength:
67
+ Enabled: false
68
+
69
+ RSpec/IndexedLet:
70
+ Enabled: false
71
+
72
+ RSpec/AlignLeftLetBrace:
73
+ Enabled: true
74
+
75
+ RSpec/MultipleExpectations:
76
+ Enabled: false
77
+
78
+ RSpec/MultipleMemoizedHelpers:
79
+ Max: 10
80
+
81
+ RSpec/NestedGroups:
82
+ Max: 4
83
+
84
+ RSpec/PendingWithoutReason:
85
+ Enabled: false
86
+
87
+ RSpec/PredicateMatcher:
88
+ Enabled: false
89
+
90
+ RSpec/SpecFilePathFormat:
91
+ Enabled: false
92
+
93
+ Style/ClassAndModuleChildren:
94
+ EnforcedStyle: nested
95
+ Exclude:
96
+ - app/events/**/*.rb
97
+ # - app/views/**/*.rb
98
+
99
+ Style/CommentedKeyword:
100
+ Enabled: false
101
+
102
+ Style/Documentation:
103
+ Enabled: false
104
+
105
+ Style/EmptyMethod:
106
+ Enabled: false
107
+
108
+ Style/FormatStringToken:
109
+ EnforcedStyle: template
110
+
111
+ Style/FrozenStringLiteralComment:
112
+ Enabled: true
113
+ EnforcedStyle: never
114
+
115
+ Style/HashSyntax:
116
+ Enabled: true
117
+ EnforcedShorthandSyntax: always
118
+
119
+ Style/PercentLiteralDelimiters:
120
+ PreferredDelimiters:
121
+ default: "()"
122
+ "%i": "[]"
123
+ "%I": "[]"
124
+ "%r": "{}"
125
+ "%w": "[]"
126
+ "%W": "[]"
127
+
128
+ Style/StringLiterals:
129
+ EnforcedStyle: double_quotes
130
+
131
+ Style/TrailingCommaInHashLiteral:
132
+ EnforcedStyleForMultiline: comma
133
+
134
+ Style/TrailingCommaInArrayLiteral:
135
+ EnforcedStyleForMultiline: comma
data/Gemfile CHANGED
@@ -4,7 +4,11 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "bundler"
7
+ gem "byebug"
8
+ gem "gem-release"
7
9
  gem "rake"
8
10
  gem "rspec"
9
- gem "byebug"
10
- gem "gem-release"
11
+ gem "rubocop"
12
+ gem "rubocop-performance"
13
+ gem "rubocop-rake"
14
+ gem "rubocop-rspec"
data/README.md CHANGED
@@ -7,7 +7,7 @@ A custom paperclip processor that uses the [libvips image processing library](ht
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'paperclip-vips'
10
+ gem 'kt-paperclip-vips'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -16,7 +16,7 @@ And then execute:
16
16
 
17
17
  Or install it yourself as:
18
18
 
19
- $ gem install paperclip-vips
19
+ $ gem install kt-paperclip-vips
20
20
 
21
21
  Note: You will need to have libvips installed on your machine for this processor to work correctly.
22
22
 
data/Rakefile CHANGED
@@ -3,4 +3,4 @@ require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "paperclip/vips"
4
+ require 'bundler/setup'
5
+ require 'paperclip/vips'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "paperclip/vips"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,13 +1,13 @@
1
1
  module Paperclip
2
2
  class Vips < Processor
3
3
  attr_accessor :auto_orient, :convert_options, :current_geometry, :format, :source_file_options,
4
- :target_geometry, :whiny
4
+ :target_geometry, :whiny
5
5
 
6
6
  def initialize(file, options = {}, attachment = nil)
7
7
  super
8
8
 
9
9
  geometry = options[:geometry].to_s
10
- @should_crop = geometry[-1,1] == '#'
10
+ @should_crop = geometry[-1, 1] == "#"
11
11
  @target_geometry = options.fetch(:string_geometry_parser, Geometry).parse(geometry)
12
12
  @current_geometry = options.fetch(:file_geometry_parser, Geometry).from_file(@file)
13
13
  @whiny = options.fetch(:whiny, true)
@@ -27,96 +27,125 @@ module Paperclip
27
27
  destination = TempfileFactory.new.generate(filename)
28
28
 
29
29
  begin
30
- thumbnail = ::Vips::Image.thumbnail(source.path, width, height: crop ? height : nil, crop: crop) if @target_geometry
31
- thumbnail = ::Vips::Image.new_from_file(source.path) if !defined?(thumbnail) || thumbnail.nil?
30
+ if @target_geometry.present?
31
+ target_width = @target_geometry.width
32
+ target_height = @target_geometry.height
33
+ modifier = @target_geometry.modifier # e.g., ">", "#", etc.
34
+
35
+ # Use thumbnail for efficient resizing and cropping
36
+ crop = (modifier == "#")
37
+ thumbnail = ::Vips::Image.thumbnail(
38
+ source.path,
39
+ target_width,
40
+ height: crop ? target_height : nil,
41
+ size: (modifier == ">" ? :down : :both), # ">" means shrink only
42
+ crop: crop ? :centre : :none
43
+ )
44
+
45
+ # Additional cropping for exact "#" dimensions if needed
46
+ if crop && (thumbnail.width != target_width || thumbnail.height != target_height)
47
+ left = [0, (thumbnail.width - target_width) / 2].max
48
+ top = [0, (thumbnail.height - target_height) / 2].max
49
+ crop_width = [target_width, thumbnail.width - left].min
50
+ crop_height = [target_height, thumbnail.height - top].min
51
+ if crop_width.positive? && crop_height.positive?
52
+ thumbnail = thumbnail.crop(left, top, crop_width,
53
+ crop_height)
54
+ end
55
+ end
56
+ end
57
+
58
+ # Fallback to original image if no geometry
59
+ thumbnail = ::Vips::Image.new_from_file(source.path) unless defined?(thumbnail) && thumbnail
60
+
61
+ # Apply convert options
32
62
  thumbnail = process_convert_options(thumbnail)
33
- save_thumbnail(thumbnail, destination.path)
34
-
35
- rescue => e
36
- p e.message, e.backtrace
37
63
 
64
+ # Save the processed image
65
+ save_thumbnail(thumbnail, destination.path)
66
+ rescue StandardError => e
67
+ puts e.message, e.backtrace
38
68
  if @whiny
39
- message = "There was an error processing the thumbnail for #{@basename}:\n" + e.message
69
+ message = "There was an error processing the thumbnail for #{@basename}:\n#{e.message}"
40
70
  raise Paperclip::Error, message
41
71
  end
42
72
  end
43
73
 
44
- return destination
74
+ destination # Return the Tempfile object
45
75
  end
46
76
 
47
77
  private
48
- def crop
49
- if @should_crop
50
- return @options[:crop] || :centre
51
- end
52
78
 
53
- nil
54
- end
79
+ def crop
80
+ return @options[:crop] || :centre if @should_crop
55
81
 
56
- def current_format(file)
57
- extension = File.extname(file.path)
58
- return extension if extension.present?
82
+ nil
83
+ end
59
84
 
60
- extension = File.extname(file.original_filename)
61
- return extension if extension.present?
85
+ def current_format(file)
86
+ extension = File.extname(file.path)
87
+ return extension if extension.present?
62
88
 
63
- return ""
64
- end
89
+ extension = File.extname(file.original_filename)
90
+ return extension if extension.present?
65
91
 
66
- def width
67
- @target_geometry&.width || @current_geometry.width
68
- end
69
-
70
- def height
71
- @target_geometry&.height || @current_geometry.height
72
- end
73
-
74
- def process_convert_options(image)
75
- if image
76
- commands = parsed_convert_commands(@convert_options)
77
- commands.each do |cmd|
78
- image = ::Vips::Operation.call(cmd[:cmd], [image, *cmd[:args]], cmd[:optional] || {})
79
- end
80
- end
92
+ ""
93
+ end
81
94
 
82
- return image
83
- end
95
+ def width
96
+ @target_geometry&.width || @current_geometry.width
97
+ end
84
98
 
85
- def parsed_convert_commands(convert_options)
86
- begin
87
- commands = JSON.parse(convert_options, symbolize_names: true)
88
- rescue
89
- commands = []
90
- end
99
+ def height
100
+ @target_geometry&.height || @current_geometry.height
101
+ end
91
102
 
92
- if @auto_orient && commands.none? { _1[:cmd] == "autorot" }
93
- commands.unshift({ cmd: "autorot" })
94
- end
103
+ def process_convert_options(image)
104
+ if image && @convert_options.present?
105
+ # Handle string-based convert_options (e.g., "-quality 80 -strip")
106
+ quality = @convert_options[/quality (\d+)/, 1]&.to_i
107
+ strip = @convert_options.include?("-strip")
95
108
 
96
- return commands
97
- end
109
+ # Apply options via instance variables for save_thumbnail
110
+ @processed_quality = quality if quality
111
+ @processed_strip = strip if strip
98
112
 
99
- def save_thumbnail(thumbnail, path)
100
- case @current_format
101
- when ".jpeg", ".jpg"
102
- save_jpg(thumbnail, path)
103
- when ".gif"
104
- save_gif(thumbnail, path)
105
- when ".png"
106
- save_png(thumbnail, path)
113
+ # Handle JSON-based commands if present
114
+ commands = parsed_convert_commands(@convert_options)
115
+ commands.each do |cmd|
116
+ image = ::Vips::Operation.call(cmd[:cmd], [image, *cmd[:args]], cmd[:optional] || {})
107
117
  end
108
118
  end
119
+ image
120
+ end
109
121
 
110
- def save_jpg(thumbnail, path)
111
- thumbnail.jpegsave(path)
122
+ def parsed_convert_commands(convert_options)
123
+ begin
124
+ commands = JSON.parse(convert_options, symbolize_names: true)
125
+ rescue StandardError
126
+ commands = []
112
127
  end
113
128
 
114
- def save_gif(thumbnail, path)
115
- thumbnail.magicksave(path)
116
- end
129
+ commands.unshift({ cmd: "autorot" }) if @auto_orient && commands.none? { |cmd| cmd[:cmd] == "autorot" }
117
130
 
118
- def save_png(thumbnail, path)
119
- thumbnail.pngsave(path)
131
+ commands
132
+ end
133
+
134
+ def save_thumbnail(thumbnail, path)
135
+ quality = @processed_quality || 75
136
+ strip = @processed_strip || false
137
+
138
+ case @format.to_s.downcase
139
+ when ".jpeg", ".jpg", "jpeg", "jpg", "webp"
140
+ thumbnail.jpegsave(path, Q: quality, strip:)
141
+ when ".gif", "gif"
142
+ thumbnail.magicksave(path, strip:) # No quality for GIF
143
+ when ".png", "png"
144
+ compression = 9 - (quality / 11.1).floor # Map 0-100 to 9-0
145
+ thumbnail.pngsave(path, compression:, strip:)
146
+ else
147
+ thumbnail.write_to_file(path) # Fallback
120
148
  end
149
+ end
121
150
  end
122
151
  end
@@ -1,3 +1,3 @@
1
1
  module PaperclipVips
2
- VERSION = "1.2.2"
2
+ VERSION = "1.2.4".freeze
3
3
  end
@@ -5,6 +5,6 @@ require "paperclip-vips/paperclip/vips"
5
5
 
6
6
  module PaperclipVips
7
7
  def self.root
8
- Gem::Specification.find_by_name('paperclip-vips').gem_dir
8
+ Gem::Specification.find_by_name("kt-paperclip-vips").gem_dir
9
9
  end
10
10
  end
@@ -1,5 +1,4 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path("lib", __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require "paperclip-vips/version"
5
4
 
@@ -9,19 +8,22 @@ Gem::Specification.new do |spec|
9
8
  spec.authors = ["Ken Greeff", "Mikael Henriksson"]
10
9
  spec.email = ["ken@kengreeff.com", "mikael@mhenrixon.com"]
11
10
 
12
- spec.summary = %q{Uses Ruby Vips to when creating thumbnails for faster generation.}
11
+ spec.summary = "Uses Ruby Vips to when creating thumbnails for faster generation."
13
12
  spec.homepage = "https://github.com/realhub/paperclip-vips"
14
13
  spec.license = "MIT"
15
14
 
15
+ spec.required_ruby_version = ">= 3.2.0"
16
+
16
17
  # Specify which files should be added to the gem when it is released.
17
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
20
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|Gemfile|mise.toml/bin)/}) }
20
21
  end
21
22
  spec.bindir = "exe"
22
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
24
  spec.require_paths = ["lib"]
24
25
 
25
- spec.add_runtime_dependency 'kt-paperclip', ">= 5.0.0"
26
- spec.add_runtime_dependency "ruby-vips", ">= 2.1"
26
+ spec.add_dependency "kt-paperclip", ">= 5.0.0"
27
+ spec.add_dependency "ruby-vips", ">= 2.1"
28
+ spec.metadata["rubygems_mfa_required"] = "true"
27
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kt-paperclip-vips
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Greeff
8
8
  - Mikael Henriksson
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-20 00:00:00.000000000 Z
11
+ date: 2025-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kt-paperclip
@@ -47,6 +47,7 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
49
  - ".rspec"
50
+ - ".rubocop.yml"
50
51
  - ".travis.yml"
51
52
  - CHANGELOG.md
52
53
  - CODE_OF_CONDUCT.md
@@ -63,7 +64,8 @@ files:
63
64
  homepage: https://github.com/realhub/paperclip-vips
64
65
  licenses:
65
66
  - MIT
66
- metadata: {}
67
+ metadata:
68
+ rubygems_mfa_required: 'true'
67
69
  rdoc_options: []
68
70
  require_paths:
69
71
  - lib
@@ -71,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
73
  requirements:
72
74
  - - ">="
73
75
  - !ruby/object:Gem::Version
74
- version: '0'
76
+ version: 3.2.0
75
77
  required_rubygems_version: !ruby/object:Gem::Requirement
76
78
  requirements:
77
79
  - - ">="