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/lib/govkit/fifty_states.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
require 'httparty'
|
2
|
-
|
3
|
-
module Govkit::FiftyStates
|
4
|
-
|
5
|
-
ROLE_MEMBER = "member"
|
6
|
-
ROLE_COMMITTEE_MEMBER = "committee member"
|
7
|
-
CHAMBER_UPPER = "upper"
|
8
|
-
CHAMBER_LOWER = "lower"
|
9
|
-
|
10
|
-
class FiftyStatesError < StandardError
|
11
|
-
attr_reader :response
|
12
|
-
|
13
|
-
def initialize(response, message = nil)
|
14
|
-
@response = response
|
15
|
-
@message = message
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
"Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class NotauthorizedError < FiftyStatesError;
|
24
|
-
end
|
25
|
-
|
26
|
-
class InvalidRequestError < StandardError;
|
27
|
-
end
|
28
|
-
|
29
|
-
class NotFoundError < FiftyStatesError;
|
30
|
-
end
|
31
|
-
|
32
|
-
class NameError < FiftyStatesError;
|
33
|
-
end
|
34
|
-
|
35
|
-
class Base
|
36
|
-
include HTTParty
|
37
|
-
format :json
|
38
|
-
default_params :output => 'json', :apikey => Govkit::configuration.fiftystates_apikey
|
39
|
-
base_uri Govkit::configuration.fiftystates_base_url
|
40
|
-
|
41
|
-
attr_accessor :attributes
|
42
|
-
|
43
|
-
def initialize(attributes = {})
|
44
|
-
@attributes = {}
|
45
|
-
unload(attributes)
|
46
|
-
end
|
47
|
-
|
48
|
-
class << self
|
49
|
-
def instantiate_record(record)
|
50
|
-
new(record)
|
51
|
-
end
|
52
|
-
|
53
|
-
def instantiate_collection(collection)
|
54
|
-
collection.collect! { |record| instantiate_record(record) }
|
55
|
-
end
|
56
|
-
|
57
|
-
def parse(json)
|
58
|
-
instantiate_record(json)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def unload(attributes)
|
63
|
-
raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
|
64
|
-
attributes.each do |key, value|
|
65
|
-
@attributes[key.to_s] =
|
66
|
-
case value
|
67
|
-
when Array
|
68
|
-
resource = resource_for_collection(key)
|
69
|
-
value.map do |attrs|
|
70
|
-
if attrs.is_a?(String) || attrs.is_a?(Numeric)
|
71
|
-
attrs.duplicable? ? attrs.dup : attrs
|
72
|
-
else
|
73
|
-
resource.new(attrs)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
when Hash
|
77
|
-
resource = find_or_create_resource_for(key)
|
78
|
-
resource.new(value)
|
79
|
-
else
|
80
|
-
value.dup rescue value
|
81
|
-
end
|
82
|
-
end
|
83
|
-
self
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
def resource_for_collection(name)
|
88
|
-
find_resource_for(name.to_s.singularize)
|
89
|
-
end
|
90
|
-
|
91
|
-
def find_resource_in_modules(resource_name, module_names)
|
92
|
-
receiver = Object
|
93
|
-
namespaces = module_names[0, module_names.size-1].map do |module_name|
|
94
|
-
receiver = receiver.const_get(module_name)
|
95
|
-
end
|
96
|
-
if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
|
97
|
-
return namespace.const_get(resource_name)
|
98
|
-
else
|
99
|
-
raise NameError, "Namespace for #{namespace} not found"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def find_resource_for(name)
|
104
|
-
resource_name = name.to_s.camelize
|
105
|
-
ancestors = self.class.name.split("::")
|
106
|
-
if ancestors.size > 1
|
107
|
-
find_resource_in_modules(resource_name, ancestors)
|
108
|
-
else
|
109
|
-
self.class.const_get(resource_name)
|
110
|
-
end
|
111
|
-
rescue NameError
|
112
|
-
#TODO: May be we should create new classes based on unknown records
|
113
|
-
end
|
114
|
-
|
115
|
-
def method_missing(method_symbol, *arguments) #:nodoc:
|
116
|
-
method_name = method_symbol.to_s
|
117
|
-
|
118
|
-
case method_name.last
|
119
|
-
when "="
|
120
|
-
attributes[method_name.first(-1)] = arguments.first
|
121
|
-
when "?"
|
122
|
-
attributes[method_name.first(-1)]
|
123
|
-
when "]"
|
124
|
-
attributes[arguments.first.to_s]
|
125
|
-
else
|
126
|
-
attributes.has_key?(method_name) ? attributes[method_name] : super
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
class State < Base
|
132
|
-
def self.find_by_abbreviation(abbreviation)
|
133
|
-
response = get("/#{abbreviation}")
|
134
|
-
instantiate_record(response)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
class Bill < Base
|
139
|
-
# http://fiftystates-dev.sunlightlabs.com/api/ca/20092010/lower/bills/AB667/
|
140
|
-
def self.find(state_abbrev, session, chamber, bill_id)
|
141
|
-
response = get("/#{state_abbrev}/#{session}/#{chamber}/bills/#{bill_id}/")
|
142
|
-
instantiate_record(response)
|
143
|
-
end
|
144
|
-
|
145
|
-
def self.search(query, options = {})
|
146
|
-
response = get('/bills/search', :query => {:q => query}.merge(options))
|
147
|
-
instantiate_collection(response)
|
148
|
-
end
|
149
|
-
|
150
|
-
def self.latest(updated_since, state_abbrev)
|
151
|
-
response = get('/bills/latest/', :query => {:updated_since => updated_since, :state => state_abbrev})
|
152
|
-
instantiate_collection(response)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
class Legislator < Base
|
157
|
-
def self.find(legislator_id)
|
158
|
-
response = get("/legislators/#{legislator_id}")
|
159
|
-
instantiate_record(response)
|
160
|
-
end
|
161
|
-
|
162
|
-
def self.search(options = {})
|
163
|
-
response = get('/legislators/search', :query => options)
|
164
|
-
instantiate_collection(response)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
class Session < Base; end
|
169
|
-
|
170
|
-
class Role < Base; end
|
171
|
-
|
172
|
-
class Action < Base; end
|
173
|
-
|
174
|
-
class Vote < Base
|
175
|
-
def self.find(vote_id)
|
176
|
-
response = get("/votes/#{vote_id}")
|
177
|
-
instantiate_record(response)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
class Roll < Base; end
|
182
|
-
|
183
|
-
class Sponsor < Base; end
|
184
|
-
|
185
|
-
class Version < Base; end
|
186
|
-
|
187
|
-
class Source < Base; end
|
188
|
-
end
|
data/lib/govkit/vote_smart.rb
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
require 'httparty'
|
2
|
-
|
3
|
-
module Govkit::VoteSmart
|
4
|
-
class VoteSmartError < StandardError
|
5
|
-
attr_reader :response
|
6
|
-
|
7
|
-
def initialize(response, message = nil)
|
8
|
-
@response = response
|
9
|
-
@message = message
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
"Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class NotauthorizedError < VoteSmartError;
|
18
|
-
end
|
19
|
-
|
20
|
-
class InvalidRequestError < StandardError;
|
21
|
-
end
|
22
|
-
|
23
|
-
class NotFoundError < VoteSmartError;
|
24
|
-
end
|
25
|
-
|
26
|
-
class NameError < VoteSmartError;
|
27
|
-
end
|
28
|
-
|
29
|
-
class Base
|
30
|
-
include HTTParty
|
31
|
-
default_params :o => 'JSON', :key => Govkit::configuration.votesmart_apikey
|
32
|
-
base_uri Govkit::configuration.votesmart_base_url
|
33
|
-
|
34
|
-
attr_accessor :attributes
|
35
|
-
|
36
|
-
def initialize(attributes = {})
|
37
|
-
@attributes = {}
|
38
|
-
unload(attributes)
|
39
|
-
end
|
40
|
-
|
41
|
-
class << self
|
42
|
-
def instantiate_record(record)
|
43
|
-
new(record)
|
44
|
-
end
|
45
|
-
|
46
|
-
def instantiate_collection(collection)
|
47
|
-
collection.collect! { |record| instantiate_record(record) }
|
48
|
-
end
|
49
|
-
|
50
|
-
def parse(json)
|
51
|
-
instantiate_record(json)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def unload(attributes)
|
56
|
-
raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
|
57
|
-
attributes.each do |key, value|
|
58
|
-
@attributes[key.to_s] =
|
59
|
-
case value
|
60
|
-
when Array
|
61
|
-
resource = resource_for_collection(key)
|
62
|
-
value.map do |attrs|
|
63
|
-
if attrs.is_a?(String) || attrs.is_a?(Numeric)
|
64
|
-
attrs.duplicable? ? attrs.dup : attrs
|
65
|
-
else
|
66
|
-
resource.new(attrs)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
when Hash
|
70
|
-
resource = find_or_create_resource_for(key)
|
71
|
-
resource.new(value)
|
72
|
-
else
|
73
|
-
value.dup rescue value
|
74
|
-
end
|
75
|
-
end
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
def resource_for_collection(name)
|
81
|
-
find_or_create_resource_for(name.to_s.singularize)
|
82
|
-
end
|
83
|
-
|
84
|
-
def find_resource_in_modules(resource_name, module_names)
|
85
|
-
receiver = Object
|
86
|
-
namespaces = module_names[0, module_names.size-1].map do |module_name|
|
87
|
-
receiver = receiver.const_get(module_name)
|
88
|
-
end
|
89
|
-
if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
|
90
|
-
return namespace.const_get(resource_name)
|
91
|
-
else
|
92
|
-
raise NameError, "Namespace for #{namespace} not found"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def find_or_create_resource_for(name)
|
97
|
-
resource_name = name.to_s.camelize
|
98
|
-
ancestors = self.class.name.split("::")
|
99
|
-
if ancestors.size > 1
|
100
|
-
find_resource_in_modules(resource_name, ancestors)
|
101
|
-
else
|
102
|
-
self.class.const_get(resource_name)
|
103
|
-
end
|
104
|
-
rescue NameError
|
105
|
-
if self.class.const_defined?(resource_name)
|
106
|
-
resource = self.class.const_get(resource_name)
|
107
|
-
else
|
108
|
-
resource = self.class.const_set(resource_name, Class.new(Base))
|
109
|
-
end
|
110
|
-
resource
|
111
|
-
end
|
112
|
-
|
113
|
-
def method_missing(method_symbol, * arguments) #:nodoc:
|
114
|
-
method_name = method_symbol.to_s
|
115
|
-
|
116
|
-
case method_name.last
|
117
|
-
when "="
|
118
|
-
attributes[method_name.first(-1)] = arguments.first
|
119
|
-
when "?"
|
120
|
-
attributes[method_name.first(-1)]
|
121
|
-
when "]"
|
122
|
-
attributes[arguments.first.to_s]
|
123
|
-
else
|
124
|
-
attributes.has_key?(method_name) ? attributes[method_name] : super
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
class Address < Base
|
130
|
-
class << self
|
131
|
-
def find(candidate_id)
|
132
|
-
response = get("/Address.getOffice", :query => {"candidateId" => candidate_id})
|
133
|
-
instantiate_record(response['address'])
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
class WebAddress < Base
|
139
|
-
class << self
|
140
|
-
def find(candidate_id)
|
141
|
-
response = get("/Address.getOfficeWebAddress", :query => {"candidateId" => candidate_id})
|
142
|
-
instantiate_record(response['webaddress'])
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|