govkit 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.markdown +9 -7
- data/Rakefile +3 -1
- data/USAGE +1 -0
- data/VERSION +1 -1
- data/generators/govkit/templates/govkit.rb +12 -2
- data/govkit.gemspec +25 -10
- data/lib/gov_kit/acts_as_citeable.rb +40 -0
- data/lib/gov_kit/configuration.rb +5 -3
- data/lib/gov_kit/follow_the_money.rb +100 -0
- data/lib/gov_kit/open_congress/bill.rb +173 -0
- data/lib/gov_kit/open_congress/blog_post.rb +19 -0
- data/lib/gov_kit/open_congress/news_post.rb +19 -0
- data/lib/gov_kit/open_congress/person.rb +143 -0
- data/lib/gov_kit/open_congress/person_stat.rb +18 -0
- data/lib/gov_kit/open_congress/roll_call.rb +16 -0
- data/lib/gov_kit/open_congress/roll_call_comparison.rb +31 -0
- data/lib/gov_kit/open_congress/voting_comparison.rb +46 -0
- data/lib/gov_kit/open_congress.rb +90 -0
- data/lib/gov_kit/search_engines/google_blog.rb +37 -0
- data/lib/gov_kit/search_engines/google_news.rb +38 -0
- data/lib/gov_kit/search_engines/technorati.rb +35 -0
- data/lib/gov_kit/search_engines.rb +5 -0
- data/lib/gov_kit/vote_smart.rb +29 -0
- data/lib/gov_kit.rb +30 -10
- data/rails/init.rb +1 -0
- metadata +46 -9
- data/lib/govkit/configuration.rb +0 -29
- data/lib/govkit/fifty_states.rb +0 -188
- data/lib/govkit/vote_smart.rb +0 -146
data/LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# Govkit
|
2
2
|
|
3
|
-
Govkit is a Ruby gem that provides simple access to open government APIs around the web
|
3
|
+
Govkit is a Ruby gem that provides simple access to open government APIs around the web, including:
|
4
|
+
|
5
|
+
* [OpenCongress](http://www.opencongress.org/api), which has an API for federal bills, votes, people, and news and blog coverage
|
6
|
+
* [The Fifty States project](http://fiftystates-dev.sunlightlabs.com/), which has a RESTful API for accessing data about state legislators, bills, votes, etc.
|
7
|
+
* [Project Vote Smart](http://www.votesmart.org/services_api.php), which has an API with congressional addresses, etc.
|
8
|
+
* [Follow The Money](http://www.followthemoney.org/), whose API reveals campaign contribution data for state officials.
|
4
9
|
|
5
10
|
# Installation
|
6
11
|
|
@@ -14,14 +19,11 @@ Add govkit to your environment.rb or Gemfile
|
|
14
19
|
|
15
20
|
Run <code>./script/generate govkit</code> to copy a config file into <code>config/initializers/govkit.rb</code>. You will need to add your API keys to this config file.
|
16
21
|
|
17
|
-
#
|
18
|
-
|
19
|
-
[http://fiftystates-dev.sunlightlabs.com/](The Fifty States project) has a RESTful API for accessing data about state legislators, bills, votes, etc.
|
22
|
+
# Examples
|
20
23
|
|
21
24
|
>> Govkit::FiftyStates::State.find_by_abbreviation('CA')
|
22
|
-
>> Govkit::VoteSmart::Address.find(
|
23
|
-
|
24
|
-
(TODO: add usage examples...)
|
25
|
+
>> Govkit::VoteSmart::Address.find(votesmart_candidate_id)
|
26
|
+
>> GovKit::OpenCongress::Bill.find(:number => 5479, :type => 'h', :congress => '111')
|
25
27
|
|
26
28
|
# Bugs? Questions?
|
27
29
|
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
|
5
|
+
|
5
6
|
begin
|
6
7
|
require 'spec/rake/spectask'
|
7
8
|
rescue LoadError
|
@@ -23,7 +24,8 @@ begin
|
|
23
24
|
gem.homepage = "http://github.com/opengovernment/govkit"
|
24
25
|
gem.authors = ["Participatory Politics Foundation", "Srinivas Aki", "Carl Tashian"]
|
25
26
|
gem.add_dependency('httparty', '>= 0.5.2')
|
26
|
-
gem.add_dependency('json', '>= 1.
|
27
|
+
gem.add_dependency('json', '>= 1.4.3')
|
28
|
+
gem.add_dependency('hpricot', '>= 0.8.2')
|
27
29
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
28
30
|
end
|
29
31
|
Jeweler::GemcutterTasks.new
|
data/USAGE
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
See README.markdown for full usage details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
@@ -1,9 +1,19 @@
|
|
1
1
|
if defined? GovKit
|
2
|
-
|
3
2
|
GovKit.configure do |config|
|
4
3
|
# Get an API key for Sunlight's Fifty States project here:
|
5
4
|
# http://services.sunlightlabs.com/accounts/register/
|
6
5
|
config.fiftystates_apikey = 'YOUR_FIFTYSTATES_API_KEY'
|
7
|
-
end
|
8
6
|
|
7
|
+
##API key for Votesmart
|
8
|
+
# http://votesmart.org/services_api.php
|
9
|
+
config.votesmart_apikey = 'YOUR_VOTESMART_API_KEY'
|
10
|
+
|
11
|
+
# API key for NIMSP. Request one here:
|
12
|
+
# http://www.followthemoney.org/membership/settings.phtml
|
13
|
+
config.ftm_apikey = 'YOUR_FTM_API_KEY'
|
14
|
+
|
15
|
+
# Api key for OpenCongress
|
16
|
+
# http://www.opencongress.org/api
|
17
|
+
config.opencongress_apikey = 'YOUR_OPENCONGRESS_API_KEY'
|
18
|
+
end
|
9
19
|
end
|
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.0
|
8
|
+
s.version = "0.1.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-
|
12
|
+
s.date = %q{2010-06-10}
|
13
13
|
s.description = %q{Govkit lets you quickly get encapsulated Ruby objects for common open government APIs. We're starting with Sunlight's Fifty States API and the Project Vote Smart API.}
|
14
14
|
s.email = %q{carl@ppolitics.org}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,14 +28,26 @@ Gem::Specification.new do |s|
|
|
28
28
|
"generators/govkit/templates/govkit.rb",
|
29
29
|
"govkit.gemspec",
|
30
30
|
"lib/gov_kit.rb",
|
31
|
+
"lib/gov_kit/acts_as_citeable.rb",
|
31
32
|
"lib/gov_kit/configuration.rb",
|
32
33
|
"lib/gov_kit/fifty_states.rb",
|
34
|
+
"lib/gov_kit/follow_the_money.rb",
|
35
|
+
"lib/gov_kit/open_congress.rb",
|
36
|
+
"lib/gov_kit/open_congress/bill.rb",
|
37
|
+
"lib/gov_kit/open_congress/blog_post.rb",
|
38
|
+
"lib/gov_kit/open_congress/news_post.rb",
|
39
|
+
"lib/gov_kit/open_congress/person.rb",
|
40
|
+
"lib/gov_kit/open_congress/person_stat.rb",
|
41
|
+
"lib/gov_kit/open_congress/roll_call.rb",
|
42
|
+
"lib/gov_kit/open_congress/roll_call_comparison.rb",
|
43
|
+
"lib/gov_kit/open_congress/voting_comparison.rb",
|
33
44
|
"lib/gov_kit/resource.rb",
|
45
|
+
"lib/gov_kit/search_engines.rb",
|
46
|
+
"lib/gov_kit/search_engines/google_blog.rb",
|
47
|
+
"lib/gov_kit/search_engines/google_news.rb",
|
48
|
+
"lib/gov_kit/search_engines/technorati.rb",
|
34
49
|
"lib/gov_kit/vote_smart.rb",
|
35
50
|
"lib/govkit.rb",
|
36
|
-
"lib/govkit/configuration.rb",
|
37
|
-
"lib/govkit/fifty_states.rb",
|
38
|
-
"lib/govkit/vote_smart.rb",
|
39
51
|
"rails/init.rb",
|
40
52
|
"spec/fifty_states_spec.rb",
|
41
53
|
"spec/spec.opts",
|
@@ -44,7 +56,7 @@ Gem::Specification.new do |s|
|
|
44
56
|
s.homepage = %q{http://github.com/opengovernment/govkit}
|
45
57
|
s.rdoc_options = ["--charset=UTF-8"]
|
46
58
|
s.require_paths = ["lib"]
|
47
|
-
s.rubygems_version = %q{1.3.
|
59
|
+
s.rubygems_version = %q{1.3.7}
|
48
60
|
s.summary = %q{Simple access to open government APIs around the web}
|
49
61
|
s.test_files = [
|
50
62
|
"spec/fifty_states_spec.rb",
|
@@ -55,16 +67,19 @@ Gem::Specification.new do |s|
|
|
55
67
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
56
68
|
s.specification_version = 3
|
57
69
|
|
58
|
-
if Gem::Version.new(Gem::
|
70
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
71
|
s.add_runtime_dependency(%q<httparty>, [">= 0.5.2"])
|
60
|
-
s.add_runtime_dependency(%q<json>, [">= 1.
|
72
|
+
s.add_runtime_dependency(%q<json>, [">= 1.4.3"])
|
73
|
+
s.add_runtime_dependency(%q<hpricot>, [">= 0.8.2"])
|
61
74
|
else
|
62
75
|
s.add_dependency(%q<httparty>, [">= 0.5.2"])
|
63
|
-
s.add_dependency(%q<json>, [">= 1.
|
76
|
+
s.add_dependency(%q<json>, [">= 1.4.3"])
|
77
|
+
s.add_dependency(%q<hpricot>, [">= 0.8.2"])
|
64
78
|
end
|
65
79
|
else
|
66
80
|
s.add_dependency(%q<httparty>, [">= 0.5.2"])
|
67
|
-
s.add_dependency(%q<json>, [">= 1.
|
81
|
+
s.add_dependency(%q<json>, [">= 1.4.3"])
|
82
|
+
s.add_dependency(%q<hpricot>, [">= 0.8.2"])
|
68
83
|
end
|
69
84
|
end
|
70
85
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GovKit::ActsAsCiteable
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ActMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ActMethods
|
8
|
+
def acts_as_citeable(options={})
|
9
|
+
options[:keywords] ||= []
|
10
|
+
|
11
|
+
class_inheritable_accessor :options
|
12
|
+
self.options = options
|
13
|
+
|
14
|
+
unless included_modules.include? InstanceMethods
|
15
|
+
extend ClassMethods
|
16
|
+
include InstanceMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
end
|
23
|
+
|
24
|
+
module InstanceMethods
|
25
|
+
|
26
|
+
def raw_citations
|
27
|
+
params = self.options[:keywords].clone
|
28
|
+
attributes = self.options[:with].clone
|
29
|
+
|
30
|
+
attributes.each do |attr|
|
31
|
+
params << self.instance_eval("#{attr}")
|
32
|
+
end
|
33
|
+
{
|
34
|
+
:google_news => GovKit::SearchEngines::GoogleNews.search(params),
|
35
|
+
:google_blogs => GovKit::SearchEngines::GoogleBlog.search(params),
|
36
|
+
:technorati => GovKit::SearchEngines::Technorati.search(params)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -2,13 +2,15 @@ module GovKit
|
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :fiftystates_apikey, :fiftystates_base_url
|
4
4
|
attr_accessor :votesmart_apikey, :votesmart_base_url
|
5
|
+
attr_accessor :ftm_apikey, :ftm_base_url
|
6
|
+
attr_accessor :opencongress_apikey, :opencongress_base_url
|
5
7
|
|
6
8
|
def initialize
|
7
|
-
@fiftystates_apikey = ''
|
9
|
+
@fiftystates_apikey = @votesmart_apikey = @ftm_apikey = ''
|
8
10
|
@fiftystates_base_url = 'fiftystates-dev.sunlightlabs.com/api'
|
9
|
-
|
10
|
-
@votesmart_apikey = ''
|
11
11
|
@votesmart_base_url = 'api.votesmart.org/'
|
12
|
+
@ftm_base_url = 'api.followthemoney.org/'
|
13
|
+
@opencongress_base_url = 'www.opencongress.org/'
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module GovKit
|
2
|
+
class FollowTheMoneyResource < Resource
|
3
|
+
default_params :key => GovKit::configuration.ftm_apikey
|
4
|
+
base_uri GovKit::configuration.ftm_base_url
|
5
|
+
end
|
6
|
+
|
7
|
+
module FollowTheMoney
|
8
|
+
class Business < FollowTheMoneyResource
|
9
|
+
def self.list
|
10
|
+
next_page, result, page_num = "yes", [], 0
|
11
|
+
|
12
|
+
until next_page == "no"
|
13
|
+
puts "Getting batch number #{page_num}"
|
14
|
+
|
15
|
+
response = get("/base_level.industries.list.php", :query => {:page => page_num})
|
16
|
+
|
17
|
+
doc = Hpricot::XML(response)
|
18
|
+
|
19
|
+
next_page = doc.search("/").first.attributes['next_page']
|
20
|
+
|
21
|
+
page_num += 1
|
22
|
+
|
23
|
+
result += doc.search('//business_detail').collect do |business|
|
24
|
+
business.attributes.to_hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
instantiate_collection(result)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Contribution < FollowTheMoneyResource
|
33
|
+
def self.find(nimsp_id)
|
34
|
+
next_page, result, page_num = "yes", [], 0
|
35
|
+
|
36
|
+
until next_page == "no"
|
37
|
+
response = get("/candidates.contributions.php", :query => {"imsp_candidate_id" => nimsp_id, :page => page_num})
|
38
|
+
doc = Hpricot::XML(response)
|
39
|
+
|
40
|
+
next_page = doc.search("/").first.attributes['next_page']
|
41
|
+
|
42
|
+
page_num += 1
|
43
|
+
|
44
|
+
result = doc.search('//contribution').collect do |contribution|
|
45
|
+
contribution.attributes.to_hash
|
46
|
+
end
|
47
|
+
end
|
48
|
+
instantiate_collection(result)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.top(nimsp_id)
|
52
|
+
response = get("/candidates.top_contributor.php", :query => {"imsp_candidate_id" => nimsp_id})
|
53
|
+
doc = Hpricot::XML(response)
|
54
|
+
result = doc.search('//top_contributor').collect do |contribution|
|
55
|
+
contribution.attributes.to_hash
|
56
|
+
end
|
57
|
+
|
58
|
+
instantiate_collection(result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class IndustryContribution < Contribution
|
63
|
+
def self.find(nimsp_id)
|
64
|
+
response = get("/candidates.industries.php", :query => {"imsp_candidate_id" => nimsp_id})
|
65
|
+
doc = Hpricot::XML(response)
|
66
|
+
|
67
|
+
result = doc.search('//candidate_industry').collect do |contribution|
|
68
|
+
contribution.attributes.to_hash
|
69
|
+
end
|
70
|
+
|
71
|
+
instantiate_collection(result)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class SectorContribution < Contribution
|
76
|
+
def self.find(nimsp_id)
|
77
|
+
response = get("/candidates.sectors.php", :query => {"imsp_candidate_id" => nimsp_id})
|
78
|
+
doc = Hpricot::XML(response)
|
79
|
+
|
80
|
+
result = doc.search('//candidate_sector').collect do |contribution|
|
81
|
+
contribution.attributes.to_hash
|
82
|
+
end
|
83
|
+
|
84
|
+
instantiate_collection(result)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class BusinessContribution < Contribution
|
89
|
+
def self.find(nimsp_id)
|
90
|
+
response = get("/candidates.businesses.php", :query => {"imsp_candidate_id" => nimsp_id})
|
91
|
+
doc = Hpricot::XML(response)
|
92
|
+
result = doc.search('//candidate_business').collect do |contribution|
|
93
|
+
contribution.attributes.to_hash
|
94
|
+
end
|
95
|
+
|
96
|
+
instantiate_collection(result)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module GovKit
|
2
|
+
module OpenCongress
|
3
|
+
class Bill < OpenCongressObject
|
4
|
+
attr_accessor :bill_type, :id, :introduced, :last_speech, :last_vote_date, :last_vote_roll, :last_vote_where, :last_action, :number, :plain_language_summary, :session, :sponsor, :co_sponsors, :title_full_common, :status, :most_recent_actions, :bill_titles, :recent_blogs, :recent_news, :ident
|
5
|
+
|
6
|
+
def initialize(params)
|
7
|
+
params.each do |key, value|
|
8
|
+
instance_variable_set("@#{key}", value) if Bill.instance_methods.include? key
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def ident
|
13
|
+
"#{session}-#{bill_type}#{number}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(params)
|
17
|
+
|
18
|
+
url = construct_url("bills", params)
|
19
|
+
|
20
|
+
if (result = make_call(url))
|
21
|
+
parse_results(result)
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.most_blogged_bills_this_week
|
29
|
+
url = construct_url("most_blogged_bills_this_week", {})
|
30
|
+
if (result = make_call(url))
|
31
|
+
bills = parse_results(result)
|
32
|
+
return bills
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.bills_in_the_news_this_week
|
39
|
+
url = construct_url("bills_in_the_news_this_week", {})
|
40
|
+
if (result = make_call(url))
|
41
|
+
bills = parse_results(result)
|
42
|
+
return bills
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.most_tracked_bills_this_week
|
49
|
+
url = construct_url("most_tracked_bills_this_week", {})
|
50
|
+
if (result = make_call(url))
|
51
|
+
bills = parse_results(result)
|
52
|
+
return bills
|
53
|
+
else
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.most_supported_bills_this_week
|
59
|
+
url = construct_url("most_supported_bills_this_week", {})
|
60
|
+
if (result = make_call(url))
|
61
|
+
bills = parse_results(result)
|
62
|
+
return bills
|
63
|
+
else
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.most_opposed_bills_this_week
|
69
|
+
url = construct_url("most_opposed_bills_this_week", {})
|
70
|
+
if (result = make_call(url))
|
71
|
+
bills = parse_results(result)
|
72
|
+
return bills
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.find_by_query(q)
|
79
|
+
url = Bill.construct_url("bills_by_query", {:q => q})
|
80
|
+
|
81
|
+
if (result = make_call(url))
|
82
|
+
bills = parse_results(result)
|
83
|
+
else
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.find_by_idents(idents)
|
89
|
+
q = []
|
90
|
+
if idents.class.to_s == "Array"
|
91
|
+
q = idents
|
92
|
+
else
|
93
|
+
q = idents.split(',')
|
94
|
+
end
|
95
|
+
|
96
|
+
url = Bill.construct_url("bills_by_ident", {:ident => q.join(',')})
|
97
|
+
|
98
|
+
if (result = make_call(url))
|
99
|
+
bills = parse_results(result)
|
100
|
+
else
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def opencongress_users_supporting_bill_are_also
|
106
|
+
url = Bill.construct_url("opencongress_users_supporting_bill_are_also/#{ident}", {})
|
107
|
+
if (result = Bill.make_call(url))
|
108
|
+
bills = Bill.parse_supporting_results(result)
|
109
|
+
return bills
|
110
|
+
else
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def opencongress_users_opposing_bill_are_also
|
116
|
+
url = Bill.construct_url("opencongress_users_opposing_bill_are_also/#{ident}", {})
|
117
|
+
if (result = Bill.make_call(url))
|
118
|
+
bills = Bill.parse_supporting_results(result)
|
119
|
+
return bills
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.parse_results(result)
|
126
|
+
|
127
|
+
bills = []
|
128
|
+
result["bills"].each do |bill|
|
129
|
+
|
130
|
+
these_recent_blogs = bill["recent_blogs"]
|
131
|
+
blogs = []
|
132
|
+
|
133
|
+
if these_recent_blogs
|
134
|
+
these_recent_blogs.each do |trb|
|
135
|
+
blogs << BlogPost.new(trb)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
bill["recent_blogs"] = blogs
|
140
|
+
|
141
|
+
|
142
|
+
these_recent_news = bill["recent_news"]
|
143
|
+
news = []
|
144
|
+
if these_recent_news
|
145
|
+
these_recent_news.each do |trb|
|
146
|
+
news << NewsPost.new(trb)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
bill["recent_news"] = news
|
151
|
+
|
152
|
+
these_co_sponsors = bill["co_sponsors"]
|
153
|
+
co_sponsors = []
|
154
|
+
if these_co_sponsors
|
155
|
+
these_co_sponsors.each do |tcs|
|
156
|
+
co_sponsors << Person.new(tcs)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
bill["co_sponsors"] = co_sponsors
|
161
|
+
|
162
|
+
|
163
|
+
bill["sponsor"] = Person.new(bill["sponsor"]) if bill["sponsor"]
|
164
|
+
|
165
|
+
|
166
|
+
bills << Bill.new(bill)
|
167
|
+
end
|
168
|
+
bills
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GovKit
|
2
|
+
module OpenCongress
|
3
|
+
|
4
|
+
class BlogPost < OpenCongressObject
|
5
|
+
|
6
|
+
attr_accessor :title, :date, :url, :source_url, :excerpt, :source, :average_rating
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(params)
|
10
|
+
params.each do |key, value|
|
11
|
+
instance_variable_set("@#{key}", value) if BlogPost.instance_methods.include? key
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GovKit
|
2
|
+
module OpenCongress
|
3
|
+
|
4
|
+
class NewsPost < OpenCongressObject
|
5
|
+
|
6
|
+
attr_accessor :title, :date, :url, :source_url, :excerpt, :source, :average_rating
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(params)
|
10
|
+
params.each do |key, value|
|
11
|
+
instance_variable_set("@#{key}", value) if NewsPost.instance_methods.include? key
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module GovKit
|
2
|
+
module OpenCongress
|
3
|
+
|
4
|
+
class Person < OpenCongressObject
|
5
|
+
|
6
|
+
attr_accessor :firstname, :lastname, :bioguideid, :birthday, :district, :email, :gender, :id, :metavid_id, :middlename,
|
7
|
+
:name, :nickname, :osid, :party, :religion, :state, :title, :unaccented_name, :url, :user_approval,
|
8
|
+
:youtube_id, :oc_user_comments, :oc_users_tracking, :abstains_percentage, :with_party_percentage, :recent_news,
|
9
|
+
:recent_blogs, :person_stats
|
10
|
+
|
11
|
+
def initialize(params)
|
12
|
+
params.each do |key, value|
|
13
|
+
instance_variable_set("@#{key}", value) if Person.instance_methods.include? key
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find(params)
|
18
|
+
|
19
|
+
url = construct_url("people", params)
|
20
|
+
if (result = make_call(url))
|
21
|
+
people = parse_results(result)
|
22
|
+
return people
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.compare(person1, person2)
|
30
|
+
url = "#{GovKit::configuration.opencongress_base_url}person/compare.json?person1=#{person1.id}&person2=#{person2.id}"
|
31
|
+
if (result = make_call(url))
|
32
|
+
comparison = VotingComparison.new(result["comparison"])
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.senators_most_in_the_news_this_week
|
40
|
+
|
41
|
+
url = construct_url("senators_most_in_the_news_this_week", {})
|
42
|
+
if (result = make_call(url))
|
43
|
+
people = parse_results(result)
|
44
|
+
return people
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.representatives_most_in_the_news_this_week
|
52
|
+
|
53
|
+
url = construct_url("representatives_most_in_the_news_this_week", {})
|
54
|
+
if (result = make_call(url))
|
55
|
+
people = parse_results(result)
|
56
|
+
return people
|
57
|
+
else
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.most_blogged_senators_this_week
|
64
|
+
|
65
|
+
url = construct_url("most_blogged_senators_this_week", {})
|
66
|
+
if (result = make_call(url))
|
67
|
+
people = parse_results(result)
|
68
|
+
return people
|
69
|
+
else
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.most_blogged_representatives_this_week
|
76
|
+
|
77
|
+
url = construct_url("most_blogged_representatives_this_week", {})
|
78
|
+
if (result = make_call(url))
|
79
|
+
people = parse_results(result)
|
80
|
+
return people
|
81
|
+
else
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def opencongress_users_supporting_person_are_also
|
88
|
+
url = Person.construct_url("opencongress_users_supporting_person_are_also/#{id}", {})
|
89
|
+
if (result = Person.make_call(url))
|
90
|
+
people = Person.parse_supporting_results(result)
|
91
|
+
return people
|
92
|
+
else
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def opencongress_users_opposing_person_are_also
|
98
|
+
url = Person.construct_url("opencongress_users_opposing_person_are_also/#{id}", {})
|
99
|
+
if (result = Person.make_call(url))
|
100
|
+
people = Person.parse_supporting_results(result)
|
101
|
+
return people
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.parse_results(result)
|
108
|
+
|
109
|
+
people = []
|
110
|
+
result["people"].each do |person|
|
111
|
+
|
112
|
+
these_recent_blogs = person["recent_blogs"]
|
113
|
+
blogs = []
|
114
|
+
these_recent_blogs.each do |trb|
|
115
|
+
blogs << BlogPost.new(trb)
|
116
|
+
end
|
117
|
+
|
118
|
+
person["recent_blogs"] = blogs
|
119
|
+
|
120
|
+
|
121
|
+
these_recent_news = person["recent_news"]
|
122
|
+
news = []
|
123
|
+
these_recent_news.each do |trb|
|
124
|
+
news << NewsPost.new(trb)
|
125
|
+
end
|
126
|
+
|
127
|
+
person["person_stats"] = PersonStat.new(person["person_stats"]) if person["person_stats"]
|
128
|
+
|
129
|
+
person["recent_news"] = news
|
130
|
+
|
131
|
+
people << Person.new(person)
|
132
|
+
end
|
133
|
+
|
134
|
+
people
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|