Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit f6d67fba7bd26d94ba0f77fe6331020aefce0145 Derek Willis committed Dec 1, 2010
Showing with 180 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +4 −0 Gemfile
  3. +2 −0 Rakefile
  4. +22 −0 campaign_cash.gemspec
  5. +11 −0 lib/campaign_cash.rb
  6. +81 −0 lib/campaign_cash/base.rb
  7. +54 −0 lib/campaign_cash/candidate.rb
  8. +3 −0 lib/campaign_cash/version.rb
@@ -0,0 +1,3 @@
+pkg/*
+*.gem
+.bundle
@@ -0,0 +1,4 @@
+source :gemcutter
+
+# Specify your gem's dependencies in campaign_cash.gemspec
+gemspec
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,22 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path("../lib/campaign_cash/version", __FILE__)
+
+Gem::Specification.new do |s|
+ s.name = "campaign_cash"
+ s.version = CampaignCash::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = []
+ s.email = []
+ s.homepage = "http://rubygems.org/gems/campaign_cash"
+ s.summary = "TODO: Write a gem summary"
+ s.description = "TODO: Write a gem description"
+
+ s.required_rubygems_version = ">= 1.3.6"
+ s.rubyforge_project = "campaign_cash"
+
+ s.add_development_dependency "bundler", ">= 1.0.0"
+
+ s.files = `git ls-files`.split("\n")
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
+ s.require_path = 'lib'
+end
@@ -0,0 +1,11 @@
+$:.unshift(File.dirname(__FILE__)) unless
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
+
+module CampaignCash
+
+end
+
+require "#{File.dirname(__FILE__)}/campaign_cash/base"
+require "#{File.dirname(__FILE__)}/campaign_cash/version"
+require "#{File.dirname(__FILE__)}/campaign_cash/candidate"
+#require "#{File.dirname(__FILE__)}/campaign_cash/committee"
@@ -0,0 +1,81 @@
+require 'rubygems'
+require 'open-uri'
+require 'json'
+
+module CampaignCash
+ class Base
+ API_SERVER = 'api.nytimes.com'
+ API_VERSION = 'v3'
+ API_NAME = 'elections/us'
+ API_BASE = "/svc/#{API_NAME}/#{API_VERSION}/finances"
+
+ @@api_key = nil
+ @@copyright = nil
+
+ class << self
+
+ ##
+ # The copyright footer to be placed at the bottom of any data from the New York Times. Note this is only set after an API call.
+ def copyright
+ @@copyright
+ end
+
+ def cycle
+ @@cycle
+ end
+
+ def base_uri
+ @@base_uri
+ end
+
+ ##
+ # Set the API key used for operations. This needs to be called before any requests against the API. To obtain an API key, go to http://developer.nytimes.com/
+ def api_key=(key)
+ @@api_key = key
+ end
+
+ def api_key
+ @@api_key
+ end
+
+ ##
+ # Builds a request URI to call the API server
+ def build_request_url(path, params)
+ URI::HTTP.build :host => API_SERVER,
+ :path => "#{API_BASE}/#{path}.json",
+ :query => params.map {|k,v| "#{k}=#{v}"}.join('&')
+ end
+
+ def invoke(path, params={})
+ begin
+ if @@api_key.nil?
+ raise "You must initialize the API key before you run any API queries"
+ end
+
+ full_params = params.merge 'api-key' => @@api_key
+
+ uri = build_request_url(path, full_params)
+
+ reply = uri.read
+ parsed_reply = JSON.parse reply
+
+ if parsed_reply.nil?
+ raise "Empty reply returned from API"
+ end
+
+ @@copyright = parsed_reply['copyright']
+ @@cycle = parsed_reply['cycle']
+ @@base_uri = parsed_reply['base_uri']
+
+ parsed_reply
+ rescue OpenURI::HTTPError => e
+ if e.message =~ /^404/
+ return nil
+ end
+
+ raise "Error connecting to URL #{uri} #{e}"
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,54 @@
+module CampaignCash
+ class Candidate < Base
+
+ attr_reader :name, :id, :state, :district, :party, :fec_uri, :committee,
+ :mailing_city, :mailing_address, :mailing_state, :mailing_zip,
+ :total_receipts, :total_contributions, :total_from_individuals,
+ :total_from_pacs, :candidate_loans, :total_disbursements,
+ :total_refunds, :debts_owed, :begin_cash, :end_cash, :status,
+ :date_coverage_to, :date_coverage_from
+
+ def initialize(params={})
+ params.each_pair do |k,v|
+ instance_variable_set("@#{k}", v)
+ end
+ end
+
+ def self.create_from_api(params={})
+ self.new :name => params['name'],
+ :id => params['id'],
+ :state => params['state'],
+ :district => params['district'],
+ :party => params['party'],
+ :fec_uri => params['fec_uri'],
+ :committee => params['committee'],
+ :mailing_city => params['mailing_city'],
+ :mailing_address => params['mailing_address'],
+ :mailing_state => params['mailing_state'],
+ :mailing_zip => params['mailing_zip'],
+ :total_receipts => params['total_receipts'],
+ :total_contributions => params['total_contributions'],
+ :total_from_individuals => params['total_from_individuals'],
+ :total_from_pacs => params['total_from_pacs'],
+ :candidate_loans => params['candidate_loans'],
+ :total_disbursements => params['total_disbursements'],
+ :total_refunds => params['total_refunds'],
+ :debts_owed => params['debts_owed'],
+ :begin_cash => params['begin_cash'],
+ :end_cash => params['end_cash'],
+ :status => params['status'],
+ :date_coverage_from => params['date_coverage_from'],
+ :date_coverage_to => params['date_coverage_to']
+ end
+
+ def self.find_by_fecid(cycle, fecid)
+
+ reply = invoke("#{cycle}/candidates/#{fecid}")
+ result = reply['results']
+ self.create_from_api(result.first) if result.first
+
+ end
+
+
+ end
+end
@@ -0,0 +1,3 @@
+module CampaignCash
+ VERSION = "0.0.1"
+end

0 comments on commit f6d67fb

Please sign in to comment.