Class: Fech::Search
- Inherits:
-
Object
- Object
- Fech::Search
- Defined in:
- lib/fech-search/search.rb,
lib/fech-search/version.rb
Overview
Fech::Search is an interface for the FEC’s electronic filing search (www.fec.gov/finance/disclosure/efile_search.shtml)
Constant Summary collapse
- VERSION =
"0.0.2"
Instance Method Summary collapse
- #body ⇒ Object
-
#initialize(search_params = {}) ⇒ Search
constructor
passed to the search form.
-
#make_params(search_params) ⇒ Hash
Convert the search parameters passed to @initialize to use the format and keys needed for the form submission.
-
#parse_committee_row(row) ⇒ Hash
For results of a search that includes a date, parse the portion of the results with information on the committee that submitted the filing.
-
#parse_committee_section(section) ⇒ Object
For results of a search that does not include a date, parse the section giving information on the committee that submitted the filing.
-
#parse_filing_row(row) ⇒ Hash
Parse a result row with information on the filing itself.
-
#results(&block) ⇒ Object
The results page is formatted differently depending on whether the search includes a date.
-
#results_from_date_search(&block) ⇒ Object
Parse the results from a search that includes a date.
-
#results_from_nondate_search(&block) ⇒ Object
Parse the results from a search that does not include a date.
-
#search ⇒ Object
Performs the search of the FEC’s electronic filing database.
-
#uri ⇒ Object
A parsed URI for the search.
- #validate_params(params) ⇒ Object
Constructor Details
#initialize(search_params = {}) ⇒ Search
passed to the search form.
11 12 13 14 15 |
# File 'lib/fech-search/search.rb', line 11 def initialize(search_params={}) @search_params = validate_params(make_params(search_params)) @search_url = 'http://query.nictusa.com/cgi-bin/dcdev/forms/' @response = search end |
Instance Method Details
#body ⇒ Object
55 56 57 |
# File 'lib/fech-search/search.rb', line 55 def body @response ? @response.body : nil end |
#make_params(search_params) ⇒ Hash
Convert the search parameters passed to @initialize to use the format and keys needed for the form submission.
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/fech-search/search.rb', line 20 def make_params(search_params) { 'comid' => search_params[:committee_id] || '', 'name' => search_params[:committee_name] || '', 'state' => search_params[:state] || '', 'party' => search_params[:party] || '', 'type' => search_params[:committee_type] || '', 'rpttype' => search_params[:report_type] || '', 'date' => search_params[:date] ? search_params[:date].strftime('%m/%d/%Y') : '', 'frmtype' => search_params[:form_type] || '' } end |
#parse_committee_row(row) ⇒ Hash
For results of a search that includes a date, parse the portion of the results with information on the committee that submitted the filing.
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/fech-search/search.rb', line 141 def parse_committee_row(row) regex = / '> (.*?) \s-\s (C\d{8}) /x match = row.match regex {:committee_name => match[1], :committee_id => match[2]} end |
#parse_committee_section(section) ⇒ Object
For results of a search that does not include a date, parse the section giving information on the committee that submitted the filing.
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/fech-search/search.rb', line 102 def parse_committee_section(section) data = [] section.gsub!(/^<BR>/, '') rows = section.split(/\n/) committee_data = parse_committee_row(rows.first) rows[1..-1].each do |row| data << committee_data.merge(parse_filing_row(row)) end data end |
#parse_filing_row(row) ⇒ Hash
Parse a result row with information on the filing itself. and, optionally, the filing that amended this filing.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/fech-search/search.rb', line 156 def parse_filing_row(row) regex = / FEC-(\d+) \s Form \s (F.*?) \s\s-\s (period\s([-\/\d]+),\s)? filed \s ([\/\d]+) \s (-\s (.*?) ($|<BR>.*?FEC-(\d+)) )? /x match = row.match regex {:filing_id => match[1], :form_type => match[2], :period => match[4], :date_filed => match[5], :description => match[7], :amended_by => match[9] } end |
#results(&block) ⇒ Object
The results page is formatted differently depending on whether the search includes a date. Use the correct method for parsing the results depending on whether a date was used in the search. Will return an array of results if called directly, or will yield the results one by one if a block is passed.
65 66 67 68 69 70 71 |
# File 'lib/fech-search/search.rb', line 65 def results(&block) if @search_params['date'] != '' results_from_date_search(&block) else results_from_nondate_search(&block) end end |
#results_from_date_search(&block) ⇒ Object
Parse the results from a search that includes a date. Will return an array of results if called directly, or will yield the results one by one if a block is passed.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/fech-search/search.rb', line 116 def results_from_date_search(&block) parsed_results = [] dl = body.match(/<DL>(.*?)<BR><P/m)[0] rows = dl.split('<DT>')[1..-1].map { |row| row.split("\n") } rows.each do |committee, *filings| committee = parse_committee_row(committee) filings.each do |filing| next if filing == "<BR><P" data = committee.merge(parse_filing_row(filing)) search_result = SearchResult.new(data) if block_given? yield search_result else parsed_results << search_result end end end block_given? ? nil : parsed_results end |
#results_from_nondate_search(&block) ⇒ Object
Parse the results from a search that does not include a date. Will return an array of results if called directly, or will yield the results one by one if a block is passed.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/fech-search/search.rb', line 76 def results_from_nondate_search(&block) parsed_results = [] regex = /<DT>(.*?)<P/m match = body.match regex return [] if match.nil? content = match[1] committee_sections = content.split(/<DT>/) committee_sections.each do |section| data = parse_committee_section(section) data.each do |result| search_result = SearchResult.new(result) if block_given? yield search_result else parsed_results << search_result end end end block_given? ? nil : parsed_results end |
#search ⇒ Object
Performs the search of the FEC’s electronic filing database.
42 43 44 45 46 47 48 |
# File 'lib/fech-search/search.rb', line 42 def search http = Net::HTTP.new(uri.host, uri.port) http.read_timeout = 5000 request = Net::HTTP::Post.new(uri.request_uri) request.set_form_data(@search_params) @response = http.request(request) end |
#uri ⇒ Object
A parsed URI for the search
51 52 53 |
# File 'lib/fech-search/search.rb', line 51 def uri uri = URI.parse(@search_url) end |
#validate_params(params) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/fech-search/search.rb', line 33 def validate_params(params) raise ArgumentError, "At least one search parameter must be given" if params.values.all? { |x| x.empty? } nonempty_keys = params.select { |k, v| !v.empty? }.keys raise ArgumentError, ":committee_id cannot be used with other search parameters" if nonempty_keys.include?("comid") && nonempty_keys.size > 1 raise ArgumentError, ":form_type must be used with at least one other search parameter" if nonempty_keys.include?("frmtype") && nonempty_keys.size == 1 params end |