govkit 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.travis.yml +2 -0
  2. data/Gemfile +11 -5
  3. data/README.md +1 -1
  4. data/Rakefile +29 -13
  5. data/VERSION +1 -1
  6. data/govkit.gemspec +25 -36
  7. data/lib/gov_kit.rb +16 -5
  8. data/lib/gov_kit/configuration.rb +5 -5
  9. data/lib/gov_kit/follow_the_money.rb +5 -2
  10. data/lib/gov_kit/open_congress.rb +3 -11
  11. data/lib/gov_kit/open_congress/bill.rb +32 -29
  12. data/lib/gov_kit/open_congress/person.rb +21 -20
  13. data/lib/gov_kit/open_states.rb +10 -15
  14. data/lib/gov_kit/railtie.rb +0 -2
  15. data/lib/gov_kit/resource.rb +0 -1
  16. data/lib/gov_kit/transparency_data.rb +1 -1
  17. data/lib/gov_kit/vote_smart.rb +81 -6
  18. data/{init.rb → rails/init.rb} +0 -0
  19. data/spec/fixtures/open_states/401.response +9 -9
  20. data/spec/fixtures/open_states/404.response +9 -9
  21. data/spec/fixtures/open_states/bill.response +9 -240
  22. data/spec/fixtures/open_states/bill_find.response +9 -0
  23. data/spec/fixtures/open_states/bill_query.response +9 -1990
  24. data/spec/fixtures/open_states/committee_find.response +9 -53
  25. data/spec/fixtures/open_states/committee_query.response +9 -190
  26. data/spec/fixtures/open_states/legislator_find.response +9 -0
  27. data/spec/fixtures/open_states/legislator_query.response +9 -144
  28. data/spec/fixtures/open_states/state.response +9 -60
  29. data/spec/follow_the_money_spec.rb +20 -16
  30. data/spec/open_congress_spec.rb +23 -35
  31. data/spec/open_states_spec.rb +63 -78
  32. data/spec/search_engines_spec.rb +10 -13
  33. data/spec/spec_helper.rb +16 -8
  34. data/spec/transparency_data_spec.rb +19 -35
  35. metadata +140 -145
  36. data/spec/fixtures/open_states/410.response +0 -6
  37. data/spec/fixtures/open_states/legislator.response +0 -34
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.2
data/Gemfile CHANGED
@@ -1,13 +1,19 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gemspec
4
-
5
- gem "activesupport", :require => 'active_support'
6
- gem "nokogiri"
7
- gem "httparty"
8
3
  gem "i18n"
4
+ gem "activesupport", :require => 'active_support'
5
+ gem "nokogiri", '~> 1.5.5'
6
+ gem "httparty", '>= 0.7.4'
7
+ gem "json", '>= 1.4.3'
8
+ gem "fastercsv", '>= 1.5.3'
9
+
10
+ group :development do
11
+ gem "jeweler"
12
+ gem "rake"
13
+ end
9
14
 
10
15
  group :test do
16
+ gem "rake"
11
17
  gem "rspec"
12
18
  gem "fakeweb"
13
19
  end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Govkit
1
+ # Govkit [![Build Status](https://secure.travis-ci.org/opengovernment/govkit.png)](http://travis-ci.org/opengovernment/govkit)
2
2
 
3
3
  Govkit is a Ruby gem that provides simple access to US open government APIs around the web, including:
4
4
 
data/Rakefile CHANGED
@@ -22,10 +22,6 @@ begin
22
22
  gem.email = "develop@opencongress.org"
23
23
  gem.homepage = "http://github.com/opengovernment/govkit"
24
24
  gem.authors = ["Participatory Politics Foundation", "Srinivas Aki", "Carl Tashian"]
25
- gem.add_dependency('httparty', '>= 0.7.4')
26
- gem.add_dependency('json', '>= 1.4.3')
27
- gem.add_dependency('nokogiri', '>= 1.4.4')
28
- gem.add_dependency('fastercsv', '>= 1.5.3')
29
25
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
30
26
  end
31
27
  Jeweler::GemcutterTasks.new
@@ -60,23 +56,43 @@ Rake::RDocTask.new do |rdoc|
60
56
  end
61
57
 
62
58
 
63
- if defined?(Spec)
59
+ if defined?(RSpec)
64
60
  desc 'Test the govkit plugin.'
65
- Spec::Rake::SpecTask.new('spec') do |t|
66
- t.spec_files = FileList['spec/**/*_spec.rb']
67
- t.spec_opts = ["-c"]
61
+ RSpec::Core::RakeTask.new('spec') do |t|
62
+ t.rspec_opts = ["-c"]
68
63
  end
69
64
 
70
65
  desc 'Test the govkit plugin with specdoc formatting and colors'
71
- Spec::Rake::SpecTask.new('specdoc') do |t|
72
- t.spec_files = FileList['spec/**/*_spec.rb']
73
- t.spec_opts = ["--format specdoc", "-c"]
66
+ RSpec::Core::RakeTask.new('specdoc') do |t|
67
+ t.rspec_opts = ["--format specdoc", "-c"]
74
68
  end
75
69
 
76
70
  desc "Run all examples with RCov"
77
- Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
78
- t.spec_files = FileList['spec/**/*_spec.rb']
71
+ RSpec::Core::RakeTask.new('examples_with_rcov') do |t|
79
72
  t.rcov = true
80
73
  t.rcov_opts = ['--exclude', 'spec,Library']
81
74
  end
82
75
  end
76
+
77
+ desc "Generate RSpec fixtures"
78
+ task :generate_rspec_fixtures do |t,args|
79
+ if ENV['APIKEY'].nil?
80
+ abort "Usage: APIKEY=12345... rake generate_rspec_fixtures"
81
+ end
82
+
83
+ { "/legislators/XXL123456/" => '401.response',
84
+ "/metadata/ca/?apikey=#{ENV['APIKEY']}" => 'state.response',
85
+ "/bills/ca/20092010/lower/AB%20667/?apikey=#{ENV['APIKEY']}" => 'bill.response',
86
+ "/bills/?apikey=#{ENV['APIKEY']}&q=cooperatives" => 'bill_find.response',
87
+ "/bills/?apikey=#{ENV['APIKEY']}&updated_since=2012-11-01&state=tx" => 'bill_query.response',
88
+ "/legislators/CAL000088/?apikey=#{ENV['APIKEY']}" => 'legislator_find.response',
89
+ "/legislators/CAL999999/?apikey=#{ENV['APIKEY']}" => '404.response',
90
+ "/legislators/?apikey=#{ENV['APIKEY']}&state=ca" => 'legislator_query.response',
91
+ "/legislators/?apikey=#{ENV['APIKEY']}&state=zz" => '404.response',
92
+ "/committees/MDC000012/?apikey=#{ENV['APIKEY']}" => 'committee_find.response',
93
+ "/committees/?apikey=#{ENV['APIKEY']}&state=md&chamber=upper" => 'committee_query.response',
94
+ }.each do |path,basename|
95
+ filepath = File.expand_path("../spec/fixtures/open_states/#{basename}", __FILE__)
96
+ `curl -s -i -o #{filepath} "http://openstates.org/api/v1#{path}"`
97
+ end
98
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.2
1
+ 0.7.3
data/govkit.gemspec CHANGED
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{govkit}
8
- s.version = "0.7.2"
7
+ s.name = "govkit"
8
+ s.version = "0.7.3"
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{2012-01-23}
13
- s.description = %q{Govkit lets you quickly get encapsulated Ruby objects for common open government APIs. We're starting with Sunlight's Open States API and the Project Vote Smart API.}
14
- s.email = %q{develop@opencongress.org}
12
+ s.date = "2012-11-20"
13
+ s.description = "Govkit lets you quickly get encapsulated Ruby objects for common open government APIs. We're starting with Sunlight's Open States API and the Project Vote Smart API."
14
+ s.email = "develop@opencongress.org"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
17
  "README.md"
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.files = [
20
20
  ".document",
21
21
  ".rspec",
22
+ ".travis.yml",
22
23
  "Gemfile",
23
24
  "LICENSE",
24
25
  "README.md",
@@ -30,7 +31,6 @@ Gem::Specification.new do |s|
30
31
  "generators/govkit/templates/govkit.rb",
31
32
  "generators/govkit/templates/mention.rb",
32
33
  "govkit.gemspec",
33
- "init.rb",
34
34
  "lib/generators/govkit/govkit_generator.rb",
35
35
  "lib/generators/govkit/templates/create_mentions.rb",
36
36
  "lib/generators/govkit/templates/govkit.rb",
@@ -60,6 +60,7 @@ Gem::Specification.new do |s|
60
60
  "lib/gov_kit/transparency_data.rb",
61
61
  "lib/gov_kit/vote_smart.rb",
62
62
  "lib/govkit.rb",
63
+ "rails/init.rb",
63
64
  "spec/fixtures/bing/news_search.response",
64
65
  "spec/fixtures/bing/no_results.response",
65
66
  "spec/fixtures/follow_the_money/business-page0.response",
@@ -73,12 +74,12 @@ Gem::Specification.new do |s|
73
74
  "spec/fixtures/open_congress/person.response",
74
75
  "spec/fixtures/open_states/401.response",
75
76
  "spec/fixtures/open_states/404.response",
76
- "spec/fixtures/open_states/410.response",
77
77
  "spec/fixtures/open_states/bill.response",
78
+ "spec/fixtures/open_states/bill_find.response",
78
79
  "spec/fixtures/open_states/bill_query.response",
79
80
  "spec/fixtures/open_states/committee_find.response",
80
81
  "spec/fixtures/open_states/committee_query.response",
81
- "spec/fixtures/open_states/legislator.response",
82
+ "spec/fixtures/open_states/legislator_find.response",
82
83
  "spec/fixtures/open_states/legislator_query.response",
83
84
  "spec/fixtures/open_states/state.response",
84
85
  "spec/fixtures/search_engines/google_news.response",
@@ -95,54 +96,42 @@ Gem::Specification.new do |s|
95
96
  "spec/spec_helper.rb",
96
97
  "spec/transparency_data_spec.rb"
97
98
  ]
98
- s.homepage = %q{http://github.com/opengovernment/govkit}
99
+ s.homepage = "http://github.com/opengovernment/govkit"
99
100
  s.require_paths = ["lib"]
100
- s.rubygems_version = %q{1.3.6}
101
- s.summary = %q{Simple access to open government APIs around the web}
102
- s.test_files = [
103
- "spec/follow_the_money_spec.rb",
104
- "spec/open_congress_spec.rb",
105
- "spec/open_states_spec.rb",
106
- "spec/search_engines_spec.rb",
107
- "spec/spec_helper.rb",
108
- "spec/transparency_data_spec.rb"
109
- ]
101
+ s.rubygems_version = "1.8.24"
102
+ s.summary = "Simple access to open government APIs around the web"
110
103
 
111
104
  if s.respond_to? :specification_version then
112
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
113
105
  s.specification_version = 3
114
106
 
115
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
116
- s.add_runtime_dependency(%q<govkit>, [">= 0"])
117
- s.add_runtime_dependency(%q<activesupport>, [">= 0"])
118
- s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
119
- s.add_runtime_dependency(%q<httparty>, [">= 0"])
107
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
120
108
  s.add_runtime_dependency(%q<i18n>, [">= 0"])
109
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
110
+ s.add_runtime_dependency(%q<nokogiri>, ["~> 1.5.5"])
121
111
  s.add_runtime_dependency(%q<httparty>, [">= 0.7.4"])
122
112
  s.add_runtime_dependency(%q<json>, [">= 1.4.3"])
123
- s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.4"])
124
113
  s.add_runtime_dependency(%q<fastercsv>, [">= 1.5.3"])
114
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
115
+ s.add_development_dependency(%q<rake>, [">= 0"])
125
116
  else
126
- s.add_dependency(%q<govkit>, [">= 0"])
127
- s.add_dependency(%q<activesupport>, [">= 0"])
128
- s.add_dependency(%q<nokogiri>, [">= 0"])
129
- s.add_dependency(%q<httparty>, [">= 0"])
130
117
  s.add_dependency(%q<i18n>, [">= 0"])
118
+ s.add_dependency(%q<activesupport>, [">= 0"])
119
+ s.add_dependency(%q<nokogiri>, ["~> 1.5.5"])
131
120
  s.add_dependency(%q<httparty>, [">= 0.7.4"])
132
121
  s.add_dependency(%q<json>, [">= 1.4.3"])
133
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
134
122
  s.add_dependency(%q<fastercsv>, [">= 1.5.3"])
123
+ s.add_dependency(%q<jeweler>, [">= 0"])
124
+ s.add_dependency(%q<rake>, [">= 0"])
135
125
  end
136
126
  else
137
- s.add_dependency(%q<govkit>, [">= 0"])
138
- s.add_dependency(%q<activesupport>, [">= 0"])
139
- s.add_dependency(%q<nokogiri>, [">= 0"])
140
- s.add_dependency(%q<httparty>, [">= 0"])
141
127
  s.add_dependency(%q<i18n>, [">= 0"])
128
+ s.add_dependency(%q<activesupport>, [">= 0"])
129
+ s.add_dependency(%q<nokogiri>, ["~> 1.5.5"])
142
130
  s.add_dependency(%q<httparty>, [">= 0.7.4"])
143
131
  s.add_dependency(%q<json>, [">= 1.4.3"])
144
- s.add_dependency(%q<nokogiri>, [">= 1.4.4"])
145
132
  s.add_dependency(%q<fastercsv>, [">= 1.5.3"])
133
+ s.add_dependency(%q<jeweler>, [">= 0"])
134
+ s.add_dependency(%q<rake>, [">= 0"])
146
135
  end
147
136
  end
148
137
 
data/lib/gov_kit.rb CHANGED
@@ -1,18 +1,29 @@
1
1
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
2
2
 
3
+ require 'csv'
3
4
  require 'digest/md5'
4
- require 'nokogiri'
5
5
  require 'iconv'
6
- require 'httparty'
7
- require 'open-uri'
8
6
  require 'json'
9
- require 'gov_kit/configuration'
10
- require 'csv'
7
+ require 'open-uri'
11
8
 
12
9
  if RUBY_VERSION[0,3] == "1.8"
13
10
  require 'fastercsv'
14
11
  end
15
12
 
13
+ require 'nokogiri'
14
+ require 'httparty'
15
+
16
+ # String#singularize in Resource#resource_for_collection
17
+ require 'active_support/inflector'
18
+ # String#last in Resource#method_missing
19
+ require 'active_support/core_ext/string'
20
+ # Object#blank? in Resource#parse
21
+ # Object#duplicable? in Resource#unload
22
+ require 'active_support/core_ext/object'
23
+
24
+ require 'gov_kit/railtie'
25
+ require 'gov_kit/configuration'
26
+
16
27
  module GovKit
17
28
  autoload :Resource, 'gov_kit/resource'
18
29
  autoload :OpenStates, 'gov_kit/open_states'
@@ -11,11 +11,11 @@ module GovKit
11
11
 
12
12
  def initialize
13
13
  @sunlight_apikey = @openstates_apikey = @votesmart_apikey = @ftm_apikey = ''
14
- @openstates_base_url = 'openstates.sunlightlabs.com/api/v1/'
15
- @transparency_data_base_url = 'transparencydata.com/api/1.0/'
16
- @votesmart_base_url = 'api.votesmart.org/'
17
- @ftm_base_url = 'api.followthemoney.org/'
18
- @opencongress_base_url = 'www.opencongress.org/'
14
+ @openstates_base_url = 'openstates.org/api/v1'
15
+ @transparency_data_base_url = 'transparencydata.com/api/1.0'
16
+ @votesmart_base_url = 'api.votesmart.org'
17
+ @ftm_base_url = 'api.followthemoney.org'
18
+ @opencongress_base_url = 'api.opencongress.org'
19
19
  @technorati_base_url = 'api.technorati.com'
20
20
  @bing_base_url = 'api.search.live.net'
21
21
  @google_blog_base_url = 'blogsearch.google.com'
@@ -6,8 +6,8 @@ module GovKit
6
6
  #
7
7
  # For the details on the FollowTheMoney queries, see {http://www.followthemoney.org/services/methods.phtml the FollowTheMoney API documentation}.
8
8
  class FollowTheMoneyResource < Resource
9
- default_params :key => GovKit::configuration.ftm_apikey
10
9
  base_uri GovKit::configuration.ftm_base_url
10
+ format :xml
11
11
 
12
12
  # Common method used by subclasses to get data from the service.
13
13
  #
@@ -19,7 +19,10 @@ module GovKit
19
19
  # doc = get_xml("/base_level.industries.list.php", :query => {:page => page_num})
20
20
  #
21
21
  def self.get_xml(path, options)
22
- doc = Nokogiri::XML(get(path, options))
22
+ options[:query] ||= {}
23
+ options[:query][:key] = GovKit::configuration.ftm_apikey
24
+
25
+ doc = Nokogiri::XML(get(path, options).body)
23
26
 
24
27
  e = doc.search("//error")
25
28
 
@@ -1,7 +1,7 @@
1
1
  require 'nokogiri'
2
2
  require 'open-uri'
3
3
  require 'json'
4
- require 'CGI'
4
+ require 'cgi'
5
5
 
6
6
  module GovKit::OpenCongress
7
7
  autoload :Bill, 'gov_kit/open_congress/bill'
@@ -33,7 +33,7 @@ module GovKit::OpenCongress
33
33
  def self.construct_url(api_method, params)
34
34
  url = nil
35
35
  getkey = GovKit::configuration.opencongress_apikey.nil? ? "" : "&key=#{GovKit::configuration.opencongress_apikey}"
36
- url = "http://#{GovKit::configuration.opencongress_base_url}api/#{api_method}?format=json#{hash2get(params)}#{getkey}"
36
+ url = "http://#{GovKit::configuration.opencongress_base_url}/#{api_method}?format=json#{hash2get(params)}#{getkey}"
37
37
  return url
38
38
  end
39
39
 
@@ -111,15 +111,7 @@ module GovKit::OpenCongress
111
111
  #
112
112
  # @return the returned data, as an array of hashes.
113
113
  def self.make_call(this_url)
114
- result = nil
115
- begin
116
- result = JSON.parse(open(this_url).read)
117
- rescue => e
118
- puts e
119
- end
120
-
121
- return result
122
-
114
+ JSON.parse(open(this_url).read)
123
115
  end
124
116
  end
125
117
  end
@@ -123,46 +123,49 @@ module GovKit
123
123
  def self.parse_results(result)
124
124
 
125
125
  bills = []
126
- result["bills"].each do |bill|
127
-
128
- these_recent_blogs = bill["recent_blogs"]
129
- blogs = []
130
-
131
- if these_recent_blogs
132
- these_recent_blogs.each do |trb|
133
- blogs << BlogPost.new(trb)
126
+ if Hash === result
127
+ result["bills"].each do |bill|
128
+ bill = bill['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
134
137
  end
135
- end
136
138
 
137
- bill["recent_blogs"] = blogs
139
+ bill["recent_blogs"] = blogs
138
140
 
139
141
 
140
- these_recent_news = bill["recent_news"]
141
- news = []
142
- if these_recent_news
143
- these_recent_news.each do |trb|
144
- news << NewsPost.new(trb)
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
145
148
  end
146
- end
147
149
 
148
- bill["recent_news"] = news
150
+ bill["recent_news"] = news
149
151
 
150
- these_co_sponsors = bill["co_sponsors"]
151
- co_sponsors = []
152
- if these_co_sponsors
153
- these_co_sponsors.each do |tcs|
154
- co_sponsors << Person.new(tcs)
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
155
158
  end
156
- end
157
159
 
158
- bill["co_sponsors"] = co_sponsors
160
+ bill["co_sponsors"] = co_sponsors
159
161
 
160
-
161
- bill["sponsor"] = Person.new(bill["sponsor"]) if bill["sponsor"]
162
-
163
-
164
- bills << Bill.new(bill)
162
+
163
+ bill["sponsor"] = Person.new(bill["sponsor"]) if bill["sponsor"]
164
+
165
+ bills << Bill.new(bill)
166
+ end
165
167
  end
168
+
166
169
  bills
167
170
  end
168
171
 
@@ -105,30 +105,31 @@ module GovKit
105
105
  def self.parse_results(result)
106
106
 
107
107
  people = []
108
- result["people"].each do |person|
109
-
110
- these_recent_blogs = person["recent_blogs"]
111
- blogs = []
112
- these_recent_blogs.each do |trb|
113
- blogs << BlogPost.new(trb)
114
- end
108
+ if Hash === result
109
+ result["people"].each do |person|
110
+ person = person['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
+ person["recent_blogs"] = blogs
115
118
 
116
- person["recent_blogs"] = blogs
119
+ these_recent_news = person["recent_news"]
120
+ news = []
121
+ these_recent_news.each do |trb|
122
+ news << NewsPost.new(trb)
123
+ end
117
124
 
125
+ person["person_stats"] = PersonStat.new(person["person_stats"]) if person["person_stats"]
118
126
 
119
- these_recent_news = person["recent_news"]
120
- news = []
121
- these_recent_news.each do |trb|
122
- news << NewsPost.new(trb)
127
+ person["recent_news"] = news
128
+
129
+ people << Person.new(person)
123
130
  end
124
-
125
- person["person_stats"] = PersonStat.new(person["person_stats"]) if person["person_stats"]
126
-
127
- person["recent_news"] = news
128
-
129
- people << Person.new(person)
130
- end
131
-
131
+ end
132
+
132
133
  people
133
134
 
134
135
  end