ynab_convert 0.1.0.pre
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/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +18 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.solargraph.yml +15 -0
- data/.travis.yml +18 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +135 -0
- data/Guardfile +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +65 -0
- data/Rakefile +40 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bin/ynab_convert +29 -0
- data/lib/core_extensions/string.rb +17 -0
- data/lib/slop/symbol.rb +12 -0
- data/lib/ynab_convert/error.rb +6 -0
- data/lib/ynab_convert/logger.rb +14 -0
- data/lib/ynab_convert/processor/base.rb +171 -0
- data/lib/ynab_convert/processor/example.rb +124 -0
- data/lib/ynab_convert/processor/revolut.rb +103 -0
- data/lib/ynab_convert/processor/ubs_chequing.rb +101 -0
- data/lib/ynab_convert/processor/ubs_credit.rb +83 -0
- data/lib/ynab_convert/processors.rb +7 -0
- data/lib/ynab_convert/version.rb +5 -0
- data/lib/ynab_convert.rb +125 -0
- data/ynab_convert.gemspec +52 -0
- metadata +260 -0
data/lib/ynab_convert.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ynab_convert/version'
|
4
|
+
require 'slop'
|
5
|
+
require 'pry'
|
6
|
+
require 'ynab_convert/logger'
|
7
|
+
require 'core_extensions/string.rb'
|
8
|
+
|
9
|
+
# The application
|
10
|
+
module YnabConvert
|
11
|
+
# Metadata about the gem
|
12
|
+
class Metadata
|
13
|
+
def short_desc
|
14
|
+
puts 'An utility to convert online banking CSV files to a format that ' \
|
15
|
+
'can be imported into YNAB 4.'
|
16
|
+
end
|
17
|
+
|
18
|
+
def version
|
19
|
+
puts "YNAB Convert #{YnabConvert::VERSION}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Operations on the CSV file to convert
|
24
|
+
class File
|
25
|
+
include YnabLogger
|
26
|
+
|
27
|
+
# @option opts [String] :file The filename or path to the file
|
28
|
+
# @option opts [Processor] :processor The class to use for converting the
|
29
|
+
# CSV file
|
30
|
+
def initialize(opts)
|
31
|
+
logger.debug opts.to_h
|
32
|
+
@file = opts[:file]
|
33
|
+
|
34
|
+
begin
|
35
|
+
@processor = opts[:processor].new(
|
36
|
+
file: @file
|
37
|
+
)
|
38
|
+
rescue Errno::ENOENT
|
39
|
+
handle_file_not_found
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Converts @file to YNAB4 format and writes it to disk
|
44
|
+
# @return [String] The path to the YNAB4 formatted CSV file created
|
45
|
+
def to_ynab!
|
46
|
+
logger.debug "Processing `#{@file}' through `#{@processor.class.name}'"
|
47
|
+
@processor.to_ynab!
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def file_not_found_message
|
53
|
+
raise Errno::ENOENT, "File `#{@file}' not found or not accessible."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# The command line interface methods
|
58
|
+
class CLI
|
59
|
+
include YnabLogger
|
60
|
+
include CoreExtensions::String::Inflections
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
@metadata = Metadata.new
|
64
|
+
@options = parse_argv
|
65
|
+
return unless no_options_given
|
66
|
+
|
67
|
+
show_usage
|
68
|
+
exit
|
69
|
+
end
|
70
|
+
|
71
|
+
def start
|
72
|
+
@file = File.new opts
|
73
|
+
logger.debug "Using processor `#{@options[:institution]}' => #{processor}"
|
74
|
+
@file.to_ynab!
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def opts
|
80
|
+
{ file: @options[:file], processor: processor }
|
81
|
+
rescue NameError => e
|
82
|
+
raise e unless e.message.match(/#{processor_class_name}/)
|
83
|
+
|
84
|
+
logger.debug "#{@options.to_h}, #{processor_class_name}"
|
85
|
+
show_unknown_institution_message
|
86
|
+
exit false
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_argv
|
90
|
+
Slop.parse do |o|
|
91
|
+
o.on '-v', '--version', 'print the version' do
|
92
|
+
puts @metadata.version
|
93
|
+
exit
|
94
|
+
end
|
95
|
+
o.string '-i', '--institution', 'name of the financial institution '\
|
96
|
+
'that generated the file to convert'
|
97
|
+
o.string '-f', '--file', 'path to the csv file to convert'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def processor_class_name
|
102
|
+
"Processor::#{@options[:institution].camel_case}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def processor
|
106
|
+
processor_class_name.split('::').inject(Object) { |o, c| o.const_get c }
|
107
|
+
end
|
108
|
+
|
109
|
+
def no_options_given
|
110
|
+
@options[:institution].nil? || @options[:file].nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
def show_usage
|
114
|
+
puts @metadata.short_desc
|
115
|
+
puts @options
|
116
|
+
end
|
117
|
+
|
118
|
+
def show_unknown_institution_message
|
119
|
+
warn 'Could not find any processor for the institution '\
|
120
|
+
"`#{@options[:institution]}'. If it's not a typo, consider "\
|
121
|
+
'contributing a new processor (see https://github.com/coaxial/'\
|
122
|
+
'ynab_convert#contributing to get started).'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'ynab_convert/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'ynab_convert'
|
9
|
+
spec.version = YnabConvert::VERSION
|
10
|
+
spec.authors = ['coaxial']
|
11
|
+
spec.email = ['hi@64b.it']
|
12
|
+
|
13
|
+
spec.summary = 'Convert online banking CSV files to YNAB 4 format.'
|
14
|
+
spec.homepage = 'https://github.com/coaxial/ynab_convert'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
|
22
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
23
|
+
spec.metadata['source_code_uri'] = 'https://github.com/coaxial/ynab_convert'
|
24
|
+
else
|
25
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
26
|
+
'public gem pushes.'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
spec.bindir = 'bin'
|
35
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ['lib']
|
37
|
+
|
38
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
39
|
+
spec.add_development_dependency 'guard-rspec'
|
40
|
+
spec.add_development_dependency 'guard-rubocop'
|
41
|
+
spec.add_development_dependency 'pry-byebug'
|
42
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
43
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
44
|
+
spec.add_development_dependency 'rspec-core'
|
45
|
+
spec.add_development_dependency 'rubocop'
|
46
|
+
spec.add_development_dependency 'rubocop-rake'
|
47
|
+
spec.add_development_dependency 'simplecov'
|
48
|
+
spec.add_development_dependency 'solargraph'
|
49
|
+
|
50
|
+
spec.add_dependency 'i18n'
|
51
|
+
spec.add_dependency 'slop'
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ynab_convert
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- coaxial
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
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
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: simplecov
|
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: solargraph
|
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: i18n
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
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: slop
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
description:
|
196
|
+
email:
|
197
|
+
- hi@64b.it
|
198
|
+
executables:
|
199
|
+
- console
|
200
|
+
- setup
|
201
|
+
- ynab_convert
|
202
|
+
extensions: []
|
203
|
+
extra_rdoc_files: []
|
204
|
+
files:
|
205
|
+
- ".gitignore"
|
206
|
+
- ".rspec"
|
207
|
+
- ".rubocop.yml"
|
208
|
+
- ".ruby-gemset"
|
209
|
+
- ".ruby-version"
|
210
|
+
- ".solargraph.yml"
|
211
|
+
- ".travis.yml"
|
212
|
+
- Gemfile
|
213
|
+
- Gemfile.lock
|
214
|
+
- Guardfile
|
215
|
+
- LICENSE.txt
|
216
|
+
- README.md
|
217
|
+
- Rakefile
|
218
|
+
- bin/console
|
219
|
+
- bin/setup
|
220
|
+
- bin/ynab_convert
|
221
|
+
- lib/core_extensions/string.rb
|
222
|
+
- lib/slop/symbol.rb
|
223
|
+
- lib/ynab_convert.rb
|
224
|
+
- lib/ynab_convert/error.rb
|
225
|
+
- lib/ynab_convert/logger.rb
|
226
|
+
- lib/ynab_convert/processor/base.rb
|
227
|
+
- lib/ynab_convert/processor/example.rb
|
228
|
+
- lib/ynab_convert/processor/revolut.rb
|
229
|
+
- lib/ynab_convert/processor/ubs_chequing.rb
|
230
|
+
- lib/ynab_convert/processor/ubs_credit.rb
|
231
|
+
- lib/ynab_convert/processors.rb
|
232
|
+
- lib/ynab_convert/version.rb
|
233
|
+
- ynab_convert.gemspec
|
234
|
+
homepage: https://github.com/coaxial/ynab_convert
|
235
|
+
licenses:
|
236
|
+
- MIT
|
237
|
+
metadata:
|
238
|
+
allowed_push_host: https://rubygems.org
|
239
|
+
homepage_uri: https://github.com/coaxial/ynab_convert
|
240
|
+
source_code_uri: https://github.com/coaxial/ynab_convert
|
241
|
+
post_install_message:
|
242
|
+
rdoc_options: []
|
243
|
+
require_paths:
|
244
|
+
- lib
|
245
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
250
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - ">"
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 1.3.1
|
255
|
+
requirements: []
|
256
|
+
rubygems_version: 3.0.6
|
257
|
+
signing_key:
|
258
|
+
specification_version: 4
|
259
|
+
summary: Convert online banking CSV files to YNAB 4 format.
|
260
|
+
test_files: []
|