ynab_convert 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []