ynab_convert 2.0.6 → 3.0.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 +4 -4
- data/.github/workflows/merge-gatekeeper.yml +20 -0
- data/.github/workflows/test.yml +1 -1
- data/.rubocop.yml +3 -3
- data/.ruby-version +1 -1
- data/Gemfile +15 -0
- data/Gemfile.lock +141 -96
- data/Guardfile +2 -2
- data/lib/ynab_convert/api_clients/currency_api.rb +3 -2
- data/lib/ynab_convert/documents/statements/statement.rb +1 -1
- data/lib/ynab_convert/documents/ynab4_files/ynab4_file.rb +3 -3
- data/lib/ynab_convert/documents.rb +1 -1
- data/lib/ynab_convert/logger.rb +6 -5
- data/lib/ynab_convert/processors/processor.rb +5 -5
- data/lib/ynab_convert/processors.rb +1 -1
- data/lib/ynab_convert/transformers/enhancers/n26_enhancer.rb +3 -3
- data/lib/ynab_convert/transformers/enhancers/wise_enhancer.rb +3 -3
- data/lib/ynab_convert/transformers/formatters/formatter.rb +1 -1
- data/lib/ynab_convert/transformers.rb +1 -1
- data/lib/ynab_convert/validators.rb +1 -1
- data/lib/ynab_convert/version.rb +1 -1
- data/lib/ynab_convert.rb +17 -27
- data/ynab_convert.gemspec +9 -26
- metadata +12 -192
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06dcfe7f73798e21268fb4d184c149506507940b5abe37357214b905258a3d95
|
4
|
+
data.tar.gz: 063d29fb485bd8bb09a2610288ce034ce30223f19e972659bfcc70c9dc55484c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e440b19643462136a52c28b8995dbb8e8a469980864bab90dc5e7b50fda47d95b151816647fd14137d94dc559707aeb6897aaa832e547e53d5ca589136413d0c
|
7
|
+
data.tar.gz: 942a9f39d87dff694a20d2d22264b99cbc2fb6ec5cbabcecd41583e3ce2181d1a972ef87de74b8fef91b26b55c8eaf18ec1773f12939caaa7905d9a2bc83b05b
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Merge Gatekeeper
|
3
|
+
|
4
|
+
on:
|
5
|
+
pull_request:
|
6
|
+
branches:
|
7
|
+
- main
|
8
|
+
- master
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
merge-gatekeeper:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
permissions:
|
14
|
+
checks: read
|
15
|
+
statuses: read
|
16
|
+
steps:
|
17
|
+
- name: Run Merge Gatekeeper
|
18
|
+
uses: upsidr/merge-gatekeeper@v1
|
19
|
+
with:
|
20
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
data/.github/workflows/test.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
---
|
2
2
|
# See https://github.com/rubocop/rubocop/blob/master/config/default.yml for all
|
3
3
|
# options
|
4
|
-
|
4
|
+
plugins:
|
5
5
|
- rubocop-rake
|
6
6
|
- rubocop-rspec
|
7
7
|
|
8
8
|
AllCops:
|
9
9
|
DisplayCopNames: true
|
10
10
|
NewCops: enable
|
11
|
-
TargetRubyVersion:
|
11
|
+
TargetRubyVersion: 3.3
|
12
12
|
|
13
13
|
Layout/LineLength:
|
14
14
|
AllowHeredoc: true
|
@@ -22,7 +22,7 @@ Metrics/BlockLength:
|
|
22
22
|
Exclude:
|
23
23
|
- Guardfile
|
24
24
|
- ynab_convert.gemspec
|
25
|
-
-
|
25
|
+
- "spec/**/*_spec.rb"
|
26
26
|
|
27
27
|
Metrics/MethodLength:
|
28
28
|
Max: 25
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-
|
1
|
+
ruby-3.3.9
|
data/Gemfile
CHANGED
@@ -4,3 +4,18 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in ynab_convert.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
gem 'bundler', '~> 2.0'
|
9
|
+
gem 'guard-rspec'
|
10
|
+
gem 'guard-rubocop'
|
11
|
+
gem 'pry-byebug'
|
12
|
+
gem 'rake', '~> 13.0'
|
13
|
+
gem 'rspec', '~> 3.0'
|
14
|
+
gem 'rspec-core'
|
15
|
+
gem 'rubocop', '~> 1.63'
|
16
|
+
gem 'rubocop-rake', '~> 0.6'
|
17
|
+
gem 'rubocop-rspec', '~> 3.7'
|
18
|
+
gem 'simplecov'
|
19
|
+
gem 'solargraph', '~> 0.50'
|
20
|
+
gem 'vcr'
|
21
|
+
gem 'webmock'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ynab_convert (
|
4
|
+
ynab_convert (3.0.0)
|
5
|
+
csv
|
5
6
|
i18n
|
6
7
|
slop
|
7
8
|
timecop
|
@@ -9,26 +10,34 @@ PATH
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
addressable (2.8.
|
13
|
-
public_suffix (>= 2.0.2, <
|
14
|
-
ast (2.4.
|
15
|
-
backport (1.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
addressable (2.8.7)
|
14
|
+
public_suffix (>= 2.0.2, < 7.0)
|
15
|
+
ast (2.4.3)
|
16
|
+
backport (1.2.0)
|
17
|
+
base64 (0.3.0)
|
18
|
+
benchmark (0.4.1)
|
19
|
+
bigdecimal (3.3.1)
|
20
|
+
byebug (12.0.0)
|
21
|
+
coderay (1.1.3)
|
22
|
+
concurrent-ruby (1.3.5)
|
23
|
+
crack (1.0.0)
|
24
|
+
bigdecimal
|
20
25
|
rexml
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
csv (3.3.5)
|
27
|
+
diff-lcs (1.6.2)
|
28
|
+
docile (1.4.1)
|
29
|
+
ffi (1.17.2)
|
30
|
+
formatador (1.2.1)
|
31
|
+
reline
|
32
|
+
guard (2.19.1)
|
26
33
|
formatador (>= 0.2.4)
|
27
34
|
listen (>= 2.7, < 4.0)
|
35
|
+
logger (~> 1.6)
|
28
36
|
lumberjack (>= 1.0.12, < 2.0)
|
29
37
|
nenv (~> 0.1)
|
30
38
|
notiffany (~> 0.0)
|
31
|
-
|
39
|
+
ostruct (~> 0.6)
|
40
|
+
pry (>= 0.13.0)
|
32
41
|
shellany (~> 0.0)
|
33
42
|
thor (>= 0.18.1)
|
34
43
|
guard-compat (1.2.1)
|
@@ -36,107 +45,143 @@ GEM
|
|
36
45
|
guard (~> 2.1)
|
37
46
|
guard-compat (~> 1.1)
|
38
47
|
rspec (>= 2.99.0, < 4.0)
|
39
|
-
guard-rubocop (1.
|
48
|
+
guard-rubocop (1.5.0)
|
40
49
|
guard (~> 2.0)
|
41
|
-
rubocop (
|
42
|
-
hashdiff (1.
|
43
|
-
|
44
|
-
i18n (1.12.0)
|
50
|
+
rubocop (< 2.0)
|
51
|
+
hashdiff (1.2.1)
|
52
|
+
i18n (1.14.7)
|
45
53
|
concurrent-ruby (~> 1.0)
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
io-console (0.8.1)
|
55
|
+
jaro_winkler (1.6.1)
|
56
|
+
json (2.15.1)
|
57
|
+
kramdown (2.5.1)
|
58
|
+
rexml (>= 3.3.9)
|
59
|
+
kramdown-parser-gfm (1.1.0)
|
60
|
+
kramdown (~> 2.0)
|
61
|
+
language_server-protocol (3.17.0.5)
|
62
|
+
lint_roller (1.1.0)
|
63
|
+
listen (3.9.0)
|
49
64
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
50
65
|
rb-inotify (~> 0.9, >= 0.9.10)
|
51
|
-
|
52
|
-
|
53
|
-
|
66
|
+
logger (1.7.0)
|
67
|
+
lumberjack (1.4.2)
|
68
|
+
method_source (1.1.0)
|
69
|
+
mini_portile2 (2.8.9)
|
54
70
|
nenv (0.3.0)
|
55
|
-
nokogiri (1.
|
56
|
-
mini_portile2 (~> 2.8.
|
71
|
+
nokogiri (1.18.10)
|
72
|
+
mini_portile2 (~> 2.8.2)
|
57
73
|
racc (~> 1.4)
|
58
74
|
notiffany (0.1.3)
|
59
75
|
nenv (~> 0.1)
|
60
76
|
shellany (~> 0.0)
|
61
|
-
|
62
|
-
|
77
|
+
observer (0.1.2)
|
78
|
+
ostruct (0.6.3)
|
79
|
+
parallel (1.27.0)
|
80
|
+
parser (3.3.9.0)
|
63
81
|
ast (~> 2.4.1)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
82
|
+
racc
|
83
|
+
prism (1.6.0)
|
84
|
+
pry (0.15.2)
|
85
|
+
coderay (~> 1.1)
|
86
|
+
method_source (~> 1.0)
|
87
|
+
pry-byebug (3.11.0)
|
88
|
+
byebug (~> 12.0)
|
89
|
+
pry (>= 0.13, < 0.16)
|
90
|
+
public_suffix (6.0.2)
|
91
|
+
racc (1.8.1)
|
72
92
|
rainbow (3.1.1)
|
73
|
-
rake (13.0
|
74
|
-
rb-fsevent (0.
|
75
|
-
rb-inotify (0.
|
93
|
+
rake (13.3.0)
|
94
|
+
rb-fsevent (0.11.2)
|
95
|
+
rb-inotify (0.11.1)
|
76
96
|
ffi (~> 1.0)
|
77
|
-
|
78
|
-
|
97
|
+
rbs (3.9.5)
|
98
|
+
logger
|
99
|
+
regexp_parser (2.11.3)
|
100
|
+
reline (0.6.2)
|
101
|
+
io-console (~> 0.5)
|
102
|
+
reverse_markdown (3.0.0)
|
79
103
|
nokogiri
|
80
|
-
rexml (3.
|
81
|
-
rspec (3.
|
82
|
-
rspec-core (~> 3.
|
83
|
-
rspec-expectations (~> 3.
|
84
|
-
rspec-mocks (~> 3.
|
85
|
-
rspec-core (3.
|
86
|
-
rspec-support (~> 3.
|
87
|
-
rspec-expectations (3.
|
104
|
+
rexml (3.4.4)
|
105
|
+
rspec (3.13.2)
|
106
|
+
rspec-core (~> 3.13.0)
|
107
|
+
rspec-expectations (~> 3.13.0)
|
108
|
+
rspec-mocks (~> 3.13.0)
|
109
|
+
rspec-core (3.13.6)
|
110
|
+
rspec-support (~> 3.13.0)
|
111
|
+
rspec-expectations (3.13.5)
|
88
112
|
diff-lcs (>= 1.2.0, < 2.0)
|
89
|
-
rspec-support (~> 3.
|
90
|
-
rspec-mocks (3.
|
113
|
+
rspec-support (~> 3.13.0)
|
114
|
+
rspec-mocks (3.13.6)
|
91
115
|
diff-lcs (>= 1.2.0, < 2.0)
|
92
|
-
rspec-support (~> 3.
|
93
|
-
rspec-support (3.
|
94
|
-
rubocop (
|
116
|
+
rspec-support (~> 3.13.0)
|
117
|
+
rspec-support (3.13.6)
|
118
|
+
rubocop (1.81.6)
|
119
|
+
json (~> 2.3)
|
120
|
+
language_server-protocol (~> 3.17.0.2)
|
121
|
+
lint_roller (~> 1.1.0)
|
95
122
|
parallel (~> 1.10)
|
96
|
-
parser (>=
|
123
|
+
parser (>= 3.3.0.2)
|
97
124
|
rainbow (>= 2.2.2, < 4.0)
|
98
|
-
regexp_parser (>=
|
99
|
-
|
100
|
-
rubocop-ast (>= 0.6.0)
|
125
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
126
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
101
127
|
ruby-progressbar (~> 1.7)
|
102
|
-
unicode-display_width (>=
|
103
|
-
rubocop-ast (1.
|
104
|
-
parser (>=
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
rubocop (
|
109
|
-
|
110
|
-
|
128
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
129
|
+
rubocop-ast (1.47.1)
|
130
|
+
parser (>= 3.3.7.2)
|
131
|
+
prism (~> 1.4)
|
132
|
+
rubocop-rake (0.7.1)
|
133
|
+
lint_roller (~> 1.1)
|
134
|
+
rubocop (>= 1.72.1)
|
135
|
+
rubocop-rspec (3.7.0)
|
136
|
+
lint_roller (~> 1.1)
|
137
|
+
rubocop (~> 1.72, >= 1.72.1)
|
138
|
+
ruby-progressbar (1.13.0)
|
111
139
|
shellany (0.0.1)
|
112
|
-
simplecov (0.
|
140
|
+
simplecov (0.22.0)
|
113
141
|
docile (~> 1.1)
|
114
|
-
|
115
|
-
|
116
|
-
simplecov-html (0.
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
142
|
+
simplecov-html (~> 0.11)
|
143
|
+
simplecov_json_formatter (~> 0.1)
|
144
|
+
simplecov-html (0.13.2)
|
145
|
+
simplecov_json_formatter (0.1.4)
|
146
|
+
slop (4.10.1)
|
147
|
+
solargraph (0.57.0)
|
148
|
+
backport (~> 1.2)
|
149
|
+
benchmark (~> 0.4)
|
150
|
+
bundler (~> 2.0)
|
151
|
+
diff-lcs (~> 1.4)
|
152
|
+
jaro_winkler (~> 1.6, >= 1.6.1)
|
153
|
+
kramdown (~> 2.3)
|
154
|
+
kramdown-parser-gfm (~> 1.1)
|
155
|
+
logger (~> 1.6)
|
156
|
+
observer (~> 0.1)
|
157
|
+
ostruct (~> 0.6)
|
158
|
+
parser (~> 3.0)
|
159
|
+
prism (~> 1.4)
|
160
|
+
rbs (>= 3.6.1, <= 4.0.0.dev.4)
|
161
|
+
reverse_markdown (~> 3.0)
|
162
|
+
rubocop (~> 1.76)
|
163
|
+
thor (~> 1.0)
|
128
164
|
tilt (~> 2.0)
|
129
|
-
yard (~> 0.9)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
165
|
+
yard (~> 0.9, >= 0.9.24)
|
166
|
+
yard-activesupport-concern (~> 0.0)
|
167
|
+
yard-solargraph (~> 0.1)
|
168
|
+
thor (1.4.0)
|
169
|
+
tilt (2.6.1)
|
170
|
+
timecop (0.9.10)
|
171
|
+
unicode-display_width (3.2.0)
|
172
|
+
unicode-emoji (~> 4.1)
|
173
|
+
unicode-emoji (4.1.0)
|
174
|
+
vcr (6.3.1)
|
175
|
+
base64
|
176
|
+
webmock (3.25.1)
|
136
177
|
addressable (>= 2.8.0)
|
137
178
|
crack (>= 0.3.2)
|
138
179
|
hashdiff (>= 0.4.0, < 2.0.0)
|
139
|
-
yard (0.9.
|
180
|
+
yard (0.9.37)
|
181
|
+
yard-activesupport-concern (0.0.1)
|
182
|
+
yard (>= 0.8)
|
183
|
+
yard-solargraph (0.1.0)
|
184
|
+
yard (~> 0.9)
|
140
185
|
|
141
186
|
PLATFORMS
|
142
187
|
ruby
|
@@ -149,11 +194,11 @@ DEPENDENCIES
|
|
149
194
|
rake (~> 13.0)
|
150
195
|
rspec (~> 3.0)
|
151
196
|
rspec-core
|
152
|
-
rubocop
|
153
|
-
rubocop-rake
|
154
|
-
rubocop-rspec
|
197
|
+
rubocop (~> 1.63)
|
198
|
+
rubocop-rake (~> 0.6)
|
199
|
+
rubocop-rspec (~> 3.7)
|
155
200
|
simplecov
|
156
|
-
solargraph
|
201
|
+
solargraph (~> 0.50)
|
157
202
|
vcr
|
158
203
|
webmock
|
159
204
|
ynab_convert!
|
data/Guardfile
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
#
|
19
19
|
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
20
20
|
|
21
|
-
#
|
21
|
+
# NOTE: The cmd option is now required due to the increasing number of ways
|
22
22
|
# rspec may be run, below are examples of the most common uses.
|
23
23
|
# * bundler: 'bundle exec rspec'
|
24
24
|
# * bundler binstubs: 'bin/rspec'
|
@@ -49,7 +49,7 @@ group :red_green_refactor, halt_on_fail: true do
|
|
49
49
|
guard :rubocop, cli: ['--auto-correct-all', '--display-cop-names'] do
|
50
50
|
watch('Gemfile')
|
51
51
|
watch('Rakefile')
|
52
|
-
watch('bin/
|
52
|
+
watch('bin/ynab_convert')
|
53
53
|
watch(/.+\.rb$/)
|
54
54
|
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
55
55
|
end
|
@@ -49,8 +49,9 @@ module APIClients
|
|
49
49
|
|
50
50
|
# @param date [Date] The date to show in the error message
|
51
51
|
def handle_date_out_of_bounds(date)
|
52
|
-
error_message = "#{date} is out of the currency-api available date "\
|
53
|
-
|
52
|
+
error_message = "#{date} is out of the currency-api available date " \
|
53
|
+
"range (#{@available_date_range[:min]}–" \
|
54
|
+
"#{@available_date_range[:max]})"
|
54
55
|
|
55
56
|
raise Errno::EDOM, error_message
|
56
57
|
end
|
@@ -12,7 +12,7 @@ module Documents
|
|
12
12
|
# @param csv_import_options [CSV::DEFAULT_OPTIONS] options describing
|
13
13
|
# the particular CSV flavour (column separator, etc). Any
|
14
14
|
# CSV::DEFAULT_OPTIONS is valid.
|
15
|
-
def initialize(filepath:, csv_import_options:
|
15
|
+
def initialize(filepath:, csv_import_options: {})
|
16
16
|
validate(filepath)
|
17
17
|
|
18
18
|
default_options = CSV::DEFAULT_OPTIONS.merge(converters: %i[numeric
|
@@ -6,9 +6,9 @@ module Documents
|
|
6
6
|
class YNAB4File
|
7
7
|
attr_reader :csv_export_options
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@format = format
|
11
|
-
@institution_name = institution_name
|
9
|
+
def initialize(options = {})
|
10
|
+
@format = options[:format] || :flows
|
11
|
+
@institution_name = options[:institution_name]
|
12
12
|
@csv_export_options = {
|
13
13
|
converters: %i[numeric date],
|
14
14
|
force_quotes: true,
|
@@ -10,7 +10,7 @@ module Documents
|
|
10
10
|
# class since files are otherwise loaded in alphabetical order
|
11
11
|
require File.join(__dir__, 'documents', "#{d}s", "#{d}.rb")
|
12
12
|
|
13
|
-
Dir[File.join(__dir__, 'documents', "#{d}s", '*.rb')].
|
13
|
+
Dir[File.join(__dir__, 'documents', "#{d}s", '*.rb')].each do |file|
|
14
14
|
require file
|
15
15
|
end
|
16
16
|
end
|
data/lib/ynab_convert/logger.rb
CHANGED
@@ -5,10 +5,11 @@ require 'logger'
|
|
5
5
|
# Add logging to classes
|
6
6
|
module YnabLogger
|
7
7
|
def logger
|
8
|
-
@logger
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
@logger ||= begin
|
9
|
+
logger = Logger.new($stderr)
|
10
|
+
logger.level = Logger::FATAL
|
11
|
+
logger.level = Logger::DEBUG if ENV['YNAB_CONVERT_DEBUG'] == 'true'
|
12
|
+
logger
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
@@ -18,13 +18,13 @@ module Processors
|
|
18
18
|
# converted value. See CSV::Converters.
|
19
19
|
# @param transformers [Array<Transformers::Transformer>] The Transformers
|
20
20
|
# to run in sequense
|
21
|
-
def initialize(
|
22
|
-
@statement = statement
|
23
|
-
@transformers = transformers
|
21
|
+
def initialize(options = {})
|
22
|
+
@statement = options[:statement]
|
23
|
+
@transformers = options[:transformers]
|
24
24
|
@validators = [::Validators::YNAB4Row]
|
25
25
|
@uid = rand(36**8).to_s(36)
|
26
|
-
@ynab4_file = ynab4_file
|
27
|
-
register_converters(converters)
|
26
|
+
@ynab4_file = options[:ynab4_file]
|
27
|
+
register_converters(options[:converters] || {})
|
28
28
|
end
|
29
29
|
|
30
30
|
def to_ynab!
|
@@ -9,7 +9,7 @@ module Transformers
|
|
9
9
|
class N26 < Enhancer
|
10
10
|
def initialize
|
11
11
|
@api_client = APIClients::CurrencyAPI.new
|
12
|
-
super
|
12
|
+
super
|
13
13
|
end
|
14
14
|
|
15
15
|
# @param row [CSV::Row] The YNAB4 formatted row to enhance
|
@@ -35,8 +35,8 @@ module Transformers
|
|
35
35
|
enhanced_row = row.dup
|
36
36
|
enhanced_row[amount_index] = converted_amount
|
37
37
|
# Put original amount and currency in Memo
|
38
|
-
memo_line = 'Original amount: '\
|
39
|
-
|
38
|
+
memo_line = 'Original amount: ' \
|
39
|
+
"#{format('%<amount>.2f', amount: amount)} #{base_currency}"
|
40
40
|
enhanced_row[2] = memo_line
|
41
41
|
enhanced_row
|
42
42
|
end
|
@@ -8,7 +8,7 @@ module Transformers
|
|
8
8
|
@api_client = APIClients::CurrencyAPI.new
|
9
9
|
@indices = { date: 0, amount: 3, memo: 2 }
|
10
10
|
|
11
|
-
super
|
11
|
+
super
|
12
12
|
end
|
13
13
|
|
14
14
|
def run(ynab_row)
|
@@ -32,8 +32,8 @@ module Transformers
|
|
32
32
|
unless converted_amount.nil?
|
33
33
|
enhanced_row[@indices[:amount]] = converted_amount
|
34
34
|
# Put original amount and currency in Memo
|
35
|
-
enhanced_row[@indices[:memo]] = 'Original amount: '\
|
36
|
-
|
35
|
+
enhanced_row[@indices[:memo]] = 'Original amount: ' \
|
36
|
+
"#{metadata[:original_amount]}"
|
37
37
|
end
|
38
38
|
|
39
39
|
# If not, clear the metadata from the Memo field
|
@@ -18,7 +18,7 @@ module Transformers
|
|
18
18
|
# (if using the :flows format)
|
19
19
|
# @option headers_indices [Array<Numeric>] :inflow transaction inflow (if
|
20
20
|
# using the :flows format)
|
21
|
-
def initialize(
|
21
|
+
def initialize(headers_indices = {})
|
22
22
|
default_values = {
|
23
23
|
memo: [] # The Memo field tends to be empty for most institutions
|
24
24
|
}
|
@@ -11,7 +11,7 @@ module Transformers
|
|
11
11
|
# class since files are otherwise loaded in alphabetical order
|
12
12
|
require File.join(__dir__, 'transformers', "#{t}s", "#{t}.rb")
|
13
13
|
|
14
|
-
Dir[File.join(__dir__, 'transformers', "#{t}s", '*.rb')].
|
14
|
+
Dir[File.join(__dir__, 'transformers', "#{t}s", '*.rb')].each do |file|
|
15
15
|
require file
|
16
16
|
end
|
17
17
|
end
|
data/lib/ynab_convert/version.rb
CHANGED
data/lib/ynab_convert.rb
CHANGED
@@ -4,6 +4,7 @@ require 'ynab_convert/version'
|
|
4
4
|
require 'slop'
|
5
5
|
require 'ynab_convert/logger'
|
6
6
|
require 'core_extensions/string'
|
7
|
+
require 'ynab_convert/processors'
|
7
8
|
require 'byebug' if ENV['YNAB_CONVERT_DEBUG']
|
8
9
|
|
9
10
|
# FIXME: The architecture in here is not the greatest... It should be
|
@@ -13,9 +14,9 @@ require 'byebug' if ENV['YNAB_CONVERT_DEBUG']
|
|
13
14
|
module YnabConvert
|
14
15
|
# Metadata about the gem
|
15
16
|
class Metadata
|
16
|
-
def
|
17
|
-
puts '
|
18
|
-
'can be imported into YNAB 4.'
|
17
|
+
def short_desc
|
18
|
+
puts 'A utility to convert online banking CSV files to a format that ' \
|
19
|
+
'can be imported into YNAB 4.'
|
19
20
|
end
|
20
21
|
|
21
22
|
def version
|
@@ -24,7 +25,7 @@ module YnabConvert
|
|
24
25
|
end
|
25
26
|
|
26
27
|
# Operations on the CSV file to convert
|
27
|
-
class
|
28
|
+
class Converter
|
28
29
|
include YnabLogger
|
29
30
|
|
30
31
|
# @option opts [String] :file The filename or path to the file
|
@@ -33,14 +34,9 @@ module YnabConvert
|
|
33
34
|
def initialize(opts)
|
34
35
|
logger.debug opts.to_h
|
35
36
|
@file = opts[:file]
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
filepath: @file
|
40
|
-
)
|
41
|
-
rescue Errno::ENOENT
|
42
|
-
handle_file_not_found
|
43
|
-
end
|
37
|
+
@processor = opts[:processor].new(
|
38
|
+
filepath: @file
|
39
|
+
)
|
44
40
|
end
|
45
41
|
|
46
42
|
# Converts @file to YNAB4 format and writes it to disk
|
@@ -49,12 +45,6 @@ module YnabConvert
|
|
49
45
|
logger.debug "Processing `#{@file}' through `#{@processor.class.name}'"
|
50
46
|
@processor.to_ynab!
|
51
47
|
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def file_not_found_message
|
56
|
-
raise Errno::ENOENT, "File `#{@file}' not found or not accessible."
|
57
|
-
end
|
58
48
|
end
|
59
49
|
|
60
50
|
# The command line interface methods
|
@@ -65,14 +55,14 @@ module YnabConvert
|
|
65
55
|
def initialize
|
66
56
|
@metadata = Metadata.new
|
67
57
|
@options = parse_argv
|
68
|
-
return unless no_options_given
|
58
|
+
return unless no_options_given?
|
69
59
|
|
70
60
|
show_usage
|
71
61
|
exit
|
72
62
|
end
|
73
63
|
|
74
64
|
def start
|
75
|
-
@file =
|
65
|
+
@file = Converter.new opts
|
76
66
|
logger.debug "Using processor `#{@options[:institution]}' => #{processor}"
|
77
67
|
@file.to_ynab!
|
78
68
|
end
|
@@ -95,8 +85,8 @@ module YnabConvert
|
|
95
85
|
puts @metadata.version
|
96
86
|
exit
|
97
87
|
end
|
98
|
-
o.string '-i', '--institution', 'name of the financial institution '\
|
99
|
-
|
88
|
+
o.string '-i', '--institution', 'name of the financial institution ' \
|
89
|
+
'that generated the file to convert'
|
100
90
|
o.string '-f', '--file', 'path to the csv file to convert'
|
101
91
|
end
|
102
92
|
end
|
@@ -124,7 +114,7 @@ module YnabConvert
|
|
124
114
|
processor_class_name.split('::').inject(Object) { |o, c| o.const_get c }
|
125
115
|
end
|
126
116
|
|
127
|
-
def no_options_given
|
117
|
+
def no_options_given?
|
128
118
|
@options[:institution].nil? || @options[:file].nil?
|
129
119
|
end
|
130
120
|
|
@@ -134,10 +124,10 @@ module YnabConvert
|
|
134
124
|
end
|
135
125
|
|
136
126
|
def show_unknown_institution_message
|
137
|
-
warn 'Could not find any processor for the institution '\
|
138
|
-
|
139
|
-
|
140
|
-
|
127
|
+
warn 'Could not find any processor for the institution ' \
|
128
|
+
"`#{@options[:institution]}'. If it's not a typo, consider " \
|
129
|
+
'contributing a new processor (see https://github.com/coaxial/' \
|
130
|
+
'ynab_convert#contributing to get started).'
|
141
131
|
end
|
142
132
|
end
|
143
133
|
end
|
data/ynab_convert.gemspec
CHANGED
@@ -15,30 +15,27 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.license = 'MIT'
|
16
16
|
spec.description = <<~DESC
|
17
17
|
Utility to convert CSV statements into the YNAB4 format for easier
|
18
|
-
|
18
|
+
transaction import. Supports several banks and can easily be extended to
|
19
19
|
add more.
|
20
20
|
DESC
|
21
21
|
|
22
|
-
spec.required_ruby_version = '~>
|
22
|
+
spec.required_ruby_version = '~> 3.3'
|
23
23
|
|
24
24
|
spec.metadata = {
|
25
25
|
'bug_tracker_uri' => 'https://github.com/coaxial/ynab_convert/issues',
|
26
26
|
'documentation_uri' => 'https://rubydoc.info/github/coaxial/ynab_convert/master',
|
27
27
|
'homepage_uri' => 'https://github.com/coaxial/ynab_convert',
|
28
|
-
'source_code_uri' => 'https://github.com/coaxial/ynab_convert'
|
28
|
+
'source_code_uri' => 'https://github.com/coaxial/ynab_convert',
|
29
|
+
'rubygems_mfa_required' => 'true',
|
30
|
+
'allowed_push_host' => 'https://rubygems.org'
|
29
31
|
}
|
30
|
-
spec.post_install_message = 'Happy
|
32
|
+
spec.post_install_message = 'Happy budgeting!'
|
31
33
|
|
32
34
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
33
35
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
34
|
-
|
35
|
-
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
36
|
-
|
37
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
38
|
-
spec.metadata['source_code_uri'] = 'https://github.com/coaxial/ynab_convert'
|
39
|
-
else
|
36
|
+
unless spec.respond_to?(:metadata)
|
40
37
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
41
|
-
|
38
|
+
'public gem pushes.'
|
42
39
|
end
|
43
40
|
|
44
41
|
# Specify which files should be added to the gem when it is released.
|
@@ -50,21 +47,7 @@ Gem::Specification.new do |spec|
|
|
50
47
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
51
48
|
spec.require_paths = ['lib']
|
52
49
|
|
53
|
-
spec.
|
54
|
-
spec.add_development_dependency 'guard-rspec'
|
55
|
-
spec.add_development_dependency 'guard-rubocop'
|
56
|
-
spec.add_development_dependency 'pry-byebug'
|
57
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
58
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
59
|
-
spec.add_development_dependency 'rspec-core'
|
60
|
-
spec.add_development_dependency 'rubocop'
|
61
|
-
spec.add_development_dependency 'rubocop-rake'
|
62
|
-
spec.add_development_dependency 'rubocop-rspec'
|
63
|
-
spec.add_development_dependency 'simplecov'
|
64
|
-
spec.add_development_dependency 'solargraph'
|
65
|
-
spec.add_development_dependency 'vcr'
|
66
|
-
spec.add_development_dependency 'webmock'
|
67
|
-
|
50
|
+
spec.add_dependency 'csv'
|
68
51
|
spec.add_dependency 'i18n'
|
69
52
|
spec.add_dependency 'slop'
|
70
53
|
spec.add_dependency 'timecop'
|
metadata
CHANGED
@@ -1,205 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ynab_convert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- coaxial
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2.0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: guard-rspec
|
14
|
+
name: csv
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '0'
|
34
|
-
type: :
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: guard-rubocop
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: pry-byebug
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '13.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '13.0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '3.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '3.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rspec-core
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rubocop-rake
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rubocop-rspec
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: simplecov
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - ">="
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - ">="
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '0'
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: solargraph
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - ">="
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
type: :development
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: vcr
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
195
|
-
- !ruby/object:Gem::Dependency
|
196
|
-
name: webmock
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
198
|
-
requirements:
|
199
|
-
- - ">="
|
200
|
-
- !ruby/object:Gem::Version
|
201
|
-
version: '0'
|
202
|
-
type: :development
|
20
|
+
type: :runtime
|
203
21
|
prerelease: false
|
204
22
|
version_requirements: !ruby/object:Gem::Requirement
|
205
23
|
requirements:
|
@@ -250,7 +68,7 @@ dependencies:
|
|
250
68
|
version: '0'
|
251
69
|
description: |
|
252
70
|
Utility to convert CSV statements into the YNAB4 format for easier
|
253
|
-
|
71
|
+
transaction import. Supports several banks and can easily be extended to
|
254
72
|
add more.
|
255
73
|
email:
|
256
74
|
- hi@64b.it
|
@@ -261,6 +79,7 @@ executables:
|
|
261
79
|
extensions: []
|
262
80
|
extra_rdoc_files: []
|
263
81
|
files:
|
82
|
+
- ".github/workflows/merge-gatekeeper.yml"
|
264
83
|
- ".github/workflows/publish.yml"
|
265
84
|
- ".github/workflows/test.yml"
|
266
85
|
- ".gitignore"
|
@@ -327,8 +146,9 @@ metadata:
|
|
327
146
|
documentation_uri: https://rubydoc.info/github/coaxial/ynab_convert/master
|
328
147
|
homepage_uri: https://github.com/coaxial/ynab_convert
|
329
148
|
source_code_uri: https://github.com/coaxial/ynab_convert
|
149
|
+
rubygems_mfa_required: 'true'
|
330
150
|
allowed_push_host: https://rubygems.org
|
331
|
-
post_install_message: Happy
|
151
|
+
post_install_message: Happy budgeting!
|
332
152
|
rdoc_options: []
|
333
153
|
require_paths:
|
334
154
|
- lib
|
@@ -336,15 +156,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
336
156
|
requirements:
|
337
157
|
- - "~>"
|
338
158
|
- !ruby/object:Gem::Version
|
339
|
-
version: '
|
159
|
+
version: '3.3'
|
340
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
341
161
|
requirements:
|
342
162
|
- - ">="
|
343
163
|
- !ruby/object:Gem::Version
|
344
164
|
version: '0'
|
345
165
|
requirements: []
|
346
|
-
rubygems_version: 3.
|
347
|
-
signing_key:
|
166
|
+
rubygems_version: 3.5.22
|
167
|
+
signing_key:
|
348
168
|
specification_version: 4
|
349
169
|
summary: Convert online banking CSV files to YNAB 4 format.
|
350
170
|
test_files: []
|