campaign_cash 2.0.8 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  pkg/*
2
2
  *.gem
3
3
  .bundle
4
+ *nyt_api_key.rb
data/README.rdoc CHANGED
@@ -12,11 +12,11 @@ Simple ruby wrapper for The New York Times Campaign Finance API[http://developer
12
12
 
13
13
  == News
14
14
 
15
+ * Feb. 8, 2012: Version 2.1.0 released. Added better support for independent expenditures and FilingSummary class for presidential candidate filings.
16
+ * Jan. 28, 2012: Version 2.0.8 released. Bugfix for Candidate#search. Thanks to @benjaminjackson for patch.
15
17
  * Jan. 24, 2012: Version 2.0.7 released. Added candidate_name attribute accessor to IndependentExpenditure objects.
16
18
  * Jan. 19, 2012: Version 2.0.6 released. Added transaction_id param to IndependentExpenditure objects.
17
19
  * Jan. 19, 2012: Version 2.0.5 released. Bugfix to add amendment param to IndependentExpenditure objects.
18
- * Jan. 18, 2012: Version 2.0.4 released. Bugfix to handle offsets better.
19
- * Jan. 14, 2012: Version 2.0.3 released. Bugfix so that President.detail returns 1 object, not an array.
20
20
 
21
21
  == INSTALL:
22
22
 
@@ -203,6 +203,7 @@ The IE responses also accept an optional offset argument, using multiples of 20.
203
203
  * Derek Willis, dwillis@nytimes.com
204
204
  * Al Shaw, almshaw@gmail.com
205
205
  * Jason Holt, jjh@offensivepolitics.net
206
+ * Benjamin Jackson, http://twitter.com/benjaminjackson
206
207
 
207
208
  == Copyright
208
209
 
data/lib/campaign_cash.rb CHANGED
@@ -1,3 +1,3 @@
1
- %w(base candidate committee contribution filing form independent_expenditure president).each do |f|
1
+ %w(base candidate committee contribution individual_contribution filing filing_summary form independent_expenditure president).each do |f|
2
2
  require File.join(File.dirname(__FILE__), '../lib/campaign_cash', f)
3
3
  end
@@ -52,7 +52,6 @@ module CampaignCash
52
52
  reply = invoke("#{cycle}/committees/#{fecid}/contributions")
53
53
  all_candidates(reply)
54
54
  end
55
- end
56
-
55
+ end
57
56
  end
58
57
  end
@@ -59,7 +59,6 @@ module CampaignCash
59
59
  end
60
60
 
61
61
  def self.by_type(cycle, form_type)
62
- cycle = cycle
63
62
  reply = Base.invoke("#{cycle}/filings/types/#{form_type}")
64
63
  results = reply['results']
65
64
  results.map{|c| Filing.create(c)}
@@ -0,0 +1,23 @@
1
+ module CampaignCash
2
+ class FilingSummary < Base
3
+
4
+ attr_reader :pac_contributions_period, :contributions_2300, :party_contributions_cycle, :fundraising_offsets_period, :primary_general, :pac_refunds_cycle, :created_at, :party_refunds_cycle, :fundraising_expenses_period, :net_party_contributions, :num_contributions_200_499, :individual_refunds_cycle, :candidate_contributions_period, :legal_offsets_cycle, :num_contributions_500_1499, :net_operating_expenses, :total_debts_owed, :refunds_200_499, :refunds_1500_2299, :transfers_out_period, :net_primary, :liquidate_period, :contributions_200_499, :operating_offsets_cycle, :num_contributions_1500_2299, :candidate_loan_repayments_period, :committee_uri, :federal_funds_cycle, :net_candidate_contributions, :candidate_loans_period, :filing_id, :net_pac_contributions, :num_refunds_200_499, :candidate_loan_repayments_cycle, :total_offsets_cycle, :party_contributions_period, :net_individual_contributions, :num_refunds_1500_2299, :net_general, :total_receipts_cycle, :federal_funds_period, :transfers_out_cycle, :cycle, :other_loan_repayments_period, :contributions_500_1499, :legal_offsets_period, :date_coverage_from, :contributions_less_than_200, :fec_form_type, :candidate_contributions_cycle, :cash_on_hand_beginning, :individual_refunds_period, :updated_at, :fundraising_expenses_cycle, :num_refunds_500_1499, :cash_on_hand_close, :num_contributions_less_than_200, :total_loans_cycle, :candidate_uri, :contributions_1500_2299, :refunds_2300, :flag_most_current_report, :total_loan_repayments_period, :other_loans_period, :operating_expenditures_cycle, :other_disbursements_period, :total_loans_period, :transfers_in_period, :transfers_in_cycle, :report, :legal_expenses_period, :candidate_loans_cycle, :individual_contributions_period, :other_disbursements_cycle, :total_disbursements_period, :other_loans_cycle, :net_transfers_in, :net_disbursements, :operating_expenditures_period, :fundraising_offsets_cycle, :date_coverage_to, :total_loan_repayments_cycle, :total_disbursements_cycle, :party_refunds_period, :individual_contributions_cycle, :net_total_contributions, :other_loan_repayments_cycle, :total_refunds_cycle, :total_receipts_period, :total_offsets_period, :total_contributions_period, :total_contributions_cycle, :refunds_500_1499, :pac_refunds_period, :flag_valid_report, :legal_expenses_cycle, :num_refunds_less_than_200, :refunds_less_than_200, :pac_contributions_cycle, :net_legal_expenses, :net_fundraising_expenses, :num_contributions_2300, :total_refunds_period, :operating_offsets_period, :num_refunds_2300
5
+
6
+ def initialize(params={})
7
+ params.each_pair do |k,v|
8
+ instance_variable_set("@#{k}", v)
9
+ end
10
+ end
11
+
12
+ def self.create(params={})
13
+ self.new(params)
14
+ end
15
+
16
+ def self.by_id(id)
17
+ cycle = CURRENT_CYCLE
18
+ result = FilingSummary.create(Base.invoke("#{cycle}/filings/#{id}")["results"]["filing_summary"])
19
+ end
20
+ end
21
+ end
22
+
23
+
@@ -14,7 +14,7 @@ module CampaignCash
14
14
  :committee_name => params['fec_committee_name'],
15
15
  :candidate => parse_candidate(params['fec_candidate']),
16
16
  :office => params['office'],
17
- :state => params['state'].strip,
17
+ :state => params['state'] ? params['state'].strip : nil,
18
18
  :district => params['district'],
19
19
  :date => date_parser(params['date']),
20
20
  :support_or_oppose => params['support_or_oppose'],
@@ -25,7 +25,9 @@ module CampaignCash
25
25
  :date_received => date_parser(params['date_received']),
26
26
  :amendment => params['amendment'],
27
27
  :transaction_id => params['transaction_id'],
28
- :candidate_name => params['candidate_name']
28
+ :candidate_name => params['candidate_name'],
29
+ # hash is a SHA1 of committee_id, date and transaction_id
30
+ :hash => params['hash']
29
31
  end
30
32
 
31
33
  def self.latest(offset=nil)
@@ -0,0 +1,35 @@
1
+ module CampaignCash
2
+ class IndividualContribution < Base
3
+
4
+ attr_reader :zip5, :system_code, :occupation, :conduit_zip, :conduit_address_two, :city, :zip, :increased_limit, :donor_candidate, :conduit_name, :conduit_city, :prefix, :memo_text, :back_ref_tran_id, :aggregate_amount, :filing_id, :donor_office, :back_ref_sched_name, :address_two, :pac_name, :exclude, :conduit_address_one, :amount, :transaction_type, :lng, :flag_orgind, :date, :fec_form_type, :donor_state, :donor_cand_id, :last_name, :full_name, :employer, :donor_district, :conduit_state, :address_one, :tran_id, :suffix, :donor_cmte_id, :display_name, :transaction_description, :prigen, :memo_code, :linenumber, :lat, :amended_cd, :state, :middle_name, :first_name
5
+
6
+ def initialize(params={})
7
+ params.each_pair do |k,v|
8
+ instance_variable_set("@#{k}", v)
9
+ end
10
+ end
11
+
12
+ def self.create(params={})
13
+ self.new(params)
14
+ end
15
+
16
+ def self.committee(fecid, offset=nil)
17
+ cycle = CURRENT_CYCLE
18
+ results = invoke("#{cycle}/contributions/committee/#{fecid}", {:offset => offset})['results']
19
+ results.map{|c| IndividualContribution.create(c["contribution"]) }
20
+ end
21
+
22
+ def self.filing(form_id, offset=nil)
23
+ cycle = CURRENT_CYCLE
24
+ results = invoke("#{cycle}/contributions/filing/#{form_id}", {:offset => offset})['results']
25
+ results.map{|c| IndividualContribution.create(c["contribution"]) }
26
+ end
27
+
28
+ def self.candidate(fecid, offset=nil)
29
+ cycle = CURRENT_CYCLE
30
+ results = invoke("#{cycle}/contributions/candidate/#{fecid}", {:offset => offset})['results']
31
+ results.map{|c| IndividualContribution.create(c["contribution"]) }
32
+ end
33
+
34
+ end
35
+ end
@@ -1,23 +1,24 @@
1
1
  module CampaignCash
2
2
  class President < Base
3
-
4
- attr_reader :committee_id, :name, :id, :party, :date_coverage_from, :date_coverage_to, :total_receipts, :total_disbursements,
5
- :end_cash, :total_refunds, :total_contributions, :net_individual_contributions, :net_pac_contributions,
3
+
4
+ attr_reader :committee_id, :name, :id, :party, :office, :date_coverage_from, :date_coverage_to, :total_receipts, :total_disbursements,
5
+ :end_cash, :total_refunds, :total_contributions, :net_individual_contributions, :net_pac_contributions,
6
6
  :net_party_contributions, :net_candidate_contributions, :net_primary_contributions, :net_general_contributions,
7
7
  :federal_funds, :contributions_less_than_200, :contributions_200_499, :contributions_500_1499, :contributions_1500_2499,
8
8
  :contributions_max
9
-
9
+
10
10
  def initialize(params={})
11
11
  params.each_pair do |k,v|
12
12
  instance_variable_set("@#{k}", v)
13
13
  end
14
14
  end
15
-
15
+
16
16
  # Creates a new president summary object from a JSON API presidential response.
17
17
  def self.create_summary(params={})
18
18
  self.new :name => params['name'],
19
19
  :id => params['candidate_id'],
20
- :party => params['party'],
20
+ :party => get_party(params['party']),
21
+ :office => 'president',
21
22
  :committee_id => params['committee_id'],
22
23
  :total_receipts => params['total_receipts'],
23
24
  :total_disbursements => params['total_disbursements'],
@@ -25,12 +26,13 @@ module CampaignCash
25
26
  :date_coverage_from => params['date_coverage_from'],
26
27
  :date_coverage_to => params['date_coverage_to']
27
28
  end
28
-
29
+
29
30
  # Creates a detailed president object
30
31
  def self.create_detail(params={})
31
32
  self.new :name => params['candidate_name'],
32
33
  :id => params['candidate_id'],
33
- :party => params['party'],
34
+ :party => get_party(params['party']),
35
+ :office => 'president',
34
36
  :committee_id => params['committee_id'],
35
37
  :total_receipts => params['total_receipts'],
36
38
  :total_contributions => params['total_contributions'],
@@ -39,20 +41,20 @@ module CampaignCash
39
41
  :date_coverage_from => params['date_coverage_from'],
40
42
  :date_coverage_to => params['date_coverage_to'],
41
43
  :total_refunds => params['total_refunds'],
42
- :net_individual_contributions => params['net_individual_contributions'],
43
- :net_pac_contributions => params['net_pac_contributions'],
44
- :net_party_contributions => params['net_party_contributions'],
45
- :net_candidate_contributions => params['net_candidate_contributions'],
46
- :net_primary_contributions => params['net_primary_contributions'],
44
+ :net_individual_contributions => params['net_individual_contributions'],
45
+ :net_pac_contributions => params['net_pac_contributions'],
46
+ :net_party_contributions => params['net_party_contributions'],
47
+ :net_candidate_contributions => params['net_candidate_contributions'],
48
+ :net_primary_contributions => params['net_primary_contributions'],
47
49
  :net_general_contributions => params['net_general_contributions'],
48
- :federal_funds => params['federal_funds'],
49
- :contributions_less_than_200 => params['total_contributions_less_than_200'],
50
- :contributions_200_499 => params['contributions_200_499'],
51
- :contributions_500_1499 => params['contributions_500_1499'],
50
+ :federal_funds => params['federal_funds'],
51
+ :contributions_less_than_200 => params['total_contributions_less_than_200'],
52
+ :contributions_200_499 => params['contributions_200_499'],
53
+ :contributions_500_1499 => params['contributions_500_1499'],
52
54
  :contributions_1500_2499 => params['contributions_1500_2499'],
53
55
  :contributions_max => params['total_contributions_max']
54
56
  end
55
-
57
+
56
58
  # Returns an array of presidential candidates for a given cycle, defaults to the current cycle.
57
59
  # Only returns candidates that The New York Times is tracking for financial activity.
58
60
  def self.summary(cycle=CURRENT_CYCLE)
@@ -60,7 +62,7 @@ module CampaignCash
60
62
  results = reply['results']
61
63
  results.map{|c| self.create_summary(c)}
62
64
  end
63
-
65
+
64
66
  # Returns a President object for a given presidential candidate in a given cycle, defaults to the current cycle.
65
67
  # Only returns candidates tracked by The New York Times.
66
68
  def self.detail(id, cycle=CURRENT_CYCLE)
@@ -68,5 +70,13 @@ module CampaignCash
68
70
  results = reply['results'].first
69
71
  create_detail(results)
70
72
  end
73
+
74
+ private
75
+
76
+ def self.get_party party_identifier
77
+ return "DEM" if party_identifier == "D"
78
+ return "REP" if party_identifier == "R"
79
+ party_identifier
80
+ end
71
81
  end
72
82
  end
@@ -1,3 +1,3 @@
1
1
  module CampaignCash
2
- VERSION = "2.0.8"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -37,5 +37,5 @@ class TestCampaignCash::TestFiling < Test::Unit::TestCase
37
37
  assert_equal @filings.size, 20
38
38
  assert_equal @filings.first.report_title, "STATEMENT OF ORGANIZATION"
39
39
  end
40
- end
40
+ end
41
41
  end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class TestCampaignCash::TestFilingSummary < Test::Unit::TestCase
4
+ include CampaignCash
5
+
6
+ context "filing summaries" do
7
+ setup do
8
+ @filing_summary = FilingSummary.by_id(751678)
9
+ end
10
+ should "get a filing by form id" do
11
+ assert_kind_of(FilingSummary, @filing_summary)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ class TestCampaignCash::TestIndividualContribution < Test::Unit::TestCase
4
+ include CampaignCash
5
+
6
+ context "get contributions" do
7
+ objs_collection = []
8
+ objs_collection << IndividualContribution.committee("C00496497")
9
+ objs_collection << IndividualContribution.filing("724196")
10
+ objs_collection << IndividualContribution.candidate("P80003353")
11
+
12
+ objs_collection.each do |objs|
13
+ should "return a list of objects of the IndividualContribution type or an empty list" do
14
+ if objs.size > 0
15
+ assert_kind_of(IndividualContribution, objs.first)
16
+ else
17
+ assert_equal([], objs)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class TestCampaignCash::TestPresident < Test::Unit::TestCase
4
4
  include CampaignCash
5
-
5
+
6
6
  context "President.summary" do
7
7
  setup do
8
8
  reply = Base.invoke('2012/president/totals', {})
@@ -10,33 +10,56 @@ class TestCampaignCash::TestPresident < Test::Unit::TestCase
10
10
  @summaries = @results.map{|r| President.create_summary(r)}
11
11
  @summary = @summaries.first
12
12
  end
13
-
13
+
14
14
  should "return an array of objects of the President type" do
15
15
  assert_kind_of(President, @summary)
16
16
  end
17
-
18
- %w(name total_contributions party total_receipts).each do |attr|
17
+
18
+ %w(name total_contributions total_receipts).each do |attr|
19
19
  should "assign the value of the @#{attr} attribute from the '#{attr}' key in the hash" do
20
20
  assert_equal(@results.first[attr], @summary.send(attr))
21
21
  end
22
22
  end
23
+
24
+ should "assign the office to 'president'" do
25
+ assert_equal('president', @summary.office)
26
+ end
27
+
28
+ should "assign the party to 'REP' if the candidate is republican or 'DEM' if democrat" do
29
+ party = @results.first['party']
30
+ party = "REP" if party == "R"
31
+ party = "DEM" if party == "D"
32
+ assert_equal(party, @summary.party)
33
+ end
34
+
23
35
  end
24
-
36
+
25
37
  context "President.detail" do
26
38
  setup do
27
39
  reply = Base.invoke('2012/president/candidates/C00496034', {})
28
40
  @results = reply['results']
29
41
  @detail = President.create_detail(@results.first)
30
42
  end
31
-
43
+
32
44
  should "return an array of objects of the President type" do
33
45
  assert_kind_of(President, @detail)
34
46
  end
35
-
36
- %w(net_primary_contributions party total_refunds).each do |attr|
47
+
48
+ %w(net_primary_contributions total_refunds).each do |attr|
37
49
  should "assign the value of the @#{attr} attribute from the '#{attr}' key in the hash" do
38
50
  assert_equal(@results.first[attr], @detail.send(attr))
39
51
  end
40
52
  end
41
- end
53
+
54
+ should "assign the office to 'president'" do
55
+ assert_equal('president', @detail.office)
56
+ end
57
+
58
+ should "assign the party to 'REP' if the candidate is republican or 'DEM' if democrat" do
59
+ party = @results.first['party']
60
+ party = "REP" if party == "R"
61
+ party = "DEM" if party == "D"
62
+ assert_equal(party, @detail.party)
63
+ end
64
+ end
42
65
  end
data/test/test_helper.rb CHANGED
@@ -4,7 +4,7 @@ require 'shoulda'
4
4
  require 'json'
5
5
  require 'ostruct'
6
6
 
7
- %w(base candidate committee contribution filing form independent_expenditure president).each do |f|
7
+ %w(base candidate committee contribution individual_contribution filing filing_summary form independent_expenditure president).each do |f|
8
8
  require File.join(File.dirname(__FILE__), '../lib/campaign_cash', f)
9
9
  end
10
10
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: campaign_cash
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
+ - 1
8
9
  - 0
9
- - 8
10
- version: 2.0.8
10
+ version: 2.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Derek Willis
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-28 00:00:00 -05:00
18
+ date: 2012-02-08 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -101,15 +101,19 @@ files:
101
101
  - lib/campaign_cash/committee.rb
102
102
  - lib/campaign_cash/contribution.rb
103
103
  - lib/campaign_cash/filing.rb
104
+ - lib/campaign_cash/filing_summary.rb
104
105
  - lib/campaign_cash/form.rb
105
106
  - lib/campaign_cash/independent_expenditure.rb
107
+ - lib/campaign_cash/individual_contribution.rb
106
108
  - lib/campaign_cash/president.rb
107
109
  - lib/campaign_cash/version.rb
108
110
  - test/campaign_cash/test_candidate.rb
109
111
  - test/campaign_cash/test_committee.rb
110
112
  - test/campaign_cash/test_filing.rb
113
+ - test/campaign_cash/test_filing_summary.rb
111
114
  - test/campaign_cash/test_form.rb
112
115
  - test/campaign_cash/test_independent_expenditure.rb
116
+ - test/campaign_cash/test_individual_contribution.rb
113
117
  - test/campaign_cash/test_president.rb
114
118
  - test/test_helper.rb
115
119
  has_rdoc: true
@@ -152,7 +156,9 @@ test_files:
152
156
  - test/campaign_cash/test_candidate.rb
153
157
  - test/campaign_cash/test_committee.rb
154
158
  - test/campaign_cash/test_filing.rb
159
+ - test/campaign_cash/test_filing_summary.rb
155
160
  - test/campaign_cash/test_form.rb
156
161
  - test/campaign_cash/test_independent_expenditure.rb
162
+ - test/campaign_cash/test_individual_contribution.rb
157
163
  - test/campaign_cash/test_president.rb
158
164
  - test/test_helper.rb