petfinder 0.1.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +36 -24
- data/{LICENSE → LICENSE.txt} +3 -1
- data/README.md +68 -0
- data/Rakefile +3 -9
- data/lib/petfinder.rb +4 -3
- data/lib/petfinder/auth.rb +7 -8
- data/lib/petfinder/breeds.rb +9 -6
- data/lib/petfinder/client.rb +35 -36
- data/lib/petfinder/pet.rb +58 -63
- data/lib/petfinder/shelter.rb +14 -17
- data/lib/petfinder/version.rb +1 -1
- data/lib/petfinder/xml_mapper.rb +21 -0
- data/petfinder.gemspec +24 -27
- data/spec/{petfinder_spec.rb → client_spec.rb} +15 -31
- data/spec/fixtures/pet.xml +2 -3
- data/spec/fixtures/shelter.xml +5 -5
- data/spec/pet_spec.rb +38 -0
- data/spec/shelter_spec.rb +20 -0
- data/spec/spec_helper.rb +4 -10
- metadata +64 -44
- data/README.rdoc +0 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6c608d8186d68bebed5f5fc24de035840f20f056
|
4
|
+
data.tar.gz: dfc97ebbb1f073ccd408f71b81cd5b7827d57fc0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 96fa520e5b8105fef2b023f7c12e5d560bbf820639846dc86e793c1698836c52d18a02113fc5659521bd2a1ea1dc956ab4d2db593067b7995e315555b3a0fe6a
|
7
|
+
data.tar.gz: aa4117a1be4cf278b48b3be8a8d88e7d4e8e0a3876c0de7d2721717b99f6a6df92a44116ad8e438dea91ed1e701f2ce3d649c4415b08ae1c16a8885dda3c2ae2
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
data/Gemfile
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gemspec
|
3
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,37 +1,49 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
petfinder (0.1.
|
5
|
-
|
6
|
-
|
4
|
+
petfinder (0.1.3)
|
5
|
+
excon
|
6
|
+
nokogiri
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rspec
|
27
|
-
|
28
|
-
|
11
|
+
addressable (2.3.5)
|
12
|
+
coderay (1.0.9)
|
13
|
+
crack (0.4.1)
|
14
|
+
safe_yaml (~> 0.9.0)
|
15
|
+
diff-lcs (1.2.4)
|
16
|
+
excon (0.26.0)
|
17
|
+
method_source (0.8.2)
|
18
|
+
mini_portile (0.5.1)
|
19
|
+
nokogiri (1.6.0)
|
20
|
+
mini_portile (~> 0.5.0)
|
21
|
+
pry (0.9.12.2)
|
22
|
+
coderay (~> 1.0.5)
|
23
|
+
method_source (~> 0.8)
|
24
|
+
slop (~> 3.4)
|
25
|
+
rake (10.1.0)
|
26
|
+
rspec (2.14.1)
|
27
|
+
rspec-core (~> 2.14.0)
|
28
|
+
rspec-expectations (~> 2.14.0)
|
29
|
+
rspec-mocks (~> 2.14.0)
|
30
|
+
rspec-core (2.14.5)
|
31
|
+
rspec-expectations (2.14.2)
|
32
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
33
|
+
rspec-mocks (2.14.3)
|
34
|
+
safe_yaml (0.9.7)
|
35
|
+
slop (3.4.6)
|
36
|
+
webmock (1.13.0)
|
37
|
+
addressable (>= 2.2.7)
|
38
|
+
crack (>= 0.3.2)
|
29
39
|
|
30
40
|
PLATFORMS
|
31
41
|
ruby
|
32
42
|
|
33
43
|
DEPENDENCIES
|
34
|
-
bundler
|
35
|
-
fakeweb
|
44
|
+
bundler (~> 1.3)
|
36
45
|
petfinder!
|
46
|
+
pry
|
47
|
+
rake
|
37
48
|
rspec
|
49
|
+
webmock
|
data/{LICENSE → LICENSE.txt}
RENAMED
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Petfinder
|
2
|
+
|
3
|
+
Ruby gem wrapper for the [Petfinder API](http://www.petfinder.com/developers/api-docs).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'petfinder'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install petfinder
|
18
|
+
|
19
|
+
## Get your API key
|
20
|
+
|
21
|
+
Get your Petfinder API key at: http://www.petfinder.com/developers/api-key
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Instantiate a client
|
26
|
+
|
27
|
+
petfinder = Petfinder::Client.new('your_api_key', 'your_api_secret')
|
28
|
+
|
29
|
+
### or configure once
|
30
|
+
|
31
|
+
Petfinder.configure do |config|
|
32
|
+
config.api_key = 'your_api_key'
|
33
|
+
config.api_secret = 'your_api_secret'
|
34
|
+
end
|
35
|
+
petfinder = Petfinder::Client.new
|
36
|
+
|
37
|
+
## Examples
|
38
|
+
|
39
|
+
#### Return a list of dogs in the "90210" zip code
|
40
|
+
|
41
|
+
pets = petfinder.find_pets('dog', '90210')
|
42
|
+
pets.count
|
43
|
+
# => "25"
|
44
|
+
|
45
|
+
pets.first.name
|
46
|
+
# => "Petey"
|
47
|
+
|
48
|
+
pets.first.shelterid
|
49
|
+
# => "CA123"
|
50
|
+
|
51
|
+
#### Return information about the shelter with id "CA123"
|
52
|
+
|
53
|
+
shelter = petfinder.shelter('CA123')
|
54
|
+
shelter.name
|
55
|
+
# => "Melrose Place SPCA"
|
56
|
+
|
57
|
+
## TODO
|
58
|
+
|
59
|
+
* Implement use of security token when Petfinder requires it
|
60
|
+
* Support paging for results
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
1. Fork it
|
65
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
66
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
67
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
68
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,12 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
require 'bundler'
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
-
spec.pattern = "spec/**/*_spec.rb"
|
10
|
-
end
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
5
|
|
12
6
|
task :default => :spec
|
data/lib/petfinder.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'excon'
|
2
|
+
require 'nokogiri'
|
3
3
|
require 'digest/md5'
|
4
4
|
|
5
5
|
require 'petfinder/client'
|
6
|
+
require 'petfinder/xml_mapper'
|
6
7
|
require 'petfinder/pet'
|
7
8
|
require 'petfinder/breeds'
|
8
9
|
require 'petfinder/shelter'
|
@@ -10,7 +11,7 @@ require 'petfinder/auth'
|
|
10
11
|
|
11
12
|
module Petfinder
|
12
13
|
|
13
|
-
class
|
14
|
+
class Error < StandardError; end
|
14
15
|
|
15
16
|
class << self
|
16
17
|
attr_accessor :api_key, :api_secret
|
data/lib/petfinder/auth.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Petfinder
|
2
|
-
|
3
2
|
class Auth
|
4
|
-
|
3
|
+
extend XmlMapper
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
5
|
+
xml_attributes :key, :token, :expires, :expires_string
|
6
|
+
|
7
|
+
def initialize(xml)
|
8
|
+
@xml = xml
|
9
|
+
end
|
12
10
|
|
11
|
+
end
|
13
12
|
end
|
data/lib/petfinder/breeds.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
module Petfinder
|
2
|
-
|
3
2
|
class Breeds
|
4
|
-
include HappyMapper
|
5
|
-
tag 'breeds'
|
6
3
|
|
7
|
-
|
8
|
-
|
4
|
+
def initialize(xml)
|
5
|
+
@xml = xml
|
6
|
+
end
|
9
7
|
|
10
|
-
|
8
|
+
def breeds
|
9
|
+
@xml.xpath("//breeds/breed").map(&:text)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
data/lib/petfinder/client.rb
CHANGED
@@ -1,71 +1,65 @@
|
|
1
1
|
module Petfinder
|
2
|
-
|
3
2
|
class Client
|
4
|
-
include HTTParty
|
5
|
-
format :xml
|
6
|
-
base_uri "http://api.petfinder.com"
|
7
3
|
|
8
4
|
def initialize(api_key = Petfinder.api_key, api_secret = Petfinder.api_secret)
|
9
5
|
@api_key, @api_secret = api_key, api_secret
|
10
|
-
raise "API key is required" unless @api_key
|
11
|
-
|
12
|
-
self.class.default_params :key => api_key
|
6
|
+
raise Petfinder::Error.new("API key is required") unless @api_key
|
13
7
|
end
|
14
8
|
|
15
9
|
# Valid animal types: barnyard, bird, cat, dog, horse, pig, reptile, smallfurry
|
16
10
|
def breeds(animal_type)
|
17
|
-
response = perform_get("/breed.list",
|
18
|
-
Breeds.
|
11
|
+
response = perform_get("/breed.list", { :animal => animal_type })
|
12
|
+
Breeds.new(response).breeds
|
19
13
|
end
|
20
14
|
|
21
15
|
def pet(id)
|
22
|
-
response = perform_get("/pet.get",
|
23
|
-
Pet.
|
16
|
+
response = perform_get("/pet.get", { :id => id })
|
17
|
+
Pet.new(response)
|
24
18
|
end
|
25
19
|
|
26
20
|
# Options available: animal, breed, size, sex, location, shelterid
|
27
21
|
def random_pet(options = {})
|
28
22
|
query = options.merge(:output => 'full')
|
29
|
-
response = perform_get("/pet.getRandom",
|
30
|
-
Pet.
|
23
|
+
response = perform_get("/pet.getRandom", query)
|
24
|
+
Pet.new(response)
|
31
25
|
end
|
32
26
|
|
33
27
|
# Options available: breed, size, sex, age, offset, count
|
34
28
|
def find_pets(animal_type, location, options = {})
|
35
29
|
query = options.merge(:animal => animal_type, :location => location)
|
36
|
-
response = perform_get("/pet.find",
|
37
|
-
Pet.
|
30
|
+
response = perform_get("/pet.find", query)
|
31
|
+
Pet.multiple(response)
|
38
32
|
end
|
39
33
|
|
40
34
|
def shelter(id)
|
41
|
-
response = perform_get("/shelter.get",
|
42
|
-
Shelter.
|
35
|
+
response = perform_get("/shelter.get", { :id => id })
|
36
|
+
Shelter.new(response)
|
43
37
|
end
|
44
38
|
|
45
39
|
# Options available: name, offset, count
|
46
40
|
def find_shelters(location, options = {})
|
47
41
|
query = options.merge(:location => location)
|
48
|
-
response = perform_get("/shelter.find",
|
49
|
-
Shelter.
|
42
|
+
response = perform_get("/shelter.find", query)
|
43
|
+
Shelter.multiple(response)
|
50
44
|
end
|
51
45
|
|
52
46
|
# Options available: offset, count
|
53
47
|
def find_shelters_by_breed(animal_type, breed, options = {})
|
54
48
|
query = options.merge(:animal => animal_type, :breed => breed)
|
55
|
-
response = perform_get("/shelter.listByBreed",
|
56
|
-
Shelter.
|
49
|
+
response = perform_get("/shelter.listByBreed", query)
|
50
|
+
Shelter.multiple(response)
|
57
51
|
end
|
58
52
|
|
59
53
|
# Options available: status, offset, count
|
60
54
|
def shelter_pets(id, options = {})
|
61
55
|
query = options.merge(:id => id)
|
62
|
-
response = perform_get("/shelter.getPets",
|
63
|
-
Pet.
|
56
|
+
response = perform_get("/shelter.getPets", query)
|
57
|
+
Pet.multiple(response)
|
64
58
|
end
|
65
59
|
|
66
60
|
def token
|
67
|
-
response = perform_get("/auth.getToken",
|
68
|
-
Auth.
|
61
|
+
response = perform_get("/auth.getToken", { :sig => digest_key_and_secret })
|
62
|
+
Auth.new(response).token
|
69
63
|
end
|
70
64
|
|
71
65
|
private
|
@@ -76,20 +70,25 @@ module Petfinder
|
|
76
70
|
end
|
77
71
|
|
78
72
|
def perform_get(uri, options = {})
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
connection = Excon.new("http://api.petfinder.com", omit_default_port: true)
|
74
|
+
response = connection.get(path: uri, query: options.merge(key: @api_key))
|
75
|
+
|
76
|
+
raise "Bad http status response from server: #{response.status}" if response.status != 200
|
77
|
+
@xml = Nokogiri::XML(response.body)
|
78
|
+
raise "#{petfinder_status_code}: #{petfinder_status_message}" if petfinder_status_code != 100
|
79
|
+
|
80
|
+
@xml
|
81
|
+
rescue RuntimeError => ex
|
82
|
+
raise Petfinder::Error.new(ex.message)
|
82
83
|
end
|
83
84
|
|
84
|
-
def
|
85
|
-
|
86
|
-
status = response['petfinder']['header']['status']
|
87
|
-
raise PetfinderError.new("(#{status['code']}) #{status['message']}") if status['code'].to_i != 100
|
88
|
-
else
|
89
|
-
raise RuntimeError.new("Invalid response from server: #{response.code}")
|
90
|
-
end
|
85
|
+
def petfinder_status_code
|
86
|
+
@xml.xpath("//header/status/code").text.to_i
|
91
87
|
end
|
92
88
|
|
93
|
-
|
89
|
+
def petfinder_status_message
|
90
|
+
@xml.xpath("//header/status/message").text
|
91
|
+
end
|
94
92
|
|
93
|
+
end
|
95
94
|
end
|
data/lib/petfinder/pet.rb
CHANGED
@@ -1,77 +1,72 @@
|
|
1
1
|
module Petfinder
|
2
|
-
|
3
|
-
|
4
|
-
include HappyMapper
|
2
|
+
class Pet
|
3
|
+
extend XmlMapper
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
attribute :size, String
|
9
|
-
element :url, String, :tag => '.'
|
10
|
-
end
|
5
|
+
xml_attributes :id, :name, :animal, :mix, :age, :shelter_id, :shelter_pet_id,
|
6
|
+
:sex, :size, :description, :last_update, :status
|
11
7
|
|
12
|
-
|
13
|
-
include HappyMapper
|
14
|
-
attr_accessor :pictures
|
15
|
-
|
16
|
-
tag 'pet'
|
17
|
-
element :id, Integer
|
18
|
-
element :shelter_id, String, :tag => 'shelterId'
|
19
|
-
element :shelter_pet_id, String, :tag => 'shelterPetId'
|
20
|
-
element :name, String
|
21
|
-
element :animal, String
|
22
|
-
has_many :breeds, String, :tag => 'breed', :deep => true
|
23
|
-
element :mix, String
|
24
|
-
element :age, String
|
25
|
-
element :sex, String
|
26
|
-
element :size, String
|
27
|
-
has_many :options, String, :tag => 'option', :deep => true
|
28
|
-
element :description, String
|
29
|
-
element :last_update, DateTime, :tag => 'lastUpdate'
|
30
|
-
element :status, String
|
31
|
-
has_many :photos, Photo, :tag => 'photo', :deep => true
|
8
|
+
attr_reader :photos
|
32
9
|
|
33
|
-
|
10
|
+
def initialize(xml)
|
11
|
+
@xml = xml
|
12
|
+
end
|
34
13
|
|
35
|
-
|
36
|
-
pet.
|
37
|
-
|
14
|
+
def self.multiple(xml)
|
15
|
+
xml.xpath("//pets/pet").map do |node|
|
16
|
+
Pet.new(Nokogiri::XML(node.to_xml))
|
17
|
+
end
|
38
18
|
end
|
39
|
-
|
40
|
-
def
|
41
|
-
|
19
|
+
|
20
|
+
def description_sanitized
|
21
|
+
Nokogiri::HTML(CGI.unescapeHTML(description)).content
|
42
22
|
end
|
43
|
-
|
44
|
-
def
|
45
|
-
@
|
46
|
-
|
47
|
-
|
23
|
+
|
24
|
+
def breeds
|
25
|
+
@xml.xpath("//pet/breeds/breed").map(&:text)
|
26
|
+
end
|
27
|
+
|
28
|
+
def options
|
29
|
+
@xml.xpath("//pet/options/option").map(&:text)
|
30
|
+
end
|
31
|
+
|
32
|
+
def photos
|
33
|
+
parse_photos unless @photos
|
34
|
+
@photos
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def parse_photos
|
40
|
+
@photos = []
|
41
|
+
@xml.xpath("//pet/media/photos/photo").each do |node|
|
42
|
+
add_photo(node.attr("id"), node.attr("size"), node.text)
|
48
43
|
end
|
49
44
|
end
|
50
|
-
end
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@thumbnail = photo.url
|
66
|
-
when "t"
|
67
|
-
@tiny = photo.url
|
68
|
-
end
|
46
|
+
def add_photo(id, size, url)
|
47
|
+
photo = @photos.find { |photo| photo.id == id } || Photo.new(id)
|
48
|
+
case size
|
49
|
+
when "x"
|
50
|
+
photo.large = url
|
51
|
+
when "pn"
|
52
|
+
photo.medium = url
|
53
|
+
when "fpm"
|
54
|
+
photo.small = url
|
55
|
+
when "pnt"
|
56
|
+
photo.thumbnail = url
|
57
|
+
when "t"
|
58
|
+
photo.tiny = url
|
69
59
|
end
|
60
|
+
@photos << photo unless @photos.include?(photo)
|
70
61
|
end
|
71
|
-
|
72
|
-
def to_s
|
73
|
-
large
|
74
|
-
end
|
75
|
-
end
|
76
62
|
|
63
|
+
class Photo
|
64
|
+
attr_accessor :id, :large, :medium, :small, :thumbnail, :tiny
|
65
|
+
|
66
|
+
def initialize(id)
|
67
|
+
@id = id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
77
72
|
end
|
data/lib/petfinder/shelter.rb
CHANGED
@@ -1,22 +1,19 @@
|
|
1
1
|
module Petfinder
|
2
|
-
|
3
2
|
class Shelter
|
4
|
-
|
3
|
+
extend XmlMapper
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
element :state, String
|
13
|
-
element :zip, String
|
14
|
-
element :country, String
|
15
|
-
element :latitude, String
|
16
|
-
element :longitude, String
|
17
|
-
element :phone, String
|
18
|
-
element :fax, String
|
19
|
-
element :email, String
|
20
|
-
end
|
5
|
+
xml_attributes :id, :name, :address1, :address2, :city, :state, :zip, :country,
|
6
|
+
:latitude, :longitude, :phone, :fax, :email
|
7
|
+
|
8
|
+
def initialize(xml)
|
9
|
+
@xml = xml
|
10
|
+
end
|
21
11
|
|
12
|
+
def self.multiple(xml)
|
13
|
+
xml.xpath("//shelters/shelter").map do |node|
|
14
|
+
Shelter.new(Nokogiri::XML(node.to_xml))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
22
19
|
end
|
data/lib/petfinder/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Petfinder
|
2
|
+
module XmlMapper
|
3
|
+
|
4
|
+
def xml_attributes(*names)
|
5
|
+
names.each { |name| xml_attribute(name) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def xml_attribute(name, xml_name = nil)
|
9
|
+
klass = self.name.split('::').last.downcase
|
10
|
+
xml_name ||= camel_case_lower(name.to_s)
|
11
|
+
define_method(name) do
|
12
|
+
@xml.xpath("//#{klass}/#{xml_name}").text
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def camel_case_lower(name)
|
17
|
+
name.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/petfinder.gemspec
CHANGED
@@ -1,31 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'petfinder/version'
|
3
5
|
|
4
|
-
Gem::Specification.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "petfinder"
|
8
|
+
spec.version = Petfinder::VERSION
|
9
|
+
spec.authors = ["Eric Hutzelman"]
|
10
|
+
spec.email = ["ehutzelman@gmail.com"]
|
11
|
+
spec.description = "REST client for the Petfinder published API."
|
12
|
+
spec.summary = "Ruby gem wrapper for the Petfinder API."
|
13
|
+
spec.homepage = "http://github.com/ehutzelman/petfinder"
|
14
|
+
spec.license = "MIT"
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
s.add_development_dependency "fakeweb"
|
19
|
-
s.add_development_dependency "bundler"
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
s.extra_rdoc_files = %w[README.rdoc LICENSE]
|
30
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
21
|
+
spec.add_dependency "excon"
|
22
|
+
spec.add_dependency "nokogiri"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "webmock"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
31
28
|
end
|
@@ -1,44 +1,28 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Petfinder::Client do
|
4
4
|
before do
|
5
5
|
@client = Petfinder::Client.new('1234567', 'mysekrit')
|
6
6
|
end
|
7
7
|
|
8
|
-
it "should get a random pet" do
|
9
|
-
stub_get("http://api.petfinder.com/pet.getRandom?key=1234567&output=full", "pet.xml")
|
10
|
-
pet = @client.random_pet
|
11
|
-
pet.name.should == 'Charlie'
|
12
|
-
end
|
13
|
-
|
14
8
|
it "should get a specific pet by id" do
|
15
9
|
stub_get("http://api.petfinder.com/pet.get?key=1234567&id=123", "pet.xml")
|
16
10
|
pet = @client.pet(123)
|
17
11
|
pet.name.should == 'Charlie'
|
18
12
|
end
|
19
|
-
|
13
|
+
|
14
|
+
it "should get a random pet" do
|
15
|
+
stub_get("http://api.petfinder.com/pet.getRandom?key=1234567&output=full", "pet.xml")
|
16
|
+
pet = @client.random_pet
|
17
|
+
pet.name.should == 'Charlie'
|
18
|
+
end
|
19
|
+
|
20
20
|
it "should find pets matching a query" do
|
21
21
|
stub_get("http://api.petfinder.com/pet.find?key=1234567&animal=dog&location=77007", "pet_list.xml")
|
22
22
|
pets = @client.find_pets('dog', '77007')
|
23
|
-
pets.first.name.should == 'Petey'
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "retrieving a pet" do
|
27
|
-
before do
|
28
|
-
stub_get("http://api.petfinder.com/pet.getRandom?key=1234567&output=full", "pet.xml")
|
29
|
-
@pet = @client.random_pet
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should hide photos collection" do
|
33
|
-
@pet.should_not respond_to(:photos)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should reorganize photos for pet as pictures" do
|
37
|
-
@pet.pictures[0].thumbnail.should == 'http://photocache.petfinder.com/fotos/IL173/IL173.10141994-1-pnt.jpg'
|
38
|
-
@pet.pictures[1].large.should == 'http://photocache.petfinder.com/fotos/IL173/IL173.10141994-2-x.jpg'
|
39
|
-
end
|
23
|
+
pets.first.name.should == 'Petey'
|
40
24
|
end
|
41
|
-
|
25
|
+
|
42
26
|
it "should get the list of breeds for the given animal type" do
|
43
27
|
stub_get("http://api.petfinder.com/breed.list?key=1234567&animal=horse", "breed_list.xml")
|
44
28
|
breeds = @client.breeds('horse')
|
@@ -62,17 +46,17 @@ describe Petfinder::Client do
|
|
62
46
|
shelters = @client.find_shelters_by_breed('horse', 'arabian')
|
63
47
|
shelters.first.name.should == 'Pup Squad Animal Rescue'
|
64
48
|
end
|
65
|
-
|
49
|
+
|
66
50
|
it "should get the list of pets available for the given shelter" do
|
67
51
|
stub_get("http://api.petfinder.com/shelter.getPets?key=1234567&id=123", "pet_list.xml")
|
68
52
|
pets = @client.shelter_pets(123)
|
69
|
-
pets.first.name.should == 'Petey'
|
53
|
+
pets.first.name.should == 'Petey'
|
70
54
|
end
|
71
|
-
|
55
|
+
|
72
56
|
it "should get an authorization token" do
|
73
57
|
digest = @client.send(:digest_key_and_secret)
|
74
58
|
stub_get("http://api.petfinder.com/auth.getToken?key=1234567&sig=#{digest}", "auth.xml")
|
75
59
|
@client.token.should == '39038a000f404335d90bab019c0c7e2d'
|
76
60
|
end
|
77
|
-
|
78
|
-
end
|
61
|
+
|
62
|
+
end
|
data/spec/fixtures/pet.xml
CHANGED
@@ -25,8 +25,7 @@
|
|
25
25
|
<option>hasShots</option>
|
26
26
|
<option>altered</option>
|
27
27
|
</options>
|
28
|
-
<description><![CDATA[
|
29
|
-
<br/><a href="http://www.petfinder.com/petdetail/10141994">View this pet on Petfinder.com</a>
|
28
|
+
<description><![CDATA[<div><p><br />Tucker is an absolutely handsome seal point siamese boy who was surrendered along with his sister, Tupence. Both cats are front paw declawed. Tupence and Tucker have been together for 9 years so they'd prefer to be adopted together. (but if 2 wonderful homes come along we might consider seperation) Both cats have a wonderful demeanor and would love to be in a home where there's lots of awesome places to take cat naps! If interested in adopting Tucker please fill out an adoption application to get the ball rolling, then our adoption coordinator will call you to set up a time to meet the cat(s). <br /><br /><strong>TUCKER is in a foster home, call to learn how to meet him. <br /></strong><br />To fill out an adoption or foster application please visit our website at: <a href=\"http://www.alleganshelter.com\" onclick=\"pageTracker._trackPageview('outbound/petnoteslinks');\" target=\"_blank\">http://www.alleganshelter.com</a><br /></div>
|
30
29
|
]]></description>
|
31
30
|
<lastUpdate>2010-04-07T13:43:33Z</lastUpdate>
|
32
31
|
<status>A</status>
|
@@ -45,4 +44,4 @@
|
|
45
44
|
</photos>
|
46
45
|
</media>
|
47
46
|
</pet>
|
48
|
-
</petfinder>
|
47
|
+
</petfinder>
|
data/spec/fixtures/shelter.xml
CHANGED
@@ -12,15 +12,15 @@
|
|
12
12
|
<id>TX1356</id>
|
13
13
|
<name>Lucky Dog Rescue</name>
|
14
14
|
<address1>P.O. Box 56512</address1>
|
15
|
-
<address2
|
15
|
+
<address2>Apt 25</address2>
|
16
16
|
<city>Houston</city>
|
17
17
|
<state>TX</state>
|
18
18
|
<zip>77019</zip>
|
19
|
-
<country
|
19
|
+
<country>USA</country>
|
20
20
|
<latitude>29.75239944</latitude>
|
21
21
|
<longitude>-95.40170288</longitude>
|
22
|
-
<phone
|
23
|
-
<fax
|
22
|
+
<phone>555-555-5555</phone>
|
23
|
+
<fax>666-666-6666</fax>
|
24
24
|
<email>millicentgerdes@gmail.com</email>
|
25
25
|
</shelter>
|
26
|
-
</petfinder>
|
26
|
+
</petfinder>
|
data/spec/pet_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Petfinder::Pet do
|
4
|
+
before do
|
5
|
+
@pet = Petfinder::Pet.new(Nokogiri::XML(fixture_file('pet.xml')))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should populate collection of photos" do
|
9
|
+
[:large, :medium, :small, :thumbnail, :tiny].each do |size|
|
10
|
+
@pet.photos[0].send(size).should =~ /http:\/\/photocache.petfinder.com\/fotos\/IL173\/*./
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should populate attributes of pet" do
|
15
|
+
[:id, :name, :animal, :mix, :age, :shelter_id, :shelter_pet_id, :sex, :size, :description, :last_update, :status].each do |attr|
|
16
|
+
@pet.send(attr).should_not == ""
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should populate array of breeds" do
|
21
|
+
@pet.breeds.should include("Domestic Short Hair-black")
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should populate array of options" do
|
26
|
+
@pet.options.should include("hasShots", "altered")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return a sanitized version of the description" do
|
30
|
+
@pet.description_sanitized.should_not =~ /<div>/
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should populate multiple pet objects" do
|
34
|
+
pets = Petfinder::Pet.multiple(Nokogiri::XML(fixture_file('pet_list.xml')))
|
35
|
+
pets.should have(25).items
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Petfinder::Pet do
|
4
|
+
before do
|
5
|
+
@shelter = Petfinder::Shelter.new(Nokogiri::XML(fixture_file('shelter.xml')))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should populate attributes of shelter" do
|
9
|
+
[:id, :name, :address1, :address2, :city, :state, :zip, :country, :latitude, :longitude, :phone, :fax, :email].each do |attr|
|
10
|
+
@shelter.send(attr).should_not == ""
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should populate multiple shelter objects" do
|
15
|
+
shelters = Petfinder::Shelter.multiple(Nokogiri::XML(fixture_file('shelter_list.xml')))
|
16
|
+
shelters.should have(25).items
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
1
|
require 'petfinder'
|
6
2
|
require 'rspec'
|
7
|
-
require '
|
3
|
+
require 'webmock/rspec'
|
8
4
|
|
9
5
|
def fixture_file(filename)
|
10
6
|
File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
|
11
7
|
end
|
12
8
|
|
13
|
-
def stub_get(url, filename
|
14
|
-
|
15
|
-
|
16
|
-
FakeWeb.register_uri(:get, url, opts)
|
17
|
-
end
|
9
|
+
def stub_get(url, filename)
|
10
|
+
stub_request(:get, url).to_return(body: fixture_file(filename), status: 200)
|
11
|
+
end
|
metadata
CHANGED
@@ -1,94 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: petfinder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Eric Hutzelman
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-10-04 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
14
|
+
name: excon
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
28
|
+
name: nokogiri
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
56
|
+
name: webmock
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
76
81
|
- !ruby/object:Gem::Version
|
77
82
|
version: '0'
|
78
83
|
- !ruby/object:Gem::Dependency
|
79
84
|
name: bundler
|
80
85
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
86
|
requirements:
|
83
|
-
- -
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
84
102
|
- !ruby/object:Gem::Version
|
85
103
|
version: '0'
|
86
104
|
type: :development
|
87
105
|
prerelease: false
|
88
106
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
107
|
requirements:
|
91
|
-
- -
|
108
|
+
- - '>='
|
92
109
|
- !ruby/object:Gem::Version
|
93
110
|
version: '0'
|
94
111
|
description: REST client for the Petfinder published API.
|
@@ -96,16 +113,15 @@ email:
|
|
96
113
|
- ehutzelman@gmail.com
|
97
114
|
executables: []
|
98
115
|
extensions: []
|
99
|
-
extra_rdoc_files:
|
100
|
-
- README.rdoc
|
101
|
-
- LICENSE
|
116
|
+
extra_rdoc_files: []
|
102
117
|
files:
|
103
118
|
- .gitignore
|
104
119
|
- .rspec
|
120
|
+
- CHANGELOG.md
|
105
121
|
- Gemfile
|
106
122
|
- Gemfile.lock
|
107
|
-
- LICENSE
|
108
|
-
- README.
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
109
125
|
- Rakefile
|
110
126
|
- lib/petfinder.rb
|
111
127
|
- lib/petfinder/auth.rb
|
@@ -114,46 +130,50 @@ files:
|
|
114
130
|
- lib/petfinder/pet.rb
|
115
131
|
- lib/petfinder/shelter.rb
|
116
132
|
- lib/petfinder/version.rb
|
133
|
+
- lib/petfinder/xml_mapper.rb
|
117
134
|
- petfinder.gemspec
|
135
|
+
- spec/client_spec.rb
|
118
136
|
- spec/fixtures/auth.xml
|
119
137
|
- spec/fixtures/breed_list.xml
|
120
138
|
- spec/fixtures/pet.xml
|
121
139
|
- spec/fixtures/pet_list.xml
|
122
140
|
- spec/fixtures/shelter.xml
|
123
141
|
- spec/fixtures/shelter_list.xml
|
124
|
-
- spec/
|
142
|
+
- spec/pet_spec.rb
|
143
|
+
- spec/shelter_spec.rb
|
125
144
|
- spec/spec_helper.rb
|
126
145
|
homepage: http://github.com/ehutzelman/petfinder
|
127
|
-
licenses:
|
146
|
+
licenses:
|
147
|
+
- MIT
|
148
|
+
metadata: {}
|
128
149
|
post_install_message:
|
129
|
-
rdoc_options:
|
130
|
-
- --charset=UTF-8
|
150
|
+
rdoc_options: []
|
131
151
|
require_paths:
|
132
152
|
- lib
|
133
153
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
154
|
requirements:
|
136
|
-
- -
|
155
|
+
- - '>='
|
137
156
|
- !ruby/object:Gem::Version
|
138
157
|
version: '0'
|
139
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
159
|
requirements:
|
142
|
-
- -
|
160
|
+
- - '>='
|
143
161
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
162
|
+
version: '0'
|
145
163
|
requirements: []
|
146
|
-
rubyforge_project:
|
147
|
-
rubygems_version: 1.
|
164
|
+
rubyforge_project:
|
165
|
+
rubygems_version: 2.1.5
|
148
166
|
signing_key:
|
149
|
-
specification_version:
|
167
|
+
specification_version: 4
|
150
168
|
summary: Ruby gem wrapper for the Petfinder API.
|
151
169
|
test_files:
|
170
|
+
- spec/client_spec.rb
|
152
171
|
- spec/fixtures/auth.xml
|
153
172
|
- spec/fixtures/breed_list.xml
|
154
173
|
- spec/fixtures/pet.xml
|
155
174
|
- spec/fixtures/pet_list.xml
|
156
175
|
- spec/fixtures/shelter.xml
|
157
176
|
- spec/fixtures/shelter_list.xml
|
158
|
-
- spec/
|
177
|
+
- spec/pet_spec.rb
|
178
|
+
- spec/shelter_spec.rb
|
159
179
|
- spec/spec_helper.rb
|
data/README.rdoc
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
= Petfinder
|
2
|
-
|
3
|
-
Ruby gem wrapper for the {Petfinder API}[http://www.petfinder.com/developers/api-docs].
|
4
|
-
|
5
|
-
== Installation
|
6
|
-
|
7
|
-
sudo gem install petfinder
|
8
|
-
|
9
|
-
== Get your API key
|
10
|
-
|
11
|
-
Get your Petfinder API key at: http://www.petfinder.com/developers/api-key
|
12
|
-
|
13
|
-
== Usage
|
14
|
-
|
15
|
-
=== Instantiate a client
|
16
|
-
|
17
|
-
petfinder = Petfinder::Client.new('your_api_key', 'your_api_secret')
|
18
|
-
|
19
|
-
=== or configure once
|
20
|
-
|
21
|
-
Petfinder.configure do |config|
|
22
|
-
config.api_key = 'your_api_key'
|
23
|
-
config.api_secret = 'your_api_secret'
|
24
|
-
end
|
25
|
-
petfinder = Petfinder::Client.new
|
26
|
-
|
27
|
-
== Examples
|
28
|
-
|
29
|
-
==== Return a list of dogs in the "90210" zip code
|
30
|
-
|
31
|
-
pets = petfinder.find_pets('dog', '90210')
|
32
|
-
pets.count
|
33
|
-
# => "25"
|
34
|
-
|
35
|
-
pets.first.name
|
36
|
-
# => "Petey"
|
37
|
-
|
38
|
-
pets.first.shelterid
|
39
|
-
# => "CA123"
|
40
|
-
|
41
|
-
==== Return information about the shelter with id "CA123"
|
42
|
-
|
43
|
-
shelter = petfinder.shelter('CA123')
|
44
|
-
shelter.name
|
45
|
-
# => "Melrose Place SPCA"
|
46
|
-
|
47
|
-
== TODO
|
48
|
-
|
49
|
-
* Implement use of security token when Petfinder requires it
|
50
|
-
|
51
|
-
== Note on Patches/Pull Requests
|
52
|
-
|
53
|
-
* Fork the project.
|
54
|
-
* Make your feature addition or bug fix.
|
55
|
-
* Add tests for it. This is important so I don't break it in a
|
56
|
-
future version unintentionally.
|
57
|
-
* Commit, do not mess with rakefile, version, or history.
|
58
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
59
|
-
* Send me a pull request. Bonus points for topic branches.
|
60
|
-
|
61
|
-
== Copyright
|
62
|
-
|
63
|
-
Copyright (c) 2010 Eric Hutzelman. See LICENSE for details.
|