govkit 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.4.0
data/govkit.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{govkit}
8
- s.version = "0.3.2"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Participatory Politics Foundation", "Srinivas Aki", "Carl Tashian"]
12
- s.date = %q{2010-09-16}
12
+ s.date = %q{2010-09-29}
13
13
  s.description = %q{Govkit lets you quickly get encapsulated Ruby objects for common open government APIs. We're starting with Sunlight's Open States API and the Project Vote Smart API.}
14
14
  s.email = %q{carl@ppolitics.org}
15
15
  s.extra_rdoc_files = [
@@ -9,13 +9,17 @@ module GovKit
9
9
 
10
10
  e = doc.search("//error")
11
11
 
12
- # API Key invalid
12
+ # Deal with whatever error comes back
13
13
  if e.size > 0
14
14
  raise case e.first.attributes['code']
15
15
  when "100"
16
16
  GovKit::NotAuthorized
17
17
  when "300"
18
18
  GovKit::InvalidRequest
19
+ when "200"
20
+ GovKit::ResourceNotFound
21
+ else
22
+ GovKit::InvalidRequest
19
23
  end, e.first.attributes['text']
20
24
  end
21
25
 
@@ -42,7 +46,7 @@ module GovKit
42
46
  end
43
47
  end
44
48
 
45
- instantiate_collection(result)
49
+ parse(result)
46
50
  end
47
51
  end
48
52
 
@@ -61,7 +65,7 @@ module GovKit
61
65
  contribution.attributes.to_hash
62
66
  end
63
67
  end
64
- instantiate_collection(result)
68
+ parse(result)
65
69
  end
66
70
 
67
71
  def self.top(nimsp_id)
@@ -71,7 +75,7 @@ module GovKit
71
75
  contribution.attributes.to_hash
72
76
  end
73
77
 
74
- instantiate_collection(result)
78
+ parse(result)
75
79
  end
76
80
  end
77
81
 
@@ -83,7 +87,7 @@ module GovKit
83
87
  contribution.attributes.to_hash
84
88
  end
85
89
 
86
- instantiate_collection(result)
90
+ parse(result)
87
91
  end
88
92
  end
89
93
 
@@ -95,7 +99,7 @@ module GovKit
95
99
  contribution.attributes.to_hash
96
100
  end
97
101
 
98
- instantiate_collection(result)
102
+ parse(result)
99
103
  end
100
104
  end
101
105
 
@@ -107,7 +111,7 @@ module GovKit
107
111
  contribution.attributes.to_hash
108
112
  end
109
113
 
110
- instantiate_collection(result)
114
+ parse(result)
111
115
  end
112
116
  end
113
117
  end
@@ -13,53 +13,58 @@ module GovKit
13
13
  class State < OpenStatesResource
14
14
  def self.find_by_abbreviation(abbreviation)
15
15
  response = get("/metadata/#{abbreviation}/")
16
- instantiate_record(response)
16
+ parse(response)
17
17
  end
18
18
  end
19
19
 
20
20
  class Bill < OpenStatesResource
21
- # http://openstates.sunlightlabs.com/api/v1/ca/20092010/lower/bills/AB667/
22
- def self.find(state_abbrev, session, chamber, bill_id)
23
- response = get("/#{state_abbrev}/#{session}/#{chamber}/bills/#{bill_id}/")
24
- instantiate_record(response)
25
- end
21
+ # http://openstates.sunlightlabs.com/api/v1/bills/ca/20092010/AB667/
22
+ class << self
23
+ def find(state_abbrev, session, bill_id, chamber = '')
24
+ response = get("/bills/#{state_abbrev}/#{session}/#{chamber.blank? ? '' : chamber + '/'}#{bill_id}/")
25
+ parse(response)
26
+ end
26
27
 
27
- def self.search(query, options = {})
28
- response = get('/bills/', :query => {:q => query}.merge(options))
29
- instantiate_collection(response)
30
- end
28
+ def search(query, options = {})
29
+ response = get('/bills/', :query => {:q => query}.merge(options))
30
+ parse(response)
31
+ end
31
32
 
32
- def self.latest(updated_since, state_abbrev)
33
- response = get('/bills/latest/', :query => {:updated_since => updated_since, :state => state_abbrev})
34
- instantiate_collection(response)
33
+ def latest(updated_since, state_abbrev)
34
+ response = get('/bills/latest/', :query => {:updated_since => updated_since, :state => state_abbrev})
35
+ parse(response)
36
+ end
35
37
  end
36
38
  end
37
39
 
38
40
  class Legislator < OpenStatesResource
39
- def self.find(legislator_id)
40
- response = get("/legislators/#{legislator_id}/")
41
- instantiate_record(response)
42
- end
41
+ class << self
42
+ def find(legislator_id)
43
+ response = get("/legislators/#{legislator_id}/")
44
+ parse(response)
45
+ end
43
46
 
44
- def self.search(options = {})
45
- response = get('/legislators/', :query => options)
46
- instantiate_collection(response)
47
+ def search(options = {})
48
+ response = get('/legislators/', :query => options)
49
+ parse(response)
50
+ end
47
51
  end
48
52
  end
49
53
 
50
54
  class Committee < OpenStatesResource
51
- def self.find(committee_id)
52
- response = get("/committees/#{committee_id}/")
53
- instantiate_record(response)
54
- end
55
+ class << self
56
+ def find(committee_id)
57
+ response = get("/committees/#{committee_id}/")
58
+ parse(response)
59
+ end
55
60
 
56
- def self.search(options = {})
57
- response = get('/committees/', :query => options)
58
- instantiate_collection(response)
61
+ def search(options = {})
62
+ response = get('/committees/', :query => options)
63
+ parse(response)
64
+ end
59
65
  end
60
66
  end
61
67
 
62
-
63
68
  class Role < OpenStatesResource; end
64
69
 
65
70
  class Sponsor < OpenStatesResource; end
@@ -75,7 +80,7 @@ module GovKit
75
80
  class Vote < OpenStatesResource
76
81
  def self.find(vote_id)
77
82
  response = get("/votes/#{vote_id}/")
78
- instantiate_record(response)
83
+ parse(response)
79
84
  end
80
85
  end
81
86
  end
@@ -9,35 +9,52 @@ module GovKit
9
9
  def initialize(attributes = {})
10
10
  @attributes = {}
11
11
  @raw_response = attributes
12
+
12
13
  unload(attributes)
13
14
  end
14
15
 
15
16
  class << self
16
- def instantiate_record(record)
17
- raise ResourceNotFound, "Resource not found" unless !record.blank?
18
- new(record)
19
- end
20
-
21
- def instantiate_collection(collection)
22
- collection.collect! { |record| instantiate_record(record) }
23
- end
17
+ def parse(response)
18
+ # This method handles the basic responses we might get back from
19
+ # Net::HTTP. But if a service returns something other than a 404 when an object is not found,
20
+ # you'll need to handle that in the subclass.
21
+
22
+ raise ResourceNotFound, "Resource not found" unless !response.blank?
24
23
 
25
- def parse(json)
26
- instantiate(json)
24
+ if response.class == HTTParty::Response
25
+ case response.response
26
+ when Net::HTTPNotFound
27
+ raise ResourceNotFound, "404 Not Found"
28
+ when Net::HTTPUnauthorized
29
+ raise NotAuthorized, "401 Not Authorized; have you set up your API key?"
30
+ end
31
+ end
32
+
33
+ instantiate(response)
27
34
  end
28
35
 
29
36
  def instantiate(record)
30
37
  case record
31
38
  when Array
32
39
  instantiate_collection(record)
33
- when Hash
40
+ else
34
41
  instantiate_record(record)
35
42
  end
36
43
  end
44
+
45
+ def instantiate_record(record)
46
+ new(record)
47
+ end
48
+
49
+ def instantiate_collection(collection)
50
+ collection.collect! { |record| instantiate_record(record) }
51
+ end
52
+
37
53
  end
38
54
 
39
55
  def unload(attributes)
40
56
  raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
57
+
41
58
  attributes.each do |key, value|
42
59
  @attributes[key.to_s] =
43
60
  case value
@@ -74,7 +91,7 @@ module GovKit
74
91
  end
75
92
 
76
93
  def find_or_create_resource_for(name)
77
- resource_name = name.to_s.gsub(/^[_+]/,'').gsub(/^(\d)/, "n#{$1}").gsub(/\s/, '').camelize
94
+ resource_name = name.to_s.gsub(/^(\d)/, "n#{$1}").gsub(/\s/, '').camelize
78
95
  if self.class.parents.size > 1
79
96
  find_resource_in_modules(resource_name, self.class.parents)
80
97
  else
@@ -10,7 +10,11 @@ module GovKit
10
10
  response = get("/wiki/#{query}")
11
11
  doc = Hpricot(Iconv.conv('utf-8//IGNORE', 'gb2312', response))
12
12
 
13
- doc.at('#bodyContent > table.toc').previous_sibling.inner_html.scrub rescue ""
13
+ bio = doc.at('#bodyContent > p:first').inner_html.scrub rescue ""
14
+
15
+ return "" if bio =~ /may refer to:/
16
+
17
+ bio
14
18
  end
15
19
 
16
20
  def self.make_request(host, path)
@@ -8,32 +8,32 @@ module GovKit
8
8
  class Address < VoteSmartResource
9
9
  def self.find(candidate_id)
10
10
  response = get("/Address.getOffice", :query => {"candidateId" => candidate_id})
11
- instantiate_record(response['address'])
11
+ parse(response['address'])
12
12
  end
13
13
  end
14
14
 
15
15
  class WebAddress < VoteSmartResource
16
16
  def self.find(candidate_id)
17
17
  response = get("/Address.getOfficeWebAddress", :query => {"candidateId" => candidate_id})
18
- instantiate_record(response['webaddress'])
18
+ parse(response['webaddress'])
19
19
  end
20
20
  end
21
21
 
22
22
  class Bio < VoteSmartResource
23
23
  def self.find(candidate_id)
24
24
  response = get("/CandidateBio.getBio", :query => {"candidateId" => candidate_id})
25
-
26
- # Sometimes this returns nil if no one is found!
27
- raise(ResourceNotFound, 'Could not find bio for candidate ' + candidate_id.to_s) if response.blank? || response['error']
28
25
 
29
- instantiate_record(response['bio']['candidate'])
26
+ # Sometimes VoteSmart returns nil if no one is found!
27
+ raise(ResourceNotFound, 'Could not find bio for candidate') if response.blank? || response['error']
28
+
29
+ parse(response['bio']['candidate'])
30
30
  end
31
31
  end
32
32
 
33
33
  class Category < VoteSmartResource
34
34
  def self.list(state_id)
35
35
  response = get("/Rating.getCategories", :query => {"stateId" => state_id})
36
- instantiate(response['categories']['category'])
36
+ parse(response['categories']['category'])
37
37
  end
38
38
  end
39
39
 
@@ -41,14 +41,14 @@ module GovKit
41
41
  def self.list(category_id, state_id)
42
42
  response = get("/Rating.getSigList", :query => {"categoryId" => category_id, "stateId" => state_id})
43
43
 
44
- raise(ResourceNotFound, response['error']['errorMessage']) if response['error'] && response['error']['errorMessage'] == 'No SIGs fit this criteria.'
44
+ raise(ResourceNotFound, response['error']['errorMessage']) if response['error']
45
45
 
46
- instantiate(response['sigs']['sig'])
46
+ parse(response['sigs']['sig'])
47
47
  end
48
48
 
49
49
  def self.find(sig_id)
50
50
  response = get("/Rating.getSig", :query => {"sigId" => sig_id})
51
- instantiate(response['sig'])
51
+ parse(response['sig'])
52
52
  end
53
53
  end
54
54
 
@@ -56,35 +56,35 @@ module GovKit
56
56
  def self.find(candidate_id, sig_id)
57
57
  response = get("/Rating.getCandidateRating", :query => {"candidateId" => candidate_id, "sigId" => sig_id})
58
58
 
59
- raise(ResourceNotFound, response['error']['errorMessage']) if response['error'] && response['error']['errorMessage'] == 'No Ratings fit this criteria.'
59
+ raise(ResourceNotFound, response['error']['errorMessage']) if response['error']
60
60
 
61
- instantiate(response['candidateRating']['rating'])
61
+ parse(response['candidateRating']['rating'])
62
62
  end
63
63
  end
64
64
 
65
65
  class Bill < VoteSmartResource
66
66
  def self.find(bill_id)
67
67
  response = get('/Votes.getBill', :query => {'billId' => bill_id})
68
- instantiate_record(response['bill'])
68
+ parse(response['bill'])
69
69
  end
70
70
 
71
71
  def self.find_by_year_and_state(year, state_abbrev)
72
72
  response = get('/Votes.getBillsByYearState', :query => {'year' => year, 'stateId' => state_abbrev})
73
73
  raise(ResourceNotFound, response['error']['errorMessage']) if response['error'] && response['error']['errorMessage'] == 'No bills for this state and year.'
74
74
 
75
- instantiate_record(response['bills'])
75
+ parse(response['bills'])
76
76
  end
77
77
 
78
78
  def self.find_recent_by_state(state_abbrev)
79
79
  response = get('/Votes.getBillsByStateRecent', :query => {'stateId' => state_abbrev})
80
- instantiate_record(response['bills'])
80
+ parse(response['bills'])
81
81
  end
82
82
 
83
83
  def self.find_by_category_and_year_and_state(category_id, year, state_abbrev = nil)
84
84
  response = get('/Votes.getBillsByCategoryYearState', :query => {'stateId' => state_abbrev, 'year' => year, 'categoryId' => category_id})
85
85
  raise(ResourceNotFound, response['error']['errorMessage']) if response['error'] && response['error']['errorMessage'] == 'No bills for this state, category, and year.'
86
86
 
87
- instantiate_record(response['bills'])
87
+ parse(response['bills'])
88
88
  end
89
89
 
90
90
  def self.find_by_category_and_year(category_id, year)
@@ -95,7 +95,7 @@ module GovKit
95
95
  class BillCategory < VoteSmartResource
96
96
  def self.find(year, state_abbrev)
97
97
  response = get("/Votes.getCategories", :query => {'year' => year, 'stateId' => state_abbrev})
98
- instantiate(response['categories']['category'])
98
+ parse(response['categories']['category'])
99
99
  end
100
100
  end
101
101
 
@@ -106,13 +106,13 @@ module GovKit
106
106
  # This method maps to Committee.getCommitteesByTypeState()
107
107
  def self.find_by_type_and_state(type_id, state_abbrev)
108
108
  response = get('/Committee.getCommitteesByTypeState', :query => {'typeId' => type_id, 'stateId' => state_abbrev})
109
- instantiate_record(response['committees'])
109
+ parse(response['committees'])
110
110
  end
111
111
 
112
112
  # Find a committee by VoteSmart committeeId. Maps to Committee.getCommittee()
113
113
  def self.find(committee_id)
114
114
  response = get('/Committee.getCommittee', :query => {'committeeId' => committee_id})
115
- instantiate_record(response['committee'])
115
+ parse(response['committee'])
116
116
  end
117
117
  end
118
118
  end
data/lib/gov_kit.rb CHANGED
@@ -21,16 +21,6 @@ module GovKit
21
21
  end
22
22
 
23
23
  class GovKitError < StandardError
24
- attr_reader :response
25
-
26
- def initialize(response, message = nil)
27
- @response = response
28
- @message = message
29
- end
30
-
31
- def to_s
32
- "Failed with #{response.code if response.respond_to?(:code)} #{response.message if response.respond_to?(:message)}"
33
- end
34
24
  end
35
25
 
36
26
  class NotAuthorized < GovKitError; end
@@ -7,7 +7,7 @@ module GovKit::OpenStates
7
7
 
8
8
  urls = [
9
9
  ['/ca/\?', 'state.response'],
10
- ['/ca/20092010/lower/bills/AB667/', 'bill.response'],
10
+ ['/bills/ca/20092010/AB667/', 'bill.response'],
11
11
  ['/bills/search/\?', 'bill_query.response'],
12
12
  ['/bills/latest/\?', 'bill_query.response'],
13
13
  ['/legislators/2462/\?', 'legislator.response'],
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 2
9
- version: 0.3.2
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Participatory Politics Foundation
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-09-16 00:00:00 -07:00
19
+ date: 2010-09-29 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency