Class: Fech::Search

Inherits:
Object
  • Object
show all
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.2.0"

Instance Method Summary collapse

Constructor Details

#initialize(search_params = {}) ⇒ Search

passed to the search form.

Parameters:

  • search_params (Hash) (defaults to: {})

    a hash of parameters to be



12
13
14
15
16
17
# File 'lib/fech-search/search.rb', line 12

def initialize(search_params={})
  @search_params = validate_params(make_params(search_params))
  @search_url = 'http://query.nictusa.com/cgi-bin/dcdev/forms/'
  @search_url = 'http://docquery.fec.gov/cgi-bin/forms/'
  @response = search
end

Instance Method Details

#bodyObject



57
58
59
# File 'lib/fech-search/search.rb', line 57

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.

Returns:

  • (Hash)


22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/fech-search/search.rb', line 22

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_line(line) ⇒ Object

Parse a line that contains committee information



94
95
96
97
# File 'lib/fech-search/search.rb', line 94

def parse_committee_line(line)
  match = line.match(/<A.*?>(?<name>.*?) - (?<id>C\d{8})<\/A/)
  {committee_name: match['name'], committee_id: match['id']}
end

#parse_filing_line(line) ⇒ Object

Parse a line that contains a filing



100
101
102
103
104
105
# File 'lib/fech-search/search.rb', line 100

def parse_filing_line(line)
  doc = Nokogiri::HTML(line)
  cells = doc.css("td").map(&:text)
  fields = [:form_type, :filing_id, :amended_by, :from, :to, :date_filed, :description]
  Hash[fields.zip(cells)]
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.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/fech-search/search.rb', line 67

def results(&block)
  lines = body.split("\n")
  parsing = false
  committee = nil
  parsed_results = []
  lines.each do |line|
    if line.match(/^<TABLE style='border:0;'>$/)
      parsing = true
    end
    next unless parsing
    if line.match(/<td colspan='8'>/)
      committee = parse_committee_line(line)
    end
    if line.match(/>FEC-\d+</)
      merged = parse_filing_line(line).merge(committee)
      search_result = SearchResult.new(merged)
      if block_given?
        yield search_result
      else
        parsed_results << search_result
      end
    end
  end
  parsed_results
end

#searchObject

Performs the search of the FEC’s electronic filing database.



44
45
46
47
48
49
50
# File 'lib/fech-search/search.rb', line 44

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

#uriObject

A parsed URI for the search



53
54
55
# File 'lib/fech-search/search.rb', line 53

def uri
  uri = URI.parse(@search_url)
end

#validate_params(params) ⇒ Object

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
# File 'lib/fech-search/search.rb', line 35

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