Skip to content

Commit

Permalink
Ruby 2.0.0 support and minimal OFX 1.0.3 support
Browse files Browse the repository at this point in the history
- Just enough OFX 1.0.3 support to keep this working for Chase accounts
  (basically just allows 103 and CLIENTUID)
- Updated gems and tests for Ruby 2.0.0
- Skips old tests that required Citi and Capital One accounts
  • Loading branch information
baconpat committed Dec 24, 2015
1 parent 920819f commit 1a211c1
Show file tree
Hide file tree
Showing 27 changed files with 188 additions and 132 deletions.
1 change: 1 addition & 0 deletions .ruby-version
@@ -0,0 +1 @@
2.0.0-p247
4 changes: 2 additions & 2 deletions Gemfile
@@ -1,2 +1,2 @@
source :rubygems
gemspec
source "https://rubygems.org"
gemspec
18 changes: 4 additions & 14 deletions Rakefile
Expand Up @@ -21,7 +21,7 @@ Bundler::GemHelper.install_tasks
require 'rake'
require 'rake/clean'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rdoc/task'


Rake::TestTask.new do |t|
Expand All @@ -37,17 +37,8 @@ Rake::RDocTask.new do |rd|
rd.rdoc_dir = "documentation/api"
end

# RCOV command, run as though from the commandline. Amend as required or perhaps move to config/environment.rb?
RCOV = "bundle exec rcov -Ilib --xref --profile"

desc "generate a unit coverage report in coverage"
task :"coverage" do
sh "#{RCOV} --output coverage test/test_*.rb test/**/test_*.rb"
end

desc "runs coverage and rdoc"
task :default => [:coverage, :rdoc]

desc "runs tests and rdoc"
task :default => [:test, :rdoc]

desc "recreates parsers"
task :parsers do
Expand All @@ -56,8 +47,7 @@ task :parsers do
end

task :test => :parsers
task :coverage => :parsers
task :rdoc => :parsers
task :build => :parsers
task :release => :parsers
task :install => :parsers
task :install => :parsers
2 changes: 1 addition & 1 deletion lib/ofx.rb
Expand Up @@ -57,4 +57,4 @@
# = Specifications
# OFX 1.0.2:: http://www.ofx.net/ofx/downloads/ofx102spec.zip
module OFX
end
end
2 changes: 1 addition & 1 deletion lib/ofx/1.0.2/header.rb
Expand Up @@ -45,4 +45,4 @@ def self.from_ofx_102_s(header_string)
header
end
end
end
end
127 changes: 66 additions & 61 deletions lib/ofx/1.0.2/lexer.rb
@@ -1,6 +1,6 @@
#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.2
# This file is automatically generated by rex 1.0.5
# from lexical definition file "ofx_102.rex".
#++

Expand Down Expand Up @@ -29,89 +29,94 @@ class Parser < Racc::Parser

class ScanError < StandardError ; end

attr_reader :lineno
attr_reader :filename
attr_reader :lineno
attr_reader :filename
attr_accessor :state

def scan_setup ; end
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end

def action &block
def action
yield
end

def scan_str( str )
scan_evaluate str
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str

def load_file( filename )
@filename = filename
open(filename, "r") do |f|
scan_evaluate f.read
scan_setup(f.read)
end
end

def scan_file( filename )
load_file filename
load_file(filename)
do_parse
end


def next_token
@rex_tokens.shift
return if @ss.eos?

# skips empty actions
until token = _next_token or @ss.eos?; end
token
end

def scan_evaluate( str )
scan_setup
@rex_tokens = []
@lineno = 1
ss = StringScanner.new(str)
state = nil
until ss.eos?
text = ss.peek(1)
@lineno += 1 if text == "\n"
case state
when nil
case
when (text = ss.scan(/\<\//))
@rex_tokens.push action { state = :TAG; [:etag_in, text] }

when (text = ss.scan(/\</))
@rex_tokens.push action { state = :TAG; [:tag_in, text] }

when (text = ss.scan(/\s+(?=\S)/))
;

when (text = ss.scan(/.*?(?=(\<|\<\/)+?)/))
@rex_tokens.push action { [:text, text] }

when (text = ss.scan(/.*\S(?=\s*$)/))
@rex_tokens.push action { [:text, text] }

when (text = ss.scan(/\s+(?=$)/))
;

else
text = ss.string[ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if

when :TAG
case
when (text = ss.scan(/\>/))
@rex_tokens.push action { state = nil; [:tag_out, text] }

when (text = ss.scan(/[\w\-\.]+/))
@rex_tokens.push action { [:element, text] }

else
text = ss.string[ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/\<\//))
action { @state = :TAG; [:etag_in, text] }

when (text = @ss.scan(/\</))
action { @state = :TAG; [:tag_in, text] }

when (text = @ss.scan(/\s+(?=\S)/))
;

when (text = @ss.scan(/.*?(?=(\<|\<\/)+?)/))
action { [:text, text] }

when (text = @ss.scan(/.*\S(?=\s*$)/))
action { [:text, text] }

when (text = @ss.scan(/\s+(?=$)/))
;

else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if

when :TAG
case
when (text = @ss.scan(/\>/))
action { @state = nil; [:tag_out, text] }

when (text = @ss.scan(/[\w\-\.]+/))
action { [:element, text] }

else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
end # until ss
end # def scan_evaluate
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if

else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token

end # class

Expand Down
6 changes: 3 additions & 3 deletions lib/ofx/1.0.2/ofx_102.rex
Expand Up @@ -28,10 +28,10 @@ macro
rule

# [:state] pattern [actions]
{ETAG_IN} { state = :TAG; [:etag_in, text] }
{TAG_IN} { state = :TAG; [:tag_in, text] }
{ETAG_IN} { @state = :TAG; [:etag_in, text] }
{TAG_IN} { @state = :TAG; [:tag_in, text] }

:TAG {TAG_OUT} { state = nil; [:tag_out, text] }
:TAG {TAG_OUT} { @state = nil; [:tag_out, text] }

:TAG [\w\-\.]+ { [:element, text] }

Expand Down
28 changes: 14 additions & 14 deletions lib/ofx/1.0.2/parser.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions lib/ofx/1.0.2/serializer.rb
Expand Up @@ -49,28 +49,30 @@ def to_http_post_body(document)
end
body += "</OFX>\n"

#print body
# puts body

body
end

def from_http_response_body(body)
# puts "Raw response:\n#{body}"

header_pattern = /(\w+\:.*\n)+/
header_match = header_pattern.match(body)

body = header_match.post_match
header = Header.from_ofx_102_s(header_match[0].strip)

parser = OFX::OFX102::Parser.new

parser.scan_str body

if parser.documents.length > 1
raise NotImplementedError, "Multiple response documents"
end

#require 'pp'
#print body
#pp parser.ofx_hashes[0]
# require 'pp'
# pp parser.ofx_hashes[0]

document = parser.documents[0]
document.header = header
Expand Down
5 changes: 3 additions & 2 deletions lib/ofx/1.0.2/signon_message_set.rb
Expand Up @@ -56,7 +56,8 @@ def ofx_102_request_body
" <LANGUAGE>#{language}\n" +
financial_institution_identification.to_ofx_102_s + "\n" +
(" <SESSCOOKIE>#{session_cookie}\n" if session_cookie).to_s +
application_identification.to_ofx_102_s
application_identification.to_ofx_102_s + "\n" +
(" <CLIENTUID>#{client_unique_identifier}" if client_unique_identifier).to_s
end
def self.from_ofx_102_hash(request_hash)
raise NotImplementedError
Expand Down Expand Up @@ -118,4 +119,4 @@ def self.from_ofx_102_hash(response_hash)
response
end
end
end
end
4 changes: 3 additions & 1 deletion lib/ofx/financial_client.rb
Expand Up @@ -23,6 +23,7 @@ class FinancialClient
@financial_institutions_and_credentials = []

attr_accessor :date_of_last_profile_update
attr_accessor :client_unique_identifier

def initialize(financial_institutions_and_credentials)
@financial_institutions_and_credentials = financial_institutions_and_credentials
Expand Down Expand Up @@ -56,6 +57,7 @@ def create_signon_request_message(financial_institution_id)
signonRequest.financial_institution_identification = self.financial_institution_identification_for(financial_institution_id)
signonRequest.session_cookie = nil
signonRequest.application_identification = self.application_identification
signonRequest.client_unique_identifier = self.client_unique_identifier
signonMessageSet.requests << signonRequest

signonMessageSet
Expand All @@ -73,4 +75,4 @@ def create_profile_update_request_message()
profileMessageSet
end
end
end
end
6 changes: 5 additions & 1 deletion lib/ofx/financial_institution.rb
Expand Up @@ -53,6 +53,10 @@ def create_request_document()
document.header.header_version = OFX::Version.new("1.0.0")
document.header.content_type = "OFXSGML"
document.header.document_version = OFX::Version.new("1.0.2")
when OFX::Version.new("1.0.3")
document.header.header_version = OFX::Version.new("1.0.0")
document.header.content_type = "OFXSGML"
document.header.document_version = OFX::Version.new("1.0.3")
else
raise NotImplementedError
end
Expand Down Expand Up @@ -80,4 +84,4 @@ def send(document)
return serializer.from_http_response_body(response_body)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/ofx/header.rb
Expand Up @@ -112,4 +112,4 @@ def previous_unique_identifier=(value)
@headers['OLDFILEUID'] = value
end
end
end
end

0 comments on commit 1a211c1

Please sign in to comment.