imgproxy 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0b6f43dc8ff8bc89edf3015f8ebac74c4c8b4f785a0c886209a66133d44c7754
4
+ data.tar.gz: 68749943510a2c6b41608ebb9fdd132d5339ad35486019710588f5ec3aa49d35
5
+ SHA512:
6
+ metadata.gz: a320137aa833b9af94bb9de211b297e49fe2bb515a2b6a08d6cfae9b512173653ec82c1bf85964e126a56e39fe92073049e4d382d789d6a0c70e8d89d551ca20
7
+ data.tar.gz: 9851452726dcadfd6b84fa6018b4d3791650a69c52860fb79a5d9d2ee48b1f275d9bebfd6e8174da69acb0968d411e03ad890c26979ab2ec1b6007c412b06d29
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 imgproxy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # imgproxy.rb
2
+
3
+ [![Gem](https://img.shields.io/gem/v/imgproxy.svg?style=for-the-badge)](https://rubygems.org/gems/imgproxy) [![rubydoc.org](https://img.shields.io/badge/rubydoc-reference-blue.svg?style=for-the-badge)](https://www.rubydoc.info/gems/imgproxy/)
4
+
5
+ Gem for [imgproxy](https://github.com/DarthSim/imgproxy) URLs generation.
6
+
7
+ [imgproxy](https://github.com/DarthSim/imgproxy) is a fast and secure standalone server for resizing and converting remote images. The main principles of imgproxy are simplicity, speed, and security.
8
+
9
+ ## Installation
10
+
11
+ ```
12
+ gem install imgproxy
13
+ ```
14
+
15
+ or add it to your `Gemfile`:
16
+
17
+ ```ruby
18
+ gem "imgproxy"
19
+ ```
20
+
21
+ ## Configuration
22
+
23
+ ```ruby
24
+ # config/initializers/imgproxy.rb
25
+
26
+ Imgproxy.configure do |config|
27
+ # imgproxy endpoint
28
+ config.endpoint = "http://imgproxy.example.com"
29
+ # hex-encoded signature key
30
+ config.hex_key = "your_key"
31
+ # hex-encoded signature salt
32
+ config.hex_salt = "your_salt"
33
+ # signature size. Defaults to 32
34
+ config.signature_size = 5
35
+ # use short processing option names (`rs` for `resize`, `g` for `gravity`, etc).
36
+ # Defaults to true
37
+ config.use_short_options = false
38
+ end
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ```ruby
44
+ Imgproxy.url_for(
45
+ "http://images.example.com/images/image.jpg",
46
+ width: 500,
47
+ height: 400,
48
+ resizing_type: :fill,
49
+ sharpen: 0.5
50
+ )
51
+ # => http://imgproxy.example.com/2tjGMpWqjO/rs:fill:500:400/sh:0.5/plain/http://images.example.com/images/image.jpg
52
+ ```
53
+
54
+ You can reuse processing options by using `Imgproxy::Builder`:
55
+
56
+ ```ruby
57
+ builder = Imgproxy::Builder.new(
58
+ width: 500,
59
+ height: 400,
60
+ resizing_type: :fill,
61
+ sharpen: 0.5
62
+ )
63
+
64
+ builder.url_for("http://images.example.com/images/image1.jpg")
65
+ builder.url_for("http://images.example.com/images/image2.jpg")
66
+ ```
67
+
68
+ Available options are:
69
+
70
+ * `resizing_type`
71
+ * `width`
72
+ * `height`
73
+ * `dpr`
74
+ * `enlarge`
75
+ * `extend`
76
+ * `gravity`
77
+ * `gravity_x`
78
+ * `gravity_y`
79
+ * `quality`
80
+ * `background`
81
+ * `blur`
82
+ * `sharpen`
83
+ * `watermark_opacity`
84
+ * `watermark_position`
85
+ * `watermark_x_offset`
86
+ * `watermark_y_offset`
87
+ * `watermark_scale`
88
+ * `preset`
89
+ * `cachebuster`
90
+ * `format`
91
+ * `use_short_options`
92
+
93
+ _See [imgproxy URL format guide](https://github.com/DarthSim/imgproxy/blob/master/docs/generating_the_url_advanced.md) for more info_
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/imgproxy/imgproxy.rb.
98
+
99
+ ## License
100
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,113 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ require 'imgproxy/options'
5
+
6
+ module Imgproxy
7
+ # Builds imgproxy URL
8
+ #
9
+ # builder = Imgproxy::Builder.new(
10
+ # width: 500,
11
+ # height: 400,
12
+ # resizing_type: :fill,
13
+ # sharpen: 0.5
14
+ # )
15
+ #
16
+ # builder.url_for("http://images.example.com/images/image1.jpg")
17
+ # builder.url_for("http://images.example.com/images/image2.jpg")
18
+ class Builder
19
+ # @param [Hash] options Processing options
20
+ # @see Imgproxy.url_for
21
+ def initialize(options = {})
22
+ @use_short_options = options.delete(:use_short_options)
23
+ @use_short_options = config.use_short_options if @use_short_options.nil?
24
+
25
+ @options = Imgproxy::Options.new(options)
26
+ end
27
+
28
+ # Genrates imgproxy URL
29
+ #
30
+ # @return [String] imgproxy URL
31
+ # @param [String] image Source image URL
32
+ # @see Imgproxy.url_for
33
+ def url_for(image)
34
+ path = [*processing_options, 'plain', escape_url(image)].join('/')
35
+ path = "#{path}@#{options[:format]}" if @options[:format]
36
+
37
+ signature = sign_path(path)
38
+
39
+ "#{Imgproxy.config.endpoint}/#{signature}/#{path}"
40
+ end
41
+
42
+ private
43
+
44
+ OPTIONS_ALIASES = {
45
+ resize: :rs,
46
+ size: :s,
47
+ resizing_type: :rt,
48
+ width: :w,
49
+ height: :h,
50
+ enlarge: :en,
51
+ extend: :ex,
52
+ gravity: :g,
53
+ quality: :q,
54
+ background: :bg,
55
+ blur: :bl,
56
+ sharpen: :sh,
57
+ watermark: :wm,
58
+ preset: :pr,
59
+ cachebuster: :cb
60
+ }.freeze
61
+
62
+ NEED_ESCAPE_RE = /@\?%/.freeze
63
+
64
+ def processing_options
65
+ @processing_options ||=
66
+ @options.build.map do |key, value|
67
+ "#{option_alias(key)}:#{wrap_array(value).join(':')}"
68
+ end
69
+ end
70
+
71
+ def option_alias(name)
72
+ return name unless config.use_short_options
73
+
74
+ OPTIONS_ALIASES.fetch(name, name)
75
+ end
76
+
77
+ def wrap_array(value)
78
+ value.is_a?(Array) ? value : [value]
79
+ end
80
+
81
+ def escape_url(url)
82
+ url =~ NEED_ESCAPE_RE ? CGI.escape(url) : url
83
+ end
84
+
85
+ def sign_path(path)
86
+ return 'unsafe' if signature_key.nil? || signature_salt.nil?
87
+
88
+ digest = OpenSSL::HMAC.digest(
89
+ OpenSSL::Digest.new('sha256'),
90
+ signature_key,
91
+ "#{signature_salt}/#{path}"
92
+ )[0, signature_size]
93
+
94
+ Base64.urlsafe_encode64(digest).tr('=', '')
95
+ end
96
+
97
+ def signature_key
98
+ config.key
99
+ end
100
+
101
+ def signature_salt
102
+ config.salt
103
+ end
104
+
105
+ def signature_size
106
+ config.signature_size
107
+ end
108
+
109
+ def config
110
+ Imgproxy.config
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,41 @@
1
+ module Imgproxy
2
+ # Imgproxy config
3
+ # @see Imgproxy.configure
4
+ class Config
5
+ # @return [String] imgproxy endpoint
6
+ attr_reader :endpoint
7
+ # @return [String] imgproxy signature key
8
+ attr_accessor :key
9
+ # @return [String] imgproxy signature salt
10
+ attr_accessor :salt
11
+ # @return [Integer] imgproxy signature size. Defaults to 32
12
+ attr_accessor :signature_size
13
+ # @return [Boolean] use short processing option names
14
+ # (`rs` for `resize`, `g` for `gravity`, etc).
15
+ # Defaults to true
16
+ attr_accessor :use_short_options
17
+
18
+ def initialize
19
+ self.signature_size = 32
20
+ self.use_short_options = true
21
+ end
22
+
23
+ # Decodes hex-encoded key and sets it to {#key}
24
+ #
25
+ # @param value [String] hex-encoded signature key
26
+ def hex_key=(value)
27
+ self.key = [value].pack('H*')
28
+ end
29
+
30
+ # Decodes hex-encoded salt and sets it to {#salt}
31
+ #
32
+ # @param value [String] hex-encoded signature salt
33
+ def hex_salt=(value)
34
+ self.salt = [value].pack('H*')
35
+ end
36
+
37
+ def endpoint=(value)
38
+ @endpoint = value.end_with?('/') ? value[0..-2] : value
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,118 @@
1
+ require 'ostruct'
2
+
3
+ module Imgproxy
4
+ # Formats and regroups processing options
5
+ class Options < Hash
6
+ STRING_OPTS = %i[resizing_type gravity watermark_position style cachebuster
7
+ format].freeze
8
+
9
+ INT_OPTS = %i[width height quality watermark_x_offset
10
+ watermark_y_offset].freeze
11
+
12
+ FLOAT_OPTS = %i[dpr gravity_x gravity_y blur sharpen watermark_opacity
13
+ watermark_scale].freeze
14
+
15
+ BOOL_OPTS = %i[enlarge extend].freeze
16
+
17
+ ARRAY_OPTS = %i[background preset].freeze
18
+
19
+ ALL_OPTS =
20
+ (STRING_OPTS + INT_OPTS + FLOAT_OPTS + BOOL_OPTS + ARRAY_OPTS).freeze
21
+
22
+ OPTS_PRIORITY = { resize: 1, size: 2 }.freeze
23
+
24
+ # @param options [Hash] raw processing options
25
+ def initialize(options)
26
+ merge!(options.slice(*ALL_OPTS))
27
+ typecast
28
+ freeze
29
+ end
30
+
31
+ # @return [Hash] formatted and regrouped processing options
32
+ def build
33
+ opts = dup
34
+
35
+ group_resizing_opts(opts)
36
+ group_gravity_opts(opts)
37
+ group_watermark_opts(opts)
38
+ encode_style(opts)
39
+
40
+ Hash[opts.sort_by { |k, _| OPTS_PRIORITY.fetch(k, 99) }]
41
+ end
42
+
43
+ private
44
+
45
+ def typecast
46
+ compact.each do |key, value|
47
+ self[key] =
48
+ case key
49
+ when *STRING_OPTS then value.to_s
50
+ when *INT_OPTS then value.to_i
51
+ when *FLOAT_OPTS then value.to_f
52
+ when *BOOL_OPTS then bool(value)
53
+ when *ARRAY_OPTS then wrap_array(value)
54
+ end
55
+ end
56
+ end
57
+
58
+ def bool(value)
59
+ value && value != 0 && value != '0' ? 1 : 0
60
+ end
61
+
62
+ def wrap_array(value)
63
+ value.is_a?(Array) ? value : [value]
64
+ end
65
+
66
+ def group_resizing_opts(opts)
67
+ return opts unless opts[:width] && opts[:height]
68
+
69
+ opts[:size] = trim_nils(
70
+ [opts.delete(:width), opts.delete(:height),
71
+ opts.delete(:enlarge), opts.delete(:extend)]
72
+ )
73
+
74
+ if opts[:resizing_type]
75
+ opts[:resize] = [opts.delete(:resizing_type), *opts.delete(:size)]
76
+ end
77
+
78
+ opts
79
+ end
80
+
81
+ def group_gravity_opts(opts)
82
+ gravity = trim_nils(
83
+ [
84
+ opts.delete(:gravity),
85
+ opts.delete(:gravity_x),
86
+ opts.delete(:gravity_y)
87
+ ]
88
+ )
89
+
90
+ opts[:gravity] = gravity unless gravity[0].nil?
91
+ end
92
+
93
+ def group_watermark_opts(opts)
94
+ watermark = trim_nils(
95
+ [
96
+ opts.delete(:watermark_opacity),
97
+ opts.delete(:watermark_position),
98
+ opts.delete(:watermark_x_offset),
99
+ opts.delete(:watermark_y_offset),
100
+ opts.delete(:watermark_scale)
101
+ ]
102
+ )
103
+
104
+ opts[:watermark] = watermark unless watermark[0].nil?
105
+ end
106
+
107
+ def encode_style(opts)
108
+ return if opts[:style].nil?
109
+
110
+ opts[:style] = Base64.urlsafe_encode64(opts[:style]).tr('=', '')
111
+ end
112
+
113
+ def trim_nils(value)
114
+ value.delete_at(-1) while !value.empty? && value[-1].nil?
115
+ value
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module Imgproxy
2
+ VERSION = '0.0.2'.freeze
3
+ end
data/lib/imgproxy.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'imgproxy/version'
2
+ require 'imgproxy/config'
3
+ require 'imgproxy/builder'
4
+
5
+ # @see Imgproxy::ClassMethods
6
+ module Imgproxy
7
+ class << self
8
+ # Imgproxy config
9
+ #
10
+ # @return [Config]
11
+ def config
12
+ @config ||= Imgproxy::Config.new
13
+ end
14
+
15
+ # Yields Imgproxy config
16
+ #
17
+ # Imgproxy.configure do |config|
18
+ # config.endpoint = "http://imgproxy.example.com"
19
+ # config.hex_key = "your_key"
20
+ # config.hex_salt = "your_salt"
21
+ # config.use_short_options = true
22
+ # end
23
+ #
24
+ # @yieldparam config [Config]
25
+ # @return [Config]
26
+ def configure
27
+ yield config
28
+ config
29
+ end
30
+
31
+ # Genrates imgproxy URL
32
+ #
33
+ # Imgproxy.url_for(
34
+ # "http://images.example.com/images/image.jpg",
35
+ # width: 500,
36
+ # height: 400,
37
+ # resizing_type: :fill,
38
+ # sharpen: 0.5
39
+ # )
40
+ #
41
+ # @return [String] imgproxy URL
42
+ # @param [String] image Source image URL
43
+ # @param [Hash] options Processing options
44
+ # @option options [String] :resizing_type
45
+ # @option options [Integer] :width
46
+ # @option options [Integer] :height
47
+ # @option options [Float] :dpr
48
+ # @option options [Boolean] :enlarge
49
+ # @option options [Boolean] :extend
50
+ # @option options [String] :gravity
51
+ # @option options [Float] :gravity_x
52
+ # @option options [Float] :gravity_y
53
+ # @option options [Integer] :quality
54
+ # @option options [Array] :background
55
+ # @option options [Float] :blur
56
+ # @option options [Float] :sharpen
57
+ # @option options [Float] :watermark_opacity
58
+ # @option options [String] :watermark_position
59
+ # @option options [Integer] :watermark_x_offset
60
+ # @option options [Integer] :watermark_y_offset
61
+ # @option options [Float] :watermark_scale
62
+ # @option options [Array] :preset
63
+ # @option options [String] :cachebuster
64
+ # @option options [String] :format
65
+ # @option options [Boolean] :use_short_options
66
+ # @see https://github.com/DarthSim/imgproxy/blob/master/docs/generating_the_url_advanced.md
67
+ # imgproxy URL format documentation
68
+ def url_for(image, options = {})
69
+ Imgproxy::Builder.new(options).url_for(image)
70
+ end
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imgproxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Sergey Alexandrovich
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem that easily generates imgproxy URLs for your images
14
+ email: darthsim@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - LICENSE
20
+ - README.md
21
+ - lib/imgproxy.rb
22
+ - lib/imgproxy/builder.rb
23
+ - lib/imgproxy/config.rb
24
+ - lib/imgproxy/options.rb
25
+ - lib/imgproxy/version.rb
26
+ homepage: https://github.com/imgproxy/imgproxy.rb
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.0.2
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: imgproxy URL generator
49
+ test_files: []