thefox-wallet 0.13.0 → 0.14.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/.gitlab-ci.yml +48 -0
- data/.travis.yml +2 -1
- data/Makefile +1 -1
- data/README.md +1 -1
- data/bin/wallet +1 -1
- data/lib/wallet/command.rb +2 -2
- data/lib/wallet/command_add.rb +1 -1
- data/lib/wallet/version.rb +2 -2
- data/lib/wallet/wallet.rb +140 -101
- data/thefox-wallet.gemspec +2 -2
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83c52b0183b88eef28a1e430a10266cbc926be80
|
4
|
+
data.tar.gz: 313cbc717b9eea9cb79444fb871bba40a6f9cad1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ceb2875dbc61138cc094ea6a8d0f755f599017869bd966ed42960efa863d712320b270d69c59807cf8539ef709cebdd1720f159cf03b97c1f6a69418e61216af
|
7
|
+
data.tar.gz: ce729b9878f78f02f923bc37c15a6ec3827dfb6e44069b12a68996fa0ff6c182da8c74e63c3aba9f04558ddae2fe9b3dba04b7a46027a968674f1f261214036b
|
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
before_script:
|
2
|
+
- ruby -v
|
3
|
+
- gem update --system
|
4
|
+
- gem install bundler -v '~>1.13'
|
5
|
+
- bundler --version
|
6
|
+
- make
|
7
|
+
|
8
|
+
stages:
|
9
|
+
- test
|
10
|
+
- release
|
11
|
+
|
12
|
+
test_21:
|
13
|
+
image: ruby:2.1
|
14
|
+
stage: test
|
15
|
+
environment: test
|
16
|
+
only:
|
17
|
+
- master
|
18
|
+
script:
|
19
|
+
- make test
|
20
|
+
|
21
|
+
test_22:
|
22
|
+
image: ruby:2.2
|
23
|
+
stage: test
|
24
|
+
environment: test
|
25
|
+
only:
|
26
|
+
- master
|
27
|
+
script:
|
28
|
+
- make test
|
29
|
+
|
30
|
+
test_23:
|
31
|
+
image: ruby:2.3
|
32
|
+
stage: test
|
33
|
+
environment: test
|
34
|
+
only:
|
35
|
+
- master
|
36
|
+
script:
|
37
|
+
- make test
|
38
|
+
|
39
|
+
release_gem:
|
40
|
+
image: ruby:2.3
|
41
|
+
stage: release
|
42
|
+
environment: release
|
43
|
+
only:
|
44
|
+
- tags
|
45
|
+
script:
|
46
|
+
- mkdir -p ~/.gem
|
47
|
+
- 'printf "%s\n:rubygems_api_key: %s" "---" "${RUBYGEMSORG_API_KEY}" > ~/.gem/credentials; chmod 0600 ~/.gem/credentials'
|
48
|
+
- make release
|
data/.travis.yml
CHANGED
data/Makefile
CHANGED
data/README.md
CHANGED
data/bin/wallet
CHANGED
data/lib/wallet/command.rb
CHANGED
@@ -8,8 +8,8 @@ module TheFox::Wallet
|
|
8
8
|
|
9
9
|
NAME = 'default'
|
10
10
|
|
11
|
-
def initialize(options =
|
12
|
-
@options = options ||
|
11
|
+
def initialize(options = Hash.new)
|
12
|
+
@options = options || Hash.new
|
13
13
|
@options[:wallet_path] ||= 'wallet'
|
14
14
|
@options[:entry_id] ||= nil
|
15
15
|
@options[:entry_title] ||= nil
|
data/lib/wallet/command_add.rb
CHANGED
@@ -64,7 +64,7 @@ module TheFox::Wallet
|
|
64
64
|
puts "category: #{@options[:entry_category]}"
|
65
65
|
puts "comment: '#{@options[:entry_comment]}'"
|
66
66
|
puts "force: #{@options[:force] ? 'YES' : 'NO'}"
|
67
|
-
puts "unique: #{is_unique ? 'YES' : 'NO'}"
|
67
|
+
puts "unique: #{is_unique ? 'YES' : 'NO'} (#{is_unique})"
|
68
68
|
|
69
69
|
entry = Entry.new(@options[:entry_id], @options[:entry_title], @options[:entry_date], @options[:entry_revenue], @options[:entry_expense], @options[:entry_category], @options[:entry_comment])
|
70
70
|
wallet = Wallet.new(@options[:wallet_path])
|
data/lib/wallet/version.rb
CHANGED
data/lib/wallet/wallet.rb
CHANGED
@@ -29,9 +29,12 @@ module TheFox
|
|
29
29
|
@tmp_path = File.expand_path('tmp', @dir_path)
|
30
30
|
|
31
31
|
@has_transaction = false
|
32
|
-
@transaction_files =
|
32
|
+
@transaction_files = Hash.new
|
33
33
|
|
34
34
|
@entries_by_ids = nil
|
35
|
+
@entries_index_file_path = File.expand_path('index.yml', @data_path)
|
36
|
+
@entries_index = Array.new
|
37
|
+
@entries_index_is_loaded = false
|
35
38
|
|
36
39
|
Signal.trap('SIGINT') do
|
37
40
|
puts
|
@@ -49,24 +52,27 @@ module TheFox
|
|
49
52
|
# puts "add, is_unique #{is_unique}"
|
50
53
|
# puts "add, entry_exist? #{entry_exist?(entry)}"
|
51
54
|
# puts
|
55
|
+
|
52
56
|
if is_unique && entry_exist?(entry)
|
53
57
|
return false
|
54
58
|
end
|
55
59
|
|
56
60
|
date = entry.date
|
57
61
|
date_s = date.to_s
|
58
|
-
dbfile_basename =
|
62
|
+
dbfile_basename = "month_#{date.strftime('%Y_%m')}.yml"
|
59
63
|
dbfile_path = File.expand_path(dbfile_basename, @data_path)
|
60
|
-
tmpfile_path = dbfile_path
|
64
|
+
tmpfile_path = "#{dbfile_path}.tmp"
|
61
65
|
file = {
|
62
66
|
'meta' => {
|
63
67
|
'version' => 1,
|
64
68
|
'created_at' => DateTime.now.to_s,
|
65
69
|
'updated_at' => DateTime.now.to_s,
|
66
70
|
},
|
67
|
-
'days' =>
|
71
|
+
'days' => Hash.new,
|
68
72
|
}
|
69
73
|
|
74
|
+
@entries_index << entry.id
|
75
|
+
|
70
76
|
# puts 'dbfile_basename: ' + dbfile_basename
|
71
77
|
# puts 'dbfile_path: ' + dbfile_path
|
72
78
|
# puts 'tmpfile_path: ' + tmpfile_path
|
@@ -90,10 +96,10 @@ module TheFox
|
|
90
96
|
end
|
91
97
|
|
92
98
|
if file['days'].is_a?(Array)
|
93
|
-
file['days'] =
|
99
|
+
file['days'] = Hash.new
|
94
100
|
end
|
95
101
|
if !file['days'].has_key?(date_s)
|
96
|
-
file['days'][date_s] =
|
102
|
+
file['days'][date_s] = Array.new
|
97
103
|
end
|
98
104
|
|
99
105
|
file['days'][date_s].push(entry.to_h)
|
@@ -108,10 +114,10 @@ module TheFox
|
|
108
114
|
end
|
109
115
|
|
110
116
|
if file['days'].is_a?(Array)
|
111
|
-
file['days'] =
|
117
|
+
file['days'] = Hash.new
|
112
118
|
end
|
113
119
|
if !file['days'].has_key?(date_s)
|
114
|
-
file['days'][date_s] =
|
120
|
+
file['days'][date_s] = Array.new
|
115
121
|
end
|
116
122
|
|
117
123
|
file['days'][date_s].push(entry.to_h)
|
@@ -122,13 +128,15 @@ module TheFox
|
|
122
128
|
store['days'] = file['days']
|
123
129
|
end
|
124
130
|
|
131
|
+
save_entries_index_file
|
132
|
+
|
125
133
|
if File.exist?(tmpfile_path)
|
126
134
|
File.rename(tmpfile_path, dbfile_path)
|
127
135
|
end
|
128
136
|
end
|
129
137
|
|
130
138
|
if @entries_by_ids.nil?
|
131
|
-
@entries_by_ids =
|
139
|
+
@entries_by_ids = Hash.new
|
132
140
|
end
|
133
141
|
@entries_by_ids[entry.id] = entry
|
134
142
|
|
@@ -137,7 +145,7 @@ module TheFox
|
|
137
145
|
|
138
146
|
def transaction_start
|
139
147
|
@has_transaction = true
|
140
|
-
@transaction_files =
|
148
|
+
@transaction_files = Hash.new
|
141
149
|
|
142
150
|
create_dirs
|
143
151
|
end
|
@@ -148,6 +156,7 @@ module TheFox
|
|
148
156
|
if @exit
|
149
157
|
throw :done
|
150
158
|
end
|
159
|
+
|
151
160
|
# puts 'keys left: ' + @transaction_files.keys.count.to_s
|
152
161
|
# puts 'tr_file_key: ' + tr_file_key
|
153
162
|
# puts 'path: ' + tr_file_data['path']
|
@@ -167,8 +176,10 @@ module TheFox
|
|
167
176
|
end
|
168
177
|
end
|
169
178
|
|
179
|
+
save_entries_index_file
|
180
|
+
|
170
181
|
@has_transaction = false
|
171
|
-
@transaction_files =
|
182
|
+
@transaction_files = Hash.new
|
172
183
|
end
|
173
184
|
|
174
185
|
def sum(year = nil, month = nil, day = nil, category = nil)
|
@@ -180,20 +191,20 @@ module TheFox
|
|
180
191
|
expense = 0.0
|
181
192
|
balance = 0.0
|
182
193
|
|
183
|
-
glob =
|
194
|
+
glob = File.expand_path('month_', @data_path)
|
184
195
|
if year == nil && month == nil
|
185
|
-
glob
|
196
|
+
glob << '*.yml'
|
186
197
|
elsif year && month == nil
|
187
|
-
glob
|
198
|
+
glob << "#{year_s}_*.yml"
|
188
199
|
elsif year && month
|
189
|
-
glob
|
200
|
+
glob << "#{year_s}_#{month_f}.yml"
|
190
201
|
end
|
191
202
|
|
192
203
|
Dir[glob].each do |file_path|
|
193
204
|
data = YAML.load_file(file_path)
|
194
205
|
|
195
206
|
if day
|
196
|
-
day_key = year_s
|
207
|
+
day_key = "#{year_s}-#{month_f}-#{day_f}"
|
197
208
|
if data['days'].has_key?(day_key)
|
198
209
|
day_sum = calc_day(data['days'][day_key], category)
|
199
210
|
revenue += day_sum[:revenue]
|
@@ -216,7 +227,7 @@ module TheFox
|
|
216
227
|
|
217
228
|
diff = revenue + expense - balance
|
218
229
|
if diff != 0
|
219
|
-
raise RuntimeError,
|
230
|
+
raise RuntimeError, "diff between revenue and expense to balance is #{diff}"
|
220
231
|
end
|
221
232
|
|
222
233
|
{
|
@@ -237,13 +248,13 @@ module TheFox
|
|
237
248
|
begin_month_f = '%02d' % begin_month.to_i
|
238
249
|
begin_day_f = '%02d' % begin_day.to_i
|
239
250
|
|
240
|
-
glob =
|
251
|
+
glob = File.expand_path('month_', @data_path)
|
241
252
|
if begin_year == nil && begin_month == nil
|
242
|
-
glob
|
253
|
+
glob << '*.yml'
|
243
254
|
elsif begin_year && begin_month == nil
|
244
|
-
glob
|
255
|
+
glob << "#{begin_year_s}_*.yml"
|
245
256
|
elsif begin_year && begin_month
|
246
|
-
glob
|
257
|
+
glob << "#{begin_year_s}_#{begin_month_f}.yml"
|
247
258
|
end
|
248
259
|
|
249
260
|
category = category.to_s.downcase
|
@@ -255,14 +266,14 @@ module TheFox
|
|
255
266
|
# puts 'category: ' + '%-10s' % category.class.to_s + ' = "' + category.to_s + '"'
|
256
267
|
# puts
|
257
268
|
|
258
|
-
entries_a =
|
269
|
+
entries_a = Hash.new
|
259
270
|
Dir[glob].each do |file_path|
|
260
271
|
#puts "path: #{file_path}"
|
261
272
|
|
262
273
|
data = YAML.load_file(file_path)
|
263
274
|
if category.length == 0
|
264
275
|
if begin_day
|
265
|
-
day_key = begin_year_s
|
276
|
+
day_key = "#{begin_year_s}-#{begin_month_f}-#{begin_day_f}"
|
266
277
|
if data['days'].has_key?(day_key)
|
267
278
|
entries_a[day_key] = data['days'][day_key]
|
268
279
|
end
|
@@ -271,7 +282,7 @@ module TheFox
|
|
271
282
|
end
|
272
283
|
else
|
273
284
|
if begin_day
|
274
|
-
day_key = begin_year_s
|
285
|
+
day_key = "#{begin_year_s}-#{begin_month_f}-#{begin_day_f}"
|
275
286
|
if data['days'].has_key?(day_key)
|
276
287
|
entries_a[day_key] = data['days'][day_key].keep_if{ |day_item|
|
277
288
|
day_item['category'].downcase == category
|
@@ -294,8 +305,8 @@ module TheFox
|
|
294
305
|
end
|
295
306
|
|
296
307
|
def categories
|
297
|
-
categories_h =
|
298
|
-
Dir[
|
308
|
+
categories_h = Hash.new
|
309
|
+
Dir[File.expand_path('month_*.yml', @data_path)].each do |file_path|
|
299
310
|
data = YAML.load_file(file_path)
|
300
311
|
|
301
312
|
data['days'].each do |day_name, day_items|
|
@@ -320,14 +331,14 @@ module TheFox
|
|
320
331
|
def gen_html
|
321
332
|
create_dirs
|
322
333
|
|
323
|
-
html_options_path =
|
334
|
+
html_options_path = File.expand_path('options.yml', @html_path)
|
324
335
|
html_options = {
|
325
336
|
'meta' => {
|
326
337
|
'version' => 1,
|
327
338
|
'created_at' => DateTime.now.to_s,
|
328
339
|
'updated_at' => DateTime.now.to_s,
|
329
340
|
},
|
330
|
-
'changes' =>
|
341
|
+
'changes' => Hash.new,
|
331
342
|
}
|
332
343
|
if Dir.exist?(@html_path)
|
333
344
|
if File.exist?(html_options_path)
|
@@ -338,16 +349,16 @@ module TheFox
|
|
338
349
|
Dir.mkdir(@html_path)
|
339
350
|
end
|
340
351
|
|
341
|
-
categories_available = categories
|
352
|
+
categories_available = categories
|
342
353
|
|
343
|
-
categories_total_balance =
|
354
|
+
categories_total_balance = Hash.new
|
344
355
|
categories_available.map{ |item| categories_total_balance[item] = 0.0 }
|
345
356
|
|
346
|
-
gitignore_file = File.open(
|
357
|
+
gitignore_file = File.open(File.expand_path('.gitignore', @html_path), 'w')
|
347
358
|
gitignore_file.write('*')
|
348
359
|
gitignore_file.close
|
349
360
|
|
350
|
-
css_file_path =
|
361
|
+
css_file_path = File.expand_path('style.css', @html_path)
|
351
362
|
css_file = File.open(css_file_path, 'w')
|
352
363
|
css_file.write('
|
353
364
|
html {
|
@@ -372,75 +383,75 @@ module TheFox
|
|
372
383
|
')
|
373
384
|
css_file.close
|
374
385
|
|
375
|
-
index_file_path =
|
386
|
+
index_file_path = File.expand_path('index.html', @html_path)
|
376
387
|
index_file = File.open(index_file_path, 'w')
|
377
388
|
index_file.write('
|
378
389
|
<html>
|
379
390
|
<head>
|
380
391
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
381
|
-
<title>'
|
392
|
+
<title>' << @dir_path << '</title>
|
382
393
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
383
394
|
</head>
|
384
395
|
<body>
|
385
|
-
<h1>'
|
386
|
-
<p>Generated @ '
|
396
|
+
<h1>' << @dir_path << '</h1>
|
397
|
+
<p>Generated @ ' << DateTime.now.strftime('%Y-%m-%d %H:%M:%S') << ' by <a href="' << ::TheFox::Wallet::HOMEPAGE << '">' << ::TheFox::Wallet::NAME << '</a> ' << ::TheFox::Wallet::VERSION << '</p>
|
387
398
|
')
|
388
399
|
|
389
|
-
years_total =
|
400
|
+
years_total = Hash.new
|
390
401
|
years.each do |year|
|
391
402
|
year_s = year.to_s
|
392
|
-
year_file_name =
|
393
|
-
year_file_path = @html_path
|
403
|
+
year_file_name = "year_#{year}.html"
|
404
|
+
year_file_path = File.expand_path(year_file_name, @html_path)
|
394
405
|
|
395
406
|
year_file = File.open(year_file_path, 'w')
|
396
407
|
year_file.write('
|
397
408
|
<html>
|
398
409
|
<head>
|
399
410
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
400
|
-
<title>'
|
411
|
+
<title>' << year_s << ' - ' << @dir_path << '</title>
|
401
412
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
402
413
|
</head>
|
403
414
|
<body>
|
404
|
-
<h1><a href="index.html">'
|
405
|
-
<p>Generated @ '
|
415
|
+
<h1><a href="index.html">' << @dir_path << '</a></h1>
|
416
|
+
<p>Generated @ ' << DateTime.now.strftime('%Y-%m-%d %H:%M:%S') << ' by <a href="' << ::TheFox::Wallet::HOMEPAGE << '">' << ::TheFox::Wallet::NAME << '</a> ' << ::TheFox::Wallet::VERSION << '</p>
|
406
417
|
|
407
|
-
<h2>Year: '
|
418
|
+
<h2>Year: ' << year_s << '</h2>
|
408
419
|
<table class="list">
|
409
420
|
<tr>
|
410
421
|
<th class="left">Month</th>
|
411
422
|
<th class="right">Revenue</th>
|
412
423
|
<th class="right">Expense</th>
|
413
424
|
<th class="right">Balance</th>
|
414
|
-
<th colspan="'
|
425
|
+
<th colspan="' << categories_available.count.to_s << '">' << categories_available.count.to_s << ' Categories</th>
|
415
426
|
</tr>
|
416
427
|
<tr>
|
417
428
|
<th colspan="4"> </th>
|
418
429
|
')
|
419
430
|
categories_available.each do |category|
|
420
|
-
year_file.write('<th class="right">'
|
431
|
+
year_file.write('<th class="right">' << category << '</th>')
|
421
432
|
end
|
422
433
|
year_file.write('</tr>')
|
423
434
|
|
424
435
|
revenue_year = 0.0
|
425
436
|
expense_year = 0.0
|
426
437
|
balance_year = 0.0
|
427
|
-
categories_year_balance =
|
438
|
+
categories_year_balance = Hash.new
|
428
439
|
categories_available.map{ |item| categories_year_balance[item] = 0.0 }
|
429
|
-
year_total =
|
440
|
+
year_total = Hash.new
|
430
441
|
|
431
|
-
puts
|
432
|
-
Dir[
|
442
|
+
puts "generate year #{year}"
|
443
|
+
Dir[File.expand_path("month_#{year}_*.yml", @data_path)].each do |file_path|
|
433
444
|
file_name = File.basename(file_path)
|
434
445
|
month_n = file_name[11, 2]
|
435
|
-
month_file_name =
|
436
|
-
month_file_path = @html_path
|
446
|
+
month_file_name = "month_#{year}_#{month_n}.html"
|
447
|
+
month_file_path = File.expand_path(month_file_name, @html_path)
|
437
448
|
|
438
|
-
month_s = Date.parse(
|
449
|
+
month_s = Date.parse("2015-#{month_n}-15").strftime('%B')
|
439
450
|
|
440
451
|
revenue_month = 0.0
|
441
452
|
expense_month = 0.0
|
442
453
|
balance_month = 0.0
|
443
|
-
categories_month_balance =
|
454
|
+
categories_month_balance = Hash.new
|
444
455
|
categories_available.map{ |item| categories_month_balance[item] = 0.0 }
|
445
456
|
|
446
457
|
entry_n = 0
|
@@ -463,21 +474,21 @@ module TheFox
|
|
463
474
|
end
|
464
475
|
|
465
476
|
if generate_html
|
466
|
-
puts "\
|
477
|
+
puts "\tfile: #{month_file_name} (from #{file_name})"
|
467
478
|
|
468
479
|
month_file = File.open(month_file_path, 'w')
|
469
480
|
month_file.write('
|
470
481
|
<html>
|
471
482
|
<head>
|
472
483
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
473
|
-
<title>'
|
484
|
+
<title>' << month_s << ' ' << year_s << ' - ' << @dir_path << '</title>
|
474
485
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
475
486
|
</head>
|
476
487
|
<body>
|
477
|
-
<h1><a href="index.html">'
|
478
|
-
<p>Generated @ '
|
488
|
+
<h1><a href="index.html">' << @dir_path << '</a></h1>
|
489
|
+
<p>Generated @ ' << DateTime.now.strftime('%Y-%m-%d %H:%M:%S') << ' by <a href="' << ::TheFox::Wallet::HOMEPAGE << '">' << ::TheFox::Wallet::NAME << '</a> ' << ::TheFox::Wallet::VERSION << ' from <code>' << file_name << '</code></p>
|
479
490
|
|
480
|
-
<h2>Month: '
|
491
|
+
<h2>Month: ' << month_s << ' <a href="' << year_file_name << '">' << year_s << '</a></h2>
|
481
492
|
<table class="list">
|
482
493
|
<tr>
|
483
494
|
<th class="left">#</th>
|
@@ -493,7 +504,6 @@ module TheFox
|
|
493
504
|
end
|
494
505
|
|
495
506
|
data['days'].sort.each do |day_name, day_items|
|
496
|
-
#puts "\t\t" + 'day: ' + day_name
|
497
507
|
day_items.each do |entry|
|
498
508
|
entry_n += 1
|
499
509
|
revenue_month += entry['revenue']
|
@@ -511,14 +521,14 @@ module TheFox
|
|
511
521
|
if generate_html
|
512
522
|
month_file.write('
|
513
523
|
<tr>
|
514
|
-
<td valign="top" class="left">'
|
515
|
-
<td valign="top" class="left">'
|
516
|
-
<td valign="top" class="left">'
|
517
|
-
<td valign="top" class="right">'
|
518
|
-
<td valign="top" class="right red">'
|
519
|
-
<td valign="top" class="right '
|
520
|
-
<td valign="top" class="right">'
|
521
|
-
<td valign="top" class="left">'
|
524
|
+
<td valign="top" class="left">' << entry_n.to_s << '</td>
|
525
|
+
<td valign="top" class="left">' << Date.parse(entry['date']).strftime('%d.%m.%y') << '</td>
|
526
|
+
<td valign="top" class="left">' << entry['title'][0, 50] << '</td>
|
527
|
+
<td valign="top" class="right">' << revenue_out << '</td>
|
528
|
+
<td valign="top" class="right red">' << expense_out << '</td>
|
529
|
+
<td valign="top" class="right ' << (entry['balance'] < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % entry['balance'] << '</td>
|
530
|
+
<td valign="top" class="right">' << category_out << '</td>
|
531
|
+
<td valign="top" class="left">' << comment_out << '</td>
|
522
532
|
</tr>
|
523
533
|
')
|
524
534
|
end
|
@@ -551,9 +561,9 @@ module TheFox
|
|
551
561
|
<th> </th>
|
552
562
|
<th> </th>
|
553
563
|
<th class="left"><b>TOTAL</b></th>
|
554
|
-
<th class="right">'
|
555
|
-
<th class="right red">'
|
556
|
-
<th class="right '
|
564
|
+
<th class="right">' << ::TheFox::Wallet::NUMBER_FORMAT % revenue_month << '</th>
|
565
|
+
<th class="right red">' << ::TheFox::Wallet::NUMBER_FORMAT % expense_month << '</th>
|
566
|
+
<th class="right ' << balance_class << '">' << ::TheFox::Wallet::NUMBER_FORMAT % balance_month << '</th>
|
557
567
|
<th> </th>
|
558
568
|
<th> </th>
|
559
569
|
</tr>
|
@@ -564,13 +574,13 @@ module TheFox
|
|
564
574
|
|
565
575
|
year_file.write('
|
566
576
|
<tr>
|
567
|
-
<td class="left"><a href="'
|
568
|
-
<td class="right">'
|
569
|
-
<td class="right red">'
|
570
|
-
<td class="right '
|
577
|
+
<td class="left"><a href="' << month_file_name << '">' << month_s << '</a></td>
|
578
|
+
<td class="right">' << ::TheFox::Wallet::NUMBER_FORMAT % revenue_month << '</td>
|
579
|
+
<td class="right red">' << ::TheFox::Wallet::NUMBER_FORMAT % expense_month << '</td>
|
580
|
+
<td class="right ' << balance_class << '">' << ::TheFox::Wallet::NUMBER_FORMAT % balance_month << '</td>')
|
571
581
|
categories_available.each do |category|
|
572
582
|
category_balance = categories_month_balance[category]
|
573
|
-
year_file.write('<td class="right '
|
583
|
+
year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % category_balance << '</td>')
|
574
584
|
end
|
575
585
|
year_file.write('</tr>')
|
576
586
|
end
|
@@ -580,12 +590,12 @@ module TheFox
|
|
580
590
|
year_file.write('
|
581
591
|
<tr>
|
582
592
|
<th class="left"><b>TOTAL</b></th>
|
583
|
-
<th class="right">'
|
584
|
-
<th class="right red">'
|
585
|
-
<th class="right '
|
593
|
+
<th class="right">' << ::TheFox::Wallet::NUMBER_FORMAT % revenue_year << '</th>
|
594
|
+
<th class="right red">' << ::TheFox::Wallet::NUMBER_FORMAT % expense_year << '</th>
|
595
|
+
<th class="right ' << (balance_year < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % balance_year << '</th>')
|
586
596
|
categories_available.each do |category|
|
587
597
|
category_balance = categories_year_balance[category]
|
588
|
-
year_file.write('<td class="right '
|
598
|
+
year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % category_balance << '</td>')
|
589
599
|
end
|
590
600
|
|
591
601
|
year_file.write('
|
@@ -593,11 +603,11 @@ module TheFox
|
|
593
603
|
</table>
|
594
604
|
')
|
595
605
|
|
596
|
-
year_file.write(
|
606
|
+
year_file.write(%{<p><img src="year_#{year_s}.png"></p>})
|
597
607
|
year_file.write('</body></html>')
|
598
608
|
year_file.close
|
599
609
|
|
600
|
-
yeardat_file_path = "
|
610
|
+
yeardat_file_path = File.expand_path("year_#{year_s}.dat", @tmp_path)
|
601
611
|
yeardat_file = File.new(yeardat_file_path, 'w')
|
602
612
|
yeardat_file.write(year_total
|
603
613
|
.map{ |k, m| "#{year_s}-#{m.month_s} #{m.revenue} #{m.expense} #{m.balance} #{m.balance_total} #{m.balance_total}" }
|
@@ -632,7 +642,7 @@ module TheFox
|
|
632
642
|
# puts "#{year_max} #{year_max.to_s.length} #{year_max_r} #{year_max_rl}"
|
633
643
|
# puts "#{year_min} #{year_min.to_s.length} #{year_min_r} #{year_min_rl}"
|
634
644
|
|
635
|
-
gnuplot_file = File.new("
|
645
|
+
gnuplot_file = File.new(File.expand_path("year_#{year_s}.gp", @tmp_path), 'w')
|
636
646
|
gnuplot_file.puts("set title 'Year #{year_s}'")
|
637
647
|
gnuplot_file.puts("set xlabel 'Months'")
|
638
648
|
gnuplot_file.puts("set ylabel 'Euro'")
|
@@ -655,14 +665,14 @@ module TheFox
|
|
655
665
|
gnuplot_file.puts("set style line 4 linecolor rgb '#0000ff' linewidth 2 linetype 1 pointtype 2")
|
656
666
|
gnuplot_file.puts("set style data linespoints")
|
657
667
|
gnuplot_file.puts("set terminal png enhanced")
|
658
|
-
gnuplot_file.puts("set output '
|
668
|
+
gnuplot_file.puts("set output '" << File.expand_path("year_#{year_s}.png", @html_path) << "'")
|
659
669
|
gnuplot_file.puts("plot sum = 0, \\")
|
660
670
|
gnuplot_file.puts("\t'#{yeardat_file_path}' using 1:2 linestyle 1 title 'Revenue', \\")
|
661
671
|
gnuplot_file.puts("\t'' using 1:3 linestyle 2 title 'Expense', \\")
|
662
672
|
gnuplot_file.puts("\t'' using 1:4 linestyle 3 title 'Balance', \\")
|
663
673
|
gnuplot_file.puts("\t'' using 1:5 linestyle 4 title '∑ Balance'")
|
664
674
|
gnuplot_file.close
|
665
|
-
system("gnuplot
|
675
|
+
system("gnuplot " << File.expand_path("year_#{year_s}.gp", @tmp_path))
|
666
676
|
|
667
677
|
years_total[year_s] = ::OpenStruct.new({
|
668
678
|
year: year_s,
|
@@ -686,11 +696,11 @@ module TheFox
|
|
686
696
|
years_total.each do |year_name, year_data|
|
687
697
|
index_file.write('
|
688
698
|
<tr>
|
689
|
-
<td class="left"><a href="year_'
|
690
|
-
<td class="right">'
|
691
|
-
<td class="right red">'
|
692
|
-
<td class="right '
|
693
|
-
<td class="right '
|
699
|
+
<td class="left"><a href="year_' << year_name << '.html">' << year_name << '</a></td>
|
700
|
+
<td class="right">' << ::TheFox::Wallet::NUMBER_FORMAT % year_data.revenue << '</td>
|
701
|
+
<td class="right red">' << ::TheFox::Wallet::NUMBER_FORMAT % year_data.expense << '</td>
|
702
|
+
<td class="right ' << (year_data.balance < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % year_data.balance << '</td>
|
703
|
+
<td class="right ' << (year_data.balance_total < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % year_data.balance_total << '</td>
|
694
704
|
</tr>')
|
695
705
|
end
|
696
706
|
|
@@ -699,9 +709,9 @@ module TheFox
|
|
699
709
|
index_file.write('
|
700
710
|
<tr>
|
701
711
|
<th class="left"><b>TOTAL</b></th>
|
702
|
-
<th class="right">'
|
703
|
-
<th class="right red">'
|
704
|
-
<th class="right '
|
712
|
+
<th class="right">' << ::TheFox::Wallet::NUMBER_FORMAT % years_total.inject(0.0){ |sum, item| sum + item[1].revenue } << '</th>
|
713
|
+
<th class="right red">' << ::TheFox::Wallet::NUMBER_FORMAT % years_total.inject(0.0){ |sum, item| sum + item[1].expense } << '</th>
|
714
|
+
<th class="right ' << (balance_total < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % balance_total << '</th>
|
705
715
|
<th> </th>
|
706
716
|
</tr>
|
707
717
|
</table>
|
@@ -726,12 +736,12 @@ module TheFox
|
|
726
736
|
end
|
727
737
|
totaldat_file_c = totaldat_file_c.join("\n")
|
728
738
|
|
729
|
-
totaldat_file_path =
|
739
|
+
totaldat_file_path = File.expand_path('total.dat', @tmp_path)
|
730
740
|
totaldat_file = File.new(totaldat_file_path, 'w')
|
731
741
|
totaldat_file.write(totaldat_file_c)
|
732
742
|
totaldat_file.close
|
733
743
|
|
734
|
-
gnuplot_file = File.new(
|
744
|
+
gnuplot_file = File.new(File.expand_path('total.gp', @tmp_path), 'w')
|
735
745
|
gnuplot_file.puts("set title 'Total'")
|
736
746
|
gnuplot_file.puts("set xlabel 'Years'")
|
737
747
|
gnuplot_file.puts("set ylabel 'Euro'")
|
@@ -746,14 +756,15 @@ module TheFox
|
|
746
756
|
gnuplot_file.puts("set style line 4 linecolor rgb '#0000ff' linewidth 2 linetype 1 pointtype 2")
|
747
757
|
gnuplot_file.puts("set style data linespoints")
|
748
758
|
gnuplot_file.puts("set terminal png enhanced")
|
749
|
-
gnuplot_file.puts("set output '
|
759
|
+
gnuplot_file.puts("set output '" << File.expand_path('total.png', @html_path) << "'")
|
750
760
|
gnuplot_file.puts("plot sum = 0, \\")
|
751
761
|
gnuplot_file.puts("\t'#{totaldat_file_path}' using 1:2 linestyle 1 title 'Revenue', \\")
|
752
762
|
gnuplot_file.puts("\t'' using 1:3 linestyle 2 title 'Expense', \\")
|
753
763
|
gnuplot_file.puts("\t'' using 1:4 linestyle 3 title 'Balance', \\")
|
754
764
|
gnuplot_file.puts("\t'' using 1:5 linestyle 4 title '∑ Balance'")
|
755
765
|
gnuplot_file.close
|
756
|
-
|
766
|
+
|
767
|
+
system("gnuplot " << File.expand_path('total.gp', @tmp_path))
|
757
768
|
end
|
758
769
|
|
759
770
|
def import_csv_file(file_path)
|
@@ -805,7 +816,7 @@ module TheFox
|
|
805
816
|
# :encoding => 'ISO-8859-1',
|
806
817
|
}
|
807
818
|
CSV.open(file_path, 'wb', csv_options) do |csv|
|
808
|
-
Dir[
|
819
|
+
Dir[File.expand_path('month_*.yml', @data_path)].each do |yaml_file_path|
|
809
820
|
puts 'export ' + File.basename(yaml_file_path)
|
810
821
|
|
811
822
|
data = YAML.load_file(yaml_file_path)
|
@@ -830,10 +841,13 @@ module TheFox
|
|
830
841
|
|
831
842
|
def entry_exist?(entry)
|
832
843
|
if !entry.is_a?(Entry)
|
833
|
-
raise ArgumentError, 'variable must be
|
844
|
+
raise ArgumentError, 'variable must be an Entry instance'
|
834
845
|
end
|
835
846
|
|
836
|
-
|
847
|
+
if @entries_index.count == 0
|
848
|
+
load_entries_index_file
|
849
|
+
end
|
850
|
+
@entries_index.include?(entry.id)
|
837
851
|
end
|
838
852
|
|
839
853
|
def build_entry_by_id_index(force = false)
|
@@ -878,12 +892,20 @@ module TheFox
|
|
878
892
|
Dir.mkdir(@tmp_path)
|
879
893
|
end
|
880
894
|
|
881
|
-
tmp_gitignore_path =
|
895
|
+
tmp_gitignore_path = File.expand_path('.gitignore', @tmp_path)
|
882
896
|
if !File.exist?(tmp_gitignore_path)
|
883
897
|
gitignore_file = File.open(tmp_gitignore_path, 'w')
|
884
898
|
gitignore_file.write('*')
|
885
899
|
gitignore_file.close
|
886
900
|
end
|
901
|
+
|
902
|
+
if File.exist?(@entries_index_file_path)
|
903
|
+
load_entries_index_file
|
904
|
+
else
|
905
|
+
build_entry_by_id_index(true)
|
906
|
+
@entries_index = @entries_by_ids.keys
|
907
|
+
save_entries_index_file
|
908
|
+
end
|
887
909
|
end
|
888
910
|
|
889
911
|
def calc_day(day, category = nil)
|
@@ -916,7 +938,24 @@ module TheFox
|
|
916
938
|
end
|
917
939
|
|
918
940
|
def years
|
919
|
-
Dir[
|
941
|
+
Dir[File.expand_path('month_*.yml', @data_path)].map{ |file_path| File.basename(file_path)[6, 4].to_i }.uniq
|
942
|
+
end
|
943
|
+
|
944
|
+
def load_entries_index_file
|
945
|
+
unless @entries_index_is_loaded
|
946
|
+
@entries_index_is_loaded = true
|
947
|
+
if File.exist?(@entries_index_file_path)
|
948
|
+
data = YAML.load_file(@entries_index_file_path)
|
949
|
+
@entries_index = data['index']
|
950
|
+
end
|
951
|
+
end
|
952
|
+
end
|
953
|
+
|
954
|
+
def save_entries_index_file
|
955
|
+
store = YAML::Store.new(@entries_index_file_path)
|
956
|
+
store.transaction do
|
957
|
+
store['index'] = @entries_index
|
958
|
+
end
|
920
959
|
end
|
921
960
|
|
922
961
|
end
|
data/thefox-wallet.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_development_dependency 'minitest', '~>5.7'
|
27
27
|
spec.add_development_dependency 'simplecov', '~>0.12'
|
28
|
-
spec.add_development_dependency 'simplecov-phpunit', '~>0.
|
28
|
+
spec.add_development_dependency 'simplecov-phpunit', '~>0.4'
|
29
29
|
|
30
|
-
spec.
|
30
|
+
spec.add_runtime_dependency 'uuid', '~>2.3'
|
31
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thefox-wallet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Mayer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
47
|
+
version: '0.4'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0.
|
54
|
+
version: '0.4'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: uuid
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- ".ackrc"
|
77
77
|
- ".editorconfig"
|
78
78
|
- ".gitignore"
|
79
|
+
- ".gitlab-ci.yml"
|
79
80
|
- ".travis.yml"
|
80
81
|
- Gemfile
|
81
82
|
- Makefile
|
@@ -115,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
116
|
version: '0'
|
116
117
|
requirements: []
|
117
118
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.
|
119
|
+
rubygems_version: 2.6.7
|
119
120
|
signing_key:
|
120
121
|
specification_version: 4
|
121
122
|
summary: Finances Tracking
|