ofx-parser 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/History.txt +5 -0
- data/Manifest.txt +0 -1
- data/lib/ofx-parser.rb +7 -6
- data/lib/ofx.rb +14 -9
- data/test/test_ofx_parser.rb +3 -1
- metadata +56 -49
- data/lib/class-extension.rb +0 -154
data/.gemtest
ADDED
File without changes
|
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/lib/ofx-parser.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'hpricot'
|
2
3
|
require 'time'
|
3
4
|
require 'date'
|
4
5
|
|
5
|
-
%w(
|
6
|
+
%w(ofx mcc).each do |fn|
|
6
7
|
require File.dirname(__FILE__) + "/#{fn}"
|
7
8
|
end
|
8
9
|
|
9
10
|
module OfxParser
|
10
|
-
VERSION = '1.0
|
11
|
+
VERSION = '1.1.0'
|
11
12
|
|
12
13
|
class OfxParser
|
13
14
|
|
@@ -55,10 +56,10 @@ module OfxParser
|
|
55
56
|
# Returns a DateTime object. Milliseconds (XXX) are ignored.
|
56
57
|
def self.parse_datetime(date)
|
57
58
|
if /\A\s*
|
58
|
-
(\d{4})(\d{2})(\d{2})
|
59
|
-
(?:(\d{2})(\d{2})(\d{2}))?
|
60
|
-
(?:\.(\d{3}))?
|
61
|
-
(?:\[(
|
59
|
+
(\d{4})(\d{2})(\d{2}) # YYYYMMDD 1,2,3
|
60
|
+
(?:(\d{2})(\d{2})(\d{2}))? # HHMMSS - optional 4,5,6
|
61
|
+
(?:\.(\d{3}))? # .XXX - optional 7
|
62
|
+
(?:\[([-+]?[\.\d]+)\:\w{3}\])? # [-n:TZ] - optional 8,9
|
62
63
|
\s*\z/ix =~ date
|
63
64
|
year = $1.to_i
|
64
65
|
mon = $2.to_i
|
data/lib/ofx.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module OfxParser
|
2
|
-
module
|
2
|
+
module MonetaryClassSupport
|
3
3
|
|
4
|
-
|
4
|
+
attr_accessor :monies
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
def monetary_vars(*methods) #:nodoc:
|
7
|
+
self.monies ||= []
|
8
|
+
self.monies += methods
|
10
9
|
end
|
10
|
+
end
|
11
11
|
|
12
|
+
module MonetarySupport
|
12
13
|
# Returns pennies for a given string amount, i.e:
|
13
14
|
# '-123.45' => -12345
|
14
15
|
# '123' => 12300
|
@@ -25,7 +26,7 @@ module OfxParser
|
|
25
26
|
|
26
27
|
def monetary_method_call?(meth) #:nodoc:
|
27
28
|
orig = original_method(meth)
|
28
|
-
|
29
|
+
self.class.monies.include?(orig) && meth.to_s == "#{orig}_in_pennies"
|
29
30
|
end
|
30
31
|
|
31
32
|
def method_missing(meth, *args) #:nodoc:
|
@@ -69,14 +70,15 @@ module OfxParser
|
|
69
70
|
end
|
70
71
|
|
71
72
|
class Account
|
72
|
-
attr_accessor :number, :statement, :transaction_uid
|
73
|
+
attr_accessor :number, :statement, :transaction_uid, :routing_number
|
73
74
|
end
|
74
75
|
|
75
76
|
class BankAccount < Account
|
76
77
|
TYPE = [:CHECKING, :SAVINGS, :MONEYMRKT, :CREDITLINE]
|
77
|
-
attr_accessor :
|
78
|
+
attr_accessor :type, :balance, :balance_date
|
78
79
|
|
79
80
|
include MonetarySupport
|
81
|
+
extend MonetaryClassSupport
|
80
82
|
monetary_vars :balance
|
81
83
|
|
82
84
|
undef type
|
@@ -89,6 +91,7 @@ module OfxParser
|
|
89
91
|
attr_accessor :remaining_credit, :remaining_credit_date, :balance, :balance_date
|
90
92
|
|
91
93
|
include MonetarySupport
|
94
|
+
extend MonetaryClassSupport
|
92
95
|
monetary_vars :remaining_credit, :balance
|
93
96
|
end
|
94
97
|
|
@@ -96,6 +99,7 @@ module OfxParser
|
|
96
99
|
attr_accessor :broker_id, :positions, :margin_balance, :short_balance, :cash_balance
|
97
100
|
|
98
101
|
include MonetarySupport
|
102
|
+
extend MonetaryClassSupport
|
99
103
|
monetary_vars :margin_balance, :short_balance, :cash_balance
|
100
104
|
end
|
101
105
|
|
@@ -108,6 +112,7 @@ module OfxParser
|
|
108
112
|
attr_accessor :type, :date, :amount, :fit_id, :check_number, :sic, :memo, :payee
|
109
113
|
|
110
114
|
include MonetarySupport
|
115
|
+
extend MonetaryClassSupport
|
111
116
|
monetary_vars :amount
|
112
117
|
|
113
118
|
TYPE = {
|
data/test/test_ofx_parser.rb
CHANGED
@@ -14,7 +14,7 @@ class OfxParserTest < Test::Unit::TestCase
|
|
14
14
|
ofx = File.read(fixtures_dir + "/#{fn}")
|
15
15
|
ofx.gsub!(/\r?\n/,"\r\n") # change line endings to \r\n
|
16
16
|
|
17
|
-
OFX_FILES[fn.scan(
|
17
|
+
OFX_FILES[fn.scan(/\w+/).first.to_sym] = ofx
|
18
18
|
end
|
19
19
|
|
20
20
|
def setup
|
@@ -39,6 +39,7 @@ class OfxParserTest < Test::Unit::TestCase
|
|
39
39
|
|
40
40
|
def test_parse_datetime
|
41
41
|
assert_equal DateTime.civil(2007, 6, 22, 19, 0, 0, Rational(-5,24)), @parser.parse_datetime('20070622190000.200[-5:CDT]')
|
42
|
+
assert_equal DateTime.civil(2007, 6, 22, 19, 0, 0, Rational(9,24)), @parser.parse_datetime('20070622190000.200[+9.0:JST]')
|
42
43
|
assert_equal DateTime.civil(2007, 6, 22), @parser.parse_datetime('20070622')
|
43
44
|
assert_equal DateTime.civil(2007, 6, 22, 19, 0, 0), @parser.parse_datetime('20070622190000')
|
44
45
|
assert_equal DateTime.civil(2007, 6, 22, 19, 0, 0), @parser.parse_datetime('20070622190000.200')
|
@@ -229,6 +230,7 @@ class OfxParserTest < Test::Unit::TestCase
|
|
229
230
|
|
230
231
|
class X
|
231
232
|
include OfxParser::MonetarySupport
|
233
|
+
extend OfxParser::MonetaryClassSupport
|
232
234
|
attr_accessor :amount
|
233
235
|
monetary_vars :amount
|
234
236
|
end
|
metadata
CHANGED
@@ -1,51 +1,58 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ofx-parser
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Andrew A. Smith
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-12-12 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: hpricot
|
17
|
-
|
18
|
-
|
19
|
-
requirements:
|
20
|
-
- -
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version:
|
23
|
-
|
24
|
-
|
16
|
+
requirement: &2159585980 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2159585980
|
25
|
+
- !ruby/object:Gem::Dependency
|
25
26
|
name: hoe
|
26
|
-
|
27
|
-
|
28
|
-
requirements:
|
29
|
-
- -
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version:
|
32
|
-
|
33
|
-
|
27
|
+
requirement: &2159585560 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.12'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2159585560
|
36
|
+
description: ! "== DESCRIPTION:\n\nofx-parser is a ruby library to parse a realistic
|
37
|
+
subset of the lengthy OFX 1.x specification.\n\n== FEATURES/PROBLEMS:\n\n* Reads
|
38
|
+
OFX responses - i.e. those downloaded from financial institutions and\n puts it
|
39
|
+
into a usable object graph.\n* Supports the 3 main message sets: banking, credit
|
40
|
+
card and investment\n accounts, as well as the required 'sign on' set.\n* Knows
|
41
|
+
about SIC codes - if your institution provides them.\n See http://www.eeoc.gov/stats/jobpat/siccodes.html\n*
|
42
|
+
Monetary amounts can be retrieved either as a raw string, or in pennies.\n* Supports
|
43
|
+
OFX timestamps."
|
34
44
|
email: andy@tinnedfruit.org
|
35
45
|
executables: []
|
36
|
-
|
37
46
|
extensions: []
|
38
|
-
|
39
|
-
extra_rdoc_files:
|
47
|
+
extra_rdoc_files:
|
40
48
|
- History.txt
|
41
49
|
- Manifest.txt
|
42
50
|
- README.txt
|
43
|
-
files:
|
51
|
+
files:
|
44
52
|
- History.txt
|
45
53
|
- Manifest.txt
|
46
54
|
- README.txt
|
47
55
|
- Rakefile
|
48
|
-
- lib/class-extension.rb
|
49
56
|
- lib/mcc.rb
|
50
57
|
- lib/ofx-parser.rb
|
51
58
|
- lib/ofx.rb
|
@@ -55,32 +62,32 @@ files:
|
|
55
62
|
- test/fixtures/malformed_header.ofx.sgml
|
56
63
|
- test/fixtures/with_spaces.ofx.sgml
|
57
64
|
- test/test_ofx_parser.rb
|
58
|
-
|
65
|
+
- .gemtest
|
59
66
|
homepage: http://ofx-parser.rubyforge.org/
|
67
|
+
licenses: []
|
60
68
|
post_install_message:
|
61
|
-
rdoc_options:
|
69
|
+
rdoc_options:
|
62
70
|
- --main
|
63
71
|
- README.txt
|
64
|
-
require_paths:
|
72
|
+
require_paths:
|
65
73
|
- lib
|
66
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
78
86
|
requirements: []
|
79
|
-
|
80
87
|
rubyforge_project: ofx-parser
|
81
|
-
rubygems_version: 1.
|
88
|
+
rubygems_version: 1.8.10
|
82
89
|
signing_key:
|
83
|
-
specification_version:
|
90
|
+
specification_version: 3
|
84
91
|
summary: ofx-parser is a ruby library for parsing OFX 1.x data.
|
85
|
-
test_files:
|
92
|
+
test_files:
|
86
93
|
- test/test_ofx_parser.rb
|
data/lib/class-extension.rb
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
# = class_extension.rb
|
2
|
-
#
|
3
|
-
# == Copyright (c) 2006 Daniel Schierbeck
|
4
|
-
#
|
5
|
-
# Ruby License
|
6
|
-
#
|
7
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
8
|
-
# software under the same terms as Ruby.
|
9
|
-
#
|
10
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
11
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
-
# FOR A PARTICULAR PURPOSE.
|
13
|
-
#
|
14
|
-
# == Special Thanks
|
15
|
-
#
|
16
|
-
# Thanks to Trans, Nobu and Ulysses for their original on this concept.
|
17
|
-
#
|
18
|
-
# == Authors and Contributors
|
19
|
-
#
|
20
|
-
# * Daniel Schierbeck
|
21
|
-
# * Thomas Sawyer
|
22
|
-
# * Nobu Nakada
|
23
|
-
# * Ulysses
|
24
|
-
|
25
|
-
# Author:: Daniel Schierbeck
|
26
|
-
# Copyright:: Copyright (c) 2006 Daniel Schierbeck
|
27
|
-
# License:: Ruby License
|
28
|
-
|
29
|
-
#
|
30
|
-
|
31
|
-
class Module #:nodoc: all
|
32
|
-
|
33
|
-
alias_method :append_features_without_class_extension, :append_features
|
34
|
-
|
35
|
-
# = class_extension
|
36
|
-
#
|
37
|
-
# Normally when including modules, class/module methods are not
|
38
|
-
# extended. To achieve this behavior requires some clever
|
39
|
-
# Ruby Karate. Instead class_extension provides an easy to use
|
40
|
-
# and clean solution. Simply place the extending class methods
|
41
|
-
# in a block of the special module method #class_extension.
|
42
|
-
#
|
43
|
-
# module Mix
|
44
|
-
# def inst_meth
|
45
|
-
# puts 'inst_meth'
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# class_extension do
|
49
|
-
# def class_meth
|
50
|
-
# "Class Method!"
|
51
|
-
# end
|
52
|
-
# end
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# class X
|
56
|
-
# include Mix
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# X.class_meth #=> "Class Method!"
|
60
|
-
#
|
61
|
-
|
62
|
-
def class_extension(&block)
|
63
|
-
@class_extension ||= Module.new do
|
64
|
-
def self.append_features(mod)
|
65
|
-
append_features_without_class_extension(mod)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
@class_extension.module_eval(&block) if block_given?
|
69
|
-
@class_extension
|
70
|
-
end
|
71
|
-
|
72
|
-
private :class_extension
|
73
|
-
|
74
|
-
def append_features(mod)
|
75
|
-
append_features_without_class_extension(mod)
|
76
|
-
mod.extend(class_extension)
|
77
|
-
if mod.instance_of? Module
|
78
|
-
mod.__send__(:class_extension).__send__(:include, class_extension)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
class Class #:nodoc: all
|
85
|
-
undef_method :class_extension
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# _____ _
|
91
|
-
# |_ _|__ ___| |_
|
92
|
-
# | |/ _ \/ __| __|
|
93
|
-
# | | __/\__ \ |_
|
94
|
-
# |_|\___||___/\__|
|
95
|
-
#
|
96
|
-
|
97
|
-
=begin test
|
98
|
-
|
99
|
-
require 'test/unit'
|
100
|
-
|
101
|
-
class TC_ClassMethods < Test::Unit::TestCase
|
102
|
-
|
103
|
-
# fixture
|
104
|
-
|
105
|
-
module N
|
106
|
-
class_extension do
|
107
|
-
def n ; 43 ; end
|
108
|
-
def s ; self ; end
|
109
|
-
end
|
110
|
-
extend class_extension
|
111
|
-
end
|
112
|
-
|
113
|
-
class X
|
114
|
-
include N
|
115
|
-
def n ; 11 ; end
|
116
|
-
end
|
117
|
-
|
118
|
-
module K
|
119
|
-
include N
|
120
|
-
class_extension do
|
121
|
-
def n ; super + 1 ; end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
class Z
|
126
|
-
include K
|
127
|
-
end
|
128
|
-
|
129
|
-
# tests
|
130
|
-
|
131
|
-
def test_01
|
132
|
-
assert_equal( 43, N.n )
|
133
|
-
assert_equal( N, N.s )
|
134
|
-
end
|
135
|
-
def test_02
|
136
|
-
assert_equal( 43, X.n )
|
137
|
-
assert_equal( X, X.s )
|
138
|
-
end
|
139
|
-
def test_03
|
140
|
-
assert_equal( 11, X.new.n )
|
141
|
-
end
|
142
|
-
def test_04
|
143
|
-
assert_equal( 43, K.n ) #notic the difference!
|
144
|
-
assert_equal( K, K.s )
|
145
|
-
end
|
146
|
-
def test_05
|
147
|
-
assert_equal( 44, Z.n )
|
148
|
-
assert_equal( Z, Z.s )
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
=end
|
154
|
-
|