pixmatch 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.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2011 Art.sy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.rdoc ADDED
@@ -0,0 +1,86 @@
1
+ = Pixmatch
2
+
3
+ Pixmatch REST API client library for TinEye[http://www.tineye.com/] reverse-image search.
4
+
5
+ == Using
6
+
7
+ gem install pixmatch
8
+
9
+ == Example
10
+
11
+ require 'rubygems'
12
+ require 'pixmatch'
13
+
14
+ Pixmatch.configure do |config|
15
+ config.username = 'username'
16
+ config.password = 'password'
17
+ config.url = 'api.tineye.com'
18
+ end
19
+
20
+ # ping the server
21
+ response = Pixmatch.ping()
22
+ puts response['status']
23
+
24
+ # count the number of images in the collection
25
+ count = Pixmatch.count()
26
+
27
+ # add an image
28
+ Pixmatch.add('images/mona-lisa.jpg')
29
+ Pixmatch.add(File.new('images/mona-lisa.jpg')
30
+
31
+ # add a collection of images
32
+ Pixmatch.add(Dir.glob('images/*.jpg'))
33
+
34
+ # list images
35
+ images = Pixmatch.list()
36
+ images.each { |filename| puts filename }
37
+
38
+ # delete an image
39
+ Pixmatch.delete('mona-lisa.jpg')
40
+
41
+ # delete an array of images
42
+ Pixmatch.delete([ 'mona-lisa.jpg', 'mona-lisa-botero.jpg' ])
43
+
44
+ # search
45
+ found = Pixmatch.search('images/mona-lisa.jpg')
46
+ found.each { |find|
47
+ puts "#{find['filename']}: #{find['score']}"
48
+ }
49
+
50
+ == Contributing
51
+
52
+ * Fork the project
53
+ * Copy 'config/pixmatch.yml.default' to 'config/pixmatch.yml'. Edit your pixmatch API credentials as follows.
54
+ test:
55
+ <<: *settings
56
+ username: '<your username>'
57
+ password: '<your password>'
58
+ endpoint: 'http://<your url>.tineye.com'
59
+ * Run 'bundle install'
60
+ * Test with 'rspec spec'
61
+ * Send pull requests.
62
+
63
+ == Copyright
64
+
65
+ Copyright (c) 2011 Art.sy
66
+
67
+ Permission is hereby granted, free of charge, to any person obtaining
68
+ a copy of this software and associated documentation files (the
69
+ "Software"), to deal in the Software without restriction, including
70
+ without limitation the rights to use, copy, modify, merge, publish,
71
+ distribute, sublicense, and/or sell copies of the Software, and to
72
+ permit persons to whom the Software is furnished to do so, subject to
73
+ the following conditions:
74
+
75
+ The above copyright notice and this permission notice shall be
76
+ included in all copies or substantial portions of the Software.
77
+
78
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
79
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
80
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
81
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
82
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
83
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
84
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
85
+
86
+
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../request', __FILE__)
2
+
3
+ # Adapted from the Ruby Twitter gem.
4
+ # @see https://github.com/jnunemaker/twitter
5
+ module Pixmatch
6
+ # @private
7
+ class API
8
+ # @private
9
+ attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
10
+
11
+ # Creates a new API
12
+ def initialize(options = {})
13
+ options = Pixmatch.options.merge(options)
14
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
15
+ send("#{key}=", options[key])
16
+ end
17
+ end
18
+
19
+ include Request
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module Pixmatch
2
+ class Client
3
+ module Add
4
+ # Index and Add a list of images to your collection.
5
+ # @param files [Array] Array of File or String objects.
6
+ def add(files)
7
+ files = [ files ] if (files.is_a?(String) || files.is_a?(File))
8
+ files_hash = { }
9
+ files.each { |f| files_hash["images[#{files_hash.size}]"] = f.is_a?(File) ? f : File.new(f, "rb") }
10
+ request(:post, 'rest', { method: :add }, { payload: files_hash })
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Pixmatch
2
+ class Client
3
+ module Count
4
+ # Get the number of items currently in the collection.
5
+ # @return Number of items currently in the collection.
6
+ def count
7
+ response = request(:get, 'rest', { method: :count })
8
+ result = response['result']
9
+ raise "Missing result in response." if result.nil?
10
+ raise "Invalid result in response (#{result.class.name})." if ! result.is_a?(Array)
11
+ raise "Invalid count in result response (#{result.size})." if result.size != 1
12
+ result[0].to_i
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Pixmatch
2
+ class Client
3
+ module Delete
4
+ # Given a list of image filenames, delete the images from the collection.
5
+ # @param files [Array] Array of file names.
6
+ def delete(filenames)
7
+ filenames = [ filenames ] if filenames.is_a?(String)
8
+ filenames_hash = { }
9
+ filenames.each { |f| filenames_hash["filenames[#{filenames_hash.size}]"] = f }
10
+ request(:post, 'rest', { method: :delete }, { payload: filenames_hash })
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Pixmatch
2
+ class Client
3
+ module List
4
+ # List the contents of the collection.
5
+ # @param offset [Integer] Offset to start at, default is zero.
6
+ # @param limit [Integer] Limit number of results, default is zero (all results).
7
+ def list(offset = 0, limit = 0)
8
+ response = request(:get, 'rest', { method: 'list', offset: offset, limit: limit })
9
+ result = response['result']
10
+ raise "Missing result in response." if result.nil?
11
+ raise "Invalid result in response (#{result.class.name})." if ! result.is_a?(Array)
12
+ result
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Pixmatch
2
+ class Client
3
+ module Ping
4
+ # Check whether the PixMatch server is running.
5
+ def ping
6
+ request(:get, 'rest', { method: :ping })
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,21 @@
1
+ module Pixmatch
2
+ class Client
3
+ module Search
4
+ # Given an image, search against our collection and return any matches with corresponding scores.
5
+ # @param image [File or String] The image file object that will be searched for.
6
+ # @param options [Hash] The following options.
7
+ # * min_score [Integer] The minimum score that should be returned, defaults to 0. Should be between 0 and 100 (inclusive).
8
+ # * max_num_matches [Integer] The maximum number of matches that should be returned, defaults to 10. A value of -1 indicates no limit.
9
+ # * check_horizontal_flip [Boolean] Indicates whether the search incorporates checking for horizontal flips, defaults to true.
10
+ # @return Array of { score, filename } hashes.
11
+ def search(image, options = {})
12
+ payload = { "image" => image.is_a?(File) ? image : File.new(image, "rb") }
13
+ response = request(:post, 'rest', { method: 'search' }.merge(options), { payload: payload })
14
+ result = response['result']
15
+ raise "Missing result in response." if result.nil?
16
+ raise "Invalid result in response (#{result.class.name})." if ! result.is_a?(Array)
17
+ result
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # Adapted from the Ruby Twitter gem.
2
+ # @see https://github.com/jnunemaker/twitter
3
+ module Pixmatch
4
+ # Wrapper for the Pixmatch REST API
5
+ class Client < API
6
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each { |f| require f }
7
+
8
+ include Pixmatch::Client::Ping
9
+ include Pixmatch::Client::Count
10
+ include Pixmatch::Client::Add
11
+ include Pixmatch::Client::List
12
+ include Pixmatch::Client::Delete
13
+ include Pixmatch::Client::Search
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ # Adapted from the Ruby Twitter gem.
2
+ # @see https://github.com/jnunemaker/twitter
3
+ module Pixmatch
4
+ # Defines constants and methods related to configuration.
5
+ module Configuration
6
+ # An array of valid keys in the options hash when configuring a {Flixated::API}.
7
+ VALID_OPTIONS_KEYS = [
8
+ :username,
9
+ :password,
10
+ :endpoint
11
+ ].freeze
12
+
13
+ # By default, don't set a username.
14
+ DEFAULT_USERNAME = nil.freeze
15
+
16
+ # By default, don't set a password.
17
+ DEFAULT_PASSWORD = nil.freeze
18
+
19
+ # The endpoint that will be used to connect if none is set.
20
+ DEFAULT_ENDPOINT = 'https://api.tineye.com'.freeze
21
+
22
+ # @private
23
+ attr_accessor(*VALID_OPTIONS_KEYS)
24
+
25
+ # When this module is extended, set all configuration options to their default values.
26
+ def self.extended(base)
27
+ base.reset
28
+ end
29
+
30
+ # Convenience method to allow configuration options to be set in a block.
31
+ def configure
32
+ yield self
33
+ end
34
+
35
+ # Create a hash of options and their values.
36
+ def options
37
+ VALID_OPTIONS_KEYS.inject({}) do |option,key|
38
+ option.merge!(key => send(key))
39
+ end
40
+ end
41
+
42
+ # Reset all configuration options to default.
43
+ def reset
44
+ self.username = DEFAULT_USERNAME
45
+ self.password = DEFAULT_PASSWORD
46
+ self.endpoint = DEFAULT_ENDPOINT
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ module Pixmatch
2
+ # Custom error class for rescuing from all known Pixmatch errors.
3
+ class Error < StandardError
4
+ attr_accessor :status, :method, :detail
5
+
6
+ def initialize(json)
7
+ @status = json['status']
8
+ @method = json['method']
9
+ @error = json['error']
10
+ @result = json['result']
11
+ end
12
+
13
+ def to_s
14
+ s = @error.nil? ? 'Unexpected Error' : @error.join('\r\n')
15
+ s += ("\r\n " + @result.join('\r\n ')) if @result
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require 'uri'
2
+ require 'rest_client'
3
+
4
+ module Pixmatch
5
+ module Request
6
+ private
7
+
8
+ def request(http_method, path, query_params = {}, data_params = {})
9
+ capture RestClient::Request.new({
10
+ method: http_method,
11
+ url: "#{endpoint}/#{paramify(path, query_params)}",
12
+ user: username,
13
+ password: password
14
+ }.merge(data_params)).execute
15
+ end
16
+
17
+ def capture(response)
18
+ json = Utils.parse_json(response)
19
+ Utils.handle_error(json)
20
+ json
21
+ end
22
+
23
+ def paramify(path, params)
24
+ URI.encode("#{path}/?#{params.map { |k,v| "#{k}=#{v}" }.join('&')}")
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ require 'hashie'
2
+ require 'yajl'
3
+
4
+ module Pixmatch
5
+ # @private
6
+ module Utils
7
+ private
8
+ def self.handle_error(json_response)
9
+ raise Pixmatch::Error.new(json_response) if (json_response['status'] != 'ok')
10
+ end
11
+
12
+ # Parses JSON and returns a Hashie::Mash
13
+ def self.parse_json(json)
14
+ Hashie::Mash.new(Yajl::Parser.new.parse(json))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Pixmatch
2
+ VERSION = '0.1.0'
3
+ end
data/lib/pixmatch.rb ADDED
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../pixmatch/version', __FILE__)
2
+ require File.expand_path('../pixmatch/configuration', __FILE__)
3
+ require File.expand_path('../pixmatch/utils', __FILE__)
4
+ require File.expand_path('../pixmatch/error', __FILE__)
5
+ require File.expand_path('../pixmatch/api', __FILE__)
6
+ require File.expand_path('../pixmatch/client', __FILE__)
7
+
8
+ # Adapted from the Ruby Twitter gem.
9
+ # @see https://github.com/jnunemaker/twitter
10
+ module Pixmatch
11
+ extend Configuration
12
+
13
+ # Alias for pixmatch::Client.new
14
+ #
15
+ # @return {pixmatch::Client}
16
+ def self.client(options = {})
17
+ Pixmatch::Client.new(options)
18
+ end
19
+
20
+ # Delegate to pixmatch::Client
21
+ def self.method_missing(method, *args, &block)
22
+ return super unless client.respond_to?(method)
23
+ client.send(method, *args, &block)
24
+ end
25
+
26
+ # Delegate to pixmatch::Client
27
+ def self.respond_to?(method)
28
+ return client.respond_to?(method) || super
29
+ end
30
+ end
@@ -0,0 +1,87 @@
1
+ require 'yaml'
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ describe "Pixmatch" do
6
+ before(:each) do
7
+ Pixmatch.configure do |config|
8
+ pixmatch_yml = File.join(File.dirname(__FILE__), '../config/pixmatch.yml')
9
+ pixmatch_yml = File.join(File.dirname(__FILE__), '../config/pixmatch.yml.default') if ! File.exists?(pixmatch_yml)
10
+ raise "missing config/pixmatch.yml" if ! File.exists?(pixmatch_yml)
11
+ pixmatch_config = YAML.load_file(pixmatch_yml)['test']
12
+ config.username = pixmatch_config['username']
13
+ config.password = pixmatch_config['password']
14
+ config.endpoint = pixmatch_config['endpoint']
15
+ end
16
+ end
17
+ describe "methods" do
18
+ it "ping" do
19
+ response = Pixmatch.ping()
20
+ response['status'].should == "ok"
21
+ response['method'].should == "ping"
22
+ end
23
+ it "count" do
24
+ count = Pixmatch.count()
25
+ count.is_a?(Integer).should be_true
26
+ count.should >= 0
27
+ end
28
+ it "add with one path" do
29
+ response = Pixmatch.add(File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg'))
30
+ response['status'].should == "ok"
31
+ response['method'].should == "add"
32
+ end
33
+ it "add with one path as an array" do
34
+ response = Pixmatch.add([ File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg') ])
35
+ response['status'].should == "ok"
36
+ response['method'].should == "add"
37
+ end
38
+ it "add with one File object" do
39
+ response = Pixmatch.add(File.new(File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg')))
40
+ response['status'].should == "ok"
41
+ response['method'].should == "add"
42
+ end
43
+ it "add with one File object as an array" do
44
+ response = Pixmatch.add([ File.new(File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg')) ])
45
+ response['status'].should == "ok"
46
+ response['method'].should == "add"
47
+ end
48
+ it "add with an array of File objects" do
49
+ response = Pixmatch.add(Dir.glob(File.join(File.dirname(__FILE__), 'assets/*.jpg')))
50
+ response['status'].should == "ok"
51
+ response['method'].should == "add"
52
+ end
53
+ it "list" do
54
+ result = Pixmatch.list()
55
+ result.is_a?(Array).should be_true
56
+ result.size.should >= 0
57
+ end
58
+ it "delete with one name" do
59
+ Pixmatch.add([ File.new(File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg')) ])
60
+ count = Pixmatch.count
61
+ response = Pixmatch.delete('mona-lisa.jpg')
62
+ response['status'].should == "ok"
63
+ response['method'].should == "delete"
64
+ Pixmatch.count.should == count - 1
65
+ end
66
+ it "delete an array of names" do
67
+ Pixmatch.add(Dir.glob(File.join(File.dirname(__FILE__), 'assets/*.jpg')))
68
+ count = Pixmatch.count
69
+ filenames = Dir.glob(File.join(File.dirname(__FILE__), 'assets/*.jpg')).map { |f| File.basename(f) }
70
+ response = Pixmatch.delete(filenames)
71
+ response['status'].should == "ok"
72
+ response['method'].should == "delete"
73
+ Pixmatch.count.should == count - filenames.size
74
+ end
75
+ it "search" do
76
+ Pixmatch.add(Dir.glob(File.join(File.dirname(__FILE__), 'assets/*.jpg')))
77
+ response = Pixmatch.search(File.join(File.dirname(__FILE__), 'assets/mona-lisa.jpg'))
78
+ response.is_a?(Array).should be_true
79
+ response.size.should >= 0
80
+ response.each { |result|
81
+ result.is_a?(Hash).should be_true
82
+ result.has_key?('score').should be_true
83
+ result.has_key?('filename').should be_true
84
+ }
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rspec'
5
+ require 'pixmatch'
6
+
7
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
8
+
9
+ RSpec.configure do |config|
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pixmatch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ prerelease: false
10
+ platform: ruby
11
+ authors:
12
+ - Daniel Doubrovkine
13
+ autorequire: !!null
14
+ bindir: bin
15
+ cert_chain: []
16
+ date: 2011-04-13 00:00:00.000000000 -04:00
17
+ default_executable: !!null
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: rest-client
21
+ requirement: &86264460 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.6.1
27
+ segments:
28
+ - 1
29
+ - 6
30
+ - 1
31
+ type: :runtime
32
+ prerelease: false
33
+ version_requirements: *86264460
34
+ - !ruby/object:Gem::Dependency
35
+ name: yajl-ruby
36
+ requirement: &86264070 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 0.8.1
42
+ segments:
43
+ - 0
44
+ - 8
45
+ - 1
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *86264070
49
+ - !ruby/object:Gem::Dependency
50
+ name: hashie
51
+ requirement: &86263680 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 1.0.0
57
+ segments:
58
+ - 1
59
+ - 0
60
+ - 0
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: *86263680
64
+ - !ruby/object:Gem::Dependency
65
+ name: rspec
66
+ requirement: &86263290 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ version: 2.5.0
72
+ segments:
73
+ - 2
74
+ - 5
75
+ - 0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: *86263290
79
+ - !ruby/object:Gem::Dependency
80
+ name: bundler
81
+ requirement: &86262900 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: 1.0.10
87
+ segments:
88
+ - 1
89
+ - 0
90
+ - 10
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: *86262900
94
+ - !ruby/object:Gem::Dependency
95
+ name: jeweler
96
+ requirement: &86262510 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.5.2
102
+ segments:
103
+ - 1
104
+ - 5
105
+ - 2
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: *86262510
109
+ - !ruby/object:Gem::Dependency
110
+ name: yard
111
+ requirement: &86262120 !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ~>
115
+ - !ruby/object:Gem::Version
116
+ version: 0.6.4
117
+ segments:
118
+ - 0
119
+ - 6
120
+ - 4
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *86262120
124
+ description: Pixmatch REST API client library for Ruby
125
+ email: dblock@dblock.org
126
+ executables: []
127
+ extensions: []
128
+ extra_rdoc_files:
129
+ - LICENSE.txt
130
+ - README.rdoc
131
+ files:
132
+ - lib/pixmatch.rb
133
+ - lib/pixmatch/api.rb
134
+ - lib/pixmatch/client.rb
135
+ - lib/pixmatch/client/add.rb
136
+ - lib/pixmatch/client/count.rb
137
+ - lib/pixmatch/client/delete.rb
138
+ - lib/pixmatch/client/list.rb
139
+ - lib/pixmatch/client/ping.rb
140
+ - lib/pixmatch/client/search.rb
141
+ - lib/pixmatch/configuration.rb
142
+ - lib/pixmatch/error.rb
143
+ - lib/pixmatch/request.rb
144
+ - lib/pixmatch/utils.rb
145
+ - lib/pixmatch/version.rb
146
+ - LICENSE.txt
147
+ - README.rdoc
148
+ - spec/pixmatch_spec.rb
149
+ - spec/spec_helper.rb
150
+ has_rdoc: true
151
+ homepage: http://github.com/dblock/pixmatch
152
+ licenses:
153
+ - MIT
154
+ post_install_message: !!null
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ segments:
165
+ - 0
166
+ hash: -137474991
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
174
+ - 0
175
+ requirements: []
176
+ rubyforge_project: !!null
177
+ rubygems_version: 1.3.7
178
+ signing_key: !!null
179
+ specification_version: 3
180
+ summary: Pixmatch REST API client library for Ruby
181
+ test_files:
182
+ - spec/pixmatch_spec.rb
183
+ - spec/spec_helper.rb