crush_pics 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4949c7fb27235f4cb80b37cfed229a157b817af5953955cfe1cc738003271ca3
4
+ data.tar.gz: 43eba8c40c1d2266e5a3cb5f470aa23b14c0f0585983990b5c20f090e6d49d0a
5
+ SHA512:
6
+ metadata.gz: 42708ecabb2716accc02ff6a55b01a5bb6b1eab3b2ccf3a2ff1ddc906632d78a5588b6f0d425441eea5221f5b3670a2b126e727dcc70924ce93467c0487e0485
7
+ data.tar.gz: e928b0cdd31e11a57fb334b0c10f759a7f1ea02cf69cc11a1188735ac1611f3fbec1fb610f61f6faddc223a37922039b508862ec39933f9b7d53aa2342b4053d
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+
6
+ require 'crush_pics/exceptions'
7
+ require 'crush_pics/configuration'
8
+ require 'crush_pics/client'
9
+ require 'crush_pics/response'
10
+
11
+ module CrushPics
12
+ def self.configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def self.configure
17
+ yield(configuration)
18
+ end
19
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ class Client
5
+ attr_reader :api_token, :response
6
+
7
+ def initialize(api_token:)
8
+ @api_token = api_token
9
+ end
10
+
11
+ def compress_async(io: nil, url: nil, level:, type:)
12
+ attrs = build_image_attributes(io: io, url: url, level: level, type: type)
13
+
14
+ http_post('original_images', attrs)
15
+ return yield(response) if block_given?
16
+
17
+ response
18
+ end
19
+
20
+ def compress_sync(io: nil, url: nil, level:, type:)
21
+ attrs = build_image_attributes(io: io, url: url, level: level, type: type)
22
+
23
+ http_post('compress', attrs)
24
+ return yield(response) if block_given?
25
+
26
+ response
27
+ end
28
+
29
+ def list_images(page = nil)
30
+ path = 'images'
31
+ path = "images/?page=#{ page }" if page
32
+ http_get(path)
33
+ return yield(response) if block_given?
34
+
35
+ response
36
+ end
37
+
38
+ def fetch_image(id)
39
+ http_get("original_images/#{ id }")
40
+ return yield(response) if block_given?
41
+
42
+ response
43
+ end
44
+
45
+ def dashboard
46
+ http_get('dashboard')
47
+ return yield(response) if block_given?
48
+
49
+ response
50
+ end
51
+
52
+ def http_get(path, headers = {})
53
+ uri = URI(base_url + '/' + path)
54
+ request = Net::HTTP::Get.new(uri)
55
+ headers.transform_keys! { |key| key.to_s.tr('_', '-') }
56
+ default_headers.merge(headers).each { |k, v| request[k] = v }
57
+
58
+ perform_request(request, uri)
59
+ end
60
+
61
+ def http_post(path, payload, headers = {})
62
+ uri = URI(base_url + '/' + path)
63
+ request = Net::HTTP::Post.new(uri)
64
+ headers.transform_keys! { |key| key.to_s.tr('_', '-') }
65
+ default_headers.merge(headers).each { |k, v| request[k] = v }
66
+ request.set_form_data(payload)
67
+
68
+ perform_request(request, uri)
69
+ end
70
+
71
+ def http_patch(path, payload, headers = {})
72
+ uri = URI(base_url + '/' + path)
73
+ request = Net::HTTP::Patch.new(uri)
74
+ headers.transform_keys! { |key| key.to_s.tr('_', '-') }
75
+ default_headers.merge(headers).each { |k, v| request[k] = v }
76
+ request.set_form_data(payload)
77
+
78
+ perform_request(request, uri)
79
+ end
80
+
81
+ def http_delete(path, headers = {})
82
+ uri = URI(base_url + '/' + path)
83
+ request = Net::HTTP::Delete.new(uri)
84
+ headers.transform_keys! { |key| key.to_s.tr('_', '-') }
85
+ default_headers.merge(headers).each { |k, v| request[k] = v }
86
+
87
+ perform_request(request, uri)
88
+ end
89
+
90
+ private
91
+
92
+ def check_response!
93
+ return if response.success? || response.validation_error?
94
+
95
+ raise(CrushPics::ServerError) if response.server_error?
96
+
97
+ raise(CrushPics::UnauthorizedError) if response.unauthorized?
98
+
99
+ raise(CrushPics::ClientError, response.response.message) if response.client_error?
100
+
101
+ raise(CrushPics::UnknownError)
102
+ end
103
+
104
+ def default_headers
105
+ { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }.tap do |h|
106
+ h.store('Authorization', "Bearer #{ api_token }") if api_token
107
+ end
108
+ end
109
+
110
+ def build_image_attributes(io: nil, url: nil, level:, type:)
111
+ attrs = { origin: 'api', compression_level: level, compression_type: type }
112
+
113
+ if io
114
+ attrs.store(:file, io)
115
+ elsif url
116
+ attrs.store(:image_url, url)
117
+ else
118
+ raise StandardError, 'Specify image IO or URL'
119
+ end
120
+
121
+ attrs
122
+ end
123
+
124
+ def base_url
125
+ URI.join(CrushPics.configuration.base_url, CrushPics.configuration.api_version).to_s
126
+ end
127
+
128
+ def perform_request(request, uri)
129
+ http = Net::HTTP.new(uri.hostname, uri.port)
130
+ http.use_ssl = true
131
+ http.read_timeout = CrushPics.configuration.read_timeout
132
+ http.set_debug_output(CrushPics.configuration.debug_logger) if CrushPics.configuration.debug_logger
133
+ @response = CrushPics::Response.new(http.request(request))
134
+ check_response!
135
+ @response
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ class Configuration
5
+ DEFAULT_API_VERSION = 'v1'
6
+ DEFAULT_BASE_URL = 'https://api.crush.pics'
7
+ DEFAULT_READ_TIMEOUT = 30
8
+
9
+ attr_writer :api_version, :base_url, :read_timeout
10
+ attr_accessor :debug_logger
11
+
12
+ def api_version
13
+ @api_version || DEFAULT_API_VERSION
14
+ end
15
+
16
+ def base_url
17
+ @base_url || DEFAULT_BASE_URL
18
+ end
19
+
20
+ def read_timeout
21
+ @read_timeout || DEFAULT_READ_TIMEOUT
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ class ServerError < StandardError; end
5
+ class ClientError < StandardError; end
6
+ class UnknownError < StandardError; end
7
+ class UnauthorizedError < StandardError; end
8
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ module Plugin
5
+ module KaminariPagination
6
+ def size
7
+ body.dig('pagination', 'count')
8
+ end
9
+
10
+ def total_pages
11
+ body.dig('pagination', 'total_pages')
12
+ end
13
+
14
+ def total_count
15
+ body.dig('pagination', 'total_count')
16
+ end
17
+
18
+ def current_page
19
+ body.dig('pagination', 'current')
20
+ end
21
+
22
+ def limit_value
23
+ body.dig('pagination', 'per_page')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ class Response
5
+ attr_reader :http
6
+
7
+ def initialize(http)
8
+ @http = http
9
+ end
10
+
11
+ def parse
12
+ return {} if unauthorized?
13
+
14
+ parsed_response
15
+ end
16
+
17
+ alias :body :parse
18
+
19
+ def unauthorized?
20
+ http.is_a?(Net::HTTPUnauthorized)
21
+ end
22
+
23
+ def created?
24
+ http.is_a?(Net::HTTPCreated)
25
+ end
26
+
27
+ def validation_error?
28
+ http.is_a?(Net::HTTPUnprocessableEntity)
29
+ end
30
+
31
+ def success?
32
+ http.is_a?(Net::HTTPSuccess)
33
+ end
34
+
35
+ def client_error?
36
+ http.is_a?(Net::HTTPClientError)
37
+ end
38
+
39
+ def server_error?
40
+ http.is_a?(Net::HTTPServerError)
41
+ end
42
+
43
+ def validation_error_message
44
+ msgs = parsed_response.fetch('message', {}).map do |k, v|
45
+ msg = v
46
+ msg = msg.join(', ') if msg.is_a?(Array)
47
+ "#{ k }: #{ msg }"
48
+ end
49
+ msgs.join(', ')
50
+ end
51
+
52
+ private
53
+
54
+ def parsed_response
55
+ @parsed_response ||= JSON.parse(http.body)
56
+ rescue TypeError, JSON::ParserError
57
+ @parsed_response = {}
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CrushPics
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crush_pics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dom Barisic
8
+ - Ilya Shcherbinin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-09-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Lightweight client for Crush.pics API
15
+ email: dom@spacesquirrel.co
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/crush_pics.rb
21
+ - lib/crush_pics/client.rb
22
+ - lib/crush_pics/configuration.rb
23
+ - lib/crush_pics/exceptions.rb
24
+ - lib/crush_pics/plugin/kaminari_pagination.rb
25
+ - lib/crush_pics/response.rb
26
+ - lib/crush_pics/version.rb
27
+ homepage: https://github.com/crush-pics/crush-pics-ruby
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.7.6
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Lightweight client for Crush.pics API
51
+ test_files: []