fech-search 0.0.2 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90335ce5578a65937b78fef37e814bf8e44e1eeb
4
- data.tar.gz: 6af0151ace9bece2b377c8599f8017a729482113
3
+ metadata.gz: dd2966cc82225142ba65490ea702ce5a2c43b024
4
+ data.tar.gz: 2ba7b2ae6ff2fcf40d325684b9e44a78ce540ced
5
5
  SHA512:
6
- metadata.gz: 7a60a65bc1673108369a12296c25b6de2327adc7c120444ad5896cdd3e8077f3bc4aa977bd6a6f3d28d2922b2d4928e17dedbfb7c07e038a72d449d8b51da9f9
7
- data.tar.gz: ea87f7e55dc46809b444dd158ab72a523c535a2dce4cadbba04b577f58d7ca9d4191c1923c6bf9f25d0d2a0e521720f9f8c5ef1d0ae7d5fc4c17d3dccab23e31
6
+ metadata.gz: 563565fb0c897400bcd8973a9e38184e63d63a7f9eed3f65a4688864636bbd8a9eae18c34716b5ac92eda6f77e525d52c9614a1a60b3fbe78ed62d03ab097c1a
7
+ data.tar.gz: 92a475a7072ad9ecc0f448daf9d05807da4594fc82e404eb3494582528dfc10a72d634ec37f34d4df246655c4b5adf0745828a607e01c9d991a5f1bc3c875339
@@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Fech::Search::VERSION
17
17
 
18
18
  gem.add_dependency "fech", "~> 1.6.2"
19
+ gem.add_dependency "nokogiri", "1.6.6.2"
19
20
 
20
21
  gem.add_development_dependency "rspec", "~> 2.13.0"
21
22
  end
@@ -1,4 +1,5 @@
1
1
  require 'net/http'
2
+ require 'nokogiri'
2
3
 
3
4
  module Fech
4
5
 
@@ -11,6 +12,7 @@ module Fech
11
12
  def initialize(search_params={})
12
13
  @search_params = validate_params(make_params(search_params))
13
14
  @search_url = 'http://query.nictusa.com/cgi-bin/dcdev/forms/'
15
+ @search_url = 'http://docquery.fec.gov/cgi-bin/forms/'
14
16
  @response = search
15
17
  end
16
18
 
@@ -63,66 +65,21 @@ module Fech
63
65
  # results if called directly, or will yield the results one
64
66
  # by one if a block is passed.
65
67
  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)
68
+ lines = body.split("\n")
69
+ parsing = false
70
+ committee = nil
77
71
  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
72
+ lines.each do |line|
73
+ if line.match(/^<TABLE style='border:0;'>$/)
74
+ parsing = true
93
75
  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)
76
+ next unless parsing
77
+ if line.match(/<td colspan='8'>/)
78
+ committee = parse_committee_line(line)
79
+ end
80
+ if line.match(/>FEC-\d+</)
81
+ merged = parse_filing_line(line).merge(committee)
82
+ search_result = SearchResult.new(merged)
126
83
  if block_given?
127
84
  yield search_result
128
85
  else
@@ -130,55 +87,21 @@ module Fech
130
87
  end
131
88
  end
132
89
  end
133
- block_given? ? nil : parsed_results
90
+ parsed_results
134
91
  end
135
92
 
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]}
93
+ # Parse a line that contains committee information
94
+ def parse_committee_line(line)
95
+ match = line.match(/<A.*?>(?<name>.*?) - (?<id>C\d{8})<\/A/)
96
+ {:committee_name => match['name'], :committee_id => match['id']}
150
97
  end
151
98
 
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
- }
99
+ # Parse a line that contains a filing
100
+ def parse_filing_line(line)
101
+ doc = Nokogiri::HTML(line)
102
+ cells = doc.css("td").map(&:text)
103
+ fields = [:form_type, :filing_id, :amended_by, :from, :to, :date_filed, :description]
104
+ Hash[fields.zip(cells)]
182
105
  end
183
106
 
184
107
  end
@@ -11,26 +11,30 @@ module Fech
11
11
 
12
12
  @committee_name = attrs[:committee_name]
13
13
  @committee_id = attrs[:committee_id]
14
- @filing_id = attrs[:filing_id]
14
+ @filing_id = attrs[:filing_id].sub(/FEC-/, '').to_i
15
15
  @form_type = attrs[:form_type]
16
- @period = parse_period(attrs[:period])
16
+ @period = parse_period(attrs[:from], attrs[:to])
17
17
  @date_filed = Date.strptime(attrs[:date_filed], @date_format)
18
18
  @description = attrs[:description]
19
19
  @amended_by = attrs[:amended_by]
20
20
  end
21
21
 
22
- # Parse the string representing a filing period.
22
+ # Parse the strings representing a filing period.
23
23
  # @param [String] period a string representing a filing period
24
24
  # @return [Hash, nil] a hash representing the start and end
25
25
  # of a filing period.
26
- def parse_period(period)
27
- return if period.nil?
28
- from, to = period.split('-')
26
+ def parse_period(from, to)
27
+ return unless valid_date(from.to_s) && valid_date(to.to_s)
29
28
  from = Date.strptime(from, @date_format)
30
29
  to = Date.strptime(to, @date_format)
31
30
  {:from => from, :to => to}
32
31
  end
33
32
 
33
+ # Check whether a date string is valid
34
+ def valid_date(s)
35
+ s.match(/\d\d?\/\d\d?\/\d{4}/)
36
+ end
37
+
34
38
  # The Fech filing object for this search result
35
39
  # @return [Fech::Filing]
36
40
  def filing(opts={})
@@ -1,5 +1,5 @@
1
1
  module Fech
2
2
  class Search
3
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -15,10 +15,10 @@ describe Fech::SearchResult do
15
15
 
16
16
  it "should have valid dates for period" do
17
17
  from = @committee_result.period[:from]
18
- from.class.should == Date
18
+ expect(from.class).to eq(Date)
19
19
  to = @committee_result.period[:to]
20
- to.class.should == Date
21
- to.should >= from
20
+ expect(to.class).to eq(Date)
21
+ expect(to).to be >= from
22
22
  end
23
23
 
24
24
  end
@@ -26,18 +26,18 @@ describe Fech::SearchResult do
26
26
  context "filing" do
27
27
 
28
28
  it "should make filing accessible" do
29
- @date_result.filing.class.should == Fech::Filing
30
- @committee_result.filing.class.should == Fech::Filing
29
+ expect(@date_result.filing.class).to eq(Fech::Filing)
30
+ expect(@committee_result.filing.class).to eq(Fech::Filing)
31
31
  end
32
32
 
33
33
  it "should create filing object for correct filing" do
34
34
  filing = @committee_result.filing
35
- filing.filing_id.should == @committee_result.filing_id
35
+ expect(filing.filing_id).to eq(@committee_result.filing_id)
36
36
  end
37
37
 
38
38
  it "should pass arguments to Fech::Filing#new" do
39
39
  filing = @date_result.filing(:download_dir => "/tmp")
40
- filing.download_dir.should == "/tmp"
40
+ expect(filing.download_dir).to eq("/tmp")
41
41
  end
42
42
 
43
43
  end
@@ -17,11 +17,11 @@ describe Fech::Search do
17
17
  end
18
18
 
19
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)
20
+ expect { Fech::Search.new(:committee_id => "C00431171") }.to_not raise_error
21
21
  end
22
22
 
23
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)
24
+ expect { Fech::Search.new(:form_type => "F3", :date => Date.new(2013, 5, 29)) }.to_not raise_error
25
25
  end
26
26
 
27
27
  end
@@ -30,20 +30,20 @@ describe Fech::Search do
30
30
 
31
31
  it "should return an array of results from committee search" do
32
32
  search = Fech::Search.new(:committee_id => "C00431171")
33
- search.results.class.should == Array
34
- search.results[0].class.should == Fech::SearchResult
33
+ expect(search.results.class).to eq(Array)
34
+ expect(search.results[0].class).to eq(Fech::SearchResult)
35
35
  end
36
36
 
37
37
  it "should return an array of results from date search" do
38
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
39
+ expect(search.results.class).to eq(Array)
40
+ expect(search.results[0].class).to eq(Fech::SearchResult)
41
41
  end
42
42
 
43
43
  it "should return an array of results from date and report_type search" do
44
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
45
+ expect(search.results.class).to eq(Array)
46
+ expect(search.results[0].class).to eq(Fech::SearchResult)
47
47
  end
48
48
 
49
49
  end
metadata CHANGED
@@ -1,41 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fech-search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Bycoffe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-22 00:00:00.000000000 Z
11
+ date: 2015-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fech
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.6.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.6.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.6.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.6.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - ~>
45
+ - - "~>"
32
46
  - !ruby/object:Gem::Version
33
47
  version: 2.13.0
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ~>
52
+ - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: 2.13.0
41
55
  description: A Fech plugin for searching electronic FEC filings
@@ -45,7 +59,7 @@ executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
- - .gitignore
62
+ - ".gitignore"
49
63
  - Gemfile
50
64
  - Gemfile.lock
51
65
  - LICENSE
@@ -67,17 +81,17 @@ require_paths:
67
81
  - lib
68
82
  required_ruby_version: !ruby/object:Gem::Requirement
69
83
  requirements:
70
- - - ! '>='
84
+ - - ">="
71
85
  - !ruby/object:Gem::Version
72
86
  version: '0'
73
87
  required_rubygems_version: !ruby/object:Gem::Requirement
74
88
  requirements:
75
- - - ! '>='
89
+ - - ">="
76
90
  - !ruby/object:Gem::Version
77
91
  version: '0'
78
92
  requirements: []
79
93
  rubyforge_project:
80
- rubygems_version: 2.0.3
94
+ rubygems_version: 2.2.2
81
95
  signing_key:
82
96
  specification_version: 4
83
97
  summary: Fech-Search provides an interface for searching for electronic filings submitted
@@ -85,4 +99,3 @@ summary: Fech-Search provides an interface for searching for electronic filings
85
99
  test_files:
86
100
  - spec/search_result_spec.rb
87
101
  - spec/search_spec.rb
88
- has_rdoc: