govkit 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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