FBO

Fetch a dated dump file from FedBizOpps and parse its contents into structures suitable for use by other programs.

The gem in its current state handles most of the notice types described in the FBO documentation for the data format.

  • Presolicitation (PRESOL)
  • Combined Synopsis/Solicitation (COMBINE)
  • Amendment to a Previous Combined Solicitation (AMDCSS)
  • Modification to a Previous Base (MOD)
  • Award (AWARD)
  • Justification and Approval (JA)
  • Intent to Bundle Requirements (ITB)
  • Fair Opportunity / Limited Sources Justification (FAIROPP)
  • Sources Sought (SRCSGT)
  • Foreign Government Standard (FSTD)
  • Special Notice (SNOTE)
  • Sale of Surplus Property (SSALE)
  • Document Archival (ARCHIVE)
  • Document Unarchival (UNARCHIVE)

Two notice types have not yet been implemented as no record of their ever having been used could be found in any of the FBO dump files dating back as far as

  1. These are:
  2. Document Upload (EPSUPLOAD)
  3. Document Deleting (DELETE)

Installation

Add this line to your application's Gemfile:

gem 'fbo'

And then execute:

$ bundle

Or install it yourself as:

$ gem install fbo

Usage

The gem includes a basic command line processor that accepts a file:

bundle exec bin/fbo_parser -f FBOFeed20171102

The source code for fbo_parser provides a model for using the gem in your own projects.

Start by creating a new FBO::File to wrap the FBO feed file that you want to work with.

file = FBO::File.new(filename)

Next, create a new FBO::Interpreter using the file you created:

interpreter = FBO::Interpreter.new(file)

The interpreter allows you to iterate through the notices in your dump file, passing both the raw text and the parsed notice as parameters to the yielded block. To get at the data values from the notice, convert the structure into a Hash and access the attributes individually as:

interpreter.each_notice do |text, notice|
  hash = notice.to_hash
  sol_nbr = hash[:solicitation_number]
  subject = hash[:subject]
  puts notice.type.to_s
  puts "#{ text.length.to_s.rjust(9) } chars"
  puts "#{ sol_nbr.ljust(40) }  #{ subject }"
  puts
end

The attributes available for each notice vary quite a bit between notice types and even notices of the same type since the specification is not always clear as to which are mandatory and which are optional.

Contributing

Code contributions gratefully accepted.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Logging any issues you might notice at the Issues tracker on GitHub is also a great way to help out.