offensivepolitics-fechell 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.
- data/README.rdoc +25 -0
- data/lib/defs/3.00.csv +1 -0
- data/lib/defs/5.00.csv +1 -0
- data/lib/defs/5.1.csv +1 -0
- data/lib/defs/5.2.csv +1 -0
- data/lib/defs/5.3.csv +1 -0
- data/lib/defs/6.1.csv +1 -0
- data/lib/defs/6.2.csv +1 -0
- data/lib/fechell.rb +196 -0
- metadata +66 -0
data/README.rdoc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
= FECHell
|
2
|
+
|
3
|
+
Parsing a loading electronically filed fundraising reports from the Federal Election Commission. FECHell uses format definition files from Watchdog.net (http://watchdog.net/data/crawl/fec/electronic/headers/).
|
4
|
+
|
5
|
+
== Install
|
6
|
+
|
7
|
+
sudo gem install offensivepolitics-fechell
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'fechell'
|
13
|
+
|
14
|
+
h = FECHell.new
|
15
|
+
|
16
|
+
h.load('path_to.fec') do |line|
|
17
|
+
schedule = line[0]
|
18
|
+
values = line[1]
|
19
|
+
puts "line is a schedule #{schedule} with keys #{values.keys.join(',')}"
|
20
|
+
end
|
21
|
+
|
22
|
+
== Todo
|
23
|
+
- Support v3.0 electronic filing
|
24
|
+
- Better error checking on failed schedule identification.
|
25
|
+
- Convert Watchdog.net CSV files into ruby classes
|
data/lib/defs/3.00.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER FEC CMTE ID ;COMMITTEE NAME;STREET 1;STREET 2;CITY;STATE;ZIP;DATE (Submitted);CHG OF COMMITTEE NAME;CHG OF ADDRESS;5. COMMITTEE TYPE;5. FEC CANDIDATE ID NUMBER;5. CANDIDATE NAME;5. CAN/OFFICE ;5. CAN/STATE;5. CAN/DIST;5. PARTY CODE;5. PARTY TYPE;6. FEC COMMITTEE ID NUMBER;6. COMMITTEE NAME (Affiliated);6. STREET 1;6. STREET 2;6. CITY;6. STATE;6. ZIP;6. RELATIONSHIP (w/ Above Cmte);6. ORGANIZATION TYPE;7. IND/NAME (Custodian Name);7. STREET 1;7. STREET 2;7. CITY;7. STATE;7. ZIP;7. TITLE;7. TELEPHONE;8. IND/NAME (Treasurer);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;8. IND/NAME (Designated Agent);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;9. IND/NAME (Bank/Depository);9. STREET 1;9. STREET 2;9. CITY;9. STATE;9. ZIP;NAME/TREASURER (as signed);DATE (Signed);;COMMITTEE EMAIL;COMMITTEE WEB URL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/5.00.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER FEC CMTE ID ;;COMMITTEE NAME;STREET 1;STREET 2;CITY;STATE;ZIP;;DATE (Submitted);;CHG OF COMMITTEE NAME;CHG OF ADDRESS;;5. COMMITTEE TYPE;;5. FEC CANDIDATE ID NUMBER;5. CANDIDATE NAME;5. CAN/OFFICE ;5. CAN/STATE;5. CAN/DIST;5. PARTY CODE;5. PARTY TYPE;;6. FEC COMMITTEE ID NUMBER;6. COMMITTEE NAME (Affiliated);6. STREET 1;6. STREET 2;6. CITY;6. STATE;6. ZIP;6. RELATIONSHIP (w/ Above Cmte);6. ORGANIZATION TYPE;;7. IND/NAME (Custodian Name);7. STREET 1;7. STREET 2;7. CITY;7. STATE;7. ZIP;7. TITLE;7. TELEPHONE;;8. IND/NAME (Treasurer);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;;8. IND/NAME (Designated Agent);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;;9. IND/NAME (Bank/Depository);9. STREET 1;9. STREET 2;9. CITY;9. STATE;9. ZIP;;NAME/TREASURER (as signed);DATE (Signed);;COMMITTEE EMAIL;COMMITTEE WEB URL;;COMMITTEE FAX NUMBER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/5.1.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER FEC CMTE ID ;;COMMITTEE NAME;STREET 1;STREET 2;CITY;STATE;ZIP;;DATE (Submitted);;CHG OF COMMITTEE NAME;CHG OF ADDRESS;;5. COMMITTEE TYPE;;5. FEC CANDIDATE ID NUMBER;5. CANDIDATE NAME;5. CAN/OFFICE ;5. CAN/STATE;5. CAN/DIST;5. PARTY CODE;5. PARTY TYPE;;6. FEC COMMITTEE ID NUMBER;6. COMMITTEE NAME (Affiliated);6. STREET 1;6. STREET 2;6. CITY;6. STATE;6. ZIP;6. RELATIONSHIP (w/ Above Cmte);6. ORGANIZATION TYPE;;7. IND/NAME (Custodian Name);7. STREET 1;7. STREET 2;7. CITY;7. STATE;7. ZIP;7. TITLE;7. TELEPHONE;;8. IND/NAME (Treasurer);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;;8. IND/NAME (Designated Agent);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;;9. IND/NAME (Bank/Depository);9. STREET 1;9. STREET 2;9. CITY;9. STATE;9. ZIP;;NAME/TREASURER (as signed);DATE (Signed);;COMMITTEE EMAIL;COMMITTEE WEB URL;;COMMITTEE FAX NUMBER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/5.2.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER FEC CMTE ID ;COMMITTEE NAME;STREET 1;STREET 2;CITY;STATE;ZIP;DATE (Submitted);CHG OF COMMITTEE NAME;CHG OF ADDRESS;5. COMMITTEE TYPE;5. FEC CANDIDATE ID NUMBER;5. CANDIDATE NAME;5. CAN/OFFICE ;5. CAN/STATE;5. CAN/DIST;5. PARTY CODE;5. PARTY TYPE;6. FEC COMMITTEE ID NUMBER;6. COMMITTEE NAME (Affiliated);6. STREET 1;6. STREET 2;6. CITY;6. STATE;6. ZIP;6. RELATIONSHIP (w/ Above Cmte);6. ORGANIZATION TYPE;7. IND/NAME (Custodian Name);7. STREET 1;7. STREET 2;7. CITY;7. STATE;7. ZIP;7. TITLE;7. TELEPHONE;8. IND/NAME (Treasurer);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;8. IND/NAME (Designated Agent);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;9. IND/NAME (Bank/Depository);9. STREET 1;9. STREET 2;9. CITY;9. STATE;9. ZIP;NAME/TREASURER (as signed);DATE (Signed);COMMITTEE EMAIL;COMMITTEE WEB URL;COMMITTEE FAX NUMBER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/5.3.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER FEC CMTE ID ;COMMITTEE NAME;STREET 1;STREET 2;CITY;STATE;ZIP;DATE (Submitted);CHG OF COMMITTEE NAME;CHG OF ADDRESS;5. COMMITTEE TYPE;5. FEC CANDIDATE ID NUMBER;5. CANDIDATE NAME;5. CAN/OFFICE ;5. CAN/STATE;5. CAN/DIST;5. PARTY CODE;5. PARTY TYPE;6. FEC COMMITTEE ID NUMBER;6. COMMITTEE NAME (Affiliated);6. STREET 1;6. STREET 2;6. CITY;6. STATE;6. ZIP;6. RELATIONSHIP (w/ Above Cmte);6. ORGANIZATION TYPE;7. IND/NAME (Custodian Name);7. STREET 1;7. STREET 2;7. CITY;7. STATE;7. ZIP;7. TITLE;7. TELEPHONE;8. IND/NAME (Treasurer);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;8. IND/NAME (Designated Agent);8. STREET 1;8. STREET 2;8. CITY;8. STATE;8. ZIP;8. TITLE;8. TELEPHONE;9. IND/NAME (Bank/Depository);9. STREET 1;9. STREET 2;9. CITY;9. STATE;9. ZIP;NAME/TREASURER (as signed);DATE (Signed);COMMITTEE EMAIL;COMMITTEE WEB URL;COMMITTEE FAX NUMBER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/6.1.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER COMMITTEE ID NUMBER;CHANGE OF COMMITTEE NAME;COMMITTEE NAME;CHANGE OF ADDRESS;STREET 1;STREET 2;CITY;STATE;ZIP;COMMITTEE EMAIL;COMMITTEE WEB URL;COMMITTEE FAX NUMBER;SUBMISSION DATE;SIGNATURE LAST NAME;SIGNATURE FIRST NAME;SIGNATURE MIDDLE NAME;SIGNATURE PREFIX;SIGNATURE SUFFIX;DATE SIGNED;5. COMMITTEE TYPE;5. CANDIDATE ID NUMBER;5. CANDIDATE LAST NAME;5. CANDIDATE FIRST NAME;5. CANDIDATE MIDDLE NAME;5. CANDIDATE PREFIX;5. CANDIDATE SUFFIX;5. CANDIDATE OFFICE ;5. CANDIDATE STATE;5. CANDIDATE DISTRICT;5. PARTY CODE;5. PARTY TYPE;7. CUSTODIAN LAST NAME;7. CUSTODIAN FIRST NAME;7. CUSTODIAN MIDDLE NAME;7. CUSTODIAN PREFIX;7. CUSTODIAN SUFFIX;7. CUSTODIAN STREET 1;7. CUSTODIAN STREET 2;7. CUSTODIAN CITY;7. CUSTODIAN STATE;7. CUSTODIAN ZIP;7. CUSTODIAN TITLE;7. CUSTODIAN TELEPHONE;8. TREASURER LAST NAME;8. TREASURER FIRST NAME;8. TREASURER MIDDLE NAME;8. TREASURER PREFIX;8. TREASURER SUFFIX;8. TREASURER STREET 1;8. TREASURER STREET 2;8. TREASURER CITY;8. TREASURER STATE;8. TREASURER ZIP;8. TREASURER TITLE;8. TREASURER TELEPHONE;6. AFFILIATED CMTTE ID NUM;6. AFFILIATED CMTTE NAME;6. AFFILIATED STREET 1;6. AFFILIATED STREET 2;6. AFFILIATED CITY;6. AFFILIATED STATE;6. AFFILIATED ZIP;"6. RELATIONSHIP (with Filing Committe named in field #4)";6. ORGANIZATION TYPE;8. AGENT LAST NAME;8. AGENT FIRST NAME;8. AGENT MIDDLE NAME;8. AGENT PREFIX;8. AGENT SUFFIX;8. AGENT STREET 1;8. AGENT STREET 2;8. AGENT CITY;8. AGENT STATE;8. AGENT ZIP;8. AGENT TITLE;8. AGENT TELEPHONE;9. a) BANK NAME;9. a) BANK STREET 1;9. a) BANK STREET 2;9. a) BANK CITY;9. a) BANK STATE;9. a) BANK ZIP;9. b) BANK NAME;9. b) BANK STREET 1;9. b) BANK STREET 2;9. b) BANK CITY;9. b) BANK STATE;9. b) BANK ZIP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/defs/6.2.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
F1;FORM TYPE;FILER COMMITTEE ID NUMBER;CHANGE OF COMMITTEE NAME;COMMITTEE NAME;CHANGE OF ADDRESS;STREET 1;STREET 2;CITY;STATE;ZIP;COMMITTEE EMAIL;COMMITTEE WEB URL;COMMITTEE FAX NUMBER;SUBMISSION DATE;SIGNATURE LAST NAME;SIGNATURE FIRST NAME;SIGNATURE MIDDLE NAME;SIGNATURE PREFIX;SIGNATURE SUFFIX;DATE SIGNED;5. COMMITTEE TYPE;5. CANDIDATE ID NUMBER;5. CANDIDATE LAST NAME;5. CANDIDATE FIRST NAME;5. CANDIDATE MIDDLE NAME;5. CANDIDATE PREFIX;5. CANDIDATE SUFFIX;5. CANDIDATE OFFICE ;5. CANDIDATE STATE;5. CANDIDATE DISTRICT;5. PARTY CODE;5. PARTY TYPE;5 (e). ORGANIZATION TYPE;5 (f). LEADERSHIP PAC;6. AFFILIATED CMTTE ID NUM;6. AFFILIATED CMTTE NAME;6. AFFILIATED STREET 1;6. AFFILIATED STREET 2;6. AFFILIATED CITY;6. AFFILIATED STATE;6. AFFILIATED ZIP;6. AFFILIATED RELATIONSHIP CODE (with Filing Committe named in field #4);7. CUSTODIAN LAST NAME;7. CUSTODIAN FIRST NAME;7. CUSTODIAN MIDDLE NAME;7. CUSTODIAN PREFIX;7. CUSTODIAN SUFFIX;7. CUSTODIAN STREET 1;7. CUSTODIAN STREET 2;7. CUSTODIAN CITY;7. CUSTODIAN STATE;7. CUSTODIAN ZIP;7. CUSTODIAN TITLE;7. CUSTODIAN TELEPHONE;8. TREASURER LAST NAME;8. TREASURER FIRST NAME;8. TREASURER MIDDLE NAME;8. TREASURER PREFIX;8. TREASURER SUFFIX;8. TREASURER STREET 1;8. TREASURER STREET 2;8. TREASURER CITY;8. TREASURER STATE;6. RELATIONSHIP (with Filing Committe named in field #4);8. TREASURER ZIP;6. ORGANIZATION TYPE;8. TREASURER TITLE;8. TREASURER TELEPHONE;8. AGENT LAST NAME;8. AGENT FIRST NAME;8. AGENT MIDDLE NAME;8. AGENT PREFIX;8. AGENT SUFFIX;8. AGENT STREET 1;8. AGENT STREET 2;8. AGENT CITY;8. AGENT STATE;8. AGENT ZIP;8. AGENT TITLE;8. AGENT TELEPHONE;9. a) BANK NAME;9. a) BANK STREET 1;9. a) BANK STREET 2;9. a) BANK CITY;9. a) BANK STATE;9. a) BANK ZIP;9. b) BANK NAME;9. b) BANK STREET 1;9. b) BANK STREET 2;9. b) BANK CITY;9. b) BANK STATE;9. b) BANK ZIP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
data/lib/fechell.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastercsv"
|
3
|
+
|
4
|
+
class FECHell
|
5
|
+
|
6
|
+
@@modules = nil
|
7
|
+
|
8
|
+
SEPERATORS = {"3.00" => ",",
|
9
|
+
"5.00" => ",",
|
10
|
+
"5.1" => ",",
|
11
|
+
"5.2" => ",",
|
12
|
+
"5.3" => ",",
|
13
|
+
"6.1" => "\x1e",
|
14
|
+
"6.2" => "\x1e"
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.load_modules
|
18
|
+
@@modules = {}
|
19
|
+
Dir["#{File.dirname(__FILE__)}/defs/*.csv"].each do |filename|
|
20
|
+
version = File.basename(filename,".csv")
|
21
|
+
|
22
|
+
formats = {}
|
23
|
+
|
24
|
+
FasterCSV.open(filename,"r",:col_sep => ';').each do |line|
|
25
|
+
schedule = line[0].gsub(' ','').gsub('Sch','S')
|
26
|
+
formats[schedule] = line[1..-1]
|
27
|
+
end
|
28
|
+
|
29
|
+
@@modules[version] = formats
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
FECHell.load_modules unless @@modules.nil? == false
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def peek_format(data)
|
40
|
+
|
41
|
+
header = {}
|
42
|
+
parts_raw = []
|
43
|
+
first_line = []
|
44
|
+
form_type = ''
|
45
|
+
|
46
|
+
lines = []
|
47
|
+
|
48
|
+
begin
|
49
|
+
|
50
|
+
if data.is_a?(Array) then
|
51
|
+
lines = data[0..1]
|
52
|
+
else
|
53
|
+
if data.is_a?(StringIO) then
|
54
|
+
file = data
|
55
|
+
elsif data.is_a?(String)
|
56
|
+
file = File.open(data,"r")
|
57
|
+
end
|
58
|
+
lines[0] = file.readline
|
59
|
+
lines[1] = file.readline
|
60
|
+
file.close
|
61
|
+
end
|
62
|
+
|
63
|
+
line = lines[0]
|
64
|
+
|
65
|
+
seperator = guess_seperator(lines[0])
|
66
|
+
parts_raw = FasterCSV.parse(line,:col_sep => seperator)[0]
|
67
|
+
|
68
|
+
header[:record_type] = parts_raw[0]
|
69
|
+
header[:ef_type] = parts_raw[1]
|
70
|
+
header[:fec_version] = parts_raw[2]
|
71
|
+
header[:software_name] = parts_raw[3]
|
72
|
+
header[:software_version] = parts_raw[4]
|
73
|
+
header[:report_id] = parts_raw[5]
|
74
|
+
header[:report_number] = parts_raw[6]
|
75
|
+
|
76
|
+
line = lines[1]
|
77
|
+
parts_raw = FasterCSV.parse(line,:col_sep => seperator)[0]
|
78
|
+
|
79
|
+
form_type = parts_raw[0]
|
80
|
+
parts_raw.shift
|
81
|
+
|
82
|
+
rescue FasterCSV::MalformedCSVError
|
83
|
+
header = {}
|
84
|
+
parts_raw = []
|
85
|
+
first_line = []
|
86
|
+
form_type = ''
|
87
|
+
end
|
88
|
+
return seperator,header,form_type,parts_raw
|
89
|
+
end
|
90
|
+
|
91
|
+
def guess_seperator(first_line)
|
92
|
+
seperator = ","
|
93
|
+
if first_line.index(28).nil? == false then
|
94
|
+
seperator = "\x1c"
|
95
|
+
end
|
96
|
+
|
97
|
+
seperator
|
98
|
+
end
|
99
|
+
|
100
|
+
def fields_for(version,schedule)
|
101
|
+
@@modules[version][schedule.upcase]
|
102
|
+
end
|
103
|
+
|
104
|
+
def guess_schedule(version,full_schedule)
|
105
|
+
schedules = []
|
106
|
+
|
107
|
+
# 1st we look for an exact match
|
108
|
+
# otherwise we look for a partial match, taking into account appended returns
|
109
|
+
full_schedule.upcase!
|
110
|
+
|
111
|
+
if @@modules[version].keys.index(full_schedule)
|
112
|
+
schedules << full_schedule
|
113
|
+
else
|
114
|
+
@@modules[version].keys.each do |key|
|
115
|
+
if full_schedule[0...1] == 'F' # F[number] can have an 'N','A' at the end
|
116
|
+
regex = "^#{key}[ANT]?"
|
117
|
+
else # TEXT or Schedules. S[Letter][numbers]
|
118
|
+
regex = "^#{key}"
|
119
|
+
end
|
120
|
+
if full_schedule.match(regex)
|
121
|
+
schedules << key
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# return the longest match first
|
127
|
+
schedules.sort { |l,r| r.size <=> l.size }
|
128
|
+
end
|
129
|
+
|
130
|
+
def header_lines(filename)
|
131
|
+
seperator,header,form_type,elements = peek_format(filename)
|
132
|
+
|
133
|
+
csv = FasterCSV.open(filename,"r",:col_sep => seperator)
|
134
|
+
|
135
|
+
schedules = guess_schedule(header[:fec_version],form_type)
|
136
|
+
|
137
|
+
line = csv.readline
|
138
|
+
line = csv.readline
|
139
|
+
schedule = line[0]
|
140
|
+
schedules1,values1 = process_line(header[:fec_version],schedule,line)
|
141
|
+
|
142
|
+
csv.close
|
143
|
+
return header[:fec_version],form_type,schedules1[0],values1
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
def process_line(fec_version,schedule,line)
|
148
|
+
guesses = guess_schedule(fec_version,schedule)
|
149
|
+
|
150
|
+
offsets = @@modules[fec_version][guesses[0]]
|
151
|
+
values = {}
|
152
|
+
index =0
|
153
|
+
offsets.each do |offset|
|
154
|
+
values[offset] = line[index]
|
155
|
+
index = index + 1
|
156
|
+
end
|
157
|
+
|
158
|
+
return guesses,values
|
159
|
+
end
|
160
|
+
|
161
|
+
def process(filename,options)
|
162
|
+
|
163
|
+
seperator,header,form_type,elements = peek_format(filename)
|
164
|
+
|
165
|
+
schedules = guess_schedule(header[:fec_version],form_type)
|
166
|
+
if schedules.size == 0 then
|
167
|
+
puts "ERROR: #{filename} - type was #{form_type} we found nothing"
|
168
|
+
end
|
169
|
+
offsets = @@modules[header[:fec_version]][schedules[0]]
|
170
|
+
begin
|
171
|
+
FasterCSV.open(filename,:col_sep => seperator).each do |line|
|
172
|
+
next if line.nil?
|
173
|
+
next if line.size == 0
|
174
|
+
sch = line[0]
|
175
|
+
|
176
|
+
next unless sch.match('^[STF]')
|
177
|
+
|
178
|
+
guesses,values = process_line(header[:fec_version],sch,line)
|
179
|
+
|
180
|
+
next if guesses.nil? || guesses.size == 0
|
181
|
+
next if values.nil?
|
182
|
+
|
183
|
+
if options[:ignore_schedules]
|
184
|
+
match_str = "^#{options[:ignore_schedules].join('|')}"
|
185
|
+
next if sch.match(match_str)
|
186
|
+
end
|
187
|
+
|
188
|
+
yield [guesses[0],values]
|
189
|
+
|
190
|
+
end
|
191
|
+
rescue FasterCSV::MalformedCSVError
|
192
|
+
puts "malformed content in file #{filename}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: offensivepolitics-fechell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Holt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-25 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Parse electronically filed FEC reports.
|
17
|
+
email: jjh@offensivepolitics.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- lib/defs/3.00.csv
|
26
|
+
- lib/defs/5.00.csv
|
27
|
+
- lib/defs/5.1.csv
|
28
|
+
- lib/defs/5.2.csv
|
29
|
+
- lib/defs/5.3.csv
|
30
|
+
- lib/defs/6.1.csv
|
31
|
+
- lib/defs/6.2.csv
|
32
|
+
- lib/fechell.rb
|
33
|
+
- README.rdoc
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://offensivepolitics.net/fechell
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --line-numbers
|
39
|
+
- --inline-source
|
40
|
+
- --title
|
41
|
+
- Fechell
|
42
|
+
- --main
|
43
|
+
- README.rdoc
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "1.2"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: fechell
|
61
|
+
rubygems_version: 1.2.0
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: Parse electronically filed FEC reports.
|
65
|
+
test_files: []
|
66
|
+
|