govkit 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module GovKit
2
+ module OpenCongress
3
+ class PersonStat < OpenCongressObject
4
+
5
+ attr_accessor :votes_most_often_with_id, :opposing_party_votes_most_often_with_id, :votes_least_often_with_id, :same_party_votes_least_often_with_id, :party_votes_percentage, :abstains_percentage, :abstains_percentage_rank, :party_votes_percentage_rank, :sponsored_bills, :cosponsored_bills, :abstains, :sponsored_bills_passed_rank, :cosponsored_bills_passed_rank, :sponsored_bills_passed, :cosponsored_bills_passed, :sponsored_bills_rank, :cosponsored_bills_rank
6
+
7
+
8
+ def initialize(params)
9
+ params.each do |key, value|
10
+ instance_variable_set("@#{key}", value) if PersonStat.instance_methods.include? key
11
+ end
12
+ end
13
+
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module GovKit
2
+ module OpenCongress
3
+ class RollCall < OpenCongressObject
4
+
5
+ attr_accessor :abstains, :presents, :roll_type, :title, :question, :republican_position, :democratic_position,
6
+ :amendment_id, :ayes, :nays, :bill, :date, :number, :id, :required, :where
7
+
8
+ def initialize(params)
9
+ params.each do |key, value|
10
+ instance_variable_set("@#{key}", value) if RollCall.instance_methods.include? key
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module GovKit
2
+ module OpenCongress
3
+ class RollCallComparison < OpenCongressObject
4
+
5
+ attr_accessor :roll_call, :person1, :person2
6
+
7
+ def initialize(params)
8
+ params.each do |key, value|
9
+ instance_variable_set("@#{key}", value) if RollCallComparison.instance_methods.include? key
10
+ end
11
+
12
+
13
+ set_people
14
+ set_roll_call
15
+
16
+ end
17
+
18
+ def set_people
19
+ self.person1 = self.person1["stong"]
20
+ self.person2 = self.person2["stong"]
21
+ end
22
+
23
+ def set_roll_call
24
+ self.roll_call = RollCall.new(self.roll_call)
25
+ end
26
+
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,46 @@
1
+ module GovKit
2
+ module OpenCongress
3
+
4
+ class VotingComparison < OpenCongressObject
5
+
6
+ attr_accessor :total_votes, :same_vote, :percentage, :person1, :person2, :shared_committees, :hot_votes,
7
+ :other_votes
8
+
9
+ def initialize(params)
10
+ params.each do |key, value|
11
+ instance_variable_set("@#{key}", value) if VotingComparison.instance_methods.include? key
12
+ end
13
+
14
+ set_people
15
+ set_votes
16
+
17
+ end
18
+
19
+ def set_people
20
+ self.person1 = Person.new(self.person1["person"])
21
+ self.person2 = Person.new(self.person2["person"])
22
+ end
23
+
24
+ def set_votes
25
+
26
+ these_hot_votes = []
27
+ hot_votes["vote"].each do |v|
28
+ nv = RollCallComparison.new(v)
29
+ these_hot_votes << nv
30
+ end
31
+
32
+ self.hot_votes = these_hot_votes
33
+
34
+ these_other_votes = []
35
+ other_votes["vote"].each do |v|
36
+ nv = RollCallComparison.new(v)
37
+ these_other_votes << nv
38
+ end
39
+
40
+ self.other_votes = these_other_votes
41
+
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,90 @@
1
+ require 'hpricot'
2
+ require 'open-uri'
3
+ require 'json'
4
+
5
+ module GovKit::OpenCongress
6
+ autoload :Bill, 'gov_kit/open_congress/bill'
7
+ autoload :BlogPost, 'gov_kit/open_congress/blog_post'
8
+ autoload :NewsPost, 'gov_kit/open_congress/news_post'
9
+ autoload :VotingComparison, 'gov_kit/open_congress/voting_comparison'
10
+ autoload :RollCallComparison, 'gov_kit/open_congress/roll_call_comparison'
11
+ autoload :Person, 'gov_kit/open_congress/person'
12
+ autoload :PersonStat, 'gov_kit/open_congress/person_stat'
13
+
14
+ class OpenCongressObject
15
+
16
+ def self.construct_url(api_method, params)
17
+ url = nil
18
+ if GovKit::configuration.opencongress_apikey == nil || GovKit::configuration.opencongress_apikey == ''
19
+ raise "Failed to provide OpenCongress API Key"
20
+ else
21
+ url = "http://#{GovKit::configuration.opencongress_base_url}api/#{api_method}?key=#{GovKit::configuration.opencongress_apikey}#{hash2get(params)}&format=json"
22
+ end
23
+ return url
24
+ end
25
+
26
+ def self.hash2get(h)
27
+ get_string = ""
28
+
29
+ h.each_pair do |key, value|
30
+ get_string += "&#{key.to_s}=#{CGI::escape(value.to_s)}"
31
+ end
32
+
33
+ get_string
34
+ end
35
+
36
+ def self.parse_supporting_results(result)
37
+ working = result["opencongress_users_tracking"]
38
+
39
+ also_supporting_bills = []
40
+ working["also_supporting_bills"]["bill"].each do |bill|
41
+ also_supporting_bills << Bill.new(bill)
42
+ end
43
+
44
+ also_opposing_bills = []
45
+ working["also_opposing_bills"]["bill"].each do |bill|
46
+ also_opposing_bills << Bill.new(bill)
47
+ end
48
+
49
+ also_disapproved_senators = []
50
+ working["also_disapproved_senators"]["person"].each do |person|
51
+ also_disapproved_senators << Person.new(person)
52
+ end
53
+
54
+ also_disapproved_representatives = []
55
+ working["also_disapproved_representatives"]["person"].each do |person|
56
+ also_disapproved_representatives << Person.new(person)
57
+ end
58
+
59
+ also_approved_senators = []
60
+ working["also_approved_senators"]["person"].each do |person|
61
+ also_approved_senators << Person.new(person)
62
+ end
63
+
64
+ also_approved_representatives = []
65
+ working["also_approved_representatives"]["person"].each do |person|
66
+ also_approved_representatives << Person.new(person)
67
+ end
68
+
69
+ return {:also_supporting_bills => also_supporting_bills,
70
+ :also_opposing_bills => also_opposing_bills,
71
+ :also_disapproved_senators => also_disapproved_senators,
72
+ :also_disapproved_representatives => also_disapproved_representatives,
73
+ :also_approved_senators => also_approved_senators,
74
+ :also_approved_representatives => also_approved_representatives}
75
+
76
+ end
77
+
78
+ def self.make_call(this_url)
79
+ result = nil
80
+ begin
81
+ result = JSON.parse(open(this_url).read)
82
+ rescue => e
83
+ puts e
84
+ end
85
+
86
+ return result
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,37 @@
1
+ module GovKit
2
+ module SearchEngines
3
+ class GoogleBlog
4
+ def self.search(options=[])
5
+ query = options.join('+')
6
+ host = "blogsearch.google.com"
7
+ path = "/blogsearch?hl=en&q=#{URI::encode(query)}&btnG=Search+Blogs&num=50"
8
+
9
+ html = make_request(host, path)
10
+ doc = Hpricot(Iconv.conv('utf-8//IGNORE', 'gb2312',html))
11
+ stories = doc.search("td.j")
12
+ titles = (doc/"a").select { |a| (a.attributes["id"] && a.attributes["id"].match(/p-(.*)/)) }
13
+
14
+ citations = []
15
+
16
+ stories.each do |story|
17
+ citation = GovKit::Citation.new
18
+ t = titles.shift
19
+
20
+ citation.title = (t.inner_html) if t #.unpack("C*").pack("U*") if t
21
+ citation.url = t.attributes["href"] if t
22
+ citation.date = story.at("font:nth(0)").inner_html
23
+ citation.excerpt = (story.at("br + font").inner_html) #.unpack("C*").pack("U*")
24
+ citation.source = story.at("a.f1").inner_html
25
+ citation.url = story.at("a.f1").attributes["href"]
26
+
27
+ citations << citation
28
+ end
29
+ citations
30
+ end
31
+
32
+ def self.make_request(host, path)
33
+ response = Net::HTTP.get(host, path)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+
4
+ module GovKit
5
+ module SearchEngines
6
+ class GoogleNews
7
+ def self.search(options=[])
8
+ query = options.join('+')
9
+ host = "news.google.com"
10
+ path = "/news?hl=en&ned=us&q=#{URI::encode(query)}&btnG=Search+News&num=50"
11
+
12
+ html = make_request(host, path)
13
+ doc = Hpricot(Iconv.conv('utf-8//IGNORE', 'gb2312',html))
14
+ stories = doc.search("div.search-results > div.story")
15
+
16
+ citations = []
17
+
18
+ stories.each do |story|
19
+ citation = GovKit::Citation.new
20
+
21
+ citation.title = story.at("h2.title a").inner_text.html_safe!
22
+ citation.url = story.at("h2.title a").attributes["href"]
23
+ citation.date = story.at("div.sub-title > span.date").inner_html.html_safe!
24
+ citation.source = story.at("div.sub-title > span.source").inner_html.html_safe!
25
+ citation.excerpt = story.at("div.body > div.snippet").inner_html.html_safe!
26
+
27
+ citations << citation
28
+ end
29
+ citations
30
+ end
31
+
32
+ def self.make_request(host, path)
33
+ puts host+path
34
+ response = Net::HTTP.get(host, path)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ module GovKit
2
+ module SearchEngines
3
+ class Technorati
4
+ def self.search(options=[])
5
+ query = options.to_query('q')
6
+ host = "api.technorati.com"
7
+ path = "/search?key=#{API_KEYS["technorati_api_key"]}&limit=50&language=en&query=#{URI::encode(query)}"
8
+
9
+ html = make_request(host, path)
10
+ doc = Hpricot(Iconv.conv('utf-8//IGNORE', 'gb2312',html))
11
+
12
+ citations = []
13
+ # doc.search("tapi/document/item").each do |i|
14
+ # citation = GovKit::Citation.new
15
+ #
16
+ # citation.url = i.text("permalink")
17
+ # citation.title = i.text("title")
18
+ # citation.excerpt = i.text("excerpt")
19
+ # citation.date = i.text("created")
20
+ # citation.source = i.text("weblog/name")
21
+ # citation.url = i.text("weblog/url")
22
+ # citation.weight = i.text("weblog/inboundlinks")
23
+ #
24
+ # citations << citation
25
+ # end
26
+ citations
27
+ []
28
+ end
29
+
30
+ def self.make_request(host, path)
31
+ response = Net::HTTP.get(host, path)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module GovKit::SearchEngines
2
+ autoload :GoogleNews, 'gov_kit/search_engines/google_news'
3
+ autoload :GoogleBlog, 'gov_kit/search_engines/google_blog'
4
+ autoload :Technorati, 'gov_kit/search_engines/technorati'
5
+ end
@@ -18,5 +18,34 @@ module GovKit
18
18
  instantiate_record(response['webaddress'])
19
19
  end
20
20
  end
21
+
22
+ class Bill < VoteSmartResource
23
+ def self.find(bill_id)
24
+ response = get("/Votes.getBill", :query => {"billId" => bill_id})
25
+ instantiate_record(response['bill'])
26
+ end
27
+
28
+ def self.find_by_year_and_state(year, state_abbrev)
29
+ response = get("/Votes.getBillsByYearState", :query => {"year" => year, "stateId" => state_abbrev})
30
+ instantiate_record(response['bills'])
31
+ end
32
+ end
33
+
34
+ # See http://api.votesmart.org/docs/Committee.html
35
+ class Committee < VoteSmartResource
36
+ # Find a committee by VoteSmart typeId and stateId (abbreviation)
37
+ # If type_id is nil, defaults to all types.
38
+ # This method maps to Committee.getCommitteesByTypeState()
39
+ def self.find_by_type_and_state(type_id, state_abbrev)
40
+ response = get("/Committee.getCommitteesByTypeState", :query => {"typeId" => type_id, "stateId" => state_abbrev})
41
+ instantiate_record(response['committees'])
42
+ end
43
+
44
+ # Find a committee by VoteSmart committeeId. Maps to Committee.getCommittee()
45
+ def self.find(committee_id)
46
+ response = get("/Committee.getCommittee", :query => {"committeeId" => committee_id})
47
+ instantiate_record(response['committee'])
48
+ end
49
+ end
21
50
  end
22
51
  end
data/lib/gov_kit.rb CHANGED
@@ -2,19 +2,39 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.i
2
2
 
3
3
  require 'active_support'
4
4
  require 'gov_kit/configuration'
5
+ require 'iconv'
6
+ require 'gov_kit/search_engines'
5
7
 
6
8
  module GovKit
7
9
  autoload :FiftyStates, 'gov_kit/fifty_states'
8
10
  autoload :VoteSmart, 'gov_kit/vote_smart'
11
+ autoload :ActsAsCiteable, 'gov_kit/acts_as_citeable'
12
+ autoload :FollowTheMoney, 'gov_kit/follow_the_money'
13
+ autoload :OpenCongress, 'gov_kit/open_congress'
14
+
15
+ class Bill < Resource;
16
+ end
17
+ class Vote < Resource;
18
+ end
19
+ class Session < Resource;
20
+ end
21
+ class Role < Resource;
22
+ end
23
+ class Legislator < Resource;
24
+ end
25
+ class Vote < Resource;
26
+ end
27
+ class Sponsor < Resource;
28
+ end
29
+ class Version < Resource;
30
+ end
31
+ class Source < Resource;
32
+ end
33
+ class Address < Resource;
34
+ end
35
+
36
+ class Citation
37
+ attr_accessor :url, :excerpt, :title, :source, :date, :weight
38
+ end
9
39
 
10
- class Bill < Resource; end
11
- class Vote < Resource; end
12
- class Session < Resource; end
13
- class Role < Resource; end
14
- class Legislator < Resource; end
15
- class Vote < Resource; end
16
- class Sponsor < Resource; end
17
- class Version < Resource; end
18
- class Source < Resource; end
19
- class Address < Resource; end
20
40
  end
data/rails/init.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  # Include hook code here
2
2
  require File.join(File.dirname(__FILE__), *%w[.. lib govkit])
3
+ ActiveRecord::Base.send(:include, GovKit::ActsAsCiteable)
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govkit
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 27
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
8
+ - 1
7
9
  - 0
8
- - 2
9
- version: 0.0.2
10
+ version: 0.1.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Participatory Politics Foundation
@@ -16,16 +17,18 @@ autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2010-05-14 00:00:00 -07:00
20
+ date: 2010-06-10 00:00:00 -07:00
20
21
  default_executable:
21
22
  dependencies:
22
23
  - !ruby/object:Gem::Dependency
23
24
  name: httparty
24
25
  prerelease: false
25
26
  requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
26
28
  requirements:
27
29
  - - ">="
28
30
  - !ruby/object:Gem::Version
31
+ hash: 15
29
32
  segments:
30
33
  - 0
31
34
  - 5
@@ -37,16 +40,34 @@ dependencies:
37
40
  name: json
38
41
  prerelease: false
39
42
  requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
40
44
  requirements:
41
45
  - - ">="
42
46
  - !ruby/object:Gem::Version
47
+ hash: 1
43
48
  segments:
44
49
  - 1
45
- - 2
46
50
  - 4
47
- version: 1.2.4
51
+ - 3
52
+ version: 1.4.3
48
53
  type: :runtime
49
54
  version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: hpricot
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 59
64
+ segments:
65
+ - 0
66
+ - 8
67
+ - 2
68
+ version: 0.8.2
69
+ type: :runtime
70
+ version_requirements: *id003
50
71
  description: 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.
51
72
  email: carl@ppolitics.org
52
73
  executables: []
@@ -68,14 +89,26 @@ files:
68
89
  - generators/govkit/templates/govkit.rb
69
90
  - govkit.gemspec
70
91
  - lib/gov_kit.rb
92
+ - lib/gov_kit/acts_as_citeable.rb
71
93
  - lib/gov_kit/configuration.rb
72
94
  - lib/gov_kit/fifty_states.rb
95
+ - lib/gov_kit/follow_the_money.rb
96
+ - lib/gov_kit/open_congress.rb
97
+ - lib/gov_kit/open_congress/bill.rb
98
+ - lib/gov_kit/open_congress/blog_post.rb
99
+ - lib/gov_kit/open_congress/news_post.rb
100
+ - lib/gov_kit/open_congress/person.rb
101
+ - lib/gov_kit/open_congress/person_stat.rb
102
+ - lib/gov_kit/open_congress/roll_call.rb
103
+ - lib/gov_kit/open_congress/roll_call_comparison.rb
104
+ - lib/gov_kit/open_congress/voting_comparison.rb
73
105
  - lib/gov_kit/resource.rb
106
+ - lib/gov_kit/search_engines.rb
107
+ - lib/gov_kit/search_engines/google_blog.rb
108
+ - lib/gov_kit/search_engines/google_news.rb
109
+ - lib/gov_kit/search_engines/technorati.rb
74
110
  - lib/gov_kit/vote_smart.rb
75
111
  - lib/govkit.rb
76
- - lib/govkit/configuration.rb
77
- - lib/govkit/fifty_states.rb
78
- - lib/govkit/vote_smart.rb
79
112
  - rails/init.rb
80
113
  - spec/fifty_states_spec.rb
81
114
  - spec/spec.opts
@@ -90,23 +123,27 @@ rdoc_options:
90
123
  require_paths:
91
124
  - lib
92
125
  required_ruby_version: !ruby/object:Gem::Requirement
126
+ none: false
93
127
  requirements:
94
128
  - - ">="
95
129
  - !ruby/object:Gem::Version
130
+ hash: 3
96
131
  segments:
97
132
  - 0
98
133
  version: "0"
99
134
  required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
100
136
  requirements:
101
137
  - - ">="
102
138
  - !ruby/object:Gem::Version
139
+ hash: 3
103
140
  segments:
104
141
  - 0
105
142
  version: "0"
106
143
  requirements: []
107
144
 
108
145
  rubyforge_project:
109
- rubygems_version: 1.3.6
146
+ rubygems_version: 1.3.7
110
147
  signing_key:
111
148
  specification_version: 3
112
149
  summary: Simple access to open government APIs around the web
@@ -1,29 +0,0 @@
1
- module Govkit
2
- class Configuration
3
- attr_accessor :fiftystates_apikey, :fiftystates_base_url
4
- attr_accessor :votesmart_apikey, :votesmart_base_url
5
-
6
- def initialize
7
- @fiftystates_apikey = ''
8
- @fiftystates_base_url = 'fiftystates-dev.sunlightlabs.com/api'
9
-
10
- @votesmart_apikey = ''
11
- @votesmart_base_url = 'api.votesmart.org/'
12
- end
13
- end
14
-
15
- class << self
16
- attr_accessor :configuration
17
- end
18
-
19
- # Configure Govkit in config/initializers/govkit.rb
20
- #
21
- # @example
22
- # Govkit.configure do |config|
23
- # config.fiftystates_apikey = ''
24
- # end
25
- def self.configure
26
- self.configuration ||= Configuration.new
27
- yield(configuration)
28
- end
29
- end