Permalink
Browse files

Merge branch 'master' into acts_improvements

  • Loading branch information...
2 parents 30c7ac0 + b8322a4 commit 013f1866656ed1baebe07c50025d4e27ced8c036 @NateBarnes committed Jul 3, 2011
Showing with 123 additions and 18 deletions.
  1. +5 −0 .gitignore
  2. +62 −2 lib/gov_kit/follow_the_money.rb
  3. +30 −0 lib/gov_kit/open_congress.rb
  4. +26 −16 lib/gov_kit/resource.rb
View
@@ -21,3 +21,8 @@ pkg
Gemfile.lock
## PROJECT::SPECIFIC
+
+## YARD
+doc
+.yardoc
+
@@ -1,8 +1,23 @@
module GovKit
+
+ # Subclass of {Resource} for FollowTheMoney data. This
+ # is subclassed further for each of the different types of record
+ # returned by FollowTheMoney.
+ #
+ # For the details on the FollowTheMoney queries, see {http://www.followthemoney.org/services/methods.phtml the FollowTheMoney API documentation}.
class FollowTheMoneyResource < Resource
default_params :key => GovKit::configuration.ftm_apikey
base_uri GovKit::configuration.ftm_base_url
+ # Common method used by subclasses to get data from the service.
+ #
+ # @return [Nokogiri::XML::Document] a {http://nokogiri.org/Nokogiri/HTML/Document.html Nokogiri XML::Document} object
+ # @param [String] path query path that specifies the required data
+ # @param [Hash] options query options
+ #
+ # @example
+ # doc = get_xml("/base_level.industries.list.php", :query => {:page => page_num})
+ #
def self.get_xml(path, options)
doc = Nokogiri::XML(get(path, options))
@@ -25,15 +40,27 @@ def self.get_xml(path, options)
doc
end
+ # Convert the hash array returned by Nokogiri, which has Nokogiri::XML::Attr objects as values,
+ # to an array of hashes with string values.
+ #
+ # @param [Array] result array of hashes, with object values.
+ # @return [Array] array of hashes, with string values.
def self.stringify_values_of(result)
- # result is an array of hashes, but all the values are Nokogiri::XML::Attr objects, not strings.
- # We want them to be strings.
result.collect! { |r| r.inject({}) {|h, (k, v)| h[k] = v.to_s; h } }
end
end
+ # Provides classes to wrap {http://www.followthemoney.org/index.phtml FollowTheMoney} data.
+ #
+ # For the details on the FollowTheMoney queries, see {http://www.followthemoney.org/services/methods.phtml the FollowTheMoney API documentation}.
module FollowTheMoney
+
+ # Wrap {http://www.followthemoney.org/services/method_doc.phtml?a=11 Industry data}
class Business < FollowTheMoneyResource
+
+ # Return a list of all business, industry, and sector categories. See the {http://www.followthemoney.org/services/method_doc.phtml?a=11 FollowTheMoney API}.
+ #
+ # @return [Business] A list of Business objects.
def self.list
next_page, result, page_num = "yes", [], 0
@@ -54,7 +81,14 @@ def self.list
end
end
+ # Wrap contributions to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=32 FollowTheMoney API}.
class Contribution < FollowTheMoneyResource
+
+ # Return contributions to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=32 FollowTheMoney API}.
+ #
+ # @param [Integer] nimsp_id the candidate id.
+ #
+ # @return [Contribution] a Contribution object, or array of Contribution objects, representing the contributions.
def self.find(nimsp_id)
next_page, result, page_num = "yes", [], 0
@@ -72,6 +106,11 @@ def self.find(nimsp_id)
parse(result)
end
+ # Return a list of the top contributors to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=20 FollowTheMoney API}.
+ #
+ # @param [Integer] nimsp_id the candidate id.
+ #
+ # @return [[Contribution]] an array of Contribution objects.
def self.top(nimsp_id)
doc = get_xml("/candidates.top_contributor.php", :query => {"imsp_candidate_id" => nimsp_id})
result = doc.search('//top_contributor').collect { |x| x.attributes }
@@ -81,7 +120,14 @@ def self.top(nimsp_id)
end
end
+ # Wrap contributions by industry to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=24 FollowTheMoney API}.
+ #
class IndustryContribution < Contribution
+ # Return contributions by industry.
+ #
+ # @param [Integer] nimsp_id the candidate id.
+ #
+ # @return [[Contribution]] an array of Contribution objects.
def self.find(nimsp_id)
doc = get_xml("/candidates.industries.php", :query => {"imsp_candidate_id" => nimsp_id})
result = doc.search('//candidate_industry').collect { |x| x.attributes }
@@ -91,7 +137,14 @@ def self.find(nimsp_id)
end
end
+ # Wrap contributions by sector to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=23 FollowTheMoney API}.
+ #
class SectorContribution < Contribution
+ # Return conributions by sector.
+ #
+ # @param [Integer] nimsp_id the candidate id.
+ #
+ # @return [[Contribution]] an array of Contribution objects.
def self.find(nimsp_id)
doc = get_xml("/candidates.sectors.php", :query => {"imsp_candidate_id" => nimsp_id})
@@ -102,7 +155,14 @@ def self.find(nimsp_id)
end
end
+ # Wrap contributions by business to a candidate. See the {http://www.followthemoney.org/services/method_doc.phtml?a=25 FollowTheMoney API}.
+ #
class BusinessContribution < Contribution
+ # Return contributions by business.
+ #
+ # @param [Integer] nimsp_id the candidate id.
+ #
+ # @return [[Contribution]] an array of Contribution objects.
def self.find(nimsp_id)
doc = get_xml("/candidates.businesses.php", :query => {"imsp_candidate_id" => nimsp_id})
@@ -12,6 +12,13 @@ module GovKit::OpenCongress
autoload :Person, 'gov_kit/open_congress/person'
autoload :PersonStat, 'gov_kit/open_congress/person_stat'
+ # Parent class for classes that wrap {http://www.opencongress.org/api OpenCongress data}.
+ #
+ # Unlike the wrapper classes for data from {FollowTheMoneyResource FollowTheMoney},
+ # {OpenStatesResource OpenStates}, {TransparencyDataResource TransparencyData},
+ # and {VoteSmartResource VoteSmart}, OpenCongressObject does not inherit
+ # from {GovKit::Resource}
+ #
class OpenCongressObject
def initialize(obj, params)
@@ -21,13 +28,19 @@ def initialize(obj, params)
end
end
+ # Create a query url, by adding the method path and query parameters to the
+ # base url of {http://www.opencongress.org/api}.
def self.construct_url(api_method, params)
url = nil
getkey = GovKit::configuration.opencongress_apikey.nil? ? "" : "&key=#{GovKit::configuration.opencongress_apikey}"
url = "http://#{GovKit::configuration.opencongress_base_url}api/#{api_method}?format=json#{hash2get(params)}#{getkey}"
return url
end
+ # Convert a hash to a string of query parameters.
+ #
+ # @param [Hash] h a hash.
+ # @return [String] a string of query parameters.
def self.hash2get(h)
get_string = ""
@@ -38,6 +51,17 @@ def self.hash2get(h)
get_string
end
+ # Iterates through the array returned by {make_call},
+ # converting each hash to an OpenCongressObject subclass.
+ #
+ # @param [Hash] results the array returned by make_call.
+ # @return a hash of arrays of OpenCongressObject objects, with these keys:
+ # * :also_supporting_bills
+ # * :also_opposing_bills
+ # * :also_disapproved_senators
+ # * :also_disapproved_representatives
+ # * :also_approved_senators
+ # * :also_approved_representatives
def self.parse_supporting_results(result)
working = result["opencongress_users_tracking"]
@@ -80,6 +104,12 @@ def self.parse_supporting_results(result)
end
+ # Get the data from {http://www.opencongress.org/api OpenCongress data}. Called by subclasses.
+ #
+ # Parses the data using {http://flori.github.com/json/doc/index.html JSON.parse}, which
+ # returns an array of hashes.
+ #
+ # @return the returned data, as an array of hashes.
def self.make_call(this_url)
result = nil
begin
@@ -1,29 +1,30 @@
module GovKit
- # This is the parent class to the classes that wrap
+
+ # This is the parent class for the classes that wrap
# the data returned to govkit.
#
- # The subclasses are responsible for fetching the data as json from
- # different web services; Resource will then parse the json,
+ # Subclasses are responsible for fetching the data from
+ # different web services; Resource will then parse the returned data,
# converting returned fields to instance methods.
#
# Initialize a Resource with a hash of attributes, or an array of hashes.
# For each attribute, add a getter and setter to this instance.
- # So if
+ # @example
# res = Resource.new { "aaa" => "111", "bbb" => "222", "ccc" => "333" }
- # then
# res.aaa == "111"
# res.bbb == "222"
# res.ccc == "333"
#
- # Includes HTTParty, which provides convenience methods like get().
- #
- # See http://rdoc.info/github/jnunemaker/httparty/master/HTTParty/ClassMethods
+ # Includes {http://rdoc.info/github/jnunemaker/httparty/master/HTTParty/ClassMethods HTTParty}, which provides convenience methods like get().
class Resource
include HTTParty
format :json
+ # The attributes data returned by the service.
attr_reader :attributes
+
+ # The response returned by the service.
attr_reader :raw_response
def initialize(attributes = {})
@@ -33,21 +34,22 @@ def initialize(attributes = {})
unload(attributes)
end
- # Returns a hash of the response object, potentially useful for comparison
- # on sync
+ # @return [Hash] the response object, potentially useful for comparison on sync
#
def to_md5
Digest::MD5.hexdigest(@raw_response.body)
end
- # Handles the basic responses we might get back from Net::HTTP.
- # On success, returns a new Resource based on the response.
+ # Handles the basic responses we might get back from a web service.
#
# On failure, throws an error.
#
# If a service returns something other than a 404 when an object is not found,
# you'll need to handle that in the subclass.
#
+ # @param [Object] response the object.
+ # @return [Resource] a new Resource created from the response.
+ #
def self.parse(response)
if response.class == HTTParty::Response
@@ -72,8 +74,8 @@ def self.parse(response)
# Instantiate new GovKit::Resources.
#
- # +record+ is a hash of values returned by a service,
- # or an array of hashes.
+ # @param [Hash] record a hash of values returned by a service, or an array of hashes.
+ # @return [Resource]
#
# If +record+ is a hash, return a single GovKit::Resource.
# If it is an array, return an array of GovKit::Resources.
@@ -86,16 +88,24 @@ def self.instantiate(record)
end
end
+ # Instantiate a set of records.
+ #
+ # @return [Array] Array of records
+ # @param [Array] collection An array of records
def self.instantiate_collection(collection)
collection.collect! { |record| new(record) }
end
- # Given a hash of attributes, assign it to the @attributes member,
- # then for each attribute, create or set a pair of member accessors with the name
+ # Given a hash of attributes, assign it to the @attributes member.
+ # Then for each attribute, create or set a pair of member accessors with the name
# of the attribute's key.
+ #
# If the value of the attribute is itself an array or a hash,
# then create a new class with the (singularized) key as a name, and with a parent class of Resource,
# and initialize it with the hash.
+ #
+ # @param [Hash] attributes the attributes returned by the web service.
+ #
def unload(attributes)
raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)

0 comments on commit 013f186

Please sign in to comment.