pitosalas-govsdk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile ADDED
@@ -0,0 +1,43 @@
1
+ h1. Overview
2
+
3
+ THIS IS INCOMPLETE. I AM STILL WORKING ON IT
4
+
5
+ h1. LICENSE
6
+
7
+ GovSDK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
8
+
9
+ GovSDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10
+
11
+ You should have received a copy of the GNU General Public License along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
12
+
13
+ h1. INTRODUCTION
14
+
15
+ There are numerous 'government' APIs from various organizations. This SDK is a model for accessing all of them in a simple and consistent way. I will try to insulate users of this library from changes that might happen in one SDK or another, and where information is available from different sources, pick the source that seems to be the most authoritative at the time. The idea is that by using this API, the developer can stay blissfully unaware of the underlying APIs, as they evolve and change.
16
+
17
+ h1. KEY IDEAS
18
+
19
+ h2. API Keys
20
+
21
+ Unfortunately for now, each of the different services request that you use it's own API key to get permission to access them. So right off the bat, there's a way that the abstraction will leak. It can't be helped, the user of this library will have to acquire API keys for the relevant services and supply them.
22
+
23
+ h2. IDs
24
+
25
+ There are various IDs (identifiers assigned by some outside, real world agency to some outside real world thing) throughout the government. One you know is a drivers license number assigned to a person. Within our universe here are some of the IDs:
26
+
27
+ # CrpId - Center for responsible politics IDs for congress persons
28
+
29
+ In many cases none of the APIs furnish a useful ID.
30
+
31
+ h1. KEY CLASSES
32
+
33
+ # APIMgr - Parent class of each of the manager classes below
34
+ ## NewYorkTimesAPI - Class managing access to the New York Times API
35
+ ## SunlightAPI - Class managing access to the Sunlight API
36
+ ## SpenSecretsAPI - Class managing the OpenSecrets API
37
+ ### Methods: setAPIKey/getAPIKey
38
+
39
+ # CongressPerson - Work with legislators: senators and congressmen
40
+
41
+ #### self.find_by_name - return an array of CongressPersons
42
+ #### self.find_by_zipcode - return an array of CongressPersons
43
+ #### self.find_by_crp_id - return the CongressPerson with specified crp id
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 1
2
+ :patch: 2
3
3
  :major: 0
4
4
  :minor: 0
@@ -1,6 +1,6 @@
1
1
  =begin
2
- * Name: GovSDK
3
- * Description:
2
+ * Name: generic_api.rb
3
+ * Description: Logic that all API handlers for GovSdk have
4
4
  * Author: Pito Salas
5
5
  * Copyright: (c) R. Pito Salas and Associates, Inc.
6
6
  * Date: January 2009
@@ -20,4 +20,20 @@
20
20
 
21
21
  You should have received a copy of the GNU General Public License
22
22
  along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require "ruby-debug"
25
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
26
+ Debugger.settings[:autoeval] = 1
27
+ Debugger.start
28
+
23
29
  =end
30
+
31
+ require 'httparty'
32
+
33
+ class GenericApi
34
+
35
+ def initialized?
36
+ !@api_key.nil? || @api_key.kind_of?(String)
37
+ end
38
+
39
+ end
@@ -0,0 +1,56 @@
1
+ =begin
2
+ * Name: google_api.rb
3
+ * Description: Interfaces to Google APIs
4
+ * Author: Pito Salas
5
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
6
+ * Date: January 2009
7
+ * License: GPL
8
+
9
+ This file is part of GovSDK.
10
+
11
+ GovSDK is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ GovSDK is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require "ruby-debug"
25
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
26
+ Debugger.settings[:autoeval] = 1
27
+ Debugger.start
28
+
29
+ =end
30
+
31
+ require 'generic_api'
32
+
33
+ class GoogleApi < GenericApi
34
+ include HTTParty
35
+ GoogleApi.base_uri "http://ajax.googleapis.com/ajax/services"
36
+ format :json
37
+
38
+ # Simply declare and remember the API Key
39
+ def key=(key)
40
+ @api_key = key
41
+ GoogleApi.default_params(:key => key, :v => '1.0')
42
+ end
43
+
44
+ def lookup_feed_url(page_url)
45
+ begin
46
+ result = GoogleApi.get("/feed/lookup", :query => {:q => page_url})
47
+ rescue Net::HTTPServerException => exception
48
+ puts "\nEXCEPTION: from GoogleApi::lookup_feed_url: #{exception.response.body}"
49
+ return nil
50
+ end
51
+ resp = result["responseData"]
52
+ resp.nil? ? nil : resp["url"]
53
+ end
54
+
55
+ end
56
+
@@ -21,70 +21,22 @@
21
21
  You should have received a copy of the GNU General Public License
22
22
  along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
23
  =end
24
+ require 'generic_api'
24
25
 
25
- require 'rubygems'
26
- require 'httparty'
27
- require 'cgi'
28
- require 'net/http'
29
-
30
- #require "ruby-debug"
31
- #Debugger.settings[:autolist] = 1 # list nearby lines on stop
32
- #Debugger.settings[:autoeval] = 1
33
- #Debugger.start
34
-
35
- class GenericAPI
36
-
37
- def initialized?
38
- !@api_key.nil? || @api_key.kind_of?(String)
39
- end
40
-
41
- end
42
-
43
- # Control Access to Sunlight API.
44
-
45
- class Sunlight < GenericAPI
46
- include HTTParty
47
- Sunlight.base_uri "services.sunlightlabs.com"
48
-
49
- def legislators_search(params)
50
- result = Sunlight.get("/api/legislators.search", :query => {:name => params})
51
- result["response"]["results"]
52
- end
53
-
54
- # Simply declare and remember the API Key
55
- def key=(key)
56
- @api_key = key
57
- Sunlight.default_params :apikey => key
58
- end
59
-
60
- # Call any of the various legal Sunlight queries
61
- def legislators_get(params)
62
- begin
63
- result = Sunlight.get("/api/legislators.get", :query => params)
64
- result = result["response"]["legislator"]
65
- rescue Net::HTTPServerException => exception
66
- puts "EXCEPTION: from Sunlight - legislators.get: #{exception.response.body}"
67
- return nil
68
- end
69
- end
70
-
71
- end
72
-
73
- # Control Access to OpenSecrets API.
74
- class OpenSecrets < GenericAPI
26
+ class OpenSecretsApi < GenericApi
75
27
  include HTTParty
76
28
  base_uri "www.opensecrets.org/api/"
77
29
  format :xml
78
30
 
79
31
  def key=(key)
80
32
  @api_key = key
81
- OpenSecrets.default_params :apikey => key
33
+ OpenSecretsApi.default_params :apikey => key
82
34
  end
83
35
 
84
36
  def get_cand_info(method_name, crpID, cycle)
85
37
  query_hash = {:method => method_name}
86
38
  begin
87
- result = OpenSecrets.get("", :query => query_hash.merge({:cid => crpID, :cycle => cycle}))
39
+ result = OpenSecretsApi.get("", :query => query_hash.merge({:cid => crpID, :cycle => cycle}))
88
40
  rescue Net::HTTPServerException => exception
89
41
  puts "EXCEPTION: from Opensecrets! #{method_name}: #{exception.response.body}"
90
42
  return nil
@@ -117,8 +69,3 @@ class OpenSecrets < GenericAPI
117
69
  end
118
70
  end
119
71
 
120
-
121
-
122
-
123
-
124
-
@@ -0,0 +1,70 @@
1
+ =begin
2
+ * Name: GovSDK
3
+ * Description:
4
+ * Author: Pito Salas
5
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
6
+ * Date: January 2009
7
+ * License: GPL
8
+
9
+ This file is part of GovSDK.
10
+
11
+ GovSDK is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ GovSDK is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+ =end
24
+
25
+ require 'rubygems'
26
+ require 'cgi'
27
+ require 'net/http'
28
+ require 'generic_api'
29
+
30
+ # Control Access to Sunlight API.
31
+
32
+ class SunlightApi < GenericApi
33
+ include HTTParty
34
+ SunlightApi.base_uri "services.sunlightlabs.com"
35
+
36
+ def legislators_search(params)
37
+ result = SunlightApi.get("/api/legislators.search", :query => {:name => params})
38
+ result["response"]["results"]
39
+ end
40
+
41
+ # Simply declare and remember the API Key
42
+ def key=(key)
43
+ @api_key = key
44
+ SunlightApi.default_params :apikey => key
45
+ end
46
+
47
+ # Call Sunlight queries returning a single legislator matching a query
48
+ def legislators_get(params)
49
+ begin
50
+ result = SunlightApi.get("/api/legislators.get", :query => params)
51
+ result = result["response"]["legislator"]
52
+ rescue Net::HTTPServerException => exception
53
+ puts "EXCEPTION: from Sunlight - legislators.get: #{exception.response.body}"
54
+ return nil
55
+ end
56
+ end
57
+
58
+ # Sunlight query returning an array of matching legislators
59
+ def legislators_getlist(params)
60
+ begin
61
+ result = SunlightApi.get("/api/legislators.getList", :query => params)
62
+ result = result["response"]["legislators"]
63
+ rescue Net::HTTPServerException => exception
64
+ puts "EXCEPTION: from Sunlight - legislators.getList: #{exception.response.body}"
65
+ return nil
66
+ end
67
+ end
68
+
69
+
70
+ end
@@ -0,0 +1,68 @@
1
+ =begin
2
+ * Name: vote_smart_api.rb
3
+ * Description: GovSdk support for votesmart api
4
+ * Author: Pito Salas
5
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
6
+ * Date: January 2009
7
+ * License: GPL
8
+
9
+ This file is part of GovSDK.
10
+
11
+ GovSDK is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ GovSDK is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+ =end
24
+
25
+ require 'generic_api'
26
+
27
+ class VoteSmartApi < GenericApi
28
+ include HTTParty
29
+ VoteSmartApi.base_uri "http://api.votesmart.org"
30
+ format :xml
31
+
32
+ # Simply declare and remember the API Key
33
+ def key=(key)
34
+ @api_key = key
35
+ VoteSmartApi.default_params :key => key
36
+ end
37
+
38
+ def get_votesmart_candidate(method_name, query)
39
+ begin
40
+ result = VoteSmartApi.get(method_name, query)
41
+ rescue Net::HTTPServerException => exception
42
+ puts "\nEXCEPTION: from votesmart_api #{method_name}: #{exception.response.body}"
43
+ return nil
44
+ end
45
+ if result.has_key?("error")
46
+ puts "\nERROR: from votesmart_api #{method_name}: #{result["error"]["errorMessage"]}"
47
+ return nil
48
+ else
49
+ result["candidateList"]["candidate"]
50
+ end
51
+ end
52
+
53
+ def candidate_fuzzy_find(lastname)
54
+ get_votesmart_candidate("/Candidates.getByLevenstein", :query => {:lastName => lastname})
55
+ end
56
+
57
+ def officials_fuzzy_find(lastname)
58
+ get_votesmart_candidate("/Officials.getByLevenstein", :query => {:lastName => lastname})
59
+ end
60
+
61
+ def candidate_getBio(candidateId)
62
+ get_votesmart_candidate("/Candidate.getBio", :query => {:candidateId => candidateId})
63
+ end
64
+
65
+ def candidate_find_for_office_and_state(office, state)
66
+ get_votesmart_candidate("/Candidate.getByOfficeState", :query => {:officeId => office, :stateId => state})
67
+ end
68
+ end
@@ -0,0 +1,187 @@
1
+ =begin
2
+ * Name: GovSDK
3
+ * Description:
4
+ * Author: Pito Salas
5
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
6
+ * Date: January 2009
7
+ * License: GPL
8
+
9
+ This file is part of GovSDK.
10
+
11
+ GovSDK is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ GovSDK is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require "ruby-debug"
25
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
26
+ Debugger.settings[:autoeval] = 1
27
+ Debugger.start
28
+
29
+ =end
30
+
31
+ class CongressPerson < GovSdkBase
32
+
33
+ attr_reader :firstname, :lastname, :party, :state, :congress_office, :phone, :fax, :emai,
34
+ :website, :webform, :website_url, :bioguide_id, :congresspedia_url, :state_machine_id,
35
+ :district, :title, :govtrack_id, :crp_id, :nickname, :votesmart_id
36
+
37
+ # Maps specific set of CongressPerson attributes to Sunlight APIs. Mapping is structured as
38
+ # "name of attr in CongressPerson object" => "name of hash key in result returned from API call"
39
+
40
+ SUNLIGHT_MAP = {
41
+ "firstname" => "firstname",
42
+ "lastname" => "lastname",
43
+ "nickname" => "nickname",
44
+ "party" => "party",
45
+ "state" => "state",
46
+ "congress_office" => "congress_office",
47
+ "phone" => "phone",
48
+ "fax" => "fax",
49
+ "email" => "email",
50
+ "website" => "website",
51
+ "webform" => "webform",
52
+ "bioguide_id" => "bioguide_id",
53
+ "votesmart_id" => "votesmart_id",
54
+ "congresspedia_url" => "congresspedia_url",
55
+ "fec_id" => "fec_id",
56
+ "district" => "district",
57
+ "title" => "title",
58
+ "govtrack_id" => "govtrack_id",
59
+ "crp_id" => "crp_id"
60
+ }
61
+
62
+ def self.copy_sun_properties(sunlight_hash, cong_person)
63
+ SUNLIGHT_MAP.each do |name, attribute|
64
+ val = sunlight_hash[attribute]
65
+ cong_person.instance_variable_set("@#{name}", val)
66
+ end
67
+ end
68
+
69
+ def self.convert_to_congressperson(sunlight_legislator)
70
+ cong_person = CongressPerson.new
71
+ leg_hash = sunlight_legislator
72
+ copy_sun_properties(leg_hash, cong_person)
73
+ cong_person
74
+ end
75
+
76
+ def self.fuzzy_find_by_name(name)
77
+ raise ArgumentError, 'names must be Strings' unless name.is_a?(String)
78
+ sunlight_hash = GovSdk.sunlight_api.legislators_search(name)
79
+ sunlight_hash.collect {|leg| convert_to_congressperson(leg["result"]["legislator"])}
80
+ end
81
+
82
+ def self.find_by_zipcode(zip)
83
+ raise ArgumentError, 'zipcodes must be Strings' unless zip.is_a?(String)
84
+ end
85
+
86
+ def self.find_by_query(query)
87
+ assume_hash query
88
+ result_array = GovSdk.sunlight_api.legislators_getlist(query)
89
+ result_array.collect { |leg| convert_to_congressperson(leg["legislator"])}
90
+ end
91
+
92
+ def self.find_by_crp_id(crpId)
93
+ raise ArgumentError, 'Crp-Id should be a string' unless crpId.kind_of?(String)
94
+ sunlight_hash = GovSdk.sunlight_api.legislators_get(:crp_id => crpId)
95
+ if !sunlight_hash.nil?
96
+ cong_person = CongressPerson.new
97
+ copy_sun_properties(sunlight_hash, cong_person)
98
+ cong_person
99
+ else
100
+ nil
101
+ end
102
+ end
103
+
104
+ def get_fundraising_summary(electionCycle = nil)
105
+ raise ArgumentError, 'election cycle should be nil or an integer' unless electionCycle.nil? || electionCycle.kind_of?(Integer)
106
+ fund_summary_hash = GovSdk.opensecrets_api.get_cand_summary_for_crpID(crp_id, electionCycle)
107
+ fr_summary = FundraisingSummary.new(fund_summary_hash)
108
+ end
109
+
110
+ def get_positions_held(electionCycle = nil)
111
+ assume_nil_or_integer electionCycle
112
+ positions = GovSdk.opensecrets_api.get_cand_pfd_positions_held(crp_id, electionCycle)
113
+ if positions.class == Array
114
+ return positions.collect {|pos| Positions.new(pos)}
115
+ elsif positions.class == Hash
116
+ return [Positions.new(positions)]
117
+ else
118
+ []
119
+ end
120
+ end
121
+
122
+ # Return url to the photo of this Congress Person. This method uses the votesmart.org/candphoto/1234.jpg resource
123
+ def photo_url
124
+ assume_not_blank votesmart_id, "Votesmart_id cannot be blank when calling get_photo_url"
125
+ "http://www.votesmart.org/canphoto/#{@votesmart_id}.jpg"
126
+ end
127
+
128
+ # Return url of the Congress Person's web site, or nil if we can't find one.
129
+ def blog_url
130
+ assume_uses_google_api
131
+ return nil if website.nil?
132
+ blog = GovSdk.google_api.lookup_feed_url(website)
133
+ if blog.nil? || blog.empty?
134
+ nil
135
+ else
136
+ blog
137
+ end
138
+ end
139
+ end
140
+
141
+ class FundraisingSummary
142
+ attr_reader :spent, :total, :cash_on_hand, :debt
143
+
144
+ # Maps specific set of FundraisingSummary attributes to OpenSecrets APIs. Mapping is structured
145
+ # "name of attr in CongressPerson object" => "name of hash key in result returned from API call"
146
+ OPENS_FUNSUMMARY_MAP = {
147
+ "spent" => "spent",
148
+ "total" => "total",
149
+ "cash_on_hand" => "cash_on_hand",
150
+ "debt" => "debt"
151
+ }
152
+
153
+ # Given a hash of FundraisingSummary values from the OpenSecrets API, populate the corresponding
154
+ # instance variables in this instance.
155
+ def initialize(init_hash)
156
+ OPENS_FUNSUMMARY_MAP.each do |name, attribute|
157
+ val = init_hash[attribute]
158
+ instance_variable_set("@#{name}", val.to_i)
159
+ end
160
+ end
161
+ end
162
+
163
+ class Positions
164
+ attr_reader :title, :organization
165
+
166
+ # Maps specific set of CongressPerson attributes to OpenSecrets APIs. Mapping is structured
167
+ # "name of attr in CongressPerson object" => "name of hash key in result returned from API call"
168
+ OPENS_POS_MAP = {
169
+ "title" => "title",
170
+ "organization" => "organization"
171
+ }
172
+
173
+ # Given a hash of Positions values from the OpenSecrets API, populate the corresponding
174
+ # instance variables in this instance.
175
+ def initialize(init_hash)
176
+ OPENS_POS_MAP.each do |name, attribute|
177
+ val = init_hash[attribute]
178
+ instance_variable_set("@#{name}", val)
179
+ end
180
+ end
181
+
182
+ # Pretty print this instance. This method is called behind the scenes when a Position
183
+ # is encountered during a PP traversal of objects.
184
+ def pretty_print(pp)
185
+ pp.text("position #{title} at #{organization}")
186
+ end
187
+ end
data/lib/govsdk.rb CHANGED
@@ -30,29 +30,37 @@
30
30
  class GovSdk
31
31
 
32
32
  def self.load_apis
33
- @sunl_api = Sunlight.new
34
- @opens_api = OpenSecrets.new
33
+ @sunlight_api = SunlightApi.new
34
+ @opensecrets_api = OpenSecretsApi.new
35
+ @votesmart_api = VoteSmartApi.new
36
+ @google_api = GoogleApi.new
37
+ end
38
+
39
+ def self.votesmart_api
40
+ @votesmart_api
35
41
  end
36
42
 
37
43
  def self.sunlight_api
38
- @sunl_api
44
+ @sunlight_api
39
45
  end
40
46
 
41
47
  def self.opensecrets_api
42
- @opens_api
48
+ @opensecrets_api
43
49
  end
44
50
 
45
- def self.followmoney_api
46
- @followm_api
51
+ def self.google_api
52
+ @google_api
47
53
  end
48
-
54
+
49
55
  def self.init(apikeys = {})
50
- apikeys.keys.each { |x| raise ArgumentError unless [:followmoney, :sunlight, :opensecrets].include?(x) }
56
+ apikeys.keys.each { |x| raise ArgumentError unless [:google, :followmoney, :sunlight, :opensecrets, :votesmart].include?(x) }
51
57
  GovSdk.load_apis
52
58
  apikeys.each do |key, val|
53
- @sunl_api.key = val if key == :sunlight
54
- @opens_api.key = val if key == :opensecrets
59
+ @sunlight_api.key = val if key == :sunlight
60
+ @opensecrets_api.key = val if key == :opensecrets
55
61
  @followm_api.key = val if key == :followmoney
62
+ @votesmart_api.key = val if key == :votesmart
63
+ @google_api.key = val if key == :google
56
64
  end
57
65
  end
58
66
 
@@ -0,0 +1,54 @@
1
+ =begin
2
+ * Name: GovSDK
3
+ * Description:
4
+ * Author: Pito Salas
5
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
6
+ * Date: January 2009
7
+ * License: GPL
8
+
9
+ This file is part of GovSDK.
10
+
11
+ GovSDK is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ GovSDK is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require "ruby-debug"
25
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
26
+ Debugger.settings[:autoeval] = 1
27
+ Debugger.start
28
+
29
+ =end
30
+
31
+ class GovSdkBase
32
+
33
+ # General error checking and reporting methods
34
+ def assume_not_blank val, message
35
+ raise ArgumentError, (message + caller.shift) unless val.nil? || val.kind_of?(String)
36
+ end
37
+
38
+ def assume_uses_google_api
39
+ raise ArgumentError, "Call requires Google API and Google key" + called.shift unless GovSdk.google_api.initialized?
40
+ end
41
+
42
+ def assume_nil_or_integer val
43
+ raise ArgumentError, "Requires nil or integer argument. Called from " + called.shift unless val.nil? || val.kind_of?(Integer)
44
+ end
45
+
46
+ def self.assume_hash val
47
+ raise ArgumentError, "Requires a hash argument. Called from " + called.shift unless val.kind_of?(Hash)
48
+ end
49
+
50
+ def assume_hash val
51
+ self.assume_hash val
52
+ end
53
+
54
+ end
data/lib/govsdkgem.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  =begin
2
- * Name: GovSDK
3
- * Description:
2
+ * Name: govsdkgem.rb
3
+ * Description: Gem root 'require' file for govsdk
4
4
  * Author: Pito Salas
5
5
  * Copyright: (c) R. Pito Salas and Associates, Inc.
6
6
  * Date: January 2009
@@ -22,6 +22,13 @@
22
22
  along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
23
  =end
24
24
 
25
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+"/../lib/apis")
26
+
25
27
  require 'govsdk'
26
- require 'apimanagers'
27
- require 'congressperson'
28
+ require 'govsdk_base'
29
+ require 'open_secrets_api'
30
+ require 'congress_person'
31
+ require 'vote_smart_api'
32
+ require 'google_api'
33
+ require 'sunlight_api'
34
+ require 'opmloco'
@@ -20,6 +20,12 @@
20
20
 
21
21
  You should have received a copy of the GNU General Public License
22
22
  along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require "ruby-debug"
25
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
26
+ Debugger.settings[:autoeval] = 1
27
+ Debugger.start
28
+
23
29
  =end
24
30
 
25
31
  require File.dirname(__FILE__) + '/test_helper'
@@ -29,8 +35,8 @@ class CongressPersonTest < Test::Unit::TestCase
29
35
  setup do
30
36
  GovSdk.load_apis
31
37
  GovSdk.sunlight_api.key = "4ffa22917ab1ed010a8e681c550c9593"
32
- @cpnone = CongressPerson.find_by_name("Pito Salas")
33
- @cpkennedy = CongressPerson.find_by_name("Kennedy")
38
+ @cpnone = CongressPerson.fuzzy_find_by_name("Pito Salas")
39
+ @cpkennedy = CongressPerson.fuzzy_find_by_name("Kennedy")
34
40
  @cpkennedy[0].nickname == "Ted" ? @ted_crp_id = @cpkennedy[0].crp_id : @ted_crp_id = @cpkennedy[1].crp_id
35
41
  end
36
42
 
@@ -58,7 +64,23 @@ class CongressPersonTest < Test::Unit::TestCase
58
64
  should "crpid should be for ted kennedy" do
59
65
  assert_equal "Ted", @cpteddy.nickname
60
66
  end
67
+
68
+ should "have votesmart_id for Ted Kennedy one" do
69
+ assert_equal "53305", @cpteddy.votesmart_id
70
+ assert_equal "http://www.votesmart.org/canphoto/53305.jpg", @cpteddy.photo_url
71
+ end
61
72
  end
73
+
74
+ context "Find all legislators with certain criteria" do
75
+ setup do
76
+ @all_kennedy = CongressPerson.find_by_query(:lastname => "kennedy")
77
+ end
78
+
79
+ should "locate 2 kennedies" do
80
+ assert_equal 2, @all_kennedy.length
81
+ end
82
+ end
83
+
62
84
 
63
85
  context "Get fundraising summary for N00000308" do
64
86
  setup do
@@ -79,7 +101,7 @@ class CongressPersonTest < Test::Unit::TestCase
79
101
  setup do
80
102
  GovSdk.opensecrets_api.key = "09c975b6d3f19eb865805b2244311065"
81
103
  @mycandidate = CongressPerson.find_by_crp_id("N00000360")
82
- @nopositioncandidate = CongressPerson.find_by_name("Clinton")
104
+ @nopositioncandidate = CongressPerson.fuzzy_find_by_name("Clinton")
83
105
  end
84
106
 
85
107
  should "see what positions were held for N00000360" do
@@ -96,7 +118,7 @@ class CongressPersonTest < Test::Unit::TestCase
96
118
  context "Try some other odd cases" do
97
119
  setup do
98
120
  GovSdk.opensecrets_api.key = "09c975b6d3f19eb865805b2244311065"
99
- @franks = CongressPerson.find_by_name("Frank")[0]
121
+ @franks = CongressPerson.fuzzy_find_by_name("Frank")[0]
100
122
  end
101
123
 
102
124
  should "see that barney frank reported zero positions" do
@@ -104,6 +126,17 @@ class CongressPersonTest < Test::Unit::TestCase
104
126
  end
105
127
  end
106
128
 
107
-
129
+ context "See if we can find the blog url correctly" do
130
+ setup do
131
+ GovSdk.load_apis
132
+ GovSdk.sunlight_api.key = "4ffa22917ab1ed010a8e681c550c9593"
133
+ GovSdk.google_api.key = "ABQIAAAAyvWaJgF_91PvBZhITx5FDxRIYAcXj39F4zFQfQ2X3IEFURxvMRRUi0aCG6WofnUSRRoI-Pgytm5yUA"
134
+ @mycandidate = CongressPerson.fuzzy_find_by_name("Abercombie")
135
+ end
136
+
137
+ should "N00000308 has a blog" do
138
+ assert_equal "http://www.house.gov/apps/list/press/hi01_abercrombie/RSS.xml", @mycandidate[0].blog_url
139
+ end
140
+ end
108
141
  end
109
142
  end
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ =begin
3
+ * Name: google_api_test.rb
4
+ * Description: Tests for google_api.rb
5
+ * Author: Pito Salas
6
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
7
+ * Date: January 2009
8
+ * License: GPL
9
+
10
+ This file is part of GovSDK.
11
+
12
+ GovSDK is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
16
+
17
+ GovSDK is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
+
25
+ require "ruby-debug"
26
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
27
+ Debugger.settings[:autoeval] = 1
28
+ Debugger.start
29
+ =end
30
+ require "ruby-debug"
31
+
32
+ class GoogleApiTest < Test::Unit::TestCase
33
+ context "brand new API manager" do
34
+ setup do
35
+ @apim = GovSdk.load_apis
36
+ end
37
+
38
+ should "not be initialized" do
39
+ assert_equal false, @apim.initialized?
40
+ end
41
+ end
42
+
43
+ context "Google API" do
44
+ setup do
45
+ GovSdk.init(:google => "ABQIAAAAyvWaJgF_91PvBZhITx5FDxRIYAcXj39F4zFQfQ2X3IEFURxvMRRUi0aCG6WofnUSRRoI-Pgytm5yUA")
46
+ @g_api = GovSdk.google_api
47
+ end
48
+
49
+ should "be initialized once APIkey is set" do
50
+ assert_equal true, @g_api.initialized?
51
+ end
52
+
53
+ should "find feed for salas.com" do
54
+ assert_equal "http://www.salas.com/feed/", @g_api.lookup_feed_url("http://www.salas.com")
55
+ end
56
+
57
+ should "not find a feed for google.com" do
58
+ assert_equal nil, @g_api.lookup_feed_url("http://www.google.com")
59
+ end
60
+
61
+ end
62
+ end
@@ -1,4 +1,3 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
1
  =begin
3
2
  * Name: GovSDK
4
3
  * Description:
@@ -23,7 +22,9 @@ require File.dirname(__FILE__) + '/test_helper'
23
22
  along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
23
  =end
25
24
 
26
- class TestAPIs < Test::Unit::TestCase
25
+ require File.dirname(__FILE__) + '/test_helper'
26
+
27
+ class TestOpenSecretsApi < Test::Unit::TestCase
27
28
  context "brand new API manager" do
28
29
  setup do
29
30
  @apim = GenericAPI.new
@@ -34,44 +35,6 @@ class TestAPIs < Test::Unit::TestCase
34
35
  end
35
36
  end
36
37
 
37
- context "Sunlight API" do
38
- setup do
39
- GovSdk.load_apis
40
- GovSdk.sunlight_api.key = "4ffa22917ab1ed010a8e681c550c9593"
41
- end
42
-
43
- should "be initialized once APIkey is set" do
44
- assert_equal true, GovSdk.sunlight_api.initialized?
45
- end
46
-
47
- should "return no legislator called Pito Salas" do
48
- result = GovSdk.sunlight_api.legislators_search("Pito Salas")
49
- assert_equal 0, result.length
50
- end
51
-
52
- should "return a single legislator called Ted Kennedy" do
53
- result = GovSdk.sunlight_api.legislators_search("Ted Kennedy")
54
- assert 1, result.length
55
- end
56
-
57
- should "return a single legislator with the nickname ted" do
58
- result = GovSdk.sunlight_api.legislators_get(:nickname => "Ted", :lastname => "Kennedy")
59
- assert_equal "Ted", result["nickname"]
60
- end
61
-
62
- should "be able to locate crp_id N00000308" do
63
- result = GovSdk.sunlight_api.legislators_get(:crp_id => "N00000308")
64
- end
65
-
66
- should "be able to go from name to crp_id and back" do
67
- result = GovSdk.sunlight_api.legislators_get(:nickname => "ted", :lastname => "Kennedy")
68
- crp_id = result["crp_id"]
69
- result = GovSdk.sunlight_api.legislators_get(:crp_id => crp_id)
70
- assert_equal "Ted", result["nickname"]
71
- end
72
-
73
- end
74
-
75
38
  context "OpenSecrets API manager" do
76
39
  setup do
77
40
  GovSdk.load_apis
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ =begin
3
+ * Name: GovSDK
4
+ * Description:
5
+ * Author: Pito Salas
6
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
7
+ * Date: January 2009
8
+ * License: GPL
9
+
10
+ This file is part of GovSDK.
11
+
12
+ GovSDK is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
16
+
17
+ GovSDK is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
+
25
+ require "ruby-debug"
26
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
27
+ Debugger.settings[:autoeval] = 1
28
+ Debugger.start
29
+ =end
30
+ include Opmloco
31
+
32
+ class MyTest < Test::Unit::TestCase
33
+ context "Test context" do
34
+ setup do
35
+
36
+ end
37
+
38
+ should "work with minimal opml case" do
39
+ s = String.new
40
+ Opml.new("hello", "world").xml.write(s)
41
+ assert_equal "<?xml version='1.0'?><opml><head><title>hello</title></head><body><outline text='world'/></body></opml>", s
42
+ end
43
+
44
+ should "work with something a little more complicated" do
45
+ s = String.new
46
+ opml = Opml.new("BlogBridge Feeds", "Good Stuff", {:namespace => {:namespace => "xmlns:bb", :value => "http://blogbridge.com/ns/2006/opml"}})
47
+ opml.feeds << Feed.new("Latest News from Congressman Trent Franks Arizona's 2nd District", "rss", "http://www.house.gov/apps/list/press/az02_franks/RSS.xml")
48
+ opml.feeds << Feed.new("Ellen's Illinois Tenth Congressional District Blog", "rss", "http://ellenofthetenth.blogspot.com/feeds/posts/default")
49
+ opml.xml.write(s)
50
+ assert_equal "<?xml version='1.0'?><opml xmlns:bb='http://blogbridge.com/ns/2006/opml'><head><title>BlogBridge Feeds</title></head><body><outline text='Good Stuff'><outline xmlUrl='http://www.house.gov/apps/list/press/az02_franks/RSS.xml' text='Latest News from Congressman Trent Franks Arizona&apos;s 2nd District' type='rss'/><outline xmlUrl='http://ellenofthetenth.blogspot.com/feeds/posts/default' text='Ellen&apos;s Illinois Tenth Congressional District Blog' type='rss'/></outline></body></opml>", s
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ =begin
3
+ * Name: GovSDK
4
+ * Description:
5
+ * Author: Pito Salas
6
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
7
+ * Date: January 2009
8
+ * License: GPL
9
+
10
+ This file is part of GovSDK.
11
+
12
+ GovSDK is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
16
+
17
+ GovSDK is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
+ =end
25
+
26
+ class SunlightApiTest < Test::Unit::TestCase
27
+ context "brand new API manager" do
28
+ setup do
29
+ @apim = GenericAPI.new
30
+ end
31
+
32
+ should "not be initialized" do
33
+ assert_equal false, @apim.initialized?
34
+ end
35
+ end
36
+
37
+ context "Sunlight API" do
38
+ setup do
39
+ GovSdk.load_apis
40
+ @slight = GovSdk.sunlight_api
41
+ @slight.key = "4ffa22917ab1ed010a8e681c550c9593"
42
+ end
43
+
44
+ should "be initialized once APIkey is set" do
45
+ assert_equal true, @slight.initialized?
46
+ end
47
+
48
+ should "return no legislator called Pito Salas" do
49
+ result = @slight.legislators_search("Pito Salas")
50
+ assert_equal 0, result.length
51
+ end
52
+
53
+ should "return a single legislator called Ted Kennedy" do
54
+ result = @slight.legislators_search("Ted Kennedy")
55
+ assert 1, result.length
56
+ end
57
+
58
+ should "find that there are 2 legislators called Kennedy" do
59
+ result = @slight.legislators_getlist(:lastname => "Kennedy")
60
+ pp result
61
+ assert 2, result.length
62
+ end
63
+
64
+ should "return a single legislator with the nickname ted" do
65
+ result = GovSdk.sunlight_api.legislators_get(:nickname => "Ted", :lastname => "Kennedy")
66
+ assert_equal "Ted", result["nickname"]
67
+ end
68
+
69
+ should "be able to locate crp_id N00000308" do
70
+ result = GovSdk.sunlight_api.legislators_get(:crp_id => "N00000308")
71
+ end
72
+
73
+ should "be able to go from name to crp_id and back" do
74
+ result = GovSdk.sunlight_api.legislators_get(:nickname => "ted", :lastname => "Kennedy")
75
+ crp_id = result["crp_id"]
76
+ result = GovSdk.sunlight_api.legislators_get(:crp_id => crp_id)
77
+ assert_equal "Ted", result["nickname"]
78
+ end
79
+ end
80
+ end
data/test/test_helper.rb CHANGED
@@ -3,11 +3,21 @@ require 'test/unit'
3
3
  require 'shoulda'
4
4
  require 'mocha'
5
5
  require 'pp'
6
+ require 'httparty'
6
7
 
7
- $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+"/../lib")
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__)+"/../lib/apis")
10
+
11
+ require 'google_api'
8
12
  require 'govsdk'
13
+ require 'govsdk_base'
9
14
  require 'apimanagers'
10
- require 'congressperson'
15
+ require 'congress_person'
16
+ require 'generic_api'
17
+ require 'sunlight_api'
18
+ require 'open_secrets_api'
19
+ require 'vote_smart_api'
20
+ require 'opmloco'
11
21
 
12
22
  class Test::Unit::TestCase
13
23
  end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ =begin
3
+ * Name: test_template.rb
4
+ * Description: Template for GovSdk Tests
5
+ * Author: Pito Salas
6
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
7
+ * Date: January 2009
8
+ * License: GPL
9
+
10
+ This file is part of GovSDK.
11
+
12
+ GovSDK is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
16
+
17
+ GovSDK is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
+
25
+ require "ruby-debug"
26
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
27
+ Debugger.settings[:autoeval] = 1
28
+ Debugger.start
29
+ =end
30
+
31
+ class MyTest < Test::Unit::TestCase
32
+ context "Test context" do
33
+ setup do
34
+
35
+ end
36
+
37
+ should "do something" do
38
+ assert_equal 1,1
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ =begin
3
+ * Name: GovSDK
4
+ * Description:
5
+ * Author: Pito Salas
6
+ * Copyright: (c) R. Pito Salas and Associates, Inc.
7
+ * Date: January 2009
8
+ * License: GPL
9
+
10
+ This file is part of GovSDK.
11
+
12
+ GovSDK is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
16
+
17
+ GovSDK is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with GovSDK. If not, see <http://www.gnu.org/licenses/>.
24
+
25
+ require "ruby-debug"
26
+ Debugger.settings[:autolist] = 1 # list nearby lines on stop
27
+ Debugger.settings[:autoeval] = 1
28
+ Debugger.start
29
+ =end
30
+
31
+ class VoteSmartApiTest < Test::Unit::TestCase
32
+ context "brand new API manager" do
33
+ setup do
34
+ @apim = GovSdk.load_apis
35
+ end
36
+
37
+ should "not be initialized" do
38
+ assert_equal false, @apim.initialized?
39
+ end
40
+ end
41
+
42
+ context "VoteSmart API" do
43
+ setup do
44
+ GovSdk.init(:votesmart => "c5056828cffa0be5e095cbd75ce3a663")
45
+ @vs_api = GovSdk.votesmart_api
46
+ end
47
+
48
+ should "be initialized once APIkey is set" do
49
+ assert_equal true, @vs_api.initialized?
50
+ end
51
+
52
+ should "find no candidates called Kennedy" do
53
+ assert_equal nil, @vs_api.candidate_fuzzy_find("Kennedy")
54
+ end
55
+
56
+ should "find more than one officials named Kennedy" do
57
+ assert 1 <= @vs_api.officials_fuzzy_find("Kennedy").length
58
+ end
59
+
60
+ end
61
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pitosalas-govsdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pito Salas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-30 00:00:00 -08:00
12
+ date: 2009-02-13 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -22,16 +22,28 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
+ - README.textile
25
26
  - VERSION.yml
26
- - lib/apimanagers.rb
27
+ - lib/apis
28
+ - lib/apis/generic_api.rb
29
+ - lib/apis/google_api.rb
30
+ - lib/apis/open_secrets_api.rb
31
+ - lib/apis/sunlight_api.rb
32
+ - lib/apis/vote_smart_api.rb
27
33
  - lib/congress_person.rb
28
34
  - lib/govsdk.rb
35
+ - lib/govsdk_base.rb
29
36
  - lib/govsdkgem.rb
30
- - lib/template.rb
31
- - test/apimanagers_test.rb
37
+ - lib/opmloco.rb
32
38
  - test/congressperson_test.rb
39
+ - test/google_api_test.rb
33
40
  - test/govsdk_test.rb
41
+ - test/open_secrets_api_test.rb
42
+ - test/opmloco_test.rb
43
+ - test/sunlight_api_test.rb
34
44
  - test/test_helper.rb
45
+ - test/test_template.rb
46
+ - test/vote_smart_api_test.rb
35
47
  has_rdoc: true
36
48
  homepage: http://github.com/pitosalas/govsdk
37
49
  post_install_message: