shrine-thumbhash 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 56d67f222347d85c3a9a72603effe992cbbf5538fa7aeaf1e63d06859c06064c
4
+ data.tar.gz: 7d808dd14643b00720a42b6c49bdc5aea910902135d4005c92a601e46c89789d
5
+ SHA512:
6
+ metadata.gz: f5b3fff17ba9bd77a9fa1755018a2a219b0dc87a32e7d868dd468bad3890b90695a7a5985265971fe0598378b792d60d0c4f5ca8911bd2b71e88360442d3498d
7
+ data.tar.gz: fbc81b2d279f6c169e85fa99b7338fe449fac80e78fc1d55e9d7e609bf3af7168240cf83e7c04c7f5c4509c25ae8dd73f94a7a196146783ab48ff4c0902c7a7f
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 2.6
4
+
5
+ Layout/LineLength:
6
+ Max: 120
7
+
8
+ Metrics/MethodLength:
9
+ Enabled: true
10
+ Max: 15
11
+
12
+ Style/StringLiterals:
13
+ Enabled: true
14
+ EnforcedStyle: double_quotes
15
+
16
+ Style/StringLiteralsInInterpolation:
17
+ Enabled: true
18
+ EnforcedStyle: double_quotes
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in shrine-thumbhash.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "rubocop", "~> 1.21"
11
+ gem "ruby-vips", "~> 2.0"
12
+
13
+ gem "shrine", ENV["SHRINE_VERSION"] unless ENV["SHRINE_VERSION"].nil?
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Shrine::Thumbhash
2
+
3
+ Shrine plugin for generate Thumbhash from image attachments.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add shrine-thumbhash
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install shrine-thumbhash
14
+
15
+ ## Requirements
16
+ - [ruby-vips gem](https://rubygems.org/gems/ruby-vips) (default or when you specify `:ruby_vips` to image_loader option)
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ require "shrine"
22
+ require "shrine/storage/memory"
23
+ require "shrine/plugins/thumbhash"
24
+
25
+ Shrine.plugin :thumbhash
26
+ Shrine.storages[:store] = Shrine::Storage::Memory.new
27
+ uploader = Shrine.new(:store)
28
+
29
+ image = File.open("path/to/image.jpg", binmode: true)
30
+ uploaded_file = uploader.upload(image)
31
+
32
+ uploaded_file.thumbhash
33
+ # => Base64 encoded thumbhash such as "YJqGPQw7sFlslqhFafSE+Q6oJ1h2iHB2Rw=="
34
+ uploaded_file.thumbhash_urlsafe
35
+ # => URLsafe Base64 encoded thumbhash such as "YJqGPQw7sFlslqhFafSE-Q6oJ1h2iHB2Rw=="
36
+ ```
37
+
38
+ ## Options
39
+
40
+ ### padding
41
+ When specify false, thumbhash will be without padding.
42
+
43
+ Default: true
44
+ ```ruby
45
+ Shrine.plugin :thumbhash, padding: false
46
+ ... # omit
47
+ uploaded_file.thumbhash
48
+ # => Base64 encoded thumbhash without padding such as "YJqGPQw7sFlslqhFafSE+Q6oJ1h2iHB2Rw"
49
+ uploaded_file.thumbhash_urlsafe
50
+ # => URLsafe Base64 encoded thumbhash without padding such as "YJqGPQw7sFlslqhFafSE-Q6oJ1h2iHB2Rw"
51
+ ```
52
+
53
+ ### image_loader
54
+ A ruby object be used for loading and resizeing image.
55
+ When you choose from our implementations, you can specify them by Symbol.
56
+
57
+ - `:ruby_vips`
58
+
59
+ Default: :ruby_vips
60
+
61
+ If you want to use something other than our implementations, you can implement it yourself.
62
+ See `lib/shrine/plugins/image_loader/ruby_vips.rb`.
63
+
64
+ ## Development
65
+
66
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
+
68
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
+
70
+ ## Contributing
71
+
72
+ Bug reports and pull requests are welcome on GitHub at https://github.com/takayamaki/shrine-thumbhash.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shrine # :nodoc:
4
+ module Plugins # :nodoc:
5
+ module Thumbhash # :nodoc:
6
+ class Image # :nodoc:
7
+ attr_reader :width, :height, :pixels
8
+
9
+ def initialize(width, height, pixels)
10
+ @width = width
11
+ @height = height
12
+ @pixels = pixels
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../image"
4
+ require "ruby-vips"
5
+
6
+ class Shrine # :nodoc:
7
+ module Plugins # :nodoc:
8
+ module Thumbhash # :nodoc:
9
+ module ImageLoader # :nodoc:
10
+ module RubyVips # :nodoc:
11
+ def self.call(io)
12
+ image = load_image(io)
13
+ image = resize_image(image)
14
+ Thumbhash::Image.new(
15
+ image.width,
16
+ image.height,
17
+ repack_pixels_to_flattened_rgba_array(image)
18
+ )
19
+ end
20
+
21
+ def self.load_image(io)
22
+ src = ::Vips::Source.new_from_descriptor(io.fileno)
23
+ ::Vips::Image.new_from_source(src, "")
24
+ end
25
+
26
+ def self.resize_image(image)
27
+ return image if image.width <= 100 && image.height <= 100
28
+
29
+ scale_factor = [100.fdiv(image.width), 100.fdiv(image.height)].min
30
+ image.resize(scale_factor)
31
+ end
32
+
33
+ def self.repack_pixels_to_flattened_rgba_array(image)
34
+ case image.bands
35
+ when 3
36
+ image.to_enum.flat_map { |line| line.flat_map { |rgb| rgb.push(255) } }
37
+ when 4
38
+ image.to_enum.flat_map(&:flatten)
39
+ else
40
+ raise "Unexpected bands: #{image.bands}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shrine
4
+ module Plugins
5
+ module Thumbhash
6
+ VERSION = "0.1.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shrine"
4
+ require "thumbhash"
5
+
6
+ class Shrine # :nodoc:
7
+ module Plugins # :nodoc:
8
+ module Thumbhash # :nodoc:
9
+ DEFAULT_OPTIONS = {
10
+ padding: true,
11
+ image_loader: :ruby_vips
12
+ }.freeze
13
+
14
+ def self.configure(uploader, **opts)
15
+ uploader.opts[:thumbhash] ||= DEFAULT_OPTIONS.dup
16
+ uploader.opts[:thumbhash].merge!(opts)
17
+ configure_image_loader(uploader.opts[:thumbhash]) if uploader.opts[:thumbhash][:image_loader_class].nil?
18
+ end
19
+
20
+ def self.configure_image_loader(opts)
21
+ return unless opts[:image_loader] == :ruby_vips
22
+
23
+ require_relative "image_loader/ruby_vips"
24
+ opts[:image_loader] = Shrine::Plugins::Thumbhash::ImageLoader::RubyVips
25
+ end
26
+
27
+ module ClassMethods # :nodoc:
28
+ def generate_thumbhash(io)
29
+ image = opts[:thumbhash][:image_loader].call(io)
30
+
31
+ ::ThumbHash.rgba_to_thumb_hash(
32
+ image.width,
33
+ image.height,
34
+ image.pixels
35
+ )
36
+ end
37
+ end
38
+
39
+ module InstanceMethods # :nodoc:
40
+ def extract_metadata(io, **options)
41
+ thumbhash = self.class.generate_thumbhash(io)
42
+ super.merge!(encode_thumbhash_as_base64(thumbhash))
43
+ end
44
+
45
+ private
46
+
47
+ def encode_thumbhash_as_base64(thumbhash)
48
+ if self.class.opts[:thumbhash][:padding]
49
+ {
50
+ "thumbhash" => Base64.strict_encode64(thumbhash),
51
+ "thumbhash_urlsafe" => Base64.urlsafe_encode64(thumbhash)
52
+ }
53
+ else
54
+ {
55
+ "thumbhash" => Base64.strict_encode64(thumbhash).gsub!("=", ""),
56
+ "thumbhash_urlsafe" => Base64.urlsafe_encode64(thumbhash, padding: false)
57
+ }
58
+ end
59
+ end
60
+ end
61
+
62
+ module FileMethods # :nodoc:
63
+ def thumbhash
64
+ metadata["thumbhash"]
65
+ end
66
+
67
+ def thumbhash_urlsafe
68
+ metadata["thumbhash_urlsafe"]
69
+ end
70
+ end
71
+ end
72
+
73
+ register_plugin(:thumbhash, Thumbhash)
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/shrine/plugins/thumbhash/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "shrine-thumbhash"
7
+ spec.version = Shrine::Plugins::Thumbhash::VERSION
8
+ spec.authors = ["takayamaki / fusagiko"]
9
+ spec.email = ["24884114+takayamaki@users.noreply.github.com"]
10
+
11
+ spec.summary = "Shrine plugin for generate Thumbhash from image attachments"
12
+ spec.homepage = "https://github.com/takayamaki/shrine-thumbhash"
13
+ spec.required_ruby_version = ">= 2.6"
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/takayamaki/shrine-thumbhash"
19
+ spec.metadata["changelog_uri"] = "https://github.com/takayamaki/shrine-thumbhash/releases"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
+ end
27
+ end
28
+ spec.require_paths = ["lib"]
29
+
30
+ # Uncomment to register a new dependency of your gem
31
+ spec.add_dependency "shrine", "~> 3.0"
32
+ spec.add_dependency "thumbhash", "~> 0.0.1"
33
+
34
+ # For more information and examples about making a new gem, check out our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ spec.metadata["rubygems_mfa_required"] = "true"
37
+ end
@@ -0,0 +1,8 @@
1
+ class Shrine
2
+ module Plugins
3
+ module Thumbhash
4
+ VERSION: String
5
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shrine-thumbhash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - takayamaki / fusagiko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: shrine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thumbhash
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.1
41
+ description:
42
+ email:
43
+ - 24884114+takayamaki@users.noreply.github.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".rspec"
49
+ - ".rubocop.yml"
50
+ - Gemfile
51
+ - README.md
52
+ - Rakefile
53
+ - lib/shrine/plugins/image.rb
54
+ - lib/shrine/plugins/image_loader/ruby_vips.rb
55
+ - lib/shrine/plugins/thumbhash.rb
56
+ - lib/shrine/plugins/thumbhash/version.rb
57
+ - shrine-thumbhash.gemspec
58
+ - sig/shrine/plugins/thumbhash.rbs
59
+ homepage: https://github.com/takayamaki/shrine-thumbhash
60
+ licenses: []
61
+ metadata:
62
+ allowed_push_host: https://rubygems.org
63
+ homepage_uri: https://github.com/takayamaki/shrine-thumbhash
64
+ source_code_uri: https://github.com/takayamaki/shrine-thumbhash
65
+ changelog_uri: https://github.com/takayamaki/shrine-thumbhash/releases
66
+ rubygems_mfa_required: 'true'
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '2.6'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.2.3
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Shrine plugin for generate Thumbhash from image attachments
86
+ test_files: []