fbo 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -5
  3. data/Gemfile +0 -2
  4. data/Rakefile +8 -1
  5. data/fbo.gemspec +14 -9
  6. data/lib/fbo.rb +7 -38
  7. data/lib/fbo/chunked_file.rb +74 -0
  8. data/lib/fbo/dump.treetop +324 -0
  9. data/lib/fbo/file.rb +17 -1
  10. data/lib/fbo/interpreter.rb +87 -0
  11. data/lib/fbo/node_extensions.rb +173 -0
  12. data/lib/fbo/parser.rb +43 -46
  13. data/lib/fbo/remote_file.rb +4 -4
  14. data/lib/fbo/version.rb +1 -1
  15. data/spec/fbo/chunked_file_spec.rb +22 -0
  16. data/spec/fbo/file_spec.rb +26 -9
  17. data/spec/fbo/interpreter_spec.rb +73 -0
  18. data/spec/fbo/parser_spec.rb +36 -38
  19. data/spec/fbo/remote_file_spec.rb +28 -24
  20. data/spec/fixtures/.keep +0 -0
  21. data/spec/fixtures/FBOFeed20130331 +52 -5529
  22. data/spec/fixtures/FBOFeed20131003 +35126 -0
  23. data/spec/spec_helper.rb +14 -16
  24. metadata +70 -108
  25. data/.rspec +0 -2
  26. data/Gemfile.lock +0 -27
  27. data/lib/fbo/notice.rb +0 -9
  28. data/lib/fbo/notices.rb +0 -6
  29. data/lib/fbo/notices/amendment.rb +0 -13
  30. data/lib/fbo/notices/archive.rb +0 -8
  31. data/lib/fbo/notices/award.rb +0 -14
  32. data/lib/fbo/notices/combined_solicitation.rb +0 -14
  33. data/lib/fbo/notices/fair_opportunity.rb +0 -15
  34. data/lib/fbo/notices/foreign_standard.rb +0 -13
  35. data/lib/fbo/notices/intent_to_bundle.rb +0 -13
  36. data/lib/fbo/notices/justification_approval.rb +0 -18
  37. data/lib/fbo/notices/modification.rb +0 -14
  38. data/lib/fbo/notices/presolicitation.rb +0 -14
  39. data/lib/fbo/notices/sale_of_surplus.rb +0 -13
  40. data/lib/fbo/notices/sources_sought.rb +0 -13
  41. data/lib/fbo/notices/special_notice.rb +0 -13
  42. data/lib/fbo/notices/unarchive.rb +0 -9
  43. data/lib/fbo/notices/unknown.rb +0 -7
  44. data/lib/fbo/parser/amendment_handler.rb +0 -58
  45. data/lib/fbo/parser/archive_handler.rb +0 -41
  46. data/lib/fbo/parser/award_handler.rb +0 -62
  47. data/lib/fbo/parser/combined_solicitation_handler.rb +0 -57
  48. data/lib/fbo/parser/fair_opportunity_handler.rb +0 -61
  49. data/lib/fbo/parser/foreign_standard_handler.rb +0 -57
  50. data/lib/fbo/parser/handler_selector.rb +0 -37
  51. data/lib/fbo/parser/intent_to_bundle_handler.rb +0 -56
  52. data/lib/fbo/parser/justification_approval_handler.rb +0 -60
  53. data/lib/fbo/parser/modification_handler.rb +0 -66
  54. data/lib/fbo/parser/notice_handler.rb +0 -27
  55. data/lib/fbo/parser/parser_helper.rb +0 -315
  56. data/lib/fbo/parser/presolicitation_handler.rb +0 -57
  57. data/lib/fbo/parser/sale_of_surplus_handler.rb +0 -57
  58. data/lib/fbo/parser/sources_sought_handler.rb +0 -57
  59. data/lib/fbo/parser/special_notice_handler.rb +0 -57
  60. data/lib/fbo/parser/unarchive_handler.rb +0 -42
  61. data/lib/fbo/parser/unknown_handler.rb +0 -20
  62. data/spec/fbo/parser/amendment_handler_spec.rb +0 -51
  63. data/spec/fbo/parser/archive_handler_spec.rb +0 -36
  64. data/spec/fbo/parser/award_handler_spec.rb +0 -56
  65. data/spec/fbo/parser/combined_solicitation_handler_spec.rb +0 -51
  66. data/spec/fbo/parser/fair_opportunity_handler_spec.rb +0 -56
  67. data/spec/fbo/parser/foreign_standard_handler_spec.rb +0 -51
  68. data/spec/fbo/parser/handler_selector_spec.rb +0 -40
  69. data/spec/fbo/parser/intent_to_bundle_handler_spec.rb +0 -52
  70. data/spec/fbo/parser/justification_approval_handler_spec.rb +0 -53
  71. data/spec/fbo/parser/modification_handler_spec.rb +0 -52
  72. data/spec/fbo/parser/presolicitation_handler_spec.rb +0 -51
  73. data/spec/fbo/parser/sale_of_surplus_handler_spec.rb +0 -53
  74. data/spec/fbo/parser/sources_sought_handler_spec.rb +0 -51
  75. data/spec/fbo/parser/special_notice_handler_spec.rb +0 -53
  76. data/spec/fbo/parser/unarchive_handler_spec.rb +0 -37
  77. data/spec/fbo/parser/unknown_handler_spec.rb +0 -24
  78. data/spec/fixtures/FBOFeed20130404 +0 -45653
  79. data/spec/fixtures/FBOFeed20130406 +0 -10152
  80. data/spec/fixtures/FBOFeed20130407 +0 -6610
  81. data/spec/fixtures/notices/amdcss +0 -26
  82. data/spec/fixtures/notices/archive +0 -10
  83. data/spec/fixtures/notices/award +0 -31
  84. data/spec/fixtures/notices/combine +0 -29
  85. data/spec/fixtures/notices/fairopp +0 -29
  86. data/spec/fixtures/notices/fstd +0 -24
  87. data/spec/fixtures/notices/itb +0 -19
  88. data/spec/fixtures/notices/ja +0 -30
  89. data/spec/fixtures/notices/mod +0 -28
  90. data/spec/fixtures/notices/notanotice +0 -7
  91. data/spec/fixtures/notices/presol +0 -25
  92. data/spec/fixtures/notices/snote +0 -26
  93. data/spec/fixtures/notices/srcsgt +0 -27
  94. data/spec/fixtures/notices/ssale +0 -24
  95. data/spec/fixtures/notices/unarchive +0 -10
@@ -1,56 +0,0 @@
1
- module FBO::Parser::IntentToBundleHandler
2
- TAGS = %w( ITB DATE YEAR CBAC PASSWORD ZIP CLASSCOD NAICS OFFADD AGENCY ) +
3
- %w( OFFICE LOCATION SUBJECT SOLNBR NTYPE ARCHDATE CONTACT DESC AWDNBR ) +
4
- %w( DONBR LINK URL EMAIL ADDRESS \/ITB )
5
-
6
- ANY_ITB_TAG = TAGS.join("|")
7
- INTENT_TO_BUNDLE_PATTERN = /^<ITB>/
8
-
9
-
10
- def is_intent_to_bundle?(text)
11
- text =~ INTENT_TO_BUNDLE_PATTERN
12
- end
13
-
14
- def parse(text)
15
- params = {
16
- date: date(text),
17
- year: year(text),
18
- zip: zip(text),
19
- class_code: classification_code(text),
20
- naics_code: naics_code(text),
21
- agency: agency(text),
22
- office: office(text),
23
- location: location(text),
24
- office_address: office_address(text),
25
- subject: subject(text),
26
- solicitation_number: solicitation_number(text),
27
- archive_date: archive_date(text),
28
- contact_info: contact(text),
29
- description: description(text),
30
- notice_type: notice_type(text),
31
- award_number: award_number(text),
32
- delivery_order_number: delivery_order_number(text),
33
- link_url: link_url(text),
34
- link_description: link_description(text),
35
- email_address: email_address(text),
36
- email_description: email_description(text),
37
- correction: correction?(text)
38
- }
39
- FBO::Notices::IntentToBundle.new(params)
40
- end
41
-
42
-
43
- protected
44
-
45
- # Returns a concatenated list of all tags for the notice
46
- #
47
- # @return [String]
48
- def any_notice_tag
49
- ANY_ITB_TAG
50
- end
51
-
52
-
53
- extend FBO::Parser::NoticeHandler
54
- extend FBO::Parser::ParserHelper
55
- extend self
56
- end
@@ -1,60 +0,0 @@
1
- module FBO::Parser::JustificationApprovalHandler
2
- TAGS = %w( JA DATE YEAR CBAC PASSWORD ZIP CLASSCOD NAICS OFFADD ) +
3
- %w( AGENCY OFFICE LOCATION SUBJECT SOLNBR NTYPE DESC CONTACT AWDNBR ) +
4
- %w( AWDDATE ARCHDATE LINK URL EMAIL ADDRESS STAUTH MODNBR ) +
5
- %w( FILELIST FILE MIMETYPE /FILE /FILELIST CORRECTION /JA )
6
-
7
- ANY_JUSTIFICATION_APPROVAL_TAG = TAGS.join("|")
8
- JA_PATTERN = /^<JA>/
9
-
10
-
11
- def is_justification_approval?(text)
12
- text =~ JA_PATTERN
13
- end
14
-
15
- def parse(text)
16
- params = {
17
- date: date(text),
18
- year: year(text),
19
- zip: zip(text),
20
- class_code: classification_code(text),
21
- naics_code: naics_code(text),
22
- agency: agency(text),
23
- office: office(text),
24
- location: location(text),
25
- office_address: office_address(text),
26
- subject: subject(text),
27
- solicitation_number: solicitation_number(text),
28
- notice_type: notice_type(text),
29
- description: description(text),
30
- contact_info: contact(text),
31
- statutory_authority: statutory_authority(text),
32
- award_number: award_number(text),
33
- modification_number: modification_number(text),
34
- award_date: award_date(text),
35
- archive_date: archive_date(text),
36
- link_url: link_url(text),
37
- link_description: link_description(text),
38
- email_address: email_address(text),
39
- email_description: email_description(text),
40
- file_list: file_list(text),
41
- correction: correction?(text)
42
- }
43
- FBO::Notices::JustificationApproval.new(params)
44
- end
45
-
46
-
47
- protected
48
-
49
- # Returns a concatenated list of all tags for the notice
50
- #
51
- # @return [String]
52
- def any_notice_tag
53
- ANY_JUSTIFICATION_APPROVAL_TAG
54
- end
55
-
56
-
57
- extend FBO::Parser::NoticeHandler
58
- extend FBO::Parser::ParserHelper
59
- extend self
60
- end
@@ -1,66 +0,0 @@
1
- module FBO::Parser::ModificationHandler
2
- TAGS = %w( MOD DATE YEAR CBAC PASSWORD ZIP CLASSCOD NAICS OFFADD AGENCY) +
3
- %w( OFFICE LOCATION SUBJECT SOLNBR NTYPE RESPDATE ARCHDATE CONTACT DESC ) +
4
- %w( LINK URL EMAIL ADDRESS SETASIDE POPADDRESS POPZIP POPCOUNTRY \/MOD )
5
-
6
- ANY_MOD_TAG = TAGS.join("|")
7
- MODIFICATION_PATTERN = /^<MOD>/
8
-
9
-
10
- def is_modification?(text)
11
- text =~ MODIFICATION_PATTERN
12
- end
13
-
14
- def parse(text)
15
- params = {
16
- date: date(text),
17
- year: year(text),
18
- zip: zip(text),
19
- class_code: classification_code(text),
20
- naics_code: naics_code(text),
21
- agency: agency(text),
22
- office: office(text),
23
- location: location(text),
24
- office_address: office_address(text),
25
- subject: subject(text),
26
- solicitation_number: solicitation_number(text),
27
- notice_type: notice_type(text),
28
- response_date: response_date(text),
29
- archive_date: archive_date(text),
30
- contact_info: contact(text),
31
- description: description(text),
32
- link_url: link_url(text),
33
- link_description: link_description(text),
34
- email_address: email_address(text),
35
- email_description: email_description(text),
36
- setaside: set_aside(text),
37
- pop_address: pop_address(text),
38
- pop_zip: pop_zip_code(text),
39
- pop_country: pop_country(text)
40
- }
41
- FBO::Notices::Modification.new(params)
42
- end
43
-
44
-
45
- protected
46
-
47
- # Returns a concatenated list of all tags for the notice
48
- #
49
- # @return [String]
50
- def any_notice_tag
51
- ANY_MOD_TAG
52
- end
53
-
54
- # Get the notice type that this modification is affecting.
55
- #
56
- # @param text [String] the full text of the notice
57
- # @return [Date] the notice type
58
- def notice_type(text)
59
- simple_tag_contents(text, "NTYPE")
60
- end
61
-
62
-
63
- extend FBO::Parser::NoticeHandler
64
- extend FBO::Parser::ParserHelper
65
- extend self
66
- end
@@ -1,27 +0,0 @@
1
- module FBO::Parser::NoticeHandler
2
-
3
- protected
4
-
5
- # Returns a concatenated list of all tags for the notice
6
- #
7
- # @return [String]
8
- def any_notice_tag
9
- ""
10
- end
11
-
12
- # Given a tag string, return the data associated with it as a String object
13
- # or nil if not present.
14
- #
15
- # @param text [String] the full text of the notice
16
- # @param tag [String] the tag that should be searched for
17
- # @return [String] contents or nil if not present
18
- def simple_tag_contents(text, tag)
19
- regexp = (tag.is_a?(Regexp) ? tag : /<#{ tag }>/)
20
- match = text.match(regexp)
21
- return nil unless match
22
- match2 = match.post_match.match(/<(?:#{ any_notice_tag })>/)
23
- prematch = match2.pre_match if match2
24
- prematch ? prematch.strip : nil
25
- end
26
-
27
- end
@@ -1,315 +0,0 @@
1
- require "date"
2
-
3
- module FBO::Parser::ParserHelper
4
- extend FBO::Parser::NoticeHandler
5
-
6
- protected
7
-
8
- # Get the date of the notice.
9
- #
10
- # @param text [String] the full text of the notice
11
- # @return [Date] the date that the notice was posted
12
- def date(text)
13
- date_string = simple_tag_contents(text, "DATE")
14
- Date.parse("#{ year(text) }#{ date_string }")
15
- end
16
-
17
- # Get the year from the notice or assume the current year.
18
- #
19
- # @param [text] the whole notice text
20
- # @return [Fixnum] the year of the notice
21
- def year(text)
22
- year_string = simple_tag_contents(text, "YEAR")
23
- "20#{ year_string }".to_i
24
- end
25
-
26
- # Get the zip code of the contracting office.
27
- #
28
- # @param text [String] the full text of the notice
29
- # @return [String] the zip code of the contracting office
30
- def zip(text)
31
- simple_tag_contents(text, "ZIP")
32
- end
33
-
34
- # Get the two-digit or single alphabetic code for classifying the notice.
35
- #
36
- # @param text [String] the full text of the notice
37
- # @return [String] the classification code as a string
38
- def classification_code(text)
39
- simple_tag_contents(text, "CLASSCOD")
40
- end
41
-
42
- # Get the NAICS code that should be referenced with this notice.
43
- #
44
- # @param text [String] the full text of the notice
45
- # @return [String] the relevant NAICS code
46
- def naics_code(text)
47
- simple_tag_contents(text, "NAICS")
48
- end
49
-
50
- # Get the agency name for this notice.
51
- #
52
- # @param text [String] the full text of the notice
53
- # @return [String] the name of the agency
54
- def agency(text)
55
- simple_tag_contents(text, "AGENCY")
56
- end
57
-
58
- # Get the agency office name for this notice.
59
- #
60
- # @param text [String] the full text of the notice
61
- # @return [String] the name of the agency office
62
- def office(text)
63
- simple_tag_contents(text, "OFFICE")
64
- end
65
-
66
- # Get the location of the office issuing the notice (often used for department).
67
- #
68
- # @param text [String] the full text of the notice
69
- # @return [String] the location text
70
- def location(text)
71
- simple_tag_contents(text, "LOCATION")
72
- end
73
-
74
- # Get the office address from which the notice is issued.
75
- #
76
- # @param text [String] the full text of the notice
77
- # @return [String] the office address
78
- def office_address(text)
79
- simple_tag_contents(text, "OFFADD")
80
- end
81
-
82
- # Get the subject of the notice.
83
- #
84
- # @param text [String] the full text of the notice
85
- # @return [String] the subject address
86
- def subject(text)
87
- simple_tag_contents(text, "SUBJECT")
88
- end
89
-
90
- # Get the solicitation number for the notice.
91
- #
92
- # @param text [String] the full text of the notice
93
- # @return [String] the solicitation number
94
- def solicitation_number(text)
95
- simple_tag_contents(text, "SOLNBR")
96
- end
97
-
98
- # Get the type of the related notice in the case of dependent notices.
99
- #
100
- # @param text [String] the full text of the notice
101
- # @return [String] the notice type
102
- def notice_type(text)
103
- simple_tag_contents(text, "NTYPE")
104
- end
105
-
106
- # Get the deadline for responding to the notice.
107
- #
108
- # @param text [String] the full text of the notice
109
- # @return [Date] the response date
110
- def response_date(text)
111
- date_string = simple_tag_contents(text, "RESPDATE")
112
- date_string ? Date.strptime(date_string, "%m%d%y") : nil
113
- end
114
-
115
- # Get the date when the notice will be archived.
116
- #
117
- # @param text [String] the full text of the notice
118
- # @return [Date] the archive date
119
- def archive_date(text)
120
- date_string = simple_tag_contents(text, "ARCHDATE")
121
- date_string ? Date.strptime(date_string, "%m%d%Y") : nil
122
- end
123
-
124
- # Get the contact information for responding to the notice.
125
- #
126
- # @param text [String] the full text of the notice
127
- # @return [String] the contact info
128
- def contact(text)
129
- simple_tag_contents(text, "CONTACT")
130
- end
131
-
132
- # Get the full description of the notice.
133
- # This implementation accounts for the fact that there may be more than one
134
- # DESC tag in the notice and that the one we want will be the first one.
135
- #
136
- # @param text [String] the full text of the notice
137
- # @return [String] the description
138
- def description(text)
139
- match = text.match(/<DESC>/)
140
- match2 = match.post_match.match(/<(?:#{ any_notice_tag })>/)
141
- prematch = match2.pre_match
142
- prematch ? prematch.strip : nil
143
- end
144
-
145
- # Get the link URL.
146
- #
147
- # @param text [String] the full text of the notice
148
- # @return [String] the URL
149
- def link_url(text)
150
- match = text.match(/<LINK>/)
151
- simple_tag_contents(match.post_match, "URL") if match
152
- end
153
-
154
- # Get the link description / text.
155
- #
156
- # @param text [String] the full text of the notice
157
- # @return [String] the link description
158
- def link_description(text)
159
- match = text.match(/<LINK>/)
160
- description(match.post_match) if match
161
- end
162
-
163
- # Get the contact email address.
164
- #
165
- # @param text [String] the full text of the notice
166
- # @return [String] the email address
167
- def email_address(text)
168
- match = text.match(/<EMAIL>/)
169
- simple_tag_contents(match.post_match, "(EMAIL|ADDRESS)") if match
170
- end
171
-
172
- # Get the contact email description (link text).
173
- #
174
- # @param text [String] the full text of the notice
175
- # @return [String] the email description
176
- def email_description(text)
177
- match = text.match(/<EMAIL>/)
178
- description(match.post_match) if match
179
- end
180
-
181
- # Get the set-aside identifier for the notice.
182
- #
183
- # @param text [String] the full text of the notice
184
- # @return [String] the set-aside
185
- def set_aside(text)
186
- simple_tag_contents(text, "SETASIDE")
187
- end
188
-
189
- # Get the address of the "place of performance".
190
- #
191
- # @param text [String] the full text of the notice
192
- # @return [String] the address
193
- def pop_address(text)
194
- simple_tag_contents(text, "POPADDRESS")
195
- end
196
-
197
- # Get the zip code of the "place of performance".
198
- #
199
- # @param text [String] the full text of the notice
200
- # @return [String] the zip code
201
- def pop_zip_code(text)
202
- simple_tag_contents(text, "POPZIP")
203
- end
204
-
205
- # Get the country of the "place of performance".
206
- #
207
- # @param text [String] the full text of the notice
208
- # @return [String] the country
209
- def pop_country(text)
210
- simple_tag_contents(text, "POPCOUNTRY")
211
- end
212
-
213
- # Get the award number with which the notice is associated.
214
- #
215
- # @param text [String] the full text of the notice
216
- # @return [String] the award number
217
- def award_number(text)
218
- simple_tag_contents(text, "AWDNBR")
219
- end
220
-
221
- # Get the amount of the award with which the notice is associated.
222
- #
223
- # @param text [String] the full text of the notice
224
- # @return [Float] the award amount (in dollars)
225
- def award_amount(text)
226
- amount_string = simple_tag_contents(text, "AWDAMT")
227
- amount_string.gsub(/[^\d\.]/, "").to_f
228
- end
229
-
230
- # Get the line number of the contract with which the award is associated.
231
- #
232
- # @param text [String] the full text of the notice
233
- # @return [String] the line number (which might not be a Fixnum)
234
- def line_number(text)
235
- simple_tag_contents(text, "LINENBR")
236
- end
237
-
238
- # Get the date of the award.
239
- #
240
- # @param text [String] the full text of the notice
241
- # @return [Date] the date that the award was given
242
- def award_date(text)
243
- date_string = simple_tag_contents(text, "AWDDATE")
244
- Date.strptime(date_string, "%m%d%y")
245
- end
246
-
247
- # Get the name of the awardee.
248
- #
249
- # @param text [String] the full text of the notice
250
- # @return [String] the awardee's name
251
- def awardee(text)
252
- simple_tag_contents(text, "AWARDEE")
253
- end
254
-
255
- # Get the DUNS number for the awardee.
256
- #
257
- # @param text [String] the full text of the notice
258
- # @return [String] the awardee's DUNS number
259
- def awardee_duns(text)
260
- simple_tag_contents(text, "AWARDEEDUNS")
261
- end
262
-
263
- # If the notice is a correction of a previous notice, return true; otherwise, false.
264
- #
265
- # @param text [String] the full text of the notice
266
- # @return [boolean]
267
- def correction?(text)
268
- correction_string = simple_tag_contents(text, "CORRECTION")
269
- if correction_string && correction_string =~ /^y/i
270
- return true
271
- end
272
- false
273
- end
274
-
275
- # Get the file list associated with the notice.
276
- #
277
- # @param text [String] the full text of the notice
278
- # @return [Array] the file list
279
- def file_list(text)
280
- []
281
- end
282
-
283
- # Get the statutory authority.
284
- #
285
- # @param text [String] the full text of the notice
286
- # @return [String] the name of the statutory authority
287
- def statutory_authority(text)
288
- simple_tag_contents(text, "STAUTH")
289
- end
290
-
291
- # Get the modification number.
292
- #
293
- # @param text [String] the full text of the notice
294
- # @return [String] the modification number
295
- def modification_number(text)
296
- simple_tag_contents(text, "MODNBR")
297
- end
298
-
299
- # Get the delivery order number.
300
- #
301
- # @param text [String] the full text of the notice
302
- # @return [String] the delivery order number
303
- def delivery_order_number(text)
304
- simple_tag_contents(text, "DONBR")
305
- end
306
-
307
- # Get the justification authority (reason).
308
- #
309
- # @param text [String] the full text of the notice
310
- # @return [String] the judstification authority
311
- def justification_authority(text)
312
- simple_tag_contents(text, "FOJA")
313
- end
314
-
315
- end