govkit 0.7.1 → 0.7.2

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.
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem "active_support"
5
+ gem "activesupport", :require => 'active_support'
6
6
  gem "nokogiri"
7
7
  gem "httparty"
8
8
  gem "i18n"
@@ -10,4 +10,4 @@ gem "i18n"
10
10
  group :test do
11
11
  gem "rspec"
12
12
  gem "fakeweb"
13
- end
13
+ end
data/README.md CHANGED
@@ -20,6 +20,14 @@ Add govkit to your environment.rb or Gemfile
20
20
 
21
21
  Run <code>rails generate govkit</code> (Rails 3.x) or <code>script/generate govkit</code> (Rails 2.x) to copy a config file into <code>config/initializers/govkit.rb</code>. You will need to add your API keys to this config file.
22
22
 
23
+ Outside of Rails you can configure your API keys like so:
24
+
25
+ >> GovKit.configure do |config|
26
+ >> config.sunlight_apikey = 'YOUR_SUNLIGHT_API_KEY'
27
+ >> config.votesmart_apikey = 'YOUR_VOTESMART_API_KEY'
28
+ >> config.ftm_apikey = 'YOUR_FTM_API_KEY'
29
+ >> end
30
+
23
31
  # Usage Examples
24
32
 
25
33
  >> GovKit::OpenStates::State.find_by_abbreviation('CA')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.1
1
+ 0.7.2
@@ -8,6 +8,10 @@ class GovkitGenerator < Rails::Generator::Base
8
8
  record do |m|
9
9
  m.directory File.join('config', 'initializers')
10
10
  m.template 'govkit.rb', File.join('config', 'initializers', 'govkit.rb')
11
+ m.directory File.join('app', 'models')
12
+ m.template 'mention.rb', File.join('app', 'models', 'mention.rb')
13
+ m.directory File.join('db', 'migrate')
14
+ m.template 'create_mentions.rb', File.join('db', 'migrate', 'create_mentions.rb')
11
15
  end
12
16
  end
13
17
 
@@ -0,0 +1,21 @@
1
+ class CreateMentions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :mentions, :force => true do |t|
4
+ t.string "url", :limit => 8000
5
+ t.string "excerpt", :limit => 4000
6
+ t.string "title", :limit => 1000
7
+ t.string "source"
8
+ t.datetime "date"
9
+ t.float "weight"
10
+ t.integer "owner_id"
11
+ t.string "owner_type"
12
+ t.string "search_source"
13
+ t.datetime "created_at"
14
+ t.datetime "updated_at"
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :mentions
20
+ end
21
+ end
@@ -11,13 +11,9 @@ if defined? GovKit
11
11
  # API key for NIMSP. Request one here:
12
12
  # http://www.followthemoney.org/membership/settings.phtml
13
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
14
 
19
15
  # Technorati API key
20
- config.technorati_apikey = 'YOUR_TECHNORATI_APIKEY'
16
+ # config.technorati_apikey = 'YOUR_TECHNORATI_APIKEY'
21
17
 
22
18
  # Bing App ID
23
19
  config.bing_appid = 'YOUR_BING_APPID'
@@ -0,0 +1,15 @@
1
+ # A model to contain mentions of the :owner in the media
2
+ class Mention < ActiveRecord::Base
3
+ belongs_to :owner, :polymorphic => true
4
+
5
+ scope :since, lambda { |d| where(["mentions.date > ?", d]) }
6
+
7
+ # Returns the mentions in JSON form
8
+ #
9
+ # @params [Hash] A hash of options
10
+ # @return The mentions in JSON form
11
+ def as_json(opts = {})
12
+ default_opts = {:except => [:owner_id, :owner_type]}
13
+ super(default_opts.merge(opts))
14
+ end
15
+ 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.7.1"
8
+ s.version = "0.7.2"
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{2011-06-30}
12
+ s.date = %q{2012-01-23}
13
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
14
  s.email = %q{develop@opencongress.org}
15
15
  s.extra_rdoc_files = [
@@ -26,11 +26,15 @@ Gem::Specification.new do |s|
26
26
  "USAGE",
27
27
  "VERSION",
28
28
  "generators/govkit/govkit_generator.rb",
29
+ "generators/govkit/templates/create_mentions.rb",
29
30
  "generators/govkit/templates/govkit.rb",
31
+ "generators/govkit/templates/mention.rb",
30
32
  "govkit.gemspec",
31
33
  "init.rb",
32
34
  "lib/generators/govkit/govkit_generator.rb",
35
+ "lib/generators/govkit/templates/create_mentions.rb",
33
36
  "lib/generators/govkit/templates/govkit.rb",
37
+ "lib/generators/govkit/templates/mention.rb",
34
38
  "lib/gov_kit.rb",
35
39
  "lib/gov_kit/acts_as_noteworthy.rb",
36
40
  "lib/gov_kit/configuration.rb",
@@ -62,6 +66,10 @@ Gem::Specification.new do |s|
62
66
  "spec/fixtures/follow_the_money/business-page1.response",
63
67
  "spec/fixtures/follow_the_money/contribution.response",
64
68
  "spec/fixtures/follow_the_money/unauthorized.response",
69
+ "spec/fixtures/open_congress/501.response",
70
+ "spec/fixtures/open_congress/bill.response",
71
+ "spec/fixtures/open_congress/empty.response",
72
+ "spec/fixtures/open_congress/fl01.response",
65
73
  "spec/fixtures/open_congress/person.response",
66
74
  "spec/fixtures/open_states/401.response",
67
75
  "spec/fixtures/open_states/404.response",
@@ -89,15 +97,24 @@ Gem::Specification.new do |s|
89
97
  ]
90
98
  s.homepage = %q{http://github.com/opengovernment/govkit}
91
99
  s.require_paths = ["lib"]
92
- s.rubygems_version = %q{1.6.2}
100
+ s.rubygems_version = %q{1.3.6}
93
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
+ ]
94
110
 
95
111
  if s.respond_to? :specification_version then
112
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
96
113
  s.specification_version = 3
97
114
 
98
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
115
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
99
116
  s.add_runtime_dependency(%q<govkit>, [">= 0"])
100
- s.add_runtime_dependency(%q<active_support>, [">= 0"])
117
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
101
118
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
102
119
  s.add_runtime_dependency(%q<httparty>, [">= 0"])
103
120
  s.add_runtime_dependency(%q<i18n>, [">= 0"])
@@ -107,7 +124,7 @@ Gem::Specification.new do |s|
107
124
  s.add_runtime_dependency(%q<fastercsv>, [">= 1.5.3"])
108
125
  else
109
126
  s.add_dependency(%q<govkit>, [">= 0"])
110
- s.add_dependency(%q<active_support>, [">= 0"])
127
+ s.add_dependency(%q<activesupport>, [">= 0"])
111
128
  s.add_dependency(%q<nokogiri>, [">= 0"])
112
129
  s.add_dependency(%q<httparty>, [">= 0"])
113
130
  s.add_dependency(%q<i18n>, [">= 0"])
@@ -118,7 +135,7 @@ Gem::Specification.new do |s|
118
135
  end
119
136
  else
120
137
  s.add_dependency(%q<govkit>, [">= 0"])
121
- s.add_dependency(%q<active_support>, [">= 0"])
138
+ s.add_dependency(%q<activesupport>, [">= 0"])
122
139
  s.add_dependency(%q<nokogiri>, [">= 0"])
123
140
  s.add_dependency(%q<httparty>, [">= 0"])
124
141
  s.add_dependency(%q<i18n>, [">= 0"])
@@ -1,17 +1,21 @@
1
1
  require 'rails/generators'
2
2
 
3
+ # Generator to setup rails app for using GovKit
3
4
  class GovkitGenerator < Rails::Generators::Base
4
5
 
5
6
  def initialize(*runtime_args)
6
7
  super
7
8
  end
8
9
 
9
- desc "Copies a config initializer to config/initializers/govkit.rb"
10
+ desc "Copies files necessary to use govkit"
10
11
 
11
12
  source_root File.join(File.dirname(__FILE__), 'templates')
12
-
13
+
14
+ # Copies the files necessary to use govkit (initializer, migrations, and models)
13
15
  def copy_initializer_file
14
16
  copy_file 'govkit.rb', File.join('config', 'initializers', 'govkit.rb')
17
+ copy_file 'mention.rb', File.join('app', 'models', 'mention.rb')
18
+ copy_file 'create_mentions.rb', File.join('db', 'migrate', "#{ Time.now.utc.strftime "%Y%m%d%H%M%S" }create_mentions.rb")
15
19
  end
16
20
 
17
21
  end
@@ -0,0 +1,21 @@
1
+ class CreateMentions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :mentions, :force => true do |t|
4
+ t.string "url", :limit => 8000
5
+ t.string "excerpt", :limit => 4000
6
+ t.string "title", :limit => 1000
7
+ t.string "source"
8
+ t.datetime "date"
9
+ t.float "weight"
10
+ t.integer "owner_id"
11
+ t.string "owner_type"
12
+ t.string "search_source"
13
+ t.datetime "created_at"
14
+ t.datetime "updated_at"
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :mentions
20
+ end
21
+ end
@@ -11,13 +11,12 @@ if defined? GovKit
11
11
  # API key for NIMSP. Request one here:
12
12
  # http://www.followthemoney.org/membership/settings.phtml
13
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
14
 
19
15
  # Technorati API key
20
- config.technorati_apikey = 'YOUR_TECHNORATI_APIKEY'
16
+ # config.technorati_apikey = 'YOUR_TECHNORATI_APIKEY'
17
+
18
+ # Bing App ID
19
+ config.bing_appid = 'YOUR_BING_APPID'
21
20
 
22
21
  # Other things you could set here include alternate URLs for
23
22
  # the APIs. See GovKit::Configuration for available attributes.
@@ -0,0 +1,15 @@
1
+ # A model to contain mentions of the :owner in the media
2
+ class Mention < ActiveRecord::Base
3
+ belongs_to :owner, :polymorphic => true
4
+
5
+ scope :since, lambda { |d| where(["mentions.date > ?", d]) }
6
+
7
+ # Returns the mentions in JSON form
8
+ #
9
+ # @params [Hash] A hash of options
10
+ # @return The mentions in JSON form
11
+ def as_json(opts = {})
12
+ default_opts = {:except => [:owner_id, :owner_type]}
13
+ super(default_opts.merge(opts))
14
+ end
15
+ end
@@ -4,7 +4,11 @@ module GovKit::ActsAsNoteworthy
4
4
  base.extend ActMethods
5
5
  end
6
6
 
7
+ # Module to make a rails model act as a noteworthy object, linking it to govkit's mention model
7
8
  module ActMethods
9
+ # Sets up the relationship between the model and the mention model
10
+ #
11
+ # @param [Hash] opts a hash of options to be used by the relationship
8
12
  def acts_as_noteworthy(options={})
9
13
  class_inheritable_accessor :options
10
14
  self.options = options
@@ -16,7 +20,7 @@ module GovKit::ActsAsNoteworthy
16
20
  with_options :as => :owner, :class_name => "Mention" do |c|
17
21
  c.has_many :google_news_mentions, :conditions => {:search_source => "Google News"}, :order => 'date desc'
18
22
  c.has_many :google_blog_mentions, :conditions => {:search_source => "Google Blogs"}, :order => 'date desc'
19
- c.has_many :technorati_mentions, :conditions => {:search_source => "Technorati"}, :order => 'date desc'
23
+ # c.has_many :technorati_mentions, :conditions => {:search_source => "Technorati"}, :order => 'date desc'
20
24
  c.has_many :bing_mentions, :conditions => {:search_source => "Bing"}, :order => 'date desc'
21
25
  end
22
26
  end
@@ -29,9 +33,12 @@ module GovKit::ActsAsNoteworthy
29
33
 
30
34
  module ClassMethods
31
35
  end
32
-
36
+
37
+ # A module that adds methods to individual instances of the noteworthy class.
33
38
  module InstanceMethods
34
-
39
+ # Generates the raw mentions to be loaded into the Mention objects
40
+ #
41
+ # @return [Hash] a hash of all the mentions found of the object in question.
35
42
  def raw_mentions
36
43
  opts = self.options.clone
37
44
  attributes = opts.delete(:with)
@@ -10,7 +10,7 @@ module GovKit
10
10
  attr_accessor :bing_appid, :bing_base_url
11
11
 
12
12
  def initialize
13
- @openstates_apikey = @votesmart_apikey = @ftm_apikey = ''
13
+ @sunlight_apikey = @openstates_apikey = @votesmart_apikey = @ftm_apikey = ''
14
14
  @openstates_base_url = 'openstates.sunlightlabs.com/api/v1/'
15
15
  @transparency_data_base_url = 'transparencydata.com/api/1.0/'
16
16
  @votesmart_base_url = 'api.votesmart.org/'
@@ -25,20 +25,34 @@ module GovKit
25
25
  # Permant home for contribution category mappings
26
26
  @transparency_data_categories_url = 'http://assets.transparencydata.org.s3.amazonaws.com/docs/catcodes.csv'
27
27
  end
28
+
29
+ def opencongress_apikey= key
30
+ warn "[DEPRECATION] OpenCongress no longer requires an API Key. Ability to set it will be removed in future versions"
31
+ @opencongress_apikey = key
32
+ end
33
+
34
+ def openstates_apikey= key
35
+ warn "[DEPRECATION] Use sunlight_apikey instead of openstates_apikey. Ability to set it will be removed in future versions"
36
+ @sunlight_apikey = key
37
+ end
28
38
  end
29
39
 
30
40
  class << self
31
41
  attr_accessor :configuration
42
+
43
+ def configuration
44
+ @configuration = Configuration.new if @configuration.nil?
45
+ @configuration
46
+ end
32
47
  end
33
48
 
34
49
  # Configure GovKit in config/initializers/govkit.rb
35
50
  #
36
51
  # @example
37
52
  # GovKit.configure do |config|
38
- # config.openstates_apikey = ''
53
+ # config.sunlight_apikey = ''
39
54
  # end
40
55
  def self.configure
41
- self.configuration ||= Configuration.new
42
56
  yield(configuration)
43
57
  end
44
58
  end
@@ -1,8 +1,23 @@
1
1
  module GovKit
2
+
3
+ # Subclass of {Resource} for FollowTheMoney data. This
4
+ # is subclassed further for each of the different types of record
5
+ # returned by FollowTheMoney.
6
+ #
7
+ # For the details on the FollowTheMoney queries, see {http://www.followthemoney.org/services/methods.phtml the FollowTheMoney API documentation}.
2
8
  class FollowTheMoneyResource < Resource
3
9
  default_params :key => GovKit::configuration.ftm_apikey
4
10
  base_uri GovKit::configuration.ftm_base_url
5
11
 
12
+ # Common method used by subclasses to get data from the service.
13
+ #
14
+ # @return [Nokogiri::XML::Document] a {http://nokogiri.org/Nokogiri/HTML/Document.html Nokogiri XML::Document} object
15
+ # @param [String] path query path that specifies the required data
16
+ # @param [Hash] options query options
17
+ #
18
+ # @example
19
+ # doc = get_xml("/base_level.industries.list.php", :query => {:page => page_num})
20
+ #
6
21
  def self.get_xml(path, options)
7
22
  doc = Nokogiri::XML(get(path, options))
8
23
 
@@ -25,15 +40,27 @@ module GovKit
25
40
  doc
26
41
  end
27
42
 
43
+ # Convert the hash array returned by Nokogiri, which has Nokogiri::XML::Attr objects as values,
44
+ # to an array of hashes with string values.
45
+ #
46
+ # @param [Array] result array of hashes, with object values.
47
+ # @return [Array] array of hashes, with string values.
28
48
  def self.stringify_values_of(result)
29
- # result is an array of hashes, but all the values are Nokogiri::XML::Attr objects, not strings.
30
- # We want them to be strings.
31
49
  result.collect! { |r| r.inject({}) {|h, (k, v)| h[k] = v.to_s; h } }
32
50
  end
33
51
  end
34
52
 
53
+ # Provides classes to wrap {http://www.followthemoney.org/index.phtml FollowTheMoney} data.
54
+ #
55
+ # For the details on the FollowTheMoney queries, see {http://www.followthemoney.org/services/methods.phtml the FollowTheMoney API documentation}.
35
56
  module FollowTheMoney
57
+
58
+ # Wrap {http://www.followthemoney.org/services/method_doc.phtml?a=11 Industry data}
36
59
  class Business < FollowTheMoneyResource
60
+
61
+ # Return a list of all business, industry, and sector categories. See the {http://www.followthemoney.org/services/method_doc.phtml?a=11 FollowTheMoney API}.
62
+ #
63
+ # @return [Business] A list of Business objects.
37
64
  def self.list
38
65
  next_page, result, page_num = "yes", [], 0
39
66
 
@@ -54,7 +81,14 @@ module GovKit
54
81
  end
55
82
  end
56
83
 
84
+ # Wrap contributions to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=32 FollowTheMoney API}.
57
85
  class Contribution < FollowTheMoneyResource
86
+
87
+ # Return contributions to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=32 FollowTheMoney API}.
88
+ #
89
+ # @param [Integer] nimsp_id the candidate id.
90
+ #
91
+ # @return [Contribution] a Contribution object, or array of Contribution objects, representing the contributions.
58
92
  def self.find(nimsp_id)
59
93
  next_page, result, page_num = "yes", [], 0
60
94
 
@@ -72,6 +106,11 @@ module GovKit
72
106
  parse(result)
73
107
  end
74
108
 
109
+ # Return a list of the top contributors to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=20 FollowTheMoney API}.
110
+ #
111
+ # @param [Integer] nimsp_id the candidate id.
112
+ #
113
+ # @return [[Contribution]] an array of Contribution objects.
75
114
  def self.top(nimsp_id)
76
115
  doc = get_xml("/candidates.top_contributor.php", :query => {"imsp_candidate_id" => nimsp_id})
77
116
  result = doc.search('//top_contributor').collect { |x| x.attributes }
@@ -81,7 +120,14 @@ module GovKit
81
120
  end
82
121
  end
83
122
 
123
+ # Wrap contributions by industry to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=24 FollowTheMoney API}.
124
+ #
84
125
  class IndustryContribution < Contribution
126
+ # Return contributions by industry.
127
+ #
128
+ # @param [Integer] nimsp_id the candidate id.
129
+ #
130
+ # @return [[Contribution]] an array of Contribution objects.
85
131
  def self.find(nimsp_id)
86
132
  doc = get_xml("/candidates.industries.php", :query => {"imsp_candidate_id" => nimsp_id})
87
133
  result = doc.search('//candidate_industry').collect { |x| x.attributes }
@@ -91,7 +137,14 @@ module GovKit
91
137
  end
92
138
  end
93
139
 
140
+ # Wrap contributions by sector to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=23 FollowTheMoney API}.
141
+ #
94
142
  class SectorContribution < Contribution
143
+ # Return conributions by sector.
144
+ #
145
+ # @param [Integer] nimsp_id the candidate id.
146
+ #
147
+ # @return [[Contribution]] an array of Contribution objects.
95
148
  def self.find(nimsp_id)
96
149
  doc = get_xml("/candidates.sectors.php", :query => {"imsp_candidate_id" => nimsp_id})
97
150
 
@@ -102,7 +155,14 @@ module GovKit
102
155
  end
103
156
  end
104
157
 
158
+ # Wrap contributions by business to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=25 FollowTheMoney API}.
159
+ #
105
160
  class BusinessContribution < Contribution
161
+ # Return contributions by business.
162
+ #
163
+ # @param [Integer] nimsp_id the candidate id.
164
+ #
165
+ # @return [[Contribution]] an array of Contribution objects.
106
166
  def self.find(nimsp_id)
107
167
  doc = get_xml("/candidates.businesses.php", :query => {"imsp_candidate_id" => nimsp_id})
108
168
 
@@ -4,14 +4,21 @@ require 'json'
4
4
  require 'CGI'
5
5
 
6
6
  module GovKit::OpenCongress
7
- autoload :Bill, 'gov_kit/open_congress/bill'
8
- autoload :BlogPost, 'gov_kit/open_congress/blog_post'
9
- autoload :NewsPost, 'gov_kit/open_congress/news_post'
10
- autoload :VotingComparison, 'gov_kit/open_congress/voting_comparison'
7
+ autoload :Bill, 'gov_kit/open_congress/bill'
8
+ autoload :BlogPost, 'gov_kit/open_congress/blog_post'
9
+ autoload :NewsPost, 'gov_kit/open_congress/news_post'
10
+ autoload :VotingComparison, 'gov_kit/open_congress/voting_comparison'
11
11
  autoload :RollCallComparison, 'gov_kit/open_congress/roll_call_comparison'
12
- autoload :Person, 'gov_kit/open_congress/person'
13
- autoload :PersonStat, 'gov_kit/open_congress/person_stat'
12
+ autoload :Person, 'gov_kit/open_congress/person'
13
+ autoload :PersonStat, 'gov_kit/open_congress/person_stat'
14
14
 
15
+ # Parent class for classes that wrap {http://www.opencongress.org/api OpenCongress data}.
16
+ #
17
+ # Unlike the wrapper classes for data from {FollowTheMoneyResource FollowTheMoney},
18
+ # {OpenStatesResource OpenStates}, {TransparencyDataResource TransparencyData},
19
+ # and {VoteSmartResource VoteSmart}, OpenCongressObject does not inherit
20
+ # from {GovKit::Resource}
21
+ #
15
22
  class OpenCongressObject
16
23
 
17
24
  def initialize(obj, params)
@@ -21,16 +28,19 @@ module GovKit::OpenCongress
21
28
  end
22
29
  end
23
30
 
31
+ # Create a query url, by adding the method path and query parameters to the
32
+ # base url of {http://www.opencongress.org/api}.
24
33
  def self.construct_url(api_method, params)
25
34
  url = nil
26
- if GovKit::configuration.opencongress_apikey == nil || GovKit::configuration.opencongress_apikey == ''
27
- raise "Failed to provide OpenCongress API Key"
28
- else
29
- url = "http://#{GovKit::configuration.opencongress_base_url}api/#{api_method}?key=#{GovKit::configuration.opencongress_apikey}#{hash2get(params)}&format=json"
30
- end
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}"
31
37
  return url
32
38
  end
33
39
 
40
+ # Convert a hash to a string of query parameters.
41
+ #
42
+ # @param [Hash] h a hash.
43
+ # @return [String] a string of query parameters.
34
44
  def self.hash2get(h)
35
45
  get_string = ""
36
46
 
@@ -41,6 +51,17 @@ module GovKit::OpenCongress
41
51
  get_string
42
52
  end
43
53
 
54
+ # Iterates through the array returned by {make_call},
55
+ # converting each hash to an OpenCongressObject subclass.
56
+ #
57
+ # @param [Hash] results the array returned by make_call.
58
+ # @return a hash of arrays of OpenCongressObject objects, with these keys:
59
+ # * :also_supporting_bills
60
+ # * :also_opposing_bills
61
+ # * :also_disapproved_senators
62
+ # * :also_disapproved_representatives
63
+ # * :also_approved_senators
64
+ # * :also_approved_representatives
44
65
  def self.parse_supporting_results(result)
45
66
  working = result["opencongress_users_tracking"]
46
67
 
@@ -83,6 +104,12 @@ module GovKit::OpenCongress
83
104
 
84
105
  end
85
106
 
107
+ # Get the data from {http://www.opencongress.org/api OpenCongress data}. Called by subclasses.
108
+ #
109
+ # Parses the data using {http://flori.github.com/json/doc/index.html JSON.parse}, which
110
+ # returns an array of hashes.
111
+ #
112
+ # @return the returned data, as an array of hashes.
86
113
  def self.make_call(this_url)
87
114
  result = nil
88
115
  begin
@@ -95,4 +122,4 @@ module GovKit::OpenCongress
95
122
 
96
123
  end
97
124
  end
98
- end
125
+ end
@@ -1,29 +1,30 @@
1
1
  module GovKit
2
2
 
3
- # This is the parent class to the classes that wrap
3
+
4
+ # This is the parent class for the classes that wrap
4
5
  # the data returned to govkit.
5
6
  #
6
- # The subclasses are responsible for fetching the data as json from
7
- # different web services; Resource will then parse the json,
7
+ # Subclasses are responsible for fetching the data from
8
+ # different web services; Resource will then parse the returned data,
8
9
  # converting returned fields to instance methods.
9
10
  #
10
11
  # Initialize a Resource with a hash of attributes, or an array of hashes.
11
12
  # For each attribute, add a getter and setter to this instance.
12
- # So if
13
+ # @example
13
14
  # res = Resource.new { "aaa" => "111", "bbb" => "222", "ccc" => "333" }
14
- # then
15
15
  # res.aaa == "111"
16
16
  # res.bbb == "222"
17
17
  # res.ccc == "333"
18
18
  #
19
- # Includes HTTParty, which provides convenience methods like get().
20
- #
21
- # See http://rdoc.info/github/jnunemaker/httparty/master/HTTParty/ClassMethods
19
+ # Includes {http://rdoc.info/github/jnunemaker/httparty/master/HTTParty/ClassMethods HTTParty}, which provides convenience methods like get().
22
20
  class Resource
23
21
  include HTTParty
24
22
  format :json
25
23
 
24
+ # The attributes data returned by the service.
26
25
  attr_reader :attributes
26
+
27
+ # The response returned by the service.
27
28
  attr_reader :raw_response
28
29
 
29
30
  def initialize(attributes = {})
@@ -33,21 +34,22 @@ module GovKit
33
34
  unload(attributes)
34
35
  end
35
36
 
36
- # Returns a hash of the response object, potentially useful for comparison
37
- # on sync
37
+ # @return [Hash] the response object, potentially useful for comparison on sync
38
38
  #
39
39
  def to_md5
40
40
  Digest::MD5.hexdigest(@raw_response.body)
41
41
  end
42
42
 
43
- # Handles the basic responses we might get back from Net::HTTP.
44
- # On success, returns a new Resource based on the response.
43
+ # Handles the basic responses we might get back from a web service.
45
44
  #
46
45
  # On failure, throws an error.
47
46
  #
48
47
  # If a service returns something other than a 404 when an object is not found,
49
48
  # you'll need to handle that in the subclass.
50
49
  #
50
+ # @param [Object] response the object.
51
+ # @return [Resource] a new Resource created from the response.
52
+ #
51
53
  def self.parse(response)
52
54
 
53
55
  if response.class == HTTParty::Response
@@ -72,8 +74,8 @@ module GovKit
72
74
 
73
75
  # Instantiate new GovKit::Resources.
74
76
  #
75
- # +record+ is a hash of values returned by a service,
76
- # or an array of hashes.
77
+ # @param [Hash] record a hash of values returned by a service, or an array of hashes.
78
+ # @return [Resource]
77
79
  #
78
80
  # If +record+ is a hash, return a single GovKit::Resource.
79
81
  # If it is an array, return an array of GovKit::Resources.
@@ -86,16 +88,24 @@ module GovKit
86
88
  end
87
89
  end
88
90
 
91
+ # Instantiate a set of records.
92
+ #
93
+ # @return [Array] Array of records
94
+ # @param [Array] collection An array of records
89
95
  def self.instantiate_collection(collection)
90
96
  collection.collect! { |record| new(record) }
91
97
  end
92
98
 
93
- # Given a hash of attributes, assign it to the @attributes member,
94
- # then for each attribute, create or set a pair of member accessors with the name
99
+ # Given a hash of attributes, assign it to the @attributes member.
100
+ # Then for each attribute, create or set a pair of member accessors with the name
95
101
  # of the attribute's key.
102
+ #
96
103
  # If the value of the attribute is itself an array or a hash,
97
104
  # then create a new class with the (singularized) key as a name, and with a parent class of Resource,
98
105
  # and initialize it with the hash.
106
+ #
107
+ # @param [Hash] attributes the attributes returned by the web service.
108
+ #
99
109
  def unload(attributes)
100
110
  raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
101
111