imagga 0.0.2
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.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/imagga.gemspec +25 -0
- data/lib/imagga.rb +7 -0
- data/lib/imagga/client.rb +42 -0
- data/lib/imagga/exceptions.rb +21 -0
- data/lib/imagga/extract_options.rb +74 -0
- data/lib/imagga/extract_result_builder.rb +11 -0
- data/lib/imagga/image.rb +71 -0
- data/lib/imagga/rank_result_builder.rb +9 -0
- data/lib/imagga/version.rb +3 -0
- data/spec/lib/client_spec.rb +352 -0
- data/spec/lib/extract_result_builder_spec.rb +25 -0
- data/spec/lib/extraction_options_spec.rb +73 -0
- data/spec/lib/image_color_spec.rb +58 -0
- data/spec/lib/image_info_spec.rb +88 -0
- data/spec/lib/image_spec.rb +25 -0
- data/spec/lib/rank_result_builder_spec.rb +25 -0
- data/spec/lib/rank_similarity_spec.rb +31 -0
- data/spec/spec_helper.rb +11 -0
- metadata +165 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Mart Karu
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
[](https://travis-ci.org/martkaru/imagga)
|
2
|
+
|
3
|
+
# Imagga
|
4
|
+
|
5
|
+
Client for Imagga image analytics services API
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'imagga'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install imagga
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Set up a client
|
24
|
+
|
25
|
+
client = Imagga::Client.new(
|
26
|
+
base_uri: '0.0.0.0', # IP of the Imagga server
|
27
|
+
api_key: '12345678', # Your api key
|
28
|
+
api_secret: '1234567890123456789' # Your api secret
|
29
|
+
)
|
30
|
+
|
31
|
+
Extract image information
|
32
|
+
|
33
|
+
results = client.extract('http://imagga.com/images/scheme_colors.png')
|
34
|
+
|
35
|
+
Extract image information with indexing and extraction options:
|
36
|
+
|
37
|
+
results = client.extract(
|
38
|
+
[
|
39
|
+
Imagga::Image.new(url: 'http://image1', id: '333'),
|
40
|
+
Imagga::Image.new(url: 'http://image2')
|
41
|
+
],
|
42
|
+
extract_overall_colors: true,
|
43
|
+
extract_object_colors: false
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/imagga.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'imagga/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "imagga"
|
8
|
+
gem.version = Imagga::VERSION
|
9
|
+
gem.authors = ["Mart Karu"]
|
10
|
+
gem.email = ["karu@metal.ee"]
|
11
|
+
gem.description = %q{Ruby client for accessing Imagga API}
|
12
|
+
gem.summary = %q{Ruby client for accessing Imagga API}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.add_dependency "httparty", "~> 0.10"
|
20
|
+
gem.add_dependency "json", "~> 1.7"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", "~> 2.12"
|
23
|
+
gem.add_development_dependency "rake"
|
24
|
+
gem.add_development_dependency "fakeweb"
|
25
|
+
end
|
data/lib/imagga.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Imagga
|
5
|
+
class Client
|
6
|
+
include HTTParty
|
7
|
+
include Imagga::Exceptions
|
8
|
+
attr_reader :api_key, :api_secret, :base_uri, :service_path
|
9
|
+
|
10
|
+
def initialize(opts={})
|
11
|
+
@api_key = opts[:api_key] || raise_missing(:api_key)
|
12
|
+
@api_secret = opts[:api_secret] || raise_missing(:api_secret)
|
13
|
+
@base_uri = opts[:base_uri] || raise_missing(:base_uri)
|
14
|
+
@service_path = '/colorsearchserver.php'
|
15
|
+
|
16
|
+
Imagga::Client.base_uri @base_uri
|
17
|
+
end
|
18
|
+
|
19
|
+
def extract(urls_or_images, additional_options={})
|
20
|
+
options = extract_options(urls_or_images, additional_options)
|
21
|
+
result = JSON.parse(self.class.post(service_path, body: options))
|
22
|
+
raise_if_request_failed!(result)
|
23
|
+
ExtractResultBuilder.new.build_from(result)
|
24
|
+
end
|
25
|
+
|
26
|
+
def rank(opts)
|
27
|
+
result = JSON.parse(self.class.post(service_path, body: rank_options(opts)))
|
28
|
+
raise_if_request_failed!(result)
|
29
|
+
RankResultBuilder.new.build_from(result)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def extract_options(urls_or_images, additional_options)
|
35
|
+
ExtractOptions.new(api_key, api_secret).options(urls_or_images, additional_options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def rank_options(opts)
|
39
|
+
RankOptions.new(api_key, api_secret).options(opts)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Imagga
|
2
|
+
module Exceptions
|
3
|
+
def raise_missing(attribute)
|
4
|
+
raise ArgumentError, "%s is missing" % attribute.to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def raise_if_request_failed!(result)
|
8
|
+
if result.respond_to?(:keys) && result.keys.include?('error_code')
|
9
|
+
raise Imagga::ClientException.new(result['error_code'].to_i), result['error_message'], caller[0..-1]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ClientException < StandardError
|
15
|
+
attr_accessor :error_code
|
16
|
+
def initialize(error_code)
|
17
|
+
@error_code = error_code
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Imagga
|
2
|
+
class BaseOptions
|
3
|
+
attr_accessor :api_key, :api_secret
|
4
|
+
|
5
|
+
def initialize(api_key, api_secret)
|
6
|
+
@version = '1.0'
|
7
|
+
@api_key = api_key || raise_missing(:api_key)
|
8
|
+
@api_secret = api_secret || raise_missing(:api_secret)
|
9
|
+
end
|
10
|
+
|
11
|
+
def base_options
|
12
|
+
{ v: @version, api_key: @api_key }
|
13
|
+
end
|
14
|
+
|
15
|
+
def sign(options)
|
16
|
+
sorted_options_string = options.keys.sort.map do |key|
|
17
|
+
"%s=%s" % [key.to_s, options[key]]
|
18
|
+
end.join('') << @api_secret
|
19
|
+
Digest::MD5.hexdigest(sorted_options_string)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ExtractOptions < BaseOptions
|
24
|
+
|
25
|
+
def options(urls_or_images, additional_options={})
|
26
|
+
options = base_options.merge(
|
27
|
+
method: 'imagga.colorsearch.extract',
|
28
|
+
urls: build_urls(urls_or_images),
|
29
|
+
)
|
30
|
+
|
31
|
+
if ids = build_ids(urls_or_images)
|
32
|
+
options.merge!(ids: ids)
|
33
|
+
end
|
34
|
+
|
35
|
+
[:extract_overall_colors, :extract_object_colors].each do |key|
|
36
|
+
if additional_options.keys.include?(key) && (value = additional_options[key] ? 1 : 0)
|
37
|
+
options.merge!(key => value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
options.merge!(sig: sign(options))
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_urls(urls_or_images)
|
45
|
+
[urls_or_images].flatten.map{ |o| o.url rescue o }.join(',')
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_ids(urls_or_images)
|
49
|
+
ids = [urls_or_images].flatten.map{ |o| o.id rescue 0 }
|
50
|
+
return if ids.uniq == [0]
|
51
|
+
ids.join(',')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class RankOptions < BaseOptions
|
57
|
+
def options(opts)
|
58
|
+
color_vector = opts.fetch(:color_vector)
|
59
|
+
type = opts.fetch(:type)
|
60
|
+
dist = opts.fetch(:dist)
|
61
|
+
count = opts.fetch(:count)
|
62
|
+
|
63
|
+
options = base_options.merge(
|
64
|
+
method: 'imagga.colorsearch.rank',
|
65
|
+
color_vector: color_vector,
|
66
|
+
type: type,
|
67
|
+
dist: dist,
|
68
|
+
count: count
|
69
|
+
)
|
70
|
+
|
71
|
+
options.merge!(sig: sign(options))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/imagga/image.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module Imagga
|
2
|
+
class Image
|
3
|
+
include Imagga::Exceptions
|
4
|
+
attr_accessor :url, :id
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
@url = opts[:url] || raise_missing(:url)
|
8
|
+
@id = opts[:id] || 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ImageInfoBase
|
13
|
+
def initialize(opts={})
|
14
|
+
self.class.fields.each { |field| send("#{field}=", opts[field]) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ImageInfo < ImageInfoBase
|
19
|
+
def self.fields
|
20
|
+
%w(url object_percentage color_variance image_packed foreground_packed background_packed)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.color_fields
|
24
|
+
%w(image_colors foreground_colors background_colors)
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(opts={})
|
28
|
+
super(opts['info'].merge('url' => opts['url']))
|
29
|
+
self.class.color_fields.each do |field|
|
30
|
+
send("#{field}=", build_image_colors(opts['info'][field]))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_image_colors(image_color_nodes)
|
35
|
+
image_color_nodes && image_color_nodes.map { |color_node| ImageColor.new(color_node) }
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor *(fields + color_fields)
|
39
|
+
|
40
|
+
def color_variance=(value)
|
41
|
+
@color_variance = value.to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ImageColor < ImageInfoBase
|
46
|
+
def self.fields
|
47
|
+
%w(percent r g b html_code closest_palette_color closest_palette_color_parent closest_palette_distance)
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor *fields
|
51
|
+
|
52
|
+
%w(r g b).each do |field|
|
53
|
+
define_method("#{field}=") do |value|
|
54
|
+
instance_variable_set("@#{field}", value.to_i)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def percent=(value)
|
59
|
+
@percent = value.to_f
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class RankSimilarity < ImageInfoBase
|
65
|
+
def self.fields
|
66
|
+
%w(id dist)
|
67
|
+
end
|
68
|
+
|
69
|
+
attr_accessor *fields
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fake_web'
|
3
|
+
|
4
|
+
describe Imagga::Client do
|
5
|
+
|
6
|
+
subject { described_class.new(api_key: '1', api_secret: '2', base_uri: 'http://example.com') }
|
7
|
+
let(:extract_response) {'{
|
8
|
+
"colors":[
|
9
|
+
{
|
10
|
+
"url":"http:\/\/www.stockpodium.com\/stock-photo-8244245\/smiling-presenting-2-apples-image.jpg",
|
11
|
+
"info":{
|
12
|
+
"image_colors":[
|
13
|
+
{
|
14
|
+
"percent":"38.90",
|
15
|
+
"r":"247",
|
16
|
+
"g":"245",
|
17
|
+
"b":"243",
|
18
|
+
"html_code":"#f7f5f3",
|
19
|
+
"closest_palette_color":"white",
|
20
|
+
"closest_palette_color_parent":"white",
|
21
|
+
"closest_palette_distance":1.8304102578
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"percent":"35.16",
|
25
|
+
"r":"206",
|
26
|
+
"g":"167",
|
27
|
+
"b":"146",
|
28
|
+
"html_code":"#cea792",
|
29
|
+
"closest_palette_color":"fresco",
|
30
|
+
"closest_palette_color_parent":"beige",
|
31
|
+
"closest_palette_distance":4.93287465177
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"percent":"10.41",
|
35
|
+
"r":"150",
|
36
|
+
"g":"60",
|
37
|
+
"b":"45",
|
38
|
+
"html_code":"#963c2d",
|
39
|
+
"closest_palette_color":"ribbon red",
|
40
|
+
"closest_palette_color_parent":"red",
|
41
|
+
"closest_palette_distance":5.6423821179
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"percent":"8.38",
|
45
|
+
"r":"55",
|
46
|
+
"g":"37",
|
47
|
+
"b":"31",
|
48
|
+
"html_code":"#37251f",
|
49
|
+
"closest_palette_color":"espresso",
|
50
|
+
"closest_palette_color_parent":"brown",
|
51
|
+
"closest_palette_distance":5.91329502182
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"percent":"7.15",
|
55
|
+
"r":"168",
|
56
|
+
"g":"181",
|
57
|
+
"b":"45",
|
58
|
+
"html_code":"#a8b52d",
|
59
|
+
"closest_palette_color":"mint",
|
60
|
+
"closest_palette_color_parent":"olive green",
|
61
|
+
"closest_palette_distance":10.7126507469
|
62
|
+
}
|
63
|
+
],
|
64
|
+
"foreground_colors":[
|
65
|
+
{
|
66
|
+
"percent":"45.92",
|
67
|
+
"r":"200",
|
68
|
+
"g":"180",
|
69
|
+
"b":"112",
|
70
|
+
"html_code":"#c8b470",
|
71
|
+
"closest_palette_color":"medium olive",
|
72
|
+
"closest_palette_color_parent":"skin",
|
73
|
+
"closest_palette_distance":7.22056402093
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"percent":"34.21",
|
77
|
+
"r":"162",
|
78
|
+
"g":"79",
|
79
|
+
"b":"61",
|
80
|
+
"html_code":"#a24f3d",
|
81
|
+
"closest_palette_color":"fiesta",
|
82
|
+
"closest_palette_color_parent":"red",
|
83
|
+
"closest_palette_distance":6.29194294147
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"percent":"19.86",
|
87
|
+
"r":"52",
|
88
|
+
"g":"35",
|
89
|
+
"b":"31",
|
90
|
+
"html_code":"#34231f",
|
91
|
+
"closest_palette_color":"espresso",
|
92
|
+
"closest_palette_color_parent":"brown",
|
93
|
+
"closest_palette_distance":6.49089812519
|
94
|
+
}
|
95
|
+
],
|
96
|
+
"background_colors":[
|
97
|
+
{
|
98
|
+
"percent":"58.05",
|
99
|
+
"r":"249",
|
100
|
+
"g":"248",
|
101
|
+
"b":"247",
|
102
|
+
"html_code":"#f9f8f7",
|
103
|
+
"closest_palette_color":"white",
|
104
|
+
"closest_palette_color_parent":"white",
|
105
|
+
"closest_palette_distance":2.48109615666
|
106
|
+
},
|
107
|
+
{
|
108
|
+
"percent":"36.41",
|
109
|
+
"r":"206",
|
110
|
+
"g":"177",
|
111
|
+
"b":"161",
|
112
|
+
"html_code":"#ceb1a1",
|
113
|
+
"closest_palette_color":"pearl pink",
|
114
|
+
"closest_palette_color_parent":"light pink",
|
115
|
+
"closest_palette_distance":4.11506425614
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"percent":"5.55",
|
119
|
+
"r":"150",
|
120
|
+
"g":"100",
|
121
|
+
"b":"77",
|
122
|
+
"html_code":"#96644d",
|
123
|
+
"closest_palette_color":"light bronze",
|
124
|
+
"closest_palette_color_parent":"skin",
|
125
|
+
"closest_palette_distance":6.37479340147
|
126
|
+
}
|
127
|
+
],
|
128
|
+
"object_percentage":38.4,
|
129
|
+
"color_variance":"33"
|
130
|
+
}
|
131
|
+
},
|
132
|
+
{
|
133
|
+
"url":"http:\/\/www.stockpodium.com\/stock-photo-9289532\/car-dirving-very-fast-under-image.jpg",
|
134
|
+
"info":{
|
135
|
+
"image_colors":[
|
136
|
+
{
|
137
|
+
"percent":"38.53",
|
138
|
+
"r":"103",
|
139
|
+
"g":"98",
|
140
|
+
"b":"98",
|
141
|
+
"html_code":"#676262",
|
142
|
+
"closest_palette_color":"blue steel",
|
143
|
+
"closest_palette_color_parent":"grey",
|
144
|
+
"closest_palette_distance":10.486937593
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"percent":"26.31",
|
148
|
+
"r":"42",
|
149
|
+
"g":"37",
|
150
|
+
"b":"33",
|
151
|
+
"html_code":"#2a2521",
|
152
|
+
"closest_palette_color":"espresso",
|
153
|
+
"closest_palette_color_parent":"brown",
|
154
|
+
"closest_palette_distance":8.14492880108
|
155
|
+
},
|
156
|
+
{
|
157
|
+
"percent":"16.19",
|
158
|
+
"r":"178",
|
159
|
+
"g":"182",
|
160
|
+
"b":"190",
|
161
|
+
"html_code":"#b2b6be",
|
162
|
+
"closest_palette_color":"frost",
|
163
|
+
"closest_palette_color_parent":"light grey",
|
164
|
+
"closest_palette_distance":2.82095071372
|
165
|
+
},
|
166
|
+
{
|
167
|
+
"percent":"12.06",
|
168
|
+
"r":"197",
|
169
|
+
"g":"51",
|
170
|
+
"b":"45",
|
171
|
+
"html_code":"#c5332d",
|
172
|
+
"closest_palette_color":"fiesta",
|
173
|
+
"closest_palette_color_parent":"red",
|
174
|
+
"closest_palette_distance":5.41278686601
|
175
|
+
},
|
176
|
+
{
|
177
|
+
"percent":"6.91",
|
178
|
+
"r":"86",
|
179
|
+
"g":"97",
|
180
|
+
"b":"28",
|
181
|
+
"html_code":"#56611c",
|
182
|
+
"closest_palette_color":"moss",
|
183
|
+
"closest_palette_color_parent":"olive green",
|
184
|
+
"closest_palette_distance":9.97695248255
|
185
|
+
}
|
186
|
+
],
|
187
|
+
"foreground_colors":[
|
188
|
+
{
|
189
|
+
"percent":"62.98",
|
190
|
+
"r":"199",
|
191
|
+
"g":"50",
|
192
|
+
"b":"43",
|
193
|
+
"html_code":"#c7322b",
|
194
|
+
"closest_palette_color":"fiesta",
|
195
|
+
"closest_palette_color_parent":"red",
|
196
|
+
"closest_palette_distance":5.44027296941
|
197
|
+
},
|
198
|
+
{
|
199
|
+
"percent":"22.01",
|
200
|
+
"r":"140",
|
201
|
+
"g":"132",
|
202
|
+
"b":"144",
|
203
|
+
"html_code":"#8c8490",
|
204
|
+
"closest_palette_color":"shadow",
|
205
|
+
"closest_palette_color_parent":"light grey",
|
206
|
+
"closest_palette_distance":3.40761167276
|
207
|
+
},
|
208
|
+
{
|
209
|
+
"percent":"15.01",
|
210
|
+
"r":"61",
|
211
|
+
"g":"38",
|
212
|
+
"b":"43",
|
213
|
+
"html_code":"#3d262b",
|
214
|
+
"closest_palette_color":"espresso",
|
215
|
+
"closest_palette_color_parent":"brown",
|
216
|
+
"closest_palette_distance":5.85441000013
|
217
|
+
}
|
218
|
+
],
|
219
|
+
"background_colors":[
|
220
|
+
{
|
221
|
+
"percent":"41.07",
|
222
|
+
"r":"103",
|
223
|
+
"g":"97",
|
224
|
+
"b":"97",
|
225
|
+
"html_code":"#676161",
|
226
|
+
"closest_palette_color":"blue steel",
|
227
|
+
"closest_palette_color_parent":"grey",
|
228
|
+
"closest_palette_distance":10.6345471176
|
229
|
+
},
|
230
|
+
{
|
231
|
+
"percent":"39.63",
|
232
|
+
"r":"53",
|
233
|
+
"g":"51",
|
234
|
+
"b":"34",
|
235
|
+
"html_code":"#353322",
|
236
|
+
"closest_palette_color":"graphite",
|
237
|
+
"closest_palette_color_parent":"black",
|
238
|
+
"closest_palette_distance":9.18317865786
|
239
|
+
},
|
240
|
+
{
|
241
|
+
"percent":"19.29",
|
242
|
+
"r":"174",
|
243
|
+
"g":"180",
|
244
|
+
"b":"187",
|
245
|
+
"html_code":"#aeb4bb",
|
246
|
+
"closest_palette_color":"frost",
|
247
|
+
"closest_palette_color_parent":"light grey",
|
248
|
+
"closest_palette_distance":2.03931376316
|
249
|
+
}
|
250
|
+
],
|
251
|
+
"object_percentage":17.99,
|
252
|
+
"color_variance":"37",
|
253
|
+
"image_packed":null,
|
254
|
+
"foreground_packed":null,
|
255
|
+
"background_packed":null
|
256
|
+
}
|
257
|
+
}
|
258
|
+
]
|
259
|
+
}'}
|
260
|
+
|
261
|
+
let(:rank_response) { '{
|
262
|
+
"rank_similarity":[
|
263
|
+
{
|
264
|
+
"id":8774077,
|
265
|
+
"dist":2597.38299
|
266
|
+
},
|
267
|
+
{
|
268
|
+
"id":9085916,
|
269
|
+
"dist":2681.33259
|
270
|
+
}
|
271
|
+
]
|
272
|
+
}'}
|
273
|
+
|
274
|
+
let(:failed_signature_response) { '{"error_code":3,"error_message":"Invalid signature"}' }
|
275
|
+
|
276
|
+
it "has api_key" do
|
277
|
+
subject.api_key.should == '1'
|
278
|
+
end
|
279
|
+
|
280
|
+
it "has api_secret" do
|
281
|
+
subject.api_secret.should == '2'
|
282
|
+
end
|
283
|
+
|
284
|
+
it "has base_uri" do
|
285
|
+
subject.base_uri.should == 'http://example.com'
|
286
|
+
end
|
287
|
+
|
288
|
+
it "knows service path" do
|
289
|
+
subject.service_path.should == '/colorsearchserver.php'
|
290
|
+
end
|
291
|
+
|
292
|
+
describe "#extract" do
|
293
|
+
it "extracts image info" do
|
294
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: extract_response)
|
295
|
+
subject.extract('http://image').size.should == 2
|
296
|
+
end
|
297
|
+
|
298
|
+
context "with failing request" do
|
299
|
+
before :each do
|
300
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: failed_signature_response)
|
301
|
+
subject.should_receive(:extract_options).with('http://image', {})
|
302
|
+
end
|
303
|
+
|
304
|
+
it "raises exception" do
|
305
|
+
expect { subject.extract('http://image') }.to raise_error(Imagga::ClientException)
|
306
|
+
end
|
307
|
+
|
308
|
+
it "populates exception object with details" do
|
309
|
+
begin
|
310
|
+
subject.extract('http://image')
|
311
|
+
rescue Imagga::ClientException => e
|
312
|
+
e.message.should == 'Invalid signature'
|
313
|
+
e.error_code.should == 3
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "#rank" do
|
320
|
+
let(:rank_arguments) { {
|
321
|
+
color_vector: [{percent: 60, r: 255, g: 0, b: 0}],
|
322
|
+
type: 'overall',
|
323
|
+
dist: 3000,
|
324
|
+
count: 200
|
325
|
+
} }
|
326
|
+
|
327
|
+
it "does a rank search" do
|
328
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: rank_response)
|
329
|
+
subject.rank(rank_arguments).size.should == 2
|
330
|
+
end
|
331
|
+
|
332
|
+
context "with failing request" do
|
333
|
+
before :each do
|
334
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: failed_signature_response)
|
335
|
+
subject.should_receive(:rank_options)
|
336
|
+
end
|
337
|
+
|
338
|
+
it "raises exception" do
|
339
|
+
expect { subject.rank(rank_arguments) }.to raise_error(Imagga::ClientException)
|
340
|
+
end
|
341
|
+
|
342
|
+
it "populates exception object with details" do
|
343
|
+
begin
|
344
|
+
subject.rank(rank_arguments)
|
345
|
+
rescue Imagga::ClientException => e
|
346
|
+
e.message.should == 'Invalid signature'
|
347
|
+
e.error_code.should == 3
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ExtractResultBuilder do
|
4
|
+
let(:result) { {
|
5
|
+
"colors" => [
|
6
|
+
{
|
7
|
+
"url" =>"http:\/\/www.stockpodium.com\/stock-photo-8244245\/smiling-presenting-2-apples-image.jpg",
|
8
|
+
"info" => {}
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"url" =>"http:\/\/www.stockpodium.com\/stock-photo-9289532\/car-dirving-very-fast-under-image.jpg",
|
12
|
+
"info" => {}
|
13
|
+
}
|
14
|
+
]
|
15
|
+
} }
|
16
|
+
|
17
|
+
subject { described_class.new }
|
18
|
+
|
19
|
+
describe '#build' do
|
20
|
+
it "builds result" do
|
21
|
+
subject.build_from(result).size.should == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ExtractOptions do
|
4
|
+
subject { described_class.new('apikey', 'secret') }
|
5
|
+
|
6
|
+
describe "#options" do
|
7
|
+
it "builds simple options" do
|
8
|
+
subject.options('http://image').should == {
|
9
|
+
urls: 'http://image',
|
10
|
+
method: 'imagga.colorsearch.extract',
|
11
|
+
sig: '76e667179a6520da86e272a609bc7fab',
|
12
|
+
api_key: 'apikey',
|
13
|
+
v: '1.0'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "builds complex options" do
|
18
|
+
subject.options([
|
19
|
+
Imagga::Image.new(url: 'http://image1', id: '333'),
|
20
|
+
Imagga::Image.new(url: 'http://image2')
|
21
|
+
], extract_overall_colors: true, extract_object_colors: false).should == {
|
22
|
+
urls: 'http://image1,http://image2',
|
23
|
+
ids: '333,0',
|
24
|
+
method: 'imagga.colorsearch.extract',
|
25
|
+
extract_overall_colors: 1,
|
26
|
+
extract_object_colors: 0,
|
27
|
+
sig: 'd66a0e3409ed08878ce7efae2827de87',
|
28
|
+
api_key: 'apikey',
|
29
|
+
v: '1.0'
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#build_urls" do
|
35
|
+
it "builds string of urls based on single image url string" do
|
36
|
+
subject.build_urls('http://image').should == 'http://image'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "builds string of urls based on image url string arrays" do
|
40
|
+
subject.build_urls(['http://image1', 'http://image2']).should == 'http://image1,http://image2'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "builds string of urls based on single image object" do
|
44
|
+
subject.build_urls(Imagga::Image.new(url: 'http://image')).should == 'http://image'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "builds string of urls based on image object array" do
|
48
|
+
subject.build_urls([
|
49
|
+
Imagga::Image.new(url: 'http://image1'),
|
50
|
+
Imagga::Image.new(url: 'http://image2')]).should == 'http://image1,http://image2'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#build_ids" do
|
55
|
+
it "returns 0 based on single image url string" do
|
56
|
+
subject.build_ids('http://image').should == nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns array of 0-s given image url string arrays" do
|
60
|
+
subject.build_ids(['http://image1', 'http://image2']).should == nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "builds string of ids based on single image object" do
|
64
|
+
subject.build_ids(Imagga::Image.new(url: 'http://image', id: '123')).should == '123'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "builds string of ids based on image object array" do
|
68
|
+
subject.build_ids([
|
69
|
+
Imagga::Image.new(url: 'http://image1', id: '123'),
|
70
|
+
Imagga::Image.new(url: 'http://image2')]).should == '123,0'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ImageColor do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"percent" => '19.29',
|
7
|
+
"r" => '174', "g" => '180', "b" => '187',
|
8
|
+
"html_code" => "#aeb4bb",
|
9
|
+
"closest_palette_color" => "frost",
|
10
|
+
"closest_palette_color_parent" => "light grey",
|
11
|
+
"closest_palette_distance" => 2.03931376316
|
12
|
+
} }
|
13
|
+
|
14
|
+
describe "initialized by hash" do
|
15
|
+
subject { described_class.new(init_hash) }
|
16
|
+
|
17
|
+
it "has percent" do
|
18
|
+
subject.percent.should == 19.29
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has r" do
|
22
|
+
subject.r.should == 174
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has g" do
|
26
|
+
subject.g.should == 180
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has b" do
|
30
|
+
subject.b.should == 187
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has html_code" do
|
34
|
+
subject.html_code.should == '#aeb4bb'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has closest palette color" do
|
38
|
+
subject.closest_palette_color.should == 'frost'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has closest parent palette color" do
|
42
|
+
subject.closest_palette_color_parent.should == 'light grey'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has closest palette distance" do
|
46
|
+
subject.closest_palette_distance.should == 2.03931376316
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "initialized by hash with not supported attributes" do
|
51
|
+
subject { described_class.new(a: 'b') }
|
52
|
+
|
53
|
+
it "ignores not supported attributes" do
|
54
|
+
expect { subject.a }.to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ImageInfo do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"url" => 'http://image',
|
7
|
+
"info" => {
|
8
|
+
"image_colors" => [ { "html_code" => "#676262", } ],
|
9
|
+
"foreground_colors" => [ { "html_code" => "#c7322b", } ],
|
10
|
+
"background_colors" => [ { "html_code" => "#676161", } ],
|
11
|
+
"object_percentage" => 17.99,
|
12
|
+
"color_variance" => "37",
|
13
|
+
"image_packed" => nil,
|
14
|
+
"foreground_packed" => nil,
|
15
|
+
"background_packed" => nil
|
16
|
+
}
|
17
|
+
} }
|
18
|
+
subject { described_class.new(init_hash) }
|
19
|
+
|
20
|
+
describe "initialized by hash" do
|
21
|
+
|
22
|
+
it "has url" do
|
23
|
+
subject.url.should == 'http://image'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "has image colors" do
|
27
|
+
subject.image_colors.should have(1).items
|
28
|
+
subject.image_colors.first.html_code.should == '#676262'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has foreground colors" do
|
32
|
+
subject.foreground_colors.should have(1).items
|
33
|
+
subject.foreground_colors.first.html_code.should == '#c7322b'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has background colors" do
|
37
|
+
subject.background_colors.should have(1).items
|
38
|
+
subject.background_colors.first.html_code.should == '#676161'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has object percentage" do
|
42
|
+
subject.object_percentage.should == 17.99
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has color variance" do
|
46
|
+
subject.color_variance.should == 37
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "initialized by hash with not supported attributes" do
|
51
|
+
subject { described_class.new(a: 'b') }
|
52
|
+
|
53
|
+
it "ignores not supported attributes" do
|
54
|
+
expect { subject.a }.to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "initialied with empty color info" do
|
59
|
+
let(:init_hash) { {
|
60
|
+
"url" => 'http://image',
|
61
|
+
"info" => {
|
62
|
+
"image_colors" => [],
|
63
|
+
"foreground_colors" => [],
|
64
|
+
"background_colors" => [],
|
65
|
+
}
|
66
|
+
} }
|
67
|
+
|
68
|
+
it "initializes color infos as empty arrays" do
|
69
|
+
subject.image_colors.should be_empty
|
70
|
+
subject.foreground_colors.should be_empty
|
71
|
+
subject.background_colors.should be_empty
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "initialied with missing color info" do
|
76
|
+
let(:init_hash) { {
|
77
|
+
"url" => 'http://image',
|
78
|
+
"info" => {}
|
79
|
+
} }
|
80
|
+
|
81
|
+
it "does not initialize color infos" do
|
82
|
+
subject.image_colors.should be_nil
|
83
|
+
subject.foreground_colors.should be_nil
|
84
|
+
subject.background_colors.should be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::Image do
|
4
|
+
subject { described_class.new(url: 'http://', id: '1234') }
|
5
|
+
|
6
|
+
it "has id" do
|
7
|
+
subject.id.should == '1234'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has url" do
|
11
|
+
subject.url.should == 'http://'
|
12
|
+
end
|
13
|
+
|
14
|
+
context "without url" do
|
15
|
+
it "throws ArgumentError" do
|
16
|
+
expect{ described_class.new(id: '1234') }.to raise_error(ArgumentError, 'url is missing')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "without id" do
|
21
|
+
it "assigns id as 0" do
|
22
|
+
described_class.new(url: 'http://').id.should == 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::RankResultBuilder do
|
4
|
+
let(:result) { {
|
5
|
+
'rank_similarity' => [
|
6
|
+
{
|
7
|
+
"id" => 8774077,
|
8
|
+
"dist" => 2597.38299
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"id" => 9085916,
|
12
|
+
"dist" => 2681.33259
|
13
|
+
}
|
14
|
+
]
|
15
|
+
} }
|
16
|
+
|
17
|
+
subject { described_class.new }
|
18
|
+
|
19
|
+
describe '#build' do
|
20
|
+
it "builds result" do
|
21
|
+
subject.build_from(result).size.should == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::RankSimilarity do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"id" => 8774077,
|
7
|
+
"dist" => 2597.38299
|
8
|
+
} }
|
9
|
+
|
10
|
+
describe "initialized by hash" do
|
11
|
+
subject { described_class.new(init_hash) }
|
12
|
+
|
13
|
+
it "has id" do
|
14
|
+
subject.id.should == 8774077
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has dist" do
|
18
|
+
subject.dist.should == 2597.38299
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# todo
|
23
|
+
describe "initialized by hash with not supported attributes" do
|
24
|
+
subject { described_class.new(a: 'b') }
|
25
|
+
|
26
|
+
it "ignores not supported attributes" do
|
27
|
+
expect { subject.a }.to raise_error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rspec/autorun'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require(:default, :development)
|
5
|
+
|
6
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
7
|
+
# in spec/support/ and its subdirectories.
|
8
|
+
Dir["spec/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: imagga
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mart Karu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.10'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.10'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.7'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.7'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.12'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.12'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: fakeweb
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Ruby client for accessing Imagga API
|
95
|
+
email:
|
96
|
+
- karu@metal.ee
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .rspec
|
103
|
+
- .travis.yml
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- imagga.gemspec
|
109
|
+
- lib/imagga.rb
|
110
|
+
- lib/imagga/client.rb
|
111
|
+
- lib/imagga/exceptions.rb
|
112
|
+
- lib/imagga/extract_options.rb
|
113
|
+
- lib/imagga/extract_result_builder.rb
|
114
|
+
- lib/imagga/image.rb
|
115
|
+
- lib/imagga/rank_result_builder.rb
|
116
|
+
- lib/imagga/version.rb
|
117
|
+
- spec/lib/client_spec.rb
|
118
|
+
- spec/lib/extract_result_builder_spec.rb
|
119
|
+
- spec/lib/extraction_options_spec.rb
|
120
|
+
- spec/lib/image_color_spec.rb
|
121
|
+
- spec/lib/image_info_spec.rb
|
122
|
+
- spec/lib/image_spec.rb
|
123
|
+
- spec/lib/rank_result_builder_spec.rb
|
124
|
+
- spec/lib/rank_similarity_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
homepage: ''
|
127
|
+
licenses: []
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
hash: 440675985594337981
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
hash: 440675985594337981
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 1.8.25
|
153
|
+
signing_key:
|
154
|
+
specification_version: 3
|
155
|
+
summary: Ruby client for accessing Imagga API
|
156
|
+
test_files:
|
157
|
+
- spec/lib/client_spec.rb
|
158
|
+
- spec/lib/extract_result_builder_spec.rb
|
159
|
+
- spec/lib/extraction_options_spec.rb
|
160
|
+
- spec/lib/image_color_spec.rb
|
161
|
+
- spec/lib/image_info_spec.rb
|
162
|
+
- spec/lib/image_spec.rb
|
163
|
+
- spec/lib/rank_result_builder_spec.rb
|
164
|
+
- spec/lib/rank_similarity_spec.rb
|
165
|
+
- spec/spec_helper.rb
|