Class: Ldgr::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/ldgr/parser.rb

Constant Summary collapse

DEFAULT_CURRENCY =
'¥'
FILEBASE =
Dir.home + '/.config/ledger/'
FILE =
FILEBASE + 'transactions.dat'
VERSION =
Ldgr::VERSION
PROGRAM_NAME =
'ldgr'
MATCH =
/(?=(\n\d\d\d\d-\d\d-\d\d)(=\d\d\d\d-\d\d-\d\d)*)|\z/
OTHER_MATCH =
/(?=(\d\d\d\d-\d\d-\d\d)(=\d\d\d\d-\d\d-\d\d)*)/

Class Method Summary collapse

Class Method Details

.add(config) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/ldgr/parser.rb', line 42

def self.add(config)
  error_policy = ->(key) { fail "You need to provide a value for #{key.to_s}." }

  transaction = Transaction.new do |t|
    date = String(config.fetch(:date) { Date.today } )
    effective = String(config.fetch(:effective) { Date.today })

    t.payee    = config.fetch(:payee) { |key| error_policy.call(key) }
    t.  = config.fetch(:account) { |key| error_policy.call(key) }
    t.amount   = config.fetch(:amount) { |key| error_policy.call(key) }
    t.currency = config.fetch(:currency) { DEFAULT_CURRENCY }
    t.equity   = config.fetch(:equity) { "Cash" }
    t.cleared  = config[:cleared] ? '* ' : ''
    t.date     = date == effective ? date : date << '=' << effective
  end

  File.open(FILE, 'a') { |file| file.puts transaction }
end

.clear(config) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ldgr/parser.rb', line 61

def self.clear(config)
  output = ''
  pattern = /((^\d{,4}-\d{,2}-\d{,2})(=\d{,4}-\d{,2}-\d{,2})?) ([^\*]+)/
  count = 0

  File.open(FILE, 'r') do |transactions|
    transactions.each_line do |transaction|
      match = pattern.match(transaction)
      if match && match[3]
        effective_date = Date.parse(match[3])
      else
        effective_date = Date.today
      end
      if match && Date.today >= effective_date
        count += 1
        front = match[1]
        back = match[4]
        puts "\n#{HighLine.color(transaction, :magenta)}"
        question = ask('Do you want to clear this?  ') do |q|
          q.default = 'No'
        end
        transaction.gsub!(pattern, "#{front} * #{back}") if question =~ /y/i
      end
      output << transaction
    end
  end
  IO.write(FILE, output)
end

.open(_) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/ldgr/parser.rb', line 127

def self.open(_)
  def self.open_file(file_to_open)
    checked_file = "#{FILEBASE}#{file_to_open}.dat"
    raise "#{checked_file} doesn't exist." unless Pathname(checked_file).exist?
    system(ENV['EDITOR'], checked_file)
  end

  open_file(ARGV[1])
end

.open_file(file_to_open) ⇒ Object



128
129
130
131
132
# File 'lib/ldgr/parser.rb', line 128

def self.open_file(file_to_open)
  checked_file = "#{FILEBASE}#{file_to_open}.dat"
  raise "#{checked_file} doesn't exist." unless Pathname(checked_file).exist?
  system(ENV['EDITOR'], checked_file)
end

.parseObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ldgr/parser.rb', line 19

def self.parse
  cli = OptionParser.new do |o|
    o.banner = "Usage #{PROGRAM_NAME} [add|sort|tag|clear|open]"
    o.program_name = PROGRAM_NAME
    o.version = VERSION

    o.define '-C', '--currency=CURRENCY', String, 'the currency of the transaction'
    o.define '-E', '--effective=EFFECTIVE_DATE', Date, 'the effective date of the transaction'
    o.define '-a', '--account=ACCOUNT', String, 'the account of the transaction'
    o.define '-c', '--cleared', TrueClass, 'clear the transaction'
    o.define '-d', '--date=DATE', Date, 'the date of the transaction'
    o.define '-e', '--equity=EQUITY', String, 'the equity of the transaction'
    o.define '-f', '--file=FILE', String, 'a file of transactions'
    o.define '-A', '--amount=AMOUNT', String, 'the amount of the transaction'
    o.define '-p', '--payee=PAYEE', String, 'the payee of the transaction'
  end

  config = {}
  command = String(cli.parse(ARGV, into: config)[0]).to_sym

  send(command, config) if methods.include? command
end

.sort(config) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/ldgr/parser.rb', line 112

def self.sort(config)
  text = File.read(FILE).gsub(/\n+|\r+/, "\n").squeeze("\n").strip
  scanner = StringScanner.new(text)
  results = []

  until scanner.eos?
    results << scanner.scan_until(MATCH)
    scanner.skip_until(OTHER_MATCH)
  end

  File.open(FILE, 'w') do |file|
    file.puts results.sort
  end
end

.tag(config) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ldgr/parser.rb', line 90

def self.tag(config)
  output = ''
  pattern = /(^\s+Expenses[^:])\s*(¥.+)/
  count = 0
  previous = ''

  File.open(FILE, 'r') do |transactions|
    transactions.each_line do |transaction|
      match = pattern.match(transaction)
      if match
        count += 1
        puts "\n#{HighLine.color(previous, :blue)} #{HighLine.color(match[2], :red)}"
        question = ask('What account does this belong to?  ') { |q| q.default = 'None' }
        transaction.gsub!(match[1], "  #{question.capitalize}  ") if question != 'None'
      end
      previous = transaction.chomp
      output << transaction
    end
  end
  IO.write(FILE, output)
end