fech-search 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/LICENSE +23 -0
- data/README.md +124 -0
- data/Rakefile +2 -0
- data/fech-search.gemspec +21 -0
- data/lib/fech-search.rb +4 -0
- data/lib/fech-search/search.rb +187 -0
- data/lib/fech-search/search_result.rb +41 -0
- data/lib/fech-search/version.rb +5 -0
- data/spec/search_result_spec.rb +46 -0
- data/spec/search_spec.rb +51 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a6af2516a3e0869ff3cdb0d4ff69d0574557cd74
|
4
|
+
data.tar.gz: 53b16020e56f3a70011df1044ec868f915f653be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7be2bf91e0b29e3faa985a133bbd5e2a7327c59bca89eb80bd127c701a21b2a50fadbe22f77dd54bb4ed8f5ae5a11cd41e26c9167c822eb9e7677514501e72d0
|
7
|
+
data.tar.gz: 3ef5499dbb83778c98d575a562bd2f1efa4389829ad91c084811ffea33dda063d7b5f269396c171ac6c6381b3711e71cd186b5de6600b00e363cf58135b5cb6a
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fech-search (0.0.1)
|
5
|
+
fech (= 1.4.1)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.2.4)
|
11
|
+
fastercsv (1.5.5)
|
12
|
+
fech (1.4.1)
|
13
|
+
fastercsv
|
14
|
+
people
|
15
|
+
people (0.2.1)
|
16
|
+
rspec (2.13.0)
|
17
|
+
rspec-core (~> 2.13.0)
|
18
|
+
rspec-expectations (~> 2.13.0)
|
19
|
+
rspec-mocks (~> 2.13.0)
|
20
|
+
rspec-core (2.13.1)
|
21
|
+
rspec-expectations (2.13.0)
|
22
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
23
|
+
rspec-mocks (2.13.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
fech-search!
|
30
|
+
rspec (= 2.13.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2013, The Huffington Post
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
12
|
+
and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
18
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
20
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
21
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
22
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
23
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Fech-Search
|
2
|
+
|
3
|
+
Fech-Search is a plugin for [Fech](http://nytimes.github.io/Fech/) that adds an interface for searching for electronic filings submitted to the Federal Election Commission. Where Fech provides a way to download and parse filings, Fech-Search provides users with a way to find the filings they're interested in.
|
4
|
+
|
5
|
+
Fech-Search is essentially a Ruby wrapper around the [electronic filing search form on the FEC's website](http://www.fec.gov/finance/disclosure/efile_search.shtml).
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Example
|
10
|
+
|
11
|
+
require 'fech-search'
|
12
|
+
|
13
|
+
Perform a search for form F3P filings (report of receipts and disbursements) submitted by Romney for President:
|
14
|
+
|
15
|
+
search = Fech::Search.new(:committee_name => "Romney for President", :form_type => "F3P")
|
16
|
+
|
17
|
+
The search is performed when `Fech::Search.new` is called. You can then access the results of the search with `search.results`, which is simply an array of `Fech::SearchResult` objects:
|
18
|
+
|
19
|
+
results = search.results
|
20
|
+
results.size
|
21
|
+
=> 100
|
22
|
+
|
23
|
+
Each `Fech::SearchResult` object has the following attributes:
|
24
|
+
|
25
|
+
- amended_by
|
26
|
+
- committee_id
|
27
|
+
- committee_name
|
28
|
+
- date_filed
|
29
|
+
- date_format
|
30
|
+
- description
|
31
|
+
- filing_id
|
32
|
+
- form_type
|
33
|
+
- period
|
34
|
+
|
35
|
+
You can now work with the results as you would any Ruby array.
|
36
|
+
|
37
|
+
Remove any filings that have been amended:
|
38
|
+
|
39
|
+
results.select! { |r| r.amended_by.nil? }
|
40
|
+
results.size
|
41
|
+
=> 41
|
42
|
+
|
43
|
+
Limit to filings covering the last six months of 2012:
|
44
|
+
|
45
|
+
results.select! { |r| r.period[:from] >= Date.new(2012, 7, 1) && r.period[:to] <= Date.new(2012, 12, 31) }
|
46
|
+
results.size
|
47
|
+
=> 6
|
48
|
+
|
49
|
+
Create a `Fech::Filing` object from one of the results and download the filing data:
|
50
|
+
|
51
|
+
filing = results.first.filing.download
|
52
|
+
|
53
|
+
You now have access to the same filing object and methods as if you had created it directly with [Fech](http://nytimes.github.io/Fech/).
|
54
|
+
|
55
|
+
To initialize the `Fech::Filing` object with parameters, pass them as arguments to the `SearchResult#filing` method:
|
56
|
+
|
57
|
+
filing = results.first.filing(:csv_parser => Fech::CsvDoctor)
|
58
|
+
|
59
|
+
Get information from the filing:
|
60
|
+
|
61
|
+
filing.summary[:col_a_total_receipts]
|
62
|
+
=> "4747984.49"
|
63
|
+
|
64
|
+
filing.summary[:col_b_total_receipts]
|
65
|
+
=> "10617838.18"
|
66
|
+
|
67
|
+
### Search parameters
|
68
|
+
|
69
|
+
The following search parameters are available:
|
70
|
+
|
71
|
+
- `:committee_id` (The nine-character committee ID assigned by the FEC)
|
72
|
+
- examples: "C00499202", "C00130187"
|
73
|
+
- `:committee_name`
|
74
|
+
- examples: "Restore Our Future", "Obama for America"
|
75
|
+
- `:state` (Two-character state abbreviation)
|
76
|
+
- examples: "MA", "FL"
|
77
|
+
- `:party` (Three-character party abbreviation)
|
78
|
+
- examples: "REP", "DEM"
|
79
|
+
- `:committee_type` (One-character committee type. [See a list of committee types](http://www.fec.gov/finance/disclosure/metadata/CommitteeTypeCodes.shtml))
|
80
|
+
- examples: "H", "P"
|
81
|
+
- `:report_type` ([See a list of report types](http://www.fec.gov/finance/disclosure/metadata/ReportTypeCodes.shtml))
|
82
|
+
- examples: "M4", "Q1"
|
83
|
+
- `:date` (A Ruby Date object)
|
84
|
+
- `:form_type` ([See the FEC's electronic filing search for a list of form types](http://www.fec.gov/finance/disclosure/efile_search.shtml))
|
85
|
+
- examples: "F3", "F24"
|
86
|
+
|
87
|
+
Any number of these parameters may be used. However, the FEC's search functionality has some limitations:
|
88
|
+
|
89
|
+
- All other parameters are ignored when `:committee_id` is used.
|
90
|
+
- `:form_type` cannot be used by itself; another parameter must be used with it.
|
91
|
+
|
92
|
+
An `ArgumentError` will be raised if either of these is violated with `Fech::Search.new`.
|
93
|
+
|
94
|
+
__Note:__ Overly broad searches can be slow, so you should make your search as specific as possible.
|
95
|
+
|
96
|
+
## Installation
|
97
|
+
|
98
|
+
Add this line to your application's Gemfile:
|
99
|
+
|
100
|
+
gem 'fech-search'
|
101
|
+
|
102
|
+
And then execute:
|
103
|
+
|
104
|
+
$ bundle
|
105
|
+
|
106
|
+
Or install it yourself as:
|
107
|
+
|
108
|
+
$ gem install fech-search
|
109
|
+
|
110
|
+
## Contributing
|
111
|
+
|
112
|
+
1. Fork it
|
113
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
114
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
115
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
116
|
+
5. Create new Pull Request
|
117
|
+
|
118
|
+
## Authors
|
119
|
+
|
120
|
+
- Aaron Bycoffe, bycoffe@huffingtonpost.com
|
121
|
+
|
122
|
+
## Copyright
|
123
|
+
|
124
|
+
Copyright © 2013 The Huffington Post. See LICENSE for details.
|
data/Rakefile
ADDED
data/fech-search.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/fech-search/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Aaron Bycoffe"]
|
6
|
+
gem.email = ["bycoffe@huffingtonpost.com"]
|
7
|
+
gem.description = %q{A Fech plugin for searching electronic FEC filings}
|
8
|
+
gem.summary = %q{Fech-Search provides an interface for searching for electronic filings submitted to the FEC, and accessing the data in those filings using Fech}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "fech-search"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Fech::Search::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "fech", "~> 1.4.1"
|
19
|
+
|
20
|
+
gem.add_development_dependency "rspec", "~> 2.13.0"
|
21
|
+
end
|
data/lib/fech-search.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Fech
|
4
|
+
|
5
|
+
# Fech::Search is an interface for the FEC's electronic filing search
|
6
|
+
# (http://www.fec.gov/finance/disclosure/efile_search.shtml)
|
7
|
+
class Search
|
8
|
+
|
9
|
+
# @param [Hash] search_params a hash of parameters to be
|
10
|
+
# passed to the search form.
|
11
|
+
def initialize(search_params={})
|
12
|
+
@search_params = validate_params(make_params(search_params))
|
13
|
+
@search_url = 'http://query.nictusa.com/cgi-bin/dcdev/forms/'
|
14
|
+
@response = search
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert the search parameters passed to @initialize to use
|
18
|
+
# the format and keys needed for the form submission.
|
19
|
+
# @return [Hash]
|
20
|
+
def make_params(search_params)
|
21
|
+
{
|
22
|
+
'comid' => search_params[:committee_id] || '',
|
23
|
+
'name' => search_params[:committee_name] || '',
|
24
|
+
'state' => search_params[:state] || '',
|
25
|
+
'party' => search_params[:party] || '',
|
26
|
+
'type' => search_params[:committee_type] || '',
|
27
|
+
'rpttype' => search_params[:report_type] || '',
|
28
|
+
'date' => search_params[:date] ? search_params[:date].strftime('%m/%d/%Y') : '',
|
29
|
+
'frmtype' => search_params[:form_type] || ''
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_params(params)
|
34
|
+
raise ArgumentError, "At least one search parameter must be given" if params.values.all? { |x| x.empty? }
|
35
|
+
nonempty_keys = params.select { |k, v| !v.empty? }.keys
|
36
|
+
raise ArgumentError, ":committee_id cannot be used with other search parameters" if nonempty_keys.include?("comid") && nonempty_keys.size > 1
|
37
|
+
raise ArgumentError, ":form_type must be used with at least one other search parameter" if nonempty_keys.include?("frmtype") && nonempty_keys.size == 1
|
38
|
+
params
|
39
|
+
end
|
40
|
+
|
41
|
+
# Performs the search of the FEC's electronic filing database.
|
42
|
+
def search
|
43
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
44
|
+
http.read_timeout = 5000
|
45
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
46
|
+
request.set_form_data(@search_params)
|
47
|
+
@response = http.request(request)
|
48
|
+
end
|
49
|
+
|
50
|
+
# A parsed URI for the search
|
51
|
+
def uri
|
52
|
+
uri = URI.parse(@search_url)
|
53
|
+
end
|
54
|
+
|
55
|
+
def body
|
56
|
+
@response ? @response.body : nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# The results page is formatted differently depending
|
60
|
+
# on whether the search includes a date. Use the correct
|
61
|
+
# method for parsing the results depending on whether
|
62
|
+
# a date was used in the search. Will return an array of
|
63
|
+
# results if called directly, or will yield the results one
|
64
|
+
# by one if a block is passed.
|
65
|
+
def results(&block)
|
66
|
+
if @search_params['date'] != ''
|
67
|
+
results_from_date_search(&block)
|
68
|
+
else
|
69
|
+
results_from_nondate_search(&block)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Parse the results from a search that does not include a date.
|
74
|
+
# Will return an array of results if called directly, or will
|
75
|
+
# yield the results one by one if a block is passed.
|
76
|
+
def results_from_nondate_search(&block)
|
77
|
+
parsed_results = []
|
78
|
+
regex = /<DT>(.*?)<P/m
|
79
|
+
match = body.match regex
|
80
|
+
return [] if match.nil?
|
81
|
+
content = match[1]
|
82
|
+
committee_sections = content.split(/<DT>/)
|
83
|
+
committee_sections.each do |section|
|
84
|
+
data = parse_committee_section(section)
|
85
|
+
data.each do |result|
|
86
|
+
search_result = SearchResult.new(result)
|
87
|
+
|
88
|
+
if block_given?
|
89
|
+
yield search_result
|
90
|
+
else
|
91
|
+
parsed_results << search_result
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
block_given? ? nil : parsed_results
|
96
|
+
end
|
97
|
+
|
98
|
+
# For results of a search that does not include a date, parse
|
99
|
+
# the section giving information on the committee that submitted
|
100
|
+
# the filing.
|
101
|
+
# @param [String] section
|
102
|
+
def parse_committee_section(section)
|
103
|
+
data = []
|
104
|
+
section.gsub!(/^<BR>/, '')
|
105
|
+
rows = section.split(/\n/)
|
106
|
+
committee_data = parse_committee_row(rows.first)
|
107
|
+
rows[1..-1].each do |row|
|
108
|
+
data << committee_data.merge(parse_filing_row(row))
|
109
|
+
end
|
110
|
+
data
|
111
|
+
end
|
112
|
+
|
113
|
+
# Parse the results from a search that includes a date.
|
114
|
+
# Will return an array of results if called directly, or will
|
115
|
+
# yield the results one by one if a block is passed.
|
116
|
+
def results_from_date_search(&block)
|
117
|
+
parsed_results = []
|
118
|
+
dl = body.match(/<DL>(.*?)<BR><P/m)[0]
|
119
|
+
rows = dl.split('<DT>')[1..-1].map { |row| row.split("\n") }
|
120
|
+
rows.each do |committee, *filings|
|
121
|
+
committee = parse_committee_row(committee)
|
122
|
+
filings.each do |filing|
|
123
|
+
next if filing == "<BR><P"
|
124
|
+
data = committee.merge(parse_filing_row(filing))
|
125
|
+
search_result = SearchResult.new(data)
|
126
|
+
if block_given?
|
127
|
+
yield search_result
|
128
|
+
else
|
129
|
+
parsed_results << search_result
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
block_given? ? nil : parsed_results
|
134
|
+
end
|
135
|
+
|
136
|
+
# For results of a search that includes a date, parse
|
137
|
+
# the portion of the results with information on the
|
138
|
+
# committee that submitted the filing.
|
139
|
+
# @param [String] row
|
140
|
+
# @return [Hash] the committee name and ID
|
141
|
+
def parse_committee_row(row)
|
142
|
+
regex = /
|
143
|
+
'>
|
144
|
+
(.*?)
|
145
|
+
\s-\s
|
146
|
+
(C\d{8})
|
147
|
+
/x
|
148
|
+
match = row.match regex
|
149
|
+
{:committee_name => match[1], :committee_id => match[2]}
|
150
|
+
end
|
151
|
+
|
152
|
+
# Parse a result row with information on the filing itself.
|
153
|
+
# @param [String] row
|
154
|
+
# @return [Hash] the filing ID, form type, period, date filed, description
|
155
|
+
# and, optionally, the filing that amended this filing.
|
156
|
+
def parse_filing_row(row)
|
157
|
+
regex = /
|
158
|
+
FEC-(\d+)
|
159
|
+
\s
|
160
|
+
Form
|
161
|
+
\s
|
162
|
+
(F.*?)
|
163
|
+
\s\s-\s
|
164
|
+
(period\s([-\/\d]+),\s)?
|
165
|
+
filed
|
166
|
+
\s
|
167
|
+
([\/\d]+)
|
168
|
+
\s
|
169
|
+
(-\s
|
170
|
+
(.*?)
|
171
|
+
($|<BR>.*?FEC-(\d+))
|
172
|
+
)?
|
173
|
+
/x
|
174
|
+
match = row.match regex
|
175
|
+
{:filing_id => match[1],
|
176
|
+
:form_type => match[2],
|
177
|
+
:period => match[4],
|
178
|
+
:date_filed => match[5],
|
179
|
+
:description => match[7],
|
180
|
+
:amended_by => match[9]
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fech
|
2
|
+
|
3
|
+
# Fech:SearchResult is a class representing a search result
|
4
|
+
# from Fech::Search.
|
5
|
+
class SearchResult
|
6
|
+
attr_reader :committee_name, :committee_id, :filing_id, :form_type, :period, :date_filed, :description, :amended_by
|
7
|
+
|
8
|
+
# @param [Hash] attrs The attributes of the search result.
|
9
|
+
def initialize(attrs)
|
10
|
+
@date_format = '%m/%d/%Y'
|
11
|
+
|
12
|
+
@committee_name = attrs[:committee_name]
|
13
|
+
@committee_id = attrs[:committee_id]
|
14
|
+
@filing_id = attrs[:filing_id]
|
15
|
+
@form_type = attrs[:form_type]
|
16
|
+
@period = parse_period(attrs[:period])
|
17
|
+
@date_filed = Date.strptime(attrs[:date_filed], @date_format)
|
18
|
+
@description = attrs[:description]
|
19
|
+
@amended_by = attrs[:amended_by]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Parse the string representing a filing period.
|
23
|
+
# @param [String] period a string representing a filing period
|
24
|
+
# @return [Hash, nil] a hash representing the start and end
|
25
|
+
# of a filing period.
|
26
|
+
def parse_period(period)
|
27
|
+
return if period.nil?
|
28
|
+
from, to = period.split('-')
|
29
|
+
from = Date.strptime(from, @date_format)
|
30
|
+
to = Date.strptime(to, @date_format)
|
31
|
+
{:from => from, :to => to}
|
32
|
+
end
|
33
|
+
|
34
|
+
# The Fech filing object for this search result
|
35
|
+
# @return [Fech::Filing]
|
36
|
+
def filing(opts={})
|
37
|
+
Fech::Filing.new(self.filing_id, opts)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'fech-search'
|
2
|
+
|
3
|
+
describe Fech::SearchResult do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@date_search = Fech::Search.new(:date => Date.new(2013, 4, 20))
|
7
|
+
@date_results = @date_search.results
|
8
|
+
@date_result = @date_results.first
|
9
|
+
@committee_search = Fech::Search.new(:committee_id => "C00431171")
|
10
|
+
@committee_results = @committee_search.results
|
11
|
+
@committee_result = @committee_results.first
|
12
|
+
end
|
13
|
+
|
14
|
+
context "creating" do
|
15
|
+
|
16
|
+
it "should have valid dates for period" do
|
17
|
+
from = @committee_result.period[:from]
|
18
|
+
from.class.should == Date
|
19
|
+
to = @committee_result.period[:to]
|
20
|
+
to.class.should == Date
|
21
|
+
to.should >= from
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
context "filing" do
|
27
|
+
|
28
|
+
it "should make filing accessible" do
|
29
|
+
@date_result.filing.class.should == Fech::Filing
|
30
|
+
@committee_result.filing.class.should == Fech::Filing
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should create filing object for correct filing" do
|
34
|
+
filing = @committee_result.filing
|
35
|
+
filing.filing_id.should == @committee_result.filing_id
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should pass arguments to Fech::Filing#new" do
|
39
|
+
filing = @date_result.filing(:download_dir => "/tmp")
|
40
|
+
filing.download_dir.should == "/tmp"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
data/spec/search_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fech-search'
|
2
|
+
|
3
|
+
describe Fech::Search do
|
4
|
+
|
5
|
+
context "creating" do
|
6
|
+
|
7
|
+
it "should raise ArgumentError if no parameters are given" do
|
8
|
+
expect { Fech::Search.new }.to raise_error(ArgumentError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should raise ArgumentError if :committee_id is given with another parameter" do
|
12
|
+
expect { Fech::Search.new(:committee_id => "C00431171", :date => Date.new(2013, 5, 16)) }.to raise_error(ArgumentError)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise ArgumentError if :form_type is given without another parameter" do
|
16
|
+
expect { Fech::Search.new(:form_type => "F3") }.to raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not raise an error if :committee_id is given by itself" do
|
20
|
+
expect { Fech::Search.new(:committee_id => "C00431171") }.to_not raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not raise an error if :form_type is given with another parameter" do
|
24
|
+
expect { Fech::Search.new(:form_type => "F3", :date => Date.new(2013, 5, 29)) }.to_not raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context "results" do
|
30
|
+
|
31
|
+
it "should return an array of results from committee search" do
|
32
|
+
search = Fech::Search.new(:committee_id => "C00431171")
|
33
|
+
search.results.class.should == Array
|
34
|
+
search.results[0].class.should == Fech::SearchResult
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return an array of results from date search" do
|
38
|
+
search = Fech::Search.new(:date => Date.new(2013, 5, 29))
|
39
|
+
search.results.class.should == Array
|
40
|
+
search.results[0].class.should == Fech::SearchResult
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return an array of results from date and report_type search" do
|
44
|
+
search = Fech::Search.new(:date => Date.new(2013, 5, 29), :report_type => "M4")
|
45
|
+
search.results.class.should == Array
|
46
|
+
search.results[0].class.should == Fech::SearchResult
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fech-search
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Bycoffe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fech
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.4.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.4.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.13.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.13.0
|
41
|
+
description: A Fech plugin for searching electronic FEC filings
|
42
|
+
email:
|
43
|
+
- bycoffe@huffingtonpost.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- Gemfile.lock
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- fech-search.gemspec
|
55
|
+
- lib/fech-search.rb
|
56
|
+
- lib/fech-search/search.rb
|
57
|
+
- lib/fech-search/search_result.rb
|
58
|
+
- lib/fech-search/version.rb
|
59
|
+
- spec/search_result_spec.rb
|
60
|
+
- spec/search_spec.rb
|
61
|
+
homepage: ''
|
62
|
+
licenses: []
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.3
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Fech-Search provides an interface for searching for electronic filings submitted
|
84
|
+
to the FEC, and accessing the data in those filings using Fech
|
85
|
+
test_files:
|
86
|
+
- spec/search_result_spec.rb
|
87
|
+
- spec/search_spec.rb
|
88
|
+
has_rdoc:
|