ofx_kit 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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +315 -0
- data/lib/generators/ofx/eject_generator.rb +25 -0
- data/lib/generators/ofx/templates/ofx_mappings.yml +33 -0
- data/lib/ofx_kit/base/account.rb +12 -0
- data/lib/ofx_kit/base/builder.rb +105 -0
- data/lib/ofx_kit/base/document.rb +32 -0
- data/lib/ofx_kit/base/entity.rb +22 -0
- data/lib/ofx_kit/base/statement.rb +20 -0
- data/lib/ofx_kit/configuration/core.rb +110 -0
- data/lib/ofx_kit/configuration/date_parser.rb +28 -0
- data/lib/ofx_kit/configuration/mapping_applicator.rb +34 -0
- data/lib/ofx_kit/configuration/section_proxy.rb +30 -0
- data/lib/ofx_kit/configuration.rb +6 -0
- data/lib/ofx_kit/domain/balance.rb +10 -0
- data/lib/ofx_kit/domain/bank_account.rb +8 -0
- data/lib/ofx_kit/domain/bank_statement.rb +9 -0
- data/lib/ofx_kit/domain/credit_card_account.rb +8 -0
- data/lib/ofx_kit/domain/credit_card_statement.rb +9 -0
- data/lib/ofx_kit/domain/transaction.rb +13 -0
- data/lib/ofx_kit/domain/transaction_collection.rb +94 -0
- data/lib/ofx_kit/errors.rb +36 -0
- data/lib/ofx_kit/mappings/core_mappings.yml +23 -0
- data/lib/ofx_kit/mappings/field_mappings.yml +19 -0
- data/lib/ofx_kit/parser.rb +131 -0
- data/lib/ofx_kit/tokenizer/base.rb +34 -0
- data/lib/ofx_kit/tokenizer/ofx1.rb +53 -0
- data/lib/ofx_kit/tokenizer/ofx2.rb +30 -0
- data/lib/ofx_kit/version.rb +5 -0
- data/lib/ofx_kit.rb +84 -0
- metadata +156 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OFX
|
|
4
|
+
module Tokenizer
|
|
5
|
+
# Tokenizer for OFX version 2 files, which use standard XML with an
|
|
6
|
+
# OFX processing instruction for header metadata.
|
|
7
|
+
class OFX2 < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def parse!
|
|
11
|
+
content = convert_to_utf8(@content)
|
|
12
|
+
doc = Nokogiri::XML(content, &:nonet)
|
|
13
|
+
|
|
14
|
+
raise InvalidBodyError, "OFX2 body could not be parsed: #{doc.errors.first}" if doc.errors.any?
|
|
15
|
+
|
|
16
|
+
@headers = parse_headers(doc)
|
|
17
|
+
@body = doc
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def parse_headers(doc)
|
|
21
|
+
pi = doc.children.find { |node| node.processing_instruction? && node.name == 'OFX' }
|
|
22
|
+
return {} unless pi
|
|
23
|
+
|
|
24
|
+
pi.content.scan(/(\w+)="([^"]*)"/).each_with_object({}) do |(key, value), result|
|
|
25
|
+
result[key] = value == 'NONE' ? nil : value
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/ofx_kit.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'money'
|
|
5
|
+
Money.rounding_mode = BigDecimal::ROUND_HALF_UP
|
|
6
|
+
Money.locale_backend = :currency
|
|
7
|
+
require 'stringio'
|
|
8
|
+
require 'time'
|
|
9
|
+
|
|
10
|
+
require_relative 'ofx_kit/version'
|
|
11
|
+
require_relative 'ofx_kit/errors'
|
|
12
|
+
require_relative 'ofx_kit/configuration'
|
|
13
|
+
require_relative 'ofx_kit/base/entity'
|
|
14
|
+
require_relative 'ofx_kit/base/account'
|
|
15
|
+
require_relative 'ofx_kit/base/statement'
|
|
16
|
+
require_relative 'ofx_kit/base/document'
|
|
17
|
+
require_relative 'ofx_kit/domain/bank_account'
|
|
18
|
+
require_relative 'ofx_kit/domain/credit_card_account'
|
|
19
|
+
require_relative 'ofx_kit/domain/transaction'
|
|
20
|
+
require_relative 'ofx_kit/domain/transaction_collection'
|
|
21
|
+
require_relative 'ofx_kit/domain/balance'
|
|
22
|
+
require_relative 'ofx_kit/domain/bank_statement'
|
|
23
|
+
require_relative 'ofx_kit/domain/credit_card_statement'
|
|
24
|
+
require_relative 'ofx_kit/base/builder'
|
|
25
|
+
require_relative 'ofx_kit/tokenizer/base'
|
|
26
|
+
require_relative 'ofx_kit/tokenizer/ofx1'
|
|
27
|
+
require_relative 'ofx_kit/tokenizer/ofx2'
|
|
28
|
+
require_relative 'ofx_kit/parser'
|
|
29
|
+
|
|
30
|
+
# Top-level namespace for the ofx_kit gem.
|
|
31
|
+
# Provides module-level access to the shared {Configuration} instance and
|
|
32
|
+
# a {.configure} block for customizing field mappings and XML tags.
|
|
33
|
+
#
|
|
34
|
+
# @example Configure custom field mappings
|
|
35
|
+
# OFX.configure do |config|
|
|
36
|
+
# config.transaction.map 'MYFIELD', to: :my_attribute
|
|
37
|
+
# end
|
|
38
|
+
module OFX
|
|
39
|
+
class << self
|
|
40
|
+
# Parses an OFX file or IO object and returns a {Parser} instance.
|
|
41
|
+
# This is the primary entry point for the gem.
|
|
42
|
+
#
|
|
43
|
+
# @param resource [String, IO] file path or IO object containing OFX data
|
|
44
|
+
# @return [Parser]
|
|
45
|
+
#
|
|
46
|
+
# @example Parse a file path
|
|
47
|
+
# ofx = OFX.new("statement.ofx")
|
|
48
|
+
# ofx.account #=> OFX::BankAccount
|
|
49
|
+
# ofx.transactions #=> OFX::TransactionCollection
|
|
50
|
+
#
|
|
51
|
+
# @example Parse an IO object
|
|
52
|
+
# ofx = OFX.new(File.open("statement.ofx"))
|
|
53
|
+
#
|
|
54
|
+
# @example Block form
|
|
55
|
+
# OFX.new("statement.ofx") do |ofx|
|
|
56
|
+
# puts ofx.balance
|
|
57
|
+
# end
|
|
58
|
+
def new(resource, &)
|
|
59
|
+
Parser.new(resource, &)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Yields the current {Configuration} instance for customization.
|
|
63
|
+
# @yieldparam config [Configuration]
|
|
64
|
+
# @raise [ConfigurationError] if the block raises any error
|
|
65
|
+
def configure
|
|
66
|
+
yield config
|
|
67
|
+
rescue ConfigurationError
|
|
68
|
+
raise
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
raise ConfigurationError, e.message
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Configuration] the shared configuration instance (lazy-initialized)
|
|
74
|
+
def config
|
|
75
|
+
@config ||= Configuration.new
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Resets the configuration to its default state.
|
|
79
|
+
# Useful in tests to restore default field mappings between examples.
|
|
80
|
+
def reset_config!
|
|
81
|
+
@config = nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ofx_kit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Lucas Geron
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: bigdecimal
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '3.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: money
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '6.16'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '6.16'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: nokogiri
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.13'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.13'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '13.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '13.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '3.13'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.13'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rubocop
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '1.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '1.0'
|
|
96
|
+
description: Parses OFX 1.x and 2.x files into typed domain objects with a fluent
|
|
97
|
+
API and configurable field mappings.
|
|
98
|
+
email: lucasf.geron@gmail.com
|
|
99
|
+
executables: []
|
|
100
|
+
extensions: []
|
|
101
|
+
extra_rdoc_files: []
|
|
102
|
+
files:
|
|
103
|
+
- LICENSE
|
|
104
|
+
- README.md
|
|
105
|
+
- lib/generators/ofx/eject_generator.rb
|
|
106
|
+
- lib/generators/ofx/templates/ofx_mappings.yml
|
|
107
|
+
- lib/ofx_kit.rb
|
|
108
|
+
- lib/ofx_kit/base/account.rb
|
|
109
|
+
- lib/ofx_kit/base/builder.rb
|
|
110
|
+
- lib/ofx_kit/base/document.rb
|
|
111
|
+
- lib/ofx_kit/base/entity.rb
|
|
112
|
+
- lib/ofx_kit/base/statement.rb
|
|
113
|
+
- lib/ofx_kit/configuration.rb
|
|
114
|
+
- lib/ofx_kit/configuration/core.rb
|
|
115
|
+
- lib/ofx_kit/configuration/date_parser.rb
|
|
116
|
+
- lib/ofx_kit/configuration/mapping_applicator.rb
|
|
117
|
+
- lib/ofx_kit/configuration/section_proxy.rb
|
|
118
|
+
- lib/ofx_kit/domain/balance.rb
|
|
119
|
+
- lib/ofx_kit/domain/bank_account.rb
|
|
120
|
+
- lib/ofx_kit/domain/bank_statement.rb
|
|
121
|
+
- lib/ofx_kit/domain/credit_card_account.rb
|
|
122
|
+
- lib/ofx_kit/domain/credit_card_statement.rb
|
|
123
|
+
- lib/ofx_kit/domain/transaction.rb
|
|
124
|
+
- lib/ofx_kit/domain/transaction_collection.rb
|
|
125
|
+
- lib/ofx_kit/errors.rb
|
|
126
|
+
- lib/ofx_kit/mappings/core_mappings.yml
|
|
127
|
+
- lib/ofx_kit/mappings/field_mappings.yml
|
|
128
|
+
- lib/ofx_kit/parser.rb
|
|
129
|
+
- lib/ofx_kit/tokenizer/base.rb
|
|
130
|
+
- lib/ofx_kit/tokenizer/ofx1.rb
|
|
131
|
+
- lib/ofx_kit/tokenizer/ofx2.rb
|
|
132
|
+
- lib/ofx_kit/version.rb
|
|
133
|
+
homepage: https://github.com/lucasgeron/ofx_kit
|
|
134
|
+
licenses:
|
|
135
|
+
- MIT
|
|
136
|
+
metadata:
|
|
137
|
+
source_code_uri: https://github.com/lucasgeron/ofx_kit
|
|
138
|
+
rubygems_mfa_required: 'true'
|
|
139
|
+
rdoc_options: []
|
|
140
|
+
require_paths:
|
|
141
|
+
- lib
|
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
|
+
requirements:
|
|
144
|
+
- - ">="
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: '3.4'
|
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
152
|
+
requirements: []
|
|
153
|
+
rubygems_version: 3.6.9
|
|
154
|
+
specification_version: 4
|
|
155
|
+
summary: OFX file parser for Ruby
|
|
156
|
+
test_files: []
|