thefox-wallet 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|