petfinder 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -5,4 +5,5 @@ tmp/*
5
5
  *.gem
6
6
  .bundle
7
7
  .rvmrc
8
- rdoc/*
8
+ rdoc/*
9
+ bin
@@ -0,0 +1,6 @@
1
+ 1.0.0
2
+ -----
3
+ * New gem dependencies: nokogiri and excon
4
+ * `Pet#pictures` is now `Pet#photos`
5
+ * `Pet#description_sanitized` offers html-free description compared to `Pet#description`
6
+ * Cleaned up internals
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ gemspec
@@ -1,37 +1,49 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- petfinder (0.1.2)
5
- happymapper
6
- httparty
4
+ petfinder (0.1.3)
5
+ excon
6
+ nokogiri
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
- diff-lcs (1.1.3)
12
- fakeweb (1.3.0)
13
- happymapper (0.4.0)
14
- libxml-ruby (~> 2.0)
15
- httparty (0.9.0)
16
- multi_json (~> 1.0)
17
- multi_xml
18
- libxml-ruby (2.3.3)
19
- multi_json (1.3.6)
20
- multi_xml (0.5.1)
21
- rspec (2.11.0)
22
- rspec-core (~> 2.11.0)
23
- rspec-expectations (~> 2.11.0)
24
- rspec-mocks (~> 2.11.0)
25
- rspec-core (2.11.1)
26
- rspec-expectations (2.11.3)
27
- diff-lcs (~> 1.1.3)
28
- rspec-mocks (2.11.2)
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
@@ -1,4 +1,6 @@
1
- Copyright (c) Eric Hutzelman
1
+ Copyright (c) 2013 Eric Hutzelman
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
@@ -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 'rake'
2
- require 'rspec'
3
- require 'rspec/core/rake_task'
4
- require 'bundler'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
5
3
 
6
- Bundler::GemHelper.install_tasks
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
@@ -1,8 +1,9 @@
1
- require 'httparty'
2
- require 'happymapper'
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 PetfinderError < StandardError; end
14
+ class Error < StandardError; end
14
15
 
15
16
  class << self
16
17
  attr_accessor :api_key, :api_secret
@@ -1,13 +1,12 @@
1
1
  module Petfinder
2
-
3
2
  class Auth
4
- include HappyMapper
3
+ extend XmlMapper
5
4
 
6
- tag 'auth'
7
- element :key, String
8
- element :token, String
9
- element :expires, String
10
- element :expiresString, String
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
@@ -1,10 +1,13 @@
1
1
  module Petfinder
2
-
3
2
  class Breeds
4
- include HappyMapper
5
- tag 'breeds'
6
3
 
7
- has_many :breeds, String, :tag => 'breed'
8
- end
4
+ def initialize(xml)
5
+ @xml = xml
6
+ end
9
7
 
10
- end
8
+ def breeds
9
+ @xml.xpath("//breeds/breed").map(&:text)
10
+ end
11
+
12
+ end
13
+ end
@@ -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", :query => {:animal => animal_type})
18
- Breeds.parse(response, :single => true).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", :query => {:id => id})
23
- Pet.parse(response, :single => true)
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", :query => query)
30
- Pet.parse(response, :single => true)
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", :query => query)
37
- Pet.parse(response)
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", :query => {:id => id})
42
- Shelter.parse(response, :single => true)
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", :query => query)
49
- Shelter.parse(response)
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", :query => query)
56
- Shelter.parse(response)
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", :query => query)
63
- Pet.parse(response)
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", :query => {:sig => digest_key_and_secret})
68
- Auth.parse(response, :single => true).token
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
- response = self.class.get(uri, options)
80
- raise_errors(response)
81
- response.body
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 raise_errors(response)
85
- if response.code.to_i == 200
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
- end
89
+ def petfinder_status_message
90
+ @xml.xpath("//header/status/message").text
91
+ end
94
92
 
93
+ end
95
94
  end
@@ -1,77 +1,72 @@
1
1
  module Petfinder
2
-
3
- class Photo
4
- include HappyMapper
2
+ class Pet
3
+ extend XmlMapper
5
4
 
6
- tag 'photo'
7
- attribute :id, String
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
- class Pet
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
- private :photos
10
+ def initialize(xml)
11
+ @xml = xml
12
+ end
34
13
 
35
- after_parse do |pet|
36
- pet.remove_link_from_description
37
- pet.consolidate_photos
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 remove_link_from_description
41
- self.description = description[0..description.index("\n") - 1] if description.index("\n")
19
+
20
+ def description_sanitized
21
+ Nokogiri::HTML(CGI.unescapeHTML(description)).content
42
22
  end
43
-
44
- def consolidate_photos
45
- @pictures = []
46
- photos.map {|photo| photo.id}.uniq.each do |id|
47
- @pictures << Picture.new(photos.select {|photo| photo.id == id})
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
- class Picture
53
- attr_reader :large, :medium, :small, :thumbnail, :tiny
54
-
55
- def initialize(photos)
56
- photos.each do |photo|
57
- case photo.size
58
- when "x"
59
- @large = photo.url
60
- when "pn"
61
- @medium = photo.url
62
- when "fpm"
63
- @small = photo.url
64
- when "pnt"
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
@@ -1,22 +1,19 @@
1
1
  module Petfinder
2
-
3
2
  class Shelter
4
- include HappyMapper
3
+ extend XmlMapper
5
4
 
6
- tag 'shelter'
7
- element :id, String
8
- element :name, String
9
- element :address1, String
10
- element :address2, String
11
- element :city, String
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
@@ -1,3 +1,3 @@
1
1
  module Petfinder
2
- VERSION = "0.1.3"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -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
@@ -1,31 +1,28 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/petfinder/version", __FILE__)
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 |s|
5
- s.name = "petfinder"
6
- s.rubyforge_project = "petfinder"
7
- s.version = Petfinder::VERSION
8
- s.authors = ["Eric Hutzelman"]
9
- s.email = ["ehutzelman@gmail.com"]
10
- s.homepage = "http://github.com/ehutzelman/petfinder"
11
- s.summary = "Ruby gem wrapper for the Petfinder API."
12
- s.description = "REST client for the Petfinder published API."
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
- # Dependencies (pullled into Gemfile with "gemspec")
15
- s.add_dependency "happymapper"
16
- s.add_dependency "httparty"
17
- s.add_development_dependency "rspec"
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
- # Standard setup that should not need modification
22
- s.required_rubygems_version = ">= 1.3.6"
23
- s.platform = Gem::Platform::RUBY
24
- s.require_path = 'lib'
25
- s.files = `git ls-files`.split("\n")
26
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
- s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
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 File.expand_path(File.dirname(__FILE__) + '/spec_helper')
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
@@ -25,8 +25,7 @@
25
25
  <option>hasShots</option>
26
26
  <option>altered</option>
27
27
  </options>
28
- <description><![CDATA[Charlie is an outgoing cat who just loves to be around all the attention. He runs around and chases anything that moves. We think he'd be great in an active household!
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&nbsp;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&#39;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&#39;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(&#39;outbound/petnoteslinks&#39;);\" 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>
@@ -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>
@@ -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
+
@@ -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 'fakeweb'
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, options={})
14
- opts = {:body => fixture_file(filename)}.merge(options)
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.1.3
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: 2012-09-08 00:00:00.000000000 Z
11
+ date: 2013-10-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: happymapper
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: httparty
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: fakeweb
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.rdoc
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/petfinder_spec.rb
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: 1.3.6
162
+ version: '0'
145
163
  requirements: []
146
- rubyforge_project: petfinder
147
- rubygems_version: 1.8.24
164
+ rubyforge_project:
165
+ rubygems_version: 2.1.5
148
166
  signing_key:
149
- specification_version: 3
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/petfinder_spec.rb
177
+ - spec/pet_spec.rb
178
+ - spec/shelter_spec.rb
159
179
  - spec/spec_helper.rb
@@ -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.