scnnr 1.0.0 → 2.0.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 +5 -5
- data/.circleci/config.yml +21 -9
- data/.rubocop.yml +153 -8
- data/CHANGELOG.md +27 -1
- data/Gemfile +9 -4
- data/Guardfile +25 -0
- data/README.md +81 -1
- data/lib/scnnr.rb +7 -0
- data/lib/scnnr/client.rb +33 -19
- data/lib/scnnr/configuration.rb +1 -1
- data/lib/scnnr/connection.rb +30 -8
- data/lib/scnnr/coordinate.rb +15 -0
- data/lib/scnnr/coordinate/item.rb +18 -0
- data/lib/scnnr/errors.rb +2 -1
- data/lib/scnnr/errors/image.rb +14 -0
- data/lib/scnnr/errors/image/response.rb +15 -0
- data/lib/scnnr/label.rb +16 -0
- data/lib/scnnr/recognition.rb +8 -2
- data/lib/scnnr/recognition/image.rb +18 -0
- data/lib/scnnr/recognition/object.rb +1 -1
- data/lib/scnnr/recognition/object/label.rb +4 -10
- data/lib/scnnr/response.rb +13 -9
- data/lib/scnnr/routing.rb +56 -0
- data/lib/scnnr/version.rb +1 -1
- data/scnnr.gemspec +4 -3
- metadata +14 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5cb9874e1854429b787e165fbff198da0e2992ae506a6a84f0c85f42199701d0
|
|
4
|
+
data.tar.gz: 8c59dba0786ab878aef02294606f10fde6eb06fb154ea39ad8473eb8b498e02a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77805ba9b1a35a675e918222e2925a56195cfbf10366ca6fe07d551d1f7ac95f8170acf7facd9d02e4e7c9b66aa3c1f3959f7d9b37c502b087b7d9c7a815d767
|
|
7
|
+
data.tar.gz: 0de1c9361be51d20fe0f95e57c9277efdac54450dceca1e065700bd07fa263db2635279438f65acb734a615b33b9cf083bfac18ef9dfb57c12891d06657db401
|
data/.circleci/config.yml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
|
|
4
4
|
#
|
|
5
|
-
version: 2
|
|
5
|
+
version: 2.1
|
|
6
6
|
jobs:
|
|
7
7
|
build: &build
|
|
8
8
|
docker:
|
|
@@ -13,13 +13,15 @@ jobs:
|
|
|
13
13
|
- run:
|
|
14
14
|
name: install dependencies
|
|
15
15
|
command: |
|
|
16
|
-
|
|
16
|
+
gem install bundler -v 2.1.2
|
|
17
|
+
bundle config set path vendor/bundle
|
|
18
|
+
bundle install --jobs=4 --retry=3
|
|
17
19
|
# run tests!
|
|
18
20
|
- run:
|
|
19
21
|
name: run tests
|
|
20
22
|
command: |
|
|
21
23
|
mkdir /tmp/test-results
|
|
22
|
-
bundle exec rubocop --format progress
|
|
24
|
+
bundle exec rubocop --format progress --format junit --out /tmp/test-results/rubocop.xml
|
|
23
25
|
bundle exec rspec --format progress \
|
|
24
26
|
--format RspecJunitFormatter \
|
|
25
27
|
--out /tmp/test-results/rspec.xml \
|
|
@@ -30,17 +32,27 @@ jobs:
|
|
|
30
32
|
- store_artifacts:
|
|
31
33
|
path: /tmp/test-results
|
|
32
34
|
destination: test-results
|
|
33
|
-
ruby-
|
|
35
|
+
ruby-24:
|
|
34
36
|
<<: *build
|
|
35
37
|
docker:
|
|
36
|
-
- image: circleci/ruby:2.
|
|
37
|
-
ruby-
|
|
38
|
+
- image: circleci/ruby:2.4
|
|
39
|
+
ruby-25:
|
|
38
40
|
<<: *build
|
|
39
41
|
docker:
|
|
40
|
-
- image: circleci/ruby:2.
|
|
42
|
+
- image: circleci/ruby:2.5
|
|
43
|
+
ruby-26:
|
|
44
|
+
<<: *build
|
|
45
|
+
docker:
|
|
46
|
+
- image: circleci/ruby:2.6
|
|
47
|
+
ruby-27:
|
|
48
|
+
<<: *build
|
|
49
|
+
docker:
|
|
50
|
+
- image: circleci/ruby:2.7
|
|
41
51
|
workflows:
|
|
42
52
|
version: 2
|
|
43
53
|
ruby-multi-build:
|
|
44
54
|
jobs:
|
|
45
|
-
- ruby-
|
|
46
|
-
- ruby-
|
|
55
|
+
- ruby-24
|
|
56
|
+
- ruby-25
|
|
57
|
+
- ruby-26
|
|
58
|
+
- ruby-27
|
data/.rubocop.yml
CHANGED
|
@@ -4,9 +4,6 @@ require:
|
|
|
4
4
|
AllCops:
|
|
5
5
|
TargetRubyVersion: 2.4
|
|
6
6
|
|
|
7
|
-
Metrics/LineLength:
|
|
8
|
-
Max: 120
|
|
9
|
-
|
|
10
7
|
Metrics/ClassLength:
|
|
11
8
|
Max: 300
|
|
12
9
|
|
|
@@ -29,7 +26,10 @@ Style/CollectionMethods:
|
|
|
29
26
|
Style/TrailingCommaInArguments:
|
|
30
27
|
EnforcedStyleForMultiline: no_comma
|
|
31
28
|
|
|
32
|
-
Style/
|
|
29
|
+
Style/TrailingCommaInArrayLiteral:
|
|
30
|
+
EnforcedStyleForMultiline: comma
|
|
31
|
+
|
|
32
|
+
Style/TrailingCommaInHashLiteral:
|
|
33
33
|
EnforcedStyleForMultiline: comma
|
|
34
34
|
|
|
35
35
|
Style/Documentation:
|
|
@@ -38,15 +38,15 @@ Style/Documentation:
|
|
|
38
38
|
Style/RedundantSelf:
|
|
39
39
|
Enabled: false
|
|
40
40
|
|
|
41
|
+
Layout/LineLength:
|
|
42
|
+
Max: 120
|
|
43
|
+
|
|
41
44
|
Layout/MultilineMethodCallIndentation:
|
|
42
45
|
EnforcedStyle: indented
|
|
43
46
|
|
|
44
|
-
Layout/
|
|
47
|
+
Layout/FirstHashElementIndentation:
|
|
45
48
|
EnforcedStyle: consistent
|
|
46
49
|
|
|
47
|
-
Style/BracesAroundHashParameters:
|
|
48
|
-
Enabled: false
|
|
49
|
-
|
|
50
50
|
RSpec/NestedGroups:
|
|
51
51
|
Max: 5
|
|
52
52
|
|
|
@@ -65,3 +65,148 @@ RSpec/MessageSpies:
|
|
|
65
65
|
RSpec/AnyInstance:
|
|
66
66
|
Exclude:
|
|
67
67
|
- 'spec/scnnr/connection_spec.rb'
|
|
68
|
+
|
|
69
|
+
RSpec/ContextWording:
|
|
70
|
+
Prefixes:
|
|
71
|
+
- when
|
|
72
|
+
- with
|
|
73
|
+
- without
|
|
74
|
+
- and
|
|
75
|
+
|
|
76
|
+
RSpec/MultipleMemoizedHelpers:
|
|
77
|
+
Max: 7
|
|
78
|
+
|
|
79
|
+
Layout/EmptyLinesAroundAttributeAccessor: # (new in 0.83)
|
|
80
|
+
Enabled: true
|
|
81
|
+
|
|
82
|
+
Layout/SpaceAroundMethodCallOperator: # (new in 0.82)
|
|
83
|
+
Enabled: true
|
|
84
|
+
|
|
85
|
+
Lint/BinaryOperatorWithIdenticalOperands: # (new in 0.89)
|
|
86
|
+
Enabled: true
|
|
87
|
+
|
|
88
|
+
Lint/DeprecatedOpenSSLConstant: # (new in 0.84)
|
|
89
|
+
Enabled: true
|
|
90
|
+
|
|
91
|
+
Lint/DuplicateElsifCondition: # (new in 0.88)
|
|
92
|
+
Enabled: true
|
|
93
|
+
|
|
94
|
+
Lint/DuplicateRequire: # (new in 0.90)
|
|
95
|
+
Enabled: true
|
|
96
|
+
|
|
97
|
+
Lint/DuplicateRescueException: # (new in 0.89)
|
|
98
|
+
Enabled: true
|
|
99
|
+
|
|
100
|
+
Lint/EmptyConditionalBody: # (new in 0.89)
|
|
101
|
+
Enabled: true
|
|
102
|
+
|
|
103
|
+
Lint/EmptyFile: # (new in 0.90)
|
|
104
|
+
Enabled: true
|
|
105
|
+
|
|
106
|
+
Lint/FloatComparison: # (new in 0.89)
|
|
107
|
+
Enabled: true
|
|
108
|
+
|
|
109
|
+
Lint/MissingSuper: # (new in 0.89)
|
|
110
|
+
Enabled: true
|
|
111
|
+
|
|
112
|
+
Lint/MixedRegexpCaptureTypes: # (new in 0.85)
|
|
113
|
+
Enabled: true
|
|
114
|
+
|
|
115
|
+
Lint/OutOfRangeRegexpRef: # (new in 0.89)
|
|
116
|
+
Enabled: true
|
|
117
|
+
|
|
118
|
+
Lint/RaiseException: # (new in 0.81)
|
|
119
|
+
Enabled: true
|
|
120
|
+
|
|
121
|
+
Lint/SelfAssignment: # (new in 0.89)
|
|
122
|
+
Enabled: true
|
|
123
|
+
|
|
124
|
+
Lint/StructNewOverride: # (new in 0.81)
|
|
125
|
+
Enabled: true
|
|
126
|
+
|
|
127
|
+
Lint/TopLevelReturnWithArgument: # (new in 0.89)
|
|
128
|
+
Enabled: true
|
|
129
|
+
|
|
130
|
+
Lint/TrailingCommaInAttributeDeclaration: # (new in 0.90)
|
|
131
|
+
Enabled: true
|
|
132
|
+
|
|
133
|
+
Lint/UnreachableLoop: # (new in 0.89)
|
|
134
|
+
Enabled: true
|
|
135
|
+
|
|
136
|
+
Lint/UselessMethodDefinition: # (new in 0.90)
|
|
137
|
+
Enabled: true
|
|
138
|
+
|
|
139
|
+
Style/AccessorGrouping: # (new in 0.87)
|
|
140
|
+
Enabled: true
|
|
141
|
+
|
|
142
|
+
Style/ArrayCoercion: # (new in 0.88)
|
|
143
|
+
Enabled: true
|
|
144
|
+
|
|
145
|
+
Style/BisectedAttrAccessor: # (new in 0.87)
|
|
146
|
+
Enabled: true
|
|
147
|
+
|
|
148
|
+
Style/CaseLikeIf: # (new in 0.88)
|
|
149
|
+
Enabled: true
|
|
150
|
+
|
|
151
|
+
Style/CombinableLoops: # (new in 0.90)
|
|
152
|
+
Enabled: true
|
|
153
|
+
|
|
154
|
+
Style/ExplicitBlockArgument: # (new in 0.89)
|
|
155
|
+
Enabled: true
|
|
156
|
+
|
|
157
|
+
Style/ExponentialNotation: # (new in 0.82)
|
|
158
|
+
Enabled: true
|
|
159
|
+
|
|
160
|
+
Style/GlobalStdStream: # (new in 0.89)
|
|
161
|
+
Enabled: true
|
|
162
|
+
|
|
163
|
+
Style/HashAsLastArrayItem: # (new in 0.88)
|
|
164
|
+
Enabled: true
|
|
165
|
+
|
|
166
|
+
Style/HashEachMethods: # (new in 0.80)
|
|
167
|
+
Enabled: true
|
|
168
|
+
|
|
169
|
+
Style/HashLikeCase: # (new in 0.88)
|
|
170
|
+
Enabled: true
|
|
171
|
+
|
|
172
|
+
Style/HashTransformKeys: # (new in 0.80)
|
|
173
|
+
Enabled: true
|
|
174
|
+
|
|
175
|
+
Style/HashTransformValues: # (new in 0.80)
|
|
176
|
+
Enabled: true
|
|
177
|
+
|
|
178
|
+
Style/KeywordParametersOrder: # (new in 0.90)
|
|
179
|
+
Enabled: true
|
|
180
|
+
|
|
181
|
+
Style/OptionalBooleanParameter: # (new in 0.89)
|
|
182
|
+
Enabled: true
|
|
183
|
+
|
|
184
|
+
Style/RedundantAssignment: # (new in 0.87)
|
|
185
|
+
Enabled: true
|
|
186
|
+
|
|
187
|
+
Style/RedundantFetchBlock: # (new in 0.86)
|
|
188
|
+
Enabled: true
|
|
189
|
+
|
|
190
|
+
Style/RedundantFileExtensionInRequire: # (new in 0.88)
|
|
191
|
+
Enabled: true
|
|
192
|
+
|
|
193
|
+
Style/RedundantRegexpCharacterClass: # (new in 0.85)
|
|
194
|
+
Enabled: true
|
|
195
|
+
|
|
196
|
+
Style/RedundantRegexpEscape: # (new in 0.85)
|
|
197
|
+
Enabled: true
|
|
198
|
+
|
|
199
|
+
Style/RedundantSelfAssignment: # (new in 0.90)
|
|
200
|
+
Enabled: true
|
|
201
|
+
|
|
202
|
+
Style/SingleArgumentDig: # (new in 0.89)
|
|
203
|
+
Enabled: true
|
|
204
|
+
|
|
205
|
+
Style/SlicingWithRange: # (new in 0.83)
|
|
206
|
+
Enabled: true
|
|
207
|
+
|
|
208
|
+
Style/SoleNestedConditional: # (new in 0.89)
|
|
209
|
+
Enabled: true
|
|
210
|
+
|
|
211
|
+
Style/StringConcatenation: # (new in 0.89)
|
|
212
|
+
Enabled: true
|
data/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,39 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.0.0] - 2020-09-14
|
|
8
|
+
### Added
|
|
9
|
+
- Start supporting Ruby 2.7.
|
|
10
|
+
- Provide image error details.
|
|
11
|
+
- Raise `UnexpectedError` for unknown recognition error types.
|
|
12
|
+
|
|
13
|
+
### Removed
|
|
14
|
+
- Support for Ruby 2.3.
|
|
15
|
+
|
|
16
|
+
## [1.3.0] - 2019-08-30
|
|
17
|
+
### Added
|
|
18
|
+
- Support a retrying feature on `Scnnr::Connection`.
|
|
19
|
+
- Start supporting Ruby 2.5 and 2.6.
|
|
20
|
+
|
|
21
|
+
## [1.2.0] - 2018-10-11
|
|
22
|
+
### Added
|
|
23
|
+
- Support `target` parameter for `Scnnr::Client#coordinate`.
|
|
24
|
+
|
|
25
|
+
## [1.1.1] - 2018-06-20
|
|
26
|
+
### Added
|
|
27
|
+
- Support `force` parameter for `Scnnr::Client#recognize_url`.
|
|
28
|
+
|
|
29
|
+
## [1.1.0] - 2018-03-23
|
|
30
|
+
### Added
|
|
31
|
+
- Support `public` parameter for `Scnnr::Client#recognize_image`.
|
|
32
|
+
- Add `Scnnr::Client#coordinate` to request `POST /v1/coordinates`.
|
|
7
33
|
|
|
8
34
|
## [1.0.0] - 2017-11-01
|
|
9
35
|
### Added
|
|
10
36
|
- Allow timeouts greater than 25s when recognising images.
|
|
11
37
|
|
|
12
38
|
### Fixed
|
|
13
|
-
- Fix that `Scnnr::Client#fetch` with a long timeout does not make multiple
|
|
39
|
+
- Fix that `Scnnr::Client#fetch` with a long timeout does not make multiple requests.
|
|
14
40
|
|
|
15
41
|
### Removed
|
|
16
42
|
- Remove `async` from `Scnnr::Response`.
|
data/Gemfile
CHANGED
|
@@ -4,18 +4,23 @@ source 'https://rubygems.org'
|
|
|
4
4
|
|
|
5
5
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
6
|
|
|
7
|
-
gem 'rake', '~>
|
|
7
|
+
gem 'rake', '~> 13.0'
|
|
8
8
|
|
|
9
9
|
group :development do
|
|
10
10
|
gem 'pry', '~> 0.10'
|
|
11
|
+
|
|
12
|
+
gem 'guard'
|
|
13
|
+
gem 'guard-rspec'
|
|
14
|
+
gem 'guard-rubocop'
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
group :test do
|
|
14
18
|
gem 'rspec', '~> 3.5'
|
|
15
19
|
gem 'rspec_junit_formatter', '~> 0.3'
|
|
16
|
-
|
|
17
|
-
gem 'rubocop
|
|
18
|
-
gem 'rubocop-rspec', '~> 1.
|
|
20
|
+
|
|
21
|
+
gem 'rubocop', '~> 0.90.0'
|
|
22
|
+
gem 'rubocop-rspec', '~> 1.43.2'
|
|
23
|
+
|
|
19
24
|
gem 'webmock', '~> 3.0'
|
|
20
25
|
end
|
|
21
26
|
|
data/Guardfile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# More info at https://github.com/guard/guard#readme
|
|
4
|
+
|
|
5
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
|
6
|
+
require 'guard/rspec/dsl'
|
|
7
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
|
8
|
+
|
|
9
|
+
# Feel free to open issues for suggestions and improvements
|
|
10
|
+
|
|
11
|
+
# RSpec files
|
|
12
|
+
rspec = dsl.rspec
|
|
13
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
14
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
|
15
|
+
watch(rspec.spec_files)
|
|
16
|
+
|
|
17
|
+
# Ruby files
|
|
18
|
+
ruby = dsl.ruby
|
|
19
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
guard :rubocop do
|
|
23
|
+
watch(/.+\.rb$/)
|
|
24
|
+
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
|
25
|
+
end
|
data/README.md
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
# Official #CBK scnnr client library for Ruby.
|
|
2
|
+
[](https://circleci.com/gh/NEWROPE/scnnr-ruby)
|
|
2
3
|
|
|
3
4
|
- [#CBK scnnr](https://scnnr.cubki.jp/)
|
|
4
5
|
- [API Documentation](https://api.scnnr.cubki.jp/v1/docs)
|
|
5
6
|
|
|
7
|
+
## Supported Ruby versions
|
|
8
|
+
- Ruby 2.4+
|
|
9
|
+
|
|
6
10
|
## Installation
|
|
11
|
+
|
|
7
12
|
### Bundler
|
|
13
|
+
|
|
8
14
|
```
|
|
9
15
|
gem 'scnnr'
|
|
10
16
|
```
|
|
11
17
|
|
|
12
18
|
### Manual
|
|
19
|
+
|
|
13
20
|
```
|
|
14
21
|
gem install scnnr
|
|
15
22
|
```
|
|
16
23
|
|
|
17
24
|
## Configuration
|
|
25
|
+
|
|
18
26
|
You can pass configuration options as a block to `Scnnr::Client.new`.
|
|
19
27
|
|
|
20
28
|
```
|
|
@@ -28,22 +36,33 @@ end
|
|
|
28
36
|
```
|
|
29
37
|
|
|
30
38
|
## Examples
|
|
39
|
+
|
|
31
40
|
### Basic usage
|
|
41
|
+
|
|
42
|
+
#### Recognize images
|
|
43
|
+
|
|
32
44
|
Request image recognition by an image URL.
|
|
33
45
|
|
|
46
|
+
Refer: [`POST /v1/remote/recognitions`](https://api.scnnr.cubki.jp/v1/docs#tag/remoterecognitions%2Fpaths%2F~1remote~1recognitions%2Fpost)
|
|
47
|
+
|
|
34
48
|
```
|
|
35
49
|
url = 'https://example.com/dummy.jpg'
|
|
36
50
|
recognition = client.recognize_url(url)
|
|
37
51
|
|
|
38
|
-
#
|
|
52
|
+
# You can override config.timeout.
|
|
39
53
|
recognition = client.recognize_url(url, timeout: 10)
|
|
40
54
|
```
|
|
41
55
|
|
|
42
56
|
Request image recognition by a binary image.
|
|
43
57
|
|
|
58
|
+
Refer: [`POST /v1/recognitions`](https://api.scnnr.cubki.jp/v1/docs#tag/recognitions%2Fpaths%2F~1recognitions%2Fpost)
|
|
59
|
+
|
|
44
60
|
```
|
|
45
61
|
img = File.open('dummy_image_file', 'rb')
|
|
46
62
|
recognition = client.recognize_image(img)
|
|
63
|
+
|
|
64
|
+
# You can use public parameter as well.
|
|
65
|
+
recognition = client.recognize_image(img, timeout: 10, public: true)
|
|
47
66
|
```
|
|
48
67
|
|
|
49
68
|
`Recognition` class represents the image recognition result from API.
|
|
@@ -81,12 +100,47 @@ recognition.to_h
|
|
|
81
100
|
"category"=>"dress",
|
|
82
101
|
"labels"=>[{"name"=>"グリーン", "score"=>0.9765959}, {"name"=>"ワンピース", "score"=>0.94697183}, {"name"=>"カーキ", "score"=>0.8136864}, {"name"=>"無地", "score"=>0.54719794}, {"name"=>"フレア", "score"=>0.51572186}]}],
|
|
83
102
|
"state"=>"finished"}
|
|
103
|
+
|
|
104
|
+
# If you recognize an image with `public` parameter, the `recognition` has `image`.
|
|
105
|
+
recognition.to_h
|
|
106
|
+
=> {"id"=>"20170829/ed4c674c-7970-4e9c-9b26-1b6076b36b49",
|
|
107
|
+
"image"=>
|
|
108
|
+
{"url"=>"some-image-url",
|
|
109
|
+
"size"=>{"height"=>400, "width"=>400}},
|
|
110
|
+
"objects"=>
|
|
111
|
+
[{"bounding_box"=>{"bottom"=>0.2696995, "left"=>0.3842466, "right"=>0.57190025, "top"=>0.14457992},
|
|
112
|
+
"category"=>"hat",
|
|
113
|
+
"labels"=>
|
|
114
|
+
[{"name"=>"ハット", "score"=>0.9985399},
|
|
115
|
+
{"name"=>"中折れ", "score"=>0.99334323},
|
|
116
|
+
{"name"=>"ストローハット", "score"=>0.95629793},
|
|
117
|
+
{"name"=>"ベージュ", "score"=>0.9062561},
|
|
118
|
+
{"name"=>"つば広ハット", "score"=>0.7737022},
|
|
119
|
+
{"name"=>"ホワイト", "score"=>0.5695046}]},
|
|
120
|
+
{"bounding_box"=>{"bottom"=>0.95560884, "left"=>0.41641566, "right"=>0.5212327, "top"=>0.8452401},
|
|
121
|
+
"category"=>"shoe",
|
|
122
|
+
"labels"=>
|
|
123
|
+
[{"name"=>"サンダル", "score"=>0.93934095},
|
|
124
|
+
{"name"=>"ホワイト", "score"=>0.74320596},
|
|
125
|
+
{"name"=>"パンプス", "score"=>0.70763165},
|
|
126
|
+
{"name"=>"サボ", "score"=>0.69153166},
|
|
127
|
+
{"name"=>"ストラップ", "score"=>0.66519636},
|
|
128
|
+
{"name"=>"ウェッジソール", "score"=>0.6325865},
|
|
129
|
+
{"name"=>"オープントゥ", "score"=>0.61965847},
|
|
130
|
+
{"name"=>"アンクルストラップ", "score"=>0.576824},
|
|
131
|
+
{"name"=>"厚底", "score"=>0.53842664}]},
|
|
132
|
+
{"bounding_box"=>{"bottom"=>0.7018228, "left"=>0.35182703, "right"=>0.6113004, "top"=>0.25296396},
|
|
133
|
+
"category"=>"dress",
|
|
134
|
+
"labels"=>[{"name"=>"グリーン", "score"=>0.9765959}, {"name"=>"ワンピース", "score"=>0.94697183}, {"name"=>"カーキ", "score"=>0.8136864}, {"name"=>"無地", "score"=>0.54719794}, {"name"=>"フレア", "score"=>0.51572186}]}],
|
|
135
|
+
"state"=>"finished"}
|
|
84
136
|
```
|
|
85
137
|
|
|
86
138
|
If the timeout value is zero or `nil`, you will get `Recognition` instance whose state is `queued`.
|
|
87
139
|
|
|
88
140
|
Then you can fetch the recognition result using `Scnnr::Client#fetch`.
|
|
89
141
|
|
|
142
|
+
Refer: [`GET /v1/recognitions/*`](https://api.scnnr.cubki.jp/v1/docs#tag/recognitions%2Fpaths%2F~1recognitions~1*%2Fget)
|
|
143
|
+
|
|
90
144
|
```
|
|
91
145
|
recognition.queued?
|
|
92
146
|
=> true
|
|
@@ -99,6 +153,32 @@ recognition.finished?
|
|
|
99
153
|
=> true
|
|
100
154
|
```
|
|
101
155
|
|
|
156
|
+
#### Generate fashion coordinates
|
|
157
|
+
|
|
158
|
+
Request fashion coordinates generation.
|
|
159
|
+
|
|
160
|
+
Refer: [`POST /v1/coordinates`](https://api.scnnr.cubki.jp/v1/docs#tag/coordinates%2Fpaths%2F~1coordinates%2Fpost)
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
tastes = { casual: 0.7, girly: 0.3 }
|
|
164
|
+
coordinate = client.coordinate('tops', ['グレー', 'パーカー'], tastes, target: 3)
|
|
165
|
+
|
|
166
|
+
coordinate.to_h
|
|
167
|
+
=> {"items"=>
|
|
168
|
+
[{"category"=>"tops", "labels"=>[{"name"=>"グレー", "score"=>nil}, {"name"=>"パーカー", "score"=>nil}]},
|
|
169
|
+
{"category"=>"shoe",
|
|
170
|
+
"labels"=>
|
|
171
|
+
[{"name"=>"ネイビー", "score"=>nil},
|
|
172
|
+
{"name"=>"スニーカー", "score"=>nil},
|
|
173
|
+
{"name"=>"ランニング", "score"=>nil}]},
|
|
174
|
+
{"category"=>"dress",
|
|
175
|
+
"labels"=>
|
|
176
|
+
[{"name"=>"デニム", "score"=>nil},
|
|
177
|
+
{"name"=>"ブルー", "score"=>nil},
|
|
178
|
+
{"name"=>"サロペット", "score"=>nil},
|
|
179
|
+
{"name"=>"オーバーオール", "score"=>nil}]}]}
|
|
180
|
+
```
|
|
181
|
+
|
|
102
182
|
### Error handling
|
|
103
183
|
|
|
104
184
|
If the recognition processing is not completed within the timeout time or the recognition failed,
|
data/lib/scnnr.rb
CHANGED
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
require 'scnnr/configuration'
|
|
4
4
|
require 'scnnr/errors'
|
|
5
|
+
require 'scnnr/errors/image'
|
|
6
|
+
require 'scnnr/errors/image/response'
|
|
7
|
+
require 'scnnr/label'
|
|
5
8
|
require 'scnnr/recognition'
|
|
9
|
+
require 'scnnr/recognition/image'
|
|
6
10
|
require 'scnnr/recognition/object'
|
|
7
11
|
require 'scnnr/recognition/object/bounding_box'
|
|
8
12
|
require 'scnnr/recognition/object/label'
|
|
13
|
+
require 'scnnr/coordinate'
|
|
14
|
+
require 'scnnr/coordinate/item'
|
|
9
15
|
require 'scnnr/client'
|
|
10
16
|
require 'scnnr/connection'
|
|
17
|
+
require 'scnnr/routing'
|
|
11
18
|
require 'scnnr/polling_manager'
|
|
12
19
|
require 'scnnr/response'
|
|
13
20
|
require 'scnnr/version'
|
data/lib/scnnr/client.rb
CHANGED
|
@@ -5,7 +5,11 @@ module Scnnr
|
|
|
5
5
|
require 'net/http'
|
|
6
6
|
require 'json'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
TASTES = %i[
|
|
9
|
+
boyish casual celebrity conservative
|
|
10
|
+
feminine girly gyaru harajuku
|
|
11
|
+
mode natural_style
|
|
12
|
+
].freeze
|
|
9
13
|
|
|
10
14
|
def initialize
|
|
11
15
|
yield(self.config) if block_given?
|
|
@@ -16,36 +20,52 @@ module Scnnr
|
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
def recognize_image(image, options = {})
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
options = merge_options options
|
|
24
|
+
PollingManager.start(self, options) do |opts|
|
|
25
|
+
uri = construct_uri('recognitions', %i[timeout public], opts)
|
|
21
26
|
response = post_connection(uri, opts).send_stream(image)
|
|
22
|
-
|
|
27
|
+
Response.new(response).build_recognition
|
|
23
28
|
end
|
|
24
29
|
end
|
|
25
30
|
|
|
26
31
|
def recognize_url(url, options = {})
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
options = merge_options options
|
|
33
|
+
PollingManager.start(self, options) do |opts|
|
|
34
|
+
uri = construct_uri('remote/recognitions', %i[timeout force], opts)
|
|
29
35
|
response = post_connection(uri, opts).send_json({ url: url })
|
|
30
|
-
|
|
36
|
+
Response.new(response).build_recognition
|
|
31
37
|
end
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
def fetch(recognition_id, options = {})
|
|
41
|
+
options = merge_options options
|
|
35
42
|
return request(recognition_id, options) if options.delete(:polling) == false
|
|
36
|
-
|
|
43
|
+
|
|
37
44
|
PollingManager.new(options.delete(:timeout)).polling(self, recognition_id, options)
|
|
38
45
|
end
|
|
39
46
|
|
|
47
|
+
def coordinate(category, labels, taste = {}, options = {})
|
|
48
|
+
options = merge_options options
|
|
49
|
+
uri = construct_uri('coordinates', %i[target], options)
|
|
50
|
+
payload = {
|
|
51
|
+
item: { category: category, labels: labels },
|
|
52
|
+
taste: TASTES.each_with_object({}) { |key, memo| memo[key] = taste[key] if taste[key] },
|
|
53
|
+
}
|
|
54
|
+
response = post_connection(uri, options).send_json(payload)
|
|
55
|
+
Response.new(response).build_coordinate
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
private
|
|
41
59
|
|
|
42
60
|
def merge_options(options = {})
|
|
43
61
|
self.config.to_h.merge(options)
|
|
44
62
|
end
|
|
45
63
|
|
|
46
|
-
def construct_uri(path, options = {})
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
def construct_uri(path, allowed_params, options = {})
|
|
65
|
+
Routing.new(
|
|
66
|
+
path, options[:api_version],
|
|
67
|
+
options, allowed_params
|
|
68
|
+
).to_url
|
|
49
69
|
end
|
|
50
70
|
|
|
51
71
|
def get_connection(uri, options = {})
|
|
@@ -57,15 +77,9 @@ module Scnnr
|
|
|
57
77
|
end
|
|
58
78
|
|
|
59
79
|
def request(recognition_id, options = {})
|
|
60
|
-
|
|
61
|
-
uri = construct_uri("recognitions/#{recognition_id}", options)
|
|
80
|
+
uri = construct_uri("recognitions/#{recognition_id}", %i[timeout], options)
|
|
62
81
|
response = get_connection(uri, options).send_request
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def handle_response(response)
|
|
67
|
-
response = Response.new(response)
|
|
68
|
-
response.build_recognition
|
|
82
|
+
Response.new(response).build_recognition
|
|
69
83
|
end
|
|
70
84
|
end
|
|
71
85
|
end
|
data/lib/scnnr/configuration.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Scnnr
|
|
|
4
4
|
Configuration = Struct.new(:api_key, :api_version, :timeout, :logger) do
|
|
5
5
|
require 'logger'
|
|
6
6
|
|
|
7
|
-
DEFAULT_LOGGER = Logger.new(
|
|
7
|
+
DEFAULT_LOGGER = Logger.new($stdout, level: :info)
|
|
8
8
|
|
|
9
9
|
def initialize
|
|
10
10
|
super(nil, 'v1', 0, DEFAULT_LOGGER)
|
data/lib/scnnr/connection.rb
CHANGED
|
@@ -5,6 +5,15 @@ module Scnnr
|
|
|
5
5
|
require 'net/http'
|
|
6
6
|
require 'json'
|
|
7
7
|
|
|
8
|
+
RETRY_LIMIT = 3
|
|
9
|
+
RETRY_SLEEP_TIME = 1
|
|
10
|
+
RETRY_ERROR_CLASSES = [
|
|
11
|
+
Timeout::Error, Errno::EINVAL,
|
|
12
|
+
Errno::ECONNRESET, EOFError,
|
|
13
|
+
Net::HTTPBadResponse, Net::ProtocolError,
|
|
14
|
+
Net::HTTPHeaderSyntaxError
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
8
17
|
def initialize(uri, method, api_key, logger)
|
|
9
18
|
@uri = uri
|
|
10
19
|
@method = method
|
|
@@ -28,19 +37,32 @@ module Scnnr
|
|
|
28
37
|
end
|
|
29
38
|
end
|
|
30
39
|
|
|
31
|
-
def send_request
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
def send_request(&block)
|
|
41
|
+
request = block_given? ? build_request(&block) : build_request
|
|
42
|
+
with_retries do
|
|
43
|
+
Net::HTTP.start(@uri.host, @uri.port, use_ssl: use_ssl?) do |http|
|
|
44
|
+
@logger&.info("Started #{@method.upcase} #{@uri}")
|
|
45
|
+
http.request(request)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
35
48
|
end
|
|
36
49
|
|
|
37
50
|
private
|
|
38
51
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
def with_retries
|
|
53
|
+
yield
|
|
54
|
+
rescue *RETRY_ERROR_CLASSES => e
|
|
55
|
+
retry_count ||= 0
|
|
56
|
+
|
|
57
|
+
if retry_count < RETRY_LIMIT
|
|
58
|
+
retry_count += 1
|
|
59
|
+
@logger&.info("Retrying to connect: #{@uri}, attempt: #{retry_count}")
|
|
60
|
+
|
|
61
|
+
sleep RETRY_SLEEP_TIME
|
|
62
|
+
retry
|
|
43
63
|
end
|
|
64
|
+
|
|
65
|
+
raise e.class, "#{e.message} (Endpoint: #{@method.upcase} #{@uri})"
|
|
44
66
|
end
|
|
45
67
|
|
|
46
68
|
def use_ssl?
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scnnr
|
|
4
|
+
class Coordinate
|
|
5
|
+
attr_reader :items
|
|
6
|
+
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
@items = attrs['items'].map { |item| Coordinate::Item.new(item) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_h
|
|
12
|
+
{ 'items' => self.items.map(&:to_h) }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scnnr
|
|
4
|
+
class Coordinate
|
|
5
|
+
class Item
|
|
6
|
+
attr_reader :category, :labels
|
|
7
|
+
|
|
8
|
+
def initialize(attrs = {})
|
|
9
|
+
@category = attrs['category']
|
|
10
|
+
@labels = (attrs['labels'] || []).map { |label| Label.new('name' => label) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_h
|
|
14
|
+
{ 'category' => self.category, 'labels' => self.labels.map(&:to_h) }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/scnnr/errors.rb
CHANGED
|
@@ -17,11 +17,12 @@ module Scnnr
|
|
|
17
17
|
class RecognitionNotFound < Error; end
|
|
18
18
|
|
|
19
19
|
class RecognitionFailed < Error
|
|
20
|
-
attr_accessor :recognition
|
|
20
|
+
attr_accessor :recognition, :image
|
|
21
21
|
|
|
22
22
|
def initialize(recognition)
|
|
23
23
|
super(recognition.error)
|
|
24
24
|
@recognition = recognition
|
|
25
|
+
@image = Scnnr::Errors::Image.new(recognition.error['image']) if recognition.error['image']
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
28
|
|
data/lib/scnnr/label.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scnnr
|
|
4
|
+
class Label
|
|
5
|
+
attr_reader :name, :score
|
|
6
|
+
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
@name = attrs['name']
|
|
9
|
+
@score = attrs['score']
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_h
|
|
13
|
+
{ 'name' => self.name, 'score' => self.score }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/scnnr/recognition.rb
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Scnnr
|
|
4
4
|
class Recognition
|
|
5
|
-
attr_reader :id, :objects, :state, :error
|
|
5
|
+
attr_reader :id, :image, :objects, :state, :error
|
|
6
6
|
|
|
7
7
|
def initialize(attrs = {})
|
|
8
8
|
@id = attrs['id']
|
|
9
|
+
@image = Image.new(attrs['image']) if attrs['image']
|
|
9
10
|
@objects = (attrs['objects'] || []).map { |obj| Object.new(obj) }
|
|
10
11
|
@state = attrs['state']&.intern
|
|
11
12
|
@error = attrs['error']
|
|
@@ -24,7 +25,12 @@ module Scnnr
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def to_h
|
|
27
|
-
{
|
|
28
|
+
{
|
|
29
|
+
'id' => self.id,
|
|
30
|
+
'image' => self.image&.to_h,
|
|
31
|
+
'objects' => self.objects.map(&:to_h),
|
|
32
|
+
'state' => self.state.to_s,
|
|
33
|
+
}
|
|
28
34
|
end
|
|
29
35
|
end
|
|
30
36
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scnnr
|
|
4
|
+
class Recognition
|
|
5
|
+
class Image
|
|
6
|
+
attr_reader :url, :size
|
|
7
|
+
|
|
8
|
+
def initialize(attrs = {})
|
|
9
|
+
@url = attrs['url']
|
|
10
|
+
@size = attrs['size']
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_h
|
|
14
|
+
{ 'url' => self.url, 'size' => self.size }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -8,7 +8,7 @@ module Scnnr
|
|
|
8
8
|
def initialize(attrs = {})
|
|
9
9
|
@bounding_box = BoundingBox.new(attrs['bounding_box'])
|
|
10
10
|
@category = attrs['category']
|
|
11
|
-
@labels = (attrs['labels'] || []).map { |label| Label.new(label) }
|
|
11
|
+
@labels = (attrs['labels'] || []).map { |label| Scnnr::Label.new(label) }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def to_h
|
|
@@ -3,16 +3,10 @@
|
|
|
3
3
|
module Scnnr
|
|
4
4
|
class Recognition
|
|
5
5
|
class Object
|
|
6
|
-
class Label
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@name = attrs['name']
|
|
11
|
-
@score = attrs['score']
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def to_h
|
|
15
|
-
{ 'name' => self.name, 'score' => self.score }
|
|
6
|
+
class Label < Scnnr::Label
|
|
7
|
+
def initialize(*args)
|
|
8
|
+
warn "[DEPRECATION] `#{self.class.name}` is deprecated. Please use `Scnnr::Label` instead."
|
|
9
|
+
super
|
|
16
10
|
end
|
|
17
11
|
end
|
|
18
12
|
end
|
data/lib/scnnr/response.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Scnnr
|
|
|
6
6
|
|
|
7
7
|
def initialize(response)
|
|
8
8
|
raise UnexpectedError, response if response.content_type != SUPPORTED_CONTENT_TYPE
|
|
9
|
+
|
|
9
10
|
@response = response
|
|
10
11
|
end
|
|
11
12
|
|
|
@@ -18,13 +19,14 @@ module Scnnr
|
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def build_recognition
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
raise_error_response unless @response.is_a? Net::HTTPSuccess
|
|
23
|
+
recognition = Recognition.new(self.parsed_body)
|
|
24
|
+
handle_recognition(recognition)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def build_coordinate
|
|
28
|
+
raise_error_response unless @response.is_a? Net::HTTPSuccess
|
|
29
|
+
Coordinate.new(self.parsed_body)
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
private
|
|
@@ -35,11 +37,13 @@ module Scnnr
|
|
|
35
37
|
case recognition.error['type']
|
|
36
38
|
when 'unexpected-content', 'bad-request'
|
|
37
39
|
raise RequestFailed, recognition.error
|
|
38
|
-
|
|
40
|
+
when 'download-timeout', 'invalid-image', 'download-failed'
|
|
41
|
+
raise RecognitionFailed, recognition
|
|
42
|
+
else raise UnexpectedError, @response
|
|
39
43
|
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
|
-
def
|
|
46
|
+
def raise_error_response
|
|
43
47
|
case @response
|
|
44
48
|
when Net::HTTPNotFound
|
|
45
49
|
raise RecognitionNotFound, self.parsed_body
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scnnr
|
|
4
|
+
class Routing
|
|
5
|
+
API_SCHEME = URI::HTTPS
|
|
6
|
+
API_HOST = 'api.scnnr.cubki.jp'
|
|
7
|
+
|
|
8
|
+
attr_reader :path_prefix
|
|
9
|
+
|
|
10
|
+
def initialize(path, path_prefix, params, allowed_params)
|
|
11
|
+
@path = path
|
|
12
|
+
@path_prefix = path_prefix
|
|
13
|
+
@queries = build_queries params, allowed_params
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_url
|
|
17
|
+
API_SCHEME.build(
|
|
18
|
+
host: API_HOST,
|
|
19
|
+
path: self.path,
|
|
20
|
+
query: query_string
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def queries
|
|
25
|
+
@queries.reject { |_, val| val.nil? }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def path
|
|
29
|
+
"/#{[self.path_prefix, @path]
|
|
30
|
+
.map { |value| value.sub(%r{\A/}, '').sub(%r{/\z}, '') }
|
|
31
|
+
.join('/')}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def query_string
|
|
37
|
+
params = self.queries
|
|
38
|
+
return if params.empty?
|
|
39
|
+
|
|
40
|
+
params
|
|
41
|
+
.map { |pair| pair.map { |val| URI.encode_www_form_component val }.join('=') }
|
|
42
|
+
.join('&')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def build_queries(params, allowed_params)
|
|
46
|
+
{}.tap do |queries|
|
|
47
|
+
(allowed_params || []).each do |param|
|
|
48
|
+
case param.intern
|
|
49
|
+
when :timeout then queries[:timeout] = params[:timeout] if params[:timeout]&.positive?
|
|
50
|
+
else queries[param] = params[param]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/scnnr/version.rb
CHANGED
data/scnnr.gemspec
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
lib = File.expand_path('
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
5
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
5
|
require 'scnnr/version'
|
|
7
6
|
|
|
@@ -23,5 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
23
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
24
23
|
spec.require_paths = ['lib']
|
|
25
24
|
|
|
26
|
-
spec.add_development_dependency 'bundler', '~> 1
|
|
25
|
+
spec.add_development_dependency 'bundler', '~> 2.1'
|
|
26
|
+
|
|
27
|
+
spec.required_ruby_version = '>= 2.4'
|
|
27
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scnnr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- NEWROPE Co. Ltd.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-09-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1
|
|
19
|
+
version: '2.1'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1
|
|
26
|
+
version: '2.1'
|
|
27
27
|
description: 'Official #CBK scnnr client library for Ruby.'
|
|
28
28
|
email:
|
|
29
29
|
- support@newrope.biz
|
|
@@ -39,6 +39,7 @@ files:
|
|
|
39
39
|
- CHANGELOG.md
|
|
40
40
|
- CODE_OF_CONDUCT.md
|
|
41
41
|
- Gemfile
|
|
42
|
+
- Guardfile
|
|
42
43
|
- LICENSE
|
|
43
44
|
- README.md
|
|
44
45
|
- Rakefile
|
|
@@ -48,13 +49,20 @@ files:
|
|
|
48
49
|
- lib/scnnr/client.rb
|
|
49
50
|
- lib/scnnr/configuration.rb
|
|
50
51
|
- lib/scnnr/connection.rb
|
|
52
|
+
- lib/scnnr/coordinate.rb
|
|
53
|
+
- lib/scnnr/coordinate/item.rb
|
|
51
54
|
- lib/scnnr/errors.rb
|
|
55
|
+
- lib/scnnr/errors/image.rb
|
|
56
|
+
- lib/scnnr/errors/image/response.rb
|
|
57
|
+
- lib/scnnr/label.rb
|
|
52
58
|
- lib/scnnr/polling_manager.rb
|
|
53
59
|
- lib/scnnr/recognition.rb
|
|
60
|
+
- lib/scnnr/recognition/image.rb
|
|
54
61
|
- lib/scnnr/recognition/object.rb
|
|
55
62
|
- lib/scnnr/recognition/object/bounding_box.rb
|
|
56
63
|
- lib/scnnr/recognition/object/label.rb
|
|
57
64
|
- lib/scnnr/response.rb
|
|
65
|
+
- lib/scnnr/routing.rb
|
|
58
66
|
- lib/scnnr/version.rb
|
|
59
67
|
- scnnr.gemspec
|
|
60
68
|
homepage: https://github.com/NEWROPE/scnnr-ruby
|
|
@@ -69,15 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
69
77
|
requirements:
|
|
70
78
|
- - ">="
|
|
71
79
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
80
|
+
version: '2.4'
|
|
73
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
82
|
requirements:
|
|
75
83
|
- - ">="
|
|
76
84
|
- !ruby/object:Gem::Version
|
|
77
85
|
version: '0'
|
|
78
86
|
requirements: []
|
|
79
|
-
|
|
80
|
-
rubygems_version: 2.6.13
|
|
87
|
+
rubygems_version: 3.0.1
|
|
81
88
|
signing_key:
|
|
82
89
|
specification_version: 4
|
|
83
90
|
summary: ''
|