thefox-wallet 0.14.0 → 0.15.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.
data/lib/wallet/wallet.rb CHANGED
@@ -5,40 +5,37 @@ require 'logger'
5
5
  require 'yaml'
6
6
  require 'yaml/store'
7
7
  require 'csv'
8
-
9
- # OpenStruct use to generate HTML.
10
- require 'ostruct'
11
-
8
+ require 'pathname'
9
+ require 'ostruct' # OpenStruct use to generate HTML.
12
10
  # require 'pp'
13
11
 
14
-
15
12
  module TheFox
16
13
  module Wallet
17
14
 
18
15
  class Wallet
19
16
 
20
17
  attr_writer :logger
21
- attr_reader :html_path
18
+ attr_reader :dir_path
22
19
 
23
- def initialize(dir_path = 'wallet')
20
+ def initialize(dir_path = nil)
24
21
  @exit = false
25
22
  @logger = nil
26
- @dir_path = dir_path
27
- @data_path = File.expand_path('data', @dir_path)
28
- @html_path = File.expand_path('html', @dir_path)
29
- @tmp_path = File.expand_path('tmp', @dir_path)
23
+ @dir_path = dir_path || Pathname.new('wallet').expand_path
24
+ @dir_path_basename = @dir_path.basename
25
+ @dir_path_basename_s = @dir_path_basename.to_s
26
+ @data_path = Pathname.new('data').expand_path(@dir_path)
27
+ @tmp_path = Pathname.new('tmp').expand_path(@dir_path)
30
28
 
31
29
  @has_transaction = false
32
30
  @transaction_files = Hash.new
33
31
 
34
32
  @entries_by_ids = nil
35
- @entries_index_file_path = File.expand_path('index.yml', @data_path)
33
+ @entries_index_file_path = Pathname.new('index.yml').expand_path(@data_path)
36
34
  @entries_index = Array.new
37
35
  @entries_index_is_loaded = false
38
36
 
39
37
  Signal.trap('SIGINT') do
40
- puts
41
- puts 'received SIGINT. break ...'
38
+ @logger.warning('received SIGINT. break ...') if @logger
42
39
  @exit = true
43
40
  end
44
41
  end
@@ -48,20 +45,18 @@ module TheFox
48
45
  raise ArgumentError, 'variable must be a Entry instance'
49
46
  end
50
47
 
51
- # puts "add, id #{entry.id}"
52
- # puts "add, is_unique #{is_unique}"
53
- # puts "add, entry_exist? #{entry_exist?(entry)}"
54
- # puts
55
-
56
48
  if is_unique && entry_exist?(entry)
57
49
  return false
58
50
  end
59
51
 
52
+ create_dirs
53
+
60
54
  date = entry.date
61
55
  date_s = date.to_s
62
- dbfile_basename = "month_#{date.strftime('%Y_%m')}.yml"
63
- dbfile_path = File.expand_path(dbfile_basename, @data_path)
64
- tmpfile_path = "#{dbfile_path}.tmp"
56
+ dbfile_basename_s = "month_#{date.strftime('%Y_%m')}.yml"
57
+ dbfile_basename_p = Pathname.new(dbfile_basename_s)
58
+ dbfile_path = dbfile_basename_p.expand_path(@data_path)
59
+ tmpfile_path = Pathname.new("#{dbfile_path}.tmp")
65
60
  file = {
66
61
  'meta' => {
67
62
  'version' => 1,
@@ -73,24 +68,19 @@ module TheFox
73
68
 
74
69
  @entries_index << entry.id
75
70
 
76
- # puts 'dbfile_basename: ' + dbfile_basename
77
- # puts 'dbfile_path: ' + dbfile_path
78
- # puts 'tmpfile_path: ' + tmpfile_path
79
- # puts
80
-
81
71
  if @has_transaction
82
- if @transaction_files.has_key?(dbfile_basename)
83
- file = @transaction_files[dbfile_basename]['file']
72
+ if @transaction_files[dbfile_basename_s]
73
+ file = @transaction_files[dbfile_basename_s]['file']
84
74
  else
85
- if File.exist?(dbfile_path)
75
+ if dbfile_path.exist?
86
76
  file = YAML.load_file(dbfile_path)
87
77
  file['meta']['updated_at'] = DateTime.now.to_s
88
78
  end
89
79
 
90
- @transaction_files[dbfile_basename] = {
91
- 'basename' => dbfile_basename,
92
- 'path' => dbfile_path,
93
- 'tmp_path' => tmpfile_path,
80
+ @transaction_files[dbfile_basename_s] = {
81
+ 'basename' => dbfile_basename_s,
82
+ 'path' => dbfile_path.to_s,
83
+ 'tmp_path' => tmpfile_path.to_s,
94
84
  'file' => file,
95
85
  }
96
86
  end
@@ -104,11 +94,9 @@ module TheFox
104
94
 
105
95
  file['days'][date_s].push(entry.to_h)
106
96
 
107
- @transaction_files[dbfile_basename]['file'] = file
97
+ @transaction_files[dbfile_basename_s]['file'] = file
108
98
  else
109
- create_dirs
110
-
111
- if File.exist?(dbfile_path)
99
+ if dbfile_path.exist?
112
100
  file = YAML.load_file(dbfile_path)
113
101
  file['meta']['updated_at'] = DateTime.now.to_s
114
102
  end
@@ -130,8 +118,8 @@ module TheFox
130
118
 
131
119
  save_entries_index_file
132
120
 
133
- if File.exist?(tmpfile_path)
134
- File.rename(tmpfile_path, dbfile_path)
121
+ if tmpfile_path.exist?
122
+ tmpfile_path.rename(dbfile_path)
135
123
  end
136
124
  end
137
125
 
@@ -157,12 +145,6 @@ module TheFox
157
145
  throw :done
158
146
  end
159
147
 
160
- # puts 'keys left: ' + @transaction_files.keys.count.to_s
161
- # puts 'tr_file_key: ' + tr_file_key
162
- # puts 'path: ' + tr_file_data['path']
163
- # puts 'tmp_path: ' + tr_file_data['tmp_path']
164
- # puts
165
-
166
148
  store = YAML::Store.new(tr_file_data['tmp_path'])
167
149
  store.transaction do
168
150
  store['meta'] = tr_file_data['file']['meta']
@@ -259,16 +241,8 @@ module TheFox
259
241
 
260
242
  category = category.to_s.downcase
261
243
 
262
- # puts 'glob: ' + glob
263
- # puts 'begin_year: ' + '%-10s' % begin_year.class.to_s + ' = "' + begin_year.to_s + '"'
264
- # puts 'begin_month: ' + '%-10s' % begin_month.class.to_s + ' = "' + begin_month.to_s + '"'
265
- # puts 'begin_day: ' + '%-10s' % begin_day.class.to_s + ' = "' + begin_day.to_s + '"'
266
- # puts 'category: ' + '%-10s' % category.class.to_s + ' = "' + category.to_s + '"'
267
- # puts
268
-
269
244
  entries_a = Hash.new
270
245
  Dir[glob].each do |file_path|
271
- #puts "path: #{file_path}"
272
246
 
273
247
  data = YAML.load_file(file_path)
274
248
  if category.length == 0
@@ -306,7 +280,7 @@ module TheFox
306
280
 
307
281
  def categories
308
282
  categories_h = Hash.new
309
- Dir[File.expand_path('month_*.yml', @data_path)].each do |file_path|
283
+ Dir[Pathname.new('month_*.yml').expand_path(@data_path)].each do |file_path|
310
284
  data = YAML.load_file(file_path)
311
285
 
312
286
  data['days'].each do |day_name, day_items|
@@ -328,10 +302,14 @@ module TheFox
328
302
  categories_a
329
303
  end
330
304
 
331
- def gen_html
305
+ def gen_html(html_path, date_start = nil, date_end = nil, category = nil)
332
306
  create_dirs
333
307
 
334
- html_options_path = File.expand_path('options.yml', @html_path)
308
+ unless html_path.exist?
309
+ html_path.mkpath
310
+ end
311
+
312
+ html_options_path = Pathname.new('options.yml').expand_path(html_path)
335
313
  html_options = {
336
314
  'meta' => {
337
315
  'version' => 1,
@@ -340,25 +318,30 @@ module TheFox
340
318
  },
341
319
  'changes' => Hash.new,
342
320
  }
343
- if Dir.exist?(@html_path)
344
- if File.exist?(html_options_path)
321
+ if html_path.exist?
322
+ if html_options_path.exist?
345
323
  html_options = YAML.load_file(html_options_path)
346
324
  html_options['meta']['updated_at'] = DateTime.now.to_s
347
325
  end
348
326
  else
349
- Dir.mkdir(@html_path)
327
+ html_path.mkpath
350
328
  end
351
329
 
352
330
  categories_available = categories
331
+ if category
332
+ filter_categories = category.split(',')
333
+ categories_available &= filter_categories
334
+ end
353
335
 
354
336
  categories_total_balance = Hash.new
355
337
  categories_available.map{ |item| categories_total_balance[item] = 0.0 }
356
338
 
357
- gitignore_file = File.open(File.expand_path('.gitignore', @html_path), 'w')
339
+ gitignore_file_path = Pathname.new('.gitignore').expand_path(html_path)
340
+ gitignore_file = File.open(gitignore_file_path, 'w')
358
341
  gitignore_file.write('*')
359
342
  gitignore_file.close
360
343
 
361
- css_file_path = File.expand_path('style.css', @html_path)
344
+ css_file_path = Pathname.new('style.css').expand_path(html_path)
362
345
  css_file = File.open(css_file_path, 'w')
363
346
  css_file.write('
364
347
  html {
@@ -383,37 +366,38 @@ module TheFox
383
366
  ')
384
367
  css_file.close
385
368
 
386
- index_file_path = File.expand_path('index.html', @html_path)
369
+ index_file_path = Pathname.new('index.html').expand_path(html_path)
387
370
  index_file = File.open(index_file_path, 'w')
388
371
  index_file.write('
389
372
  <html>
390
373
  <head>
391
374
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
392
- <title>' << @dir_path << '</title>
375
+ <title>' << @dir_path_basename_s << '</title>
393
376
  <link rel="stylesheet" href="style.css" type="text/css" />
394
377
  </head>
395
378
  <body>
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>
379
+ <h1>' << @dir_path_basename_s << '</h1>
380
+ <p>Generated @ ' << DateTime.now.strftime('%F %T') << ' by <a href="' << HOMEPAGE << '">' << NAME << '</a> v' << VERSION << '</p>
398
381
  ')
399
382
 
400
383
  years_total = Hash.new
401
- years.each do |year|
384
+ years(date_start, date_end).each do |year|
402
385
  year_s = year.to_s
403
- year_file_name = "year_#{year}.html"
404
- year_file_path = File.expand_path(year_file_name, @html_path)
386
+ year_file_name_s = "year_#{year}.html"
387
+ year_file_name_p = Pathname.new(year_file_name_s)
388
+ year_file_path = year_file_name_p.expand_path(html_path)
405
389
 
406
390
  year_file = File.open(year_file_path, 'w')
407
391
  year_file.write('
408
392
  <html>
409
393
  <head>
410
394
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
411
- <title>' << year_s << ' - ' << @dir_path << '</title>
395
+ <title>' << year_s << ' - ' << @dir_path_basename_s << '</title>
412
396
  <link rel="stylesheet" href="style.css" type="text/css" />
413
397
  </head>
414
398
  <body>
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>
399
+ <h1><a href="index.html">' << @dir_path_basename_s << '</a></h1>
400
+ <p>Generated @ ' << DateTime.now.strftime('%Y-%m-%d %H:%M:%S') << ' by <a href="' << HOMEPAGE << '">' << NAME << '</a> v' << VERSION << '</p>
417
401
 
418
402
  <h2>Year: ' << year_s << '</h2>
419
403
  <table class="list">
@@ -428,7 +412,7 @@ module TheFox
428
412
  <th colspan="4">&nbsp;</th>
429
413
  ')
430
414
  categories_available.each do |category|
431
- year_file.write('<th class="right">' << category << '</th>')
415
+ year_file.write(%(<th class="right">#{category}</th>))
432
416
  end
433
417
  year_file.write('</tr>')
434
418
 
@@ -439,15 +423,32 @@ module TheFox
439
423
  categories_available.map{ |item| categories_year_balance[item] = 0.0 }
440
424
  year_total = Hash.new
441
425
 
442
- puts "generate year #{year}"
443
- Dir[File.expand_path("month_#{year}_*.yml", @data_path)].each do |file_path|
444
- file_name = File.basename(file_path)
445
- month_n = file_name[11, 2]
446
- month_file_name = "month_#{year}_#{month_n}.html"
447
- month_file_path = File.expand_path(month_file_name, @html_path)
426
+ @logger.info("generate year #{year}") if @logger
427
+ @data_path.each_child do |file_path|
428
+ file_name_p = file_path.basename
429
+ file_name_s = file_name_p.to_s
430
+
431
+ if file_path.extname != '.yml' || Regexp.new("^month_#{year}_").match(file_name_s).nil?
432
+ next
433
+ end
434
+
435
+ month_n = file_name_s[11, 2]
436
+ month_file_name_s = "month_#{year}_#{month_n}.html"
437
+ month_file_name_p = Pathname.new(month_file_name_s)
438
+ month_file_path = month_file_name_p.expand_path(html_path)
448
439
 
449
440
  month_s = Date.parse("2015-#{month_n}-15").strftime('%B')
450
441
 
442
+ if date_start && date_end
443
+ file_date_start = Date.parse("#{year}-#{month_n}-01")
444
+ file_date_end = Date.parse("#{year}-#{month_n}-01").next_month.prev_day
445
+
446
+ if date_end < file_date_start ||
447
+ date_start > file_date_end
448
+ next
449
+ end
450
+ end
451
+
451
452
  revenue_month = 0.0
452
453
  expense_month = 0.0
453
454
  balance_month = 0.0
@@ -458,37 +459,37 @@ module TheFox
458
459
  data = YAML.load_file(file_path)
459
460
 
460
461
  generate_html = false
461
- if html_options['changes'].has_key?(file_name)
462
- if html_options['changes'][file_name]['updated_at'] != data['meta']['updated_at']
463
- html_options['changes'][file_name]['updated_at'] = data['meta']['updated_at']
462
+ if html_options['changes'][file_name_s]
463
+ if html_options['changes'][file_name_s]['updated_at'] != data['meta']['updated_at']
464
+ html_options['changes'][file_name_s]['updated_at'] = data['meta']['updated_at']
464
465
  generate_html = true
465
466
  end
466
467
  else
467
- html_options['changes'][file_name] = {
468
+ html_options['changes'][file_name_s] = {
468
469
  'updated_at' => data['meta']['updated_at'],
469
470
  }
470
471
  generate_html = true
471
472
  end
472
- if !File.exist?(month_file_path)
473
+ unless month_file_path.exist?
473
474
  generate_html = true
474
475
  end
475
476
 
476
477
  if generate_html
477
- puts "\tfile: #{month_file_name} (from #{file_name})"
478
+ @logger.debug("file: #{month_file_name_s} (from #{file_name_s})") if @logger
478
479
 
479
480
  month_file = File.open(month_file_path, 'w')
480
481
  month_file.write('
481
482
  <html>
482
483
  <head>
483
484
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
484
- <title>' << month_s << ' ' << year_s << ' - ' << @dir_path << '</title>
485
+ <title>' << month_s << ' ' << year_s << ' - ' << @dir_path_basename_s << '</title>
485
486
  <link rel="stylesheet" href="style.css" type="text/css" />
486
487
  </head>
487
488
  <body>
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>
489
+ <h1><a href="index.html">' << @dir_path_basename_s << '</a></h1>
490
+ <p>Generated @ ' << DateTime.now.strftime('%Y-%m-%d %H:%M:%S') << ' by <a href="' << HOMEPAGE << '">' << NAME << '</a> v' << VERSION << ' from <code>' << file_name_s << '</code></p>
490
491
 
491
- <h2>Month: ' << month_s << ' <a href="' << year_file_name << '">' << year_s << '</a></h2>
492
+ <h2>Month: ' << month_s << ' <a href="' << year_file_name_s << '">' << year_s << '</a></h2>
492
493
  <table class="list">
493
494
  <tr>
494
495
  <th class="left">#</th>
@@ -505,6 +506,19 @@ module TheFox
505
506
 
506
507
  data['days'].sort.each do |day_name, day_items|
507
508
  day_items.each do |entry|
509
+ entry_date = Date.parse(entry['date'])
510
+ entry_date_s = entry_date.strftime('%d.%m.%y')
511
+
512
+ date_start_oor = date_start > entry_date
513
+ date_end_oor = date_end < entry_date
514
+
515
+ if category && !categories_available.include?(entry['category']) ||
516
+ date_start > entry_date ||
517
+ date_end < entry_date
518
+
519
+ next
520
+ end
521
+
508
522
  entry_n += 1
509
523
  revenue_month += entry['revenue']
510
524
  expense_month += entry['expense']
@@ -513,8 +527,8 @@ module TheFox
513
527
  categories_year_balance[entry['category']] += entry['balance']
514
528
  categories_month_balance[entry['category']] += entry['balance']
515
529
 
516
- revenue_out = entry['revenue'] > 0 ? ::TheFox::Wallet::NUMBER_FORMAT % entry['revenue'] : '&nbsp;'
517
- expense_out = entry['expense'] < 0 ? ::TheFox::Wallet::NUMBER_FORMAT % entry['expense'] : '&nbsp;'
530
+ revenue_out = entry['revenue'] > 0 ? NUMBER_FORMAT % entry['revenue'] : '&nbsp;'
531
+ expense_out = entry['expense'] < 0 ? NUMBER_FORMAT % entry['expense'] : '&nbsp;'
518
532
  category_out = entry['category'] == 'default' ? '&nbsp;' : entry['category']
519
533
  comment_out = entry['comment'] == '' ? '&nbsp;' : entry['comment']
520
534
 
@@ -522,11 +536,11 @@ module TheFox
522
536
  month_file.write('
523
537
  <tr>
524
538
  <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>
539
+ <td valign="top" class="left">' << entry_date_s << '</td>
526
540
  <td valign="top" class="left">' << entry['title'][0, 50] << '</td>
527
541
  <td valign="top" class="right">' << revenue_out << '</td>
528
542
  <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>
543
+ <td valign="top" class="right ' << (entry['balance'] < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % entry['balance'] << '</td>
530
544
  <td valign="top" class="right">' << category_out << '</td>
531
545
  <td valign="top" class="left">' << comment_out << '</td>
532
546
  </tr>
@@ -561,9 +575,9 @@ module TheFox
561
575
  <th>&nbsp;</th>
562
576
  <th>&nbsp;</th>
563
577
  <th class="left"><b>TOTAL</b></th>
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>
578
+ <th class="right">' << NUMBER_FORMAT % revenue_month << '</th>
579
+ <th class="right red">' << NUMBER_FORMAT % expense_month << '</th>
580
+ <th class="right ' << balance_class << '">' << NUMBER_FORMAT % balance_month << '</th>
567
581
  <th>&nbsp;</th>
568
582
  <th>&nbsp;</th>
569
583
  </tr>
@@ -574,13 +588,13 @@ module TheFox
574
588
 
575
589
  year_file.write('
576
590
  <tr>
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>')
591
+ <td class="left"><a href="' << month_file_name_s << '">' << month_s << '</a></td>
592
+ <td class="right">' << NUMBER_FORMAT % revenue_month << '</td>
593
+ <td class="right red">' << NUMBER_FORMAT % expense_month << '</td>
594
+ <td class="right ' << balance_class << '">' << NUMBER_FORMAT % balance_month << '</td>')
581
595
  categories_available.each do |category|
582
596
  category_balance = categories_month_balance[category]
583
- year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % category_balance << '</td>')
597
+ year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % category_balance << '</td>')
584
598
  end
585
599
  year_file.write('</tr>')
586
600
  end
@@ -590,12 +604,12 @@ module TheFox
590
604
  year_file.write('
591
605
  <tr>
592
606
  <th class="left"><b>TOTAL</b></th>
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>')
607
+ <th class="right">' << NUMBER_FORMAT % revenue_year << '</th>
608
+ <th class="right red">' << NUMBER_FORMAT % expense_year << '</th>
609
+ <th class="right ' << (balance_year < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % balance_year << '</th>')
596
610
  categories_available.each do |category|
597
611
  category_balance = categories_year_balance[category]
598
- year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << ::TheFox::Wallet::NUMBER_FORMAT % category_balance << '</td>')
612
+ year_file.write('<td class="right ' << (category_balance < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % category_balance << '</td>')
599
613
  end
600
614
 
601
615
  year_file.write('
@@ -607,42 +621,15 @@ module TheFox
607
621
  year_file.write('</body></html>')
608
622
  year_file.close
609
623
 
610
- yeardat_file_path = File.expand_path("year_#{year_s}.dat", @tmp_path)
624
+ yeardat_file_path = Pathname.new("year_#{year_s}.dat").expand_path(@tmp_path)
611
625
  yeardat_file = File.new(yeardat_file_path, 'w')
612
626
  yeardat_file.write(year_total
613
627
  .map{ |k, m| "#{year_s}-#{m.month_s} #{m.revenue} #{m.expense} #{m.balance} #{m.balance_total} #{m.balance_total}" }
614
628
  .join("\n"))
615
629
  yeardat_file.close
616
630
 
617
- # year_max = year_total
618
- # .map{ |k, m| [m.revenue, m.balance, m.balance_total] }
619
- # .flatten
620
- # .max
621
- # .to_i
622
-
623
- # year_min = year_total
624
- # .map{ |k, m| [m.expense, m.balance, m.balance_total] }
625
- # .flatten
626
- # .min
627
- # .to_i
628
- # .abs
629
-
630
- # year_max_rl = year_max.to_s.length - 2
631
- # year_max_r = year_max.round(-year_max_rl)
632
- # year_max_d = year_max_r - year_max
633
- # year_max_r = year_max_r + 5 * 10 ** (year_max_rl - 1) if year_max_r < year_max
634
- # year_max_r += 100
635
-
636
- # year_min_rl = year_min.to_s.length - 2
637
- # year_min_r = year_min.round(-year_min_rl)
638
- # year_min_d = year_min_r - year_min
639
- # year_min_r = year_min_r + 5 * 10 ** (year_min_rl - 1) if year_min_r < year_min
640
- # year_min_r += 100
641
-
642
- # puts "#{year_max} #{year_max.to_s.length} #{year_max_r} #{year_max_rl}"
643
- # puts "#{year_min} #{year_min.to_s.length} #{year_min_r} #{year_min_rl}"
644
-
645
- gnuplot_file = File.new(File.expand_path("year_#{year_s}.gp", @tmp_path), 'w')
631
+ gnuplot_file_path = Pathname.new("year_#{year_s}.gp").expand_path(@tmp_path)
632
+ gnuplot_file = File.new(gnuplot_file_path, 'w')
646
633
  gnuplot_file.puts("set title 'Year #{year_s}'")
647
634
  gnuplot_file.puts("set xlabel 'Months'")
648
635
  gnuplot_file.puts("set ylabel 'Euro'")
@@ -665,14 +652,14 @@ module TheFox
665
652
  gnuplot_file.puts("set style line 4 linecolor rgb '#0000ff' linewidth 2 linetype 1 pointtype 2")
666
653
  gnuplot_file.puts("set style data linespoints")
667
654
  gnuplot_file.puts("set terminal png enhanced")
668
- gnuplot_file.puts("set output '" << File.expand_path("year_#{year_s}.png", @html_path) << "'")
655
+ gnuplot_file.puts("set output '" << File.expand_path("year_#{year_s}.png", html_path) << "'")
669
656
  gnuplot_file.puts("plot sum = 0, \\")
670
657
  gnuplot_file.puts("\t'#{yeardat_file_path}' using 1:2 linestyle 1 title 'Revenue', \\")
671
658
  gnuplot_file.puts("\t'' using 1:3 linestyle 2 title 'Expense', \\")
672
659
  gnuplot_file.puts("\t'' using 1:4 linestyle 3 title 'Balance', \\")
673
660
  gnuplot_file.puts("\t'' using 1:5 linestyle 4 title '∑ Balance'")
674
661
  gnuplot_file.close
675
- system("gnuplot " << File.expand_path("year_#{year_s}.gp", @tmp_path))
662
+ system("gnuplot #{gnuplot_file_path} &> /dev/null")
676
663
 
677
664
  years_total[year_s] = ::OpenStruct.new({
678
665
  year: year_s,
@@ -697,10 +684,10 @@ module TheFox
697
684
  index_file.write('
698
685
  <tr>
699
686
  <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>
687
+ <td class="right">' << NUMBER_FORMAT % year_data.revenue << '</td>
688
+ <td class="right red">' << NUMBER_FORMAT % year_data.expense << '</td>
689
+ <td class="right ' << (year_data.balance < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % year_data.balance << '</td>
690
+ <td class="right ' << (year_data.balance_total < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % year_data.balance_total << '</td>
704
691
  </tr>')
705
692
  end
706
693
 
@@ -709,9 +696,9 @@ module TheFox
709
696
  index_file.write('
710
697
  <tr>
711
698
  <th class="left"><b>TOTAL</b></th>
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>
699
+ <th class="right">' << NUMBER_FORMAT % years_total.inject(0.0){ |sum, item| sum + item[1].revenue } << '</th>
700
+ <th class="right red">' << NUMBER_FORMAT % years_total.inject(0.0){ |sum, item| sum + item[1].expense } << '</th>
701
+ <th class="right ' << (balance_total < 0 ? 'red' : '') << '">' << NUMBER_FORMAT % balance_total << '</th>
715
702
  <th>&nbsp;</th>
716
703
  </tr>
717
704
  </table>
@@ -731,17 +718,20 @@ module TheFox
731
718
  end
732
719
 
733
720
  totaldat_file_c = years_total.map{ |k, y| "#{y.year} #{y.revenue} #{y.expense} #{y.balance} #{y.balance_total}" }
734
- if totaldat_file_c.count > 6
735
- totaldat_file_c = totaldat_file_c.slice(-6, 6)
721
+ if totaldat_file_c.count > 10
722
+ totaldat_file_c = totaldat_file_c.slice(-10, 10)
736
723
  end
737
724
  totaldat_file_c = totaldat_file_c.join("\n")
738
725
 
739
- totaldat_file_path = File.expand_path('total.dat', @tmp_path)
726
+ totaldat_file_path = Pathname.new('total.dat').expand_path(@tmp_path)
740
727
  totaldat_file = File.new(totaldat_file_path, 'w')
741
728
  totaldat_file.write(totaldat_file_c)
742
729
  totaldat_file.close
743
730
 
744
- gnuplot_file = File.new(File.expand_path('total.gp', @tmp_path), 'w')
731
+ png_file_path = Pathname.new('total.png').expand_path(html_path)
732
+
733
+ gnuplot_file_path = Pathname.new('total.gp').expand_path(@tmp_path)
734
+ gnuplot_file = File.new(gnuplot_file_path, 'w')
745
735
  gnuplot_file.puts("set title 'Total'")
746
736
  gnuplot_file.puts("set xlabel 'Years'")
747
737
  gnuplot_file.puts("set ylabel 'Euro'")
@@ -756,7 +746,7 @@ module TheFox
756
746
  gnuplot_file.puts("set style line 4 linecolor rgb '#0000ff' linewidth 2 linetype 1 pointtype 2")
757
747
  gnuplot_file.puts("set style data linespoints")
758
748
  gnuplot_file.puts("set terminal png enhanced")
759
- gnuplot_file.puts("set output '" << File.expand_path('total.png', @html_path) << "'")
749
+ gnuplot_file.puts("set output '#{png_file_path}'")
760
750
  gnuplot_file.puts("plot sum = 0, \\")
761
751
  gnuplot_file.puts("\t'#{totaldat_file_path}' using 1:2 linestyle 1 title 'Revenue', \\")
762
752
  gnuplot_file.puts("\t'' using 1:3 linestyle 2 title 'Expense', \\")
@@ -764,7 +754,7 @@ module TheFox
764
754
  gnuplot_file.puts("\t'' using 1:5 linestyle 4 title '∑ Balance'")
765
755
  gnuplot_file.close
766
756
 
767
- system("gnuplot " << File.expand_path('total.gp', @tmp_path))
757
+ system("gnuplot #{gnuplot_file_path} &> /dev/null")
768
758
  end
769
759
 
770
760
  def import_csv_file(file_path)
@@ -796,11 +786,10 @@ module TheFox
796
786
 
797
787
  added = add(Entry.new(id, title, date, revenue, expense, category, comment), true)
798
788
 
799
- puts "import row '#{id}' -- #{added ? 'YES' : 'NO'}"
789
+ @logger.debug("import row '#{id}' -- #{added ? 'YES' : 'NO'}") if @logger
800
790
  end
801
791
 
802
- puts
803
- puts 'save data ...'
792
+ @logger.info('save data ...') if @logger
804
793
 
805
794
  transaction_end
806
795
  end
@@ -816,8 +805,8 @@ module TheFox
816
805
  # :encoding => 'ISO-8859-1',
817
806
  }
818
807
  CSV.open(file_path, 'wb', csv_options) do |csv|
819
- Dir[File.expand_path('month_*.yml', @data_path)].each do |yaml_file_path|
820
- puts 'export ' + File.basename(yaml_file_path)
808
+ Dir[Pathname.new('month_*.yml').expand_path(@data_path)].each do |yaml_file_path|
809
+ @logger.info("export #{File.basename(yaml_file_path)}") if @logger
821
810
 
822
811
  data = YAML.load_file(yaml_file_path)
823
812
 
@@ -827,9 +816,9 @@ module TheFox
827
816
  entry['id'],
828
817
  entry['date'],
829
818
  entry['title'],
830
- ::TheFox::Wallet::NUMBER_FORMAT % entry['revenue'],
831
- ::TheFox::Wallet::NUMBER_FORMAT % entry['expense'],
832
- ::TheFox::Wallet::NUMBER_FORMAT % entry['balance'],
819
+ NUMBER_FORMAT % entry['revenue'],
820
+ NUMBER_FORMAT % entry['expense'],
821
+ NUMBER_FORMAT % entry['balance'],
833
822
  entry['category'],
834
823
  entry['comment'],
835
824
  ]
@@ -854,9 +843,9 @@ module TheFox
854
843
  if @entries_by_ids.nil? || force
855
844
  @logger.debug('build entry-by-id index') if @logger
856
845
 
857
- glob = File.expand_path('month_*.yml', @data_path)
846
+ glob = Pathname.new('month_*.yml').expand_path(@data_path)
858
847
 
859
- @entries_by_ids = Dir[glob].map { |file_path|
848
+ @entries_by_ids = Dir[glob.to_s].map { |file_path|
860
849
  data = YAML.load_file(file_path)
861
850
  data['days'].map{ |day_name, day_items|
862
851
  day_items.map{ |entry|
@@ -866,8 +855,6 @@ module TheFox
866
855
  }.flatten.map{ |entry|
867
856
  [entry.id, entry]
868
857
  }.to_h
869
-
870
- # pp @entries_by_ids
871
858
  end
872
859
  end
873
860
 
@@ -880,26 +867,26 @@ module TheFox
880
867
  private
881
868
 
882
869
  def create_dirs
883
- if !Dir.exist?(@dir_path)
884
- Dir.mkdir(@dir_path)
870
+ unless @dir_path.exist?
871
+ @dir_path.mkpath
885
872
  end
886
873
 
887
- if !Dir.exist?(@data_path)
888
- Dir.mkdir(@data_path)
874
+ unless @data_path.exist?
875
+ @data_path.mkpath
889
876
  end
890
877
 
891
- if !Dir.exist?(@tmp_path)
892
- Dir.mkdir(@tmp_path)
878
+ unless @tmp_path.exist?
879
+ @tmp_path.mkpath
893
880
  end
894
881
 
895
- tmp_gitignore_path = File.expand_path('.gitignore', @tmp_path)
896
- if !File.exist?(tmp_gitignore_path)
882
+ tmp_gitignore_path = Pathname.new('.gitignore').expand_path(@tmp_path)
883
+ unless tmp_gitignore_path.exist?
897
884
  gitignore_file = File.open(tmp_gitignore_path, 'w')
898
885
  gitignore_file.write('*')
899
886
  gitignore_file.close
900
887
  end
901
888
 
902
- if File.exist?(@entries_index_file_path)
889
+ if @entries_index_file_path.exist?
903
890
  load_entries_index_file
904
891
  else
905
892
  build_entry_by_id_index(true)
@@ -937,22 +924,39 @@ module TheFox
937
924
  }
938
925
  end
939
926
 
940
- def years
941
- Dir[File.expand_path('month_*.yml', @data_path)].map{ |file_path| File.basename(file_path)[6, 4].to_i }.uniq
927
+ def years(date_start = nil, date_end = nil)
928
+
929
+ files = Array.new
930
+ @data_path.each_child(false) do |file|
931
+ if file.extname == '.yml' && /^month_/.match(file.to_s)
932
+ files << file
933
+ end
934
+ end
935
+
936
+ date_start_year = 0
937
+ date_start_year = date_start.year if date_start
938
+
939
+ date_end_year = 9999
940
+ date_end_year = date_end.year if date_end
941
+
942
+ files
943
+ .map{ |file| file.to_s[6, 4].to_i }
944
+ .uniq
945
+ .keep_if{ |year| year >= date_start_year && year <= date_end_year }
942
946
  end
943
947
 
944
948
  def load_entries_index_file
945
949
  unless @entries_index_is_loaded
946
950
  @entries_index_is_loaded = true
947
- if File.exist?(@entries_index_file_path)
948
- data = YAML.load_file(@entries_index_file_path)
951
+ if @entries_index_file_path.exist?
952
+ data = YAML.load_file(@entries_index_file_path.to_s)
949
953
  @entries_index = data['index']
950
954
  end
951
955
  end
952
956
  end
953
957
 
954
958
  def save_entries_index_file
955
- store = YAML::Store.new(@entries_index_file_path)
959
+ store = YAML::Store.new(@entries_index_file_path.to_s)
956
960
  store.transaction do
957
961
  store['index'] = @entries_index
958
962
  end