Class: Ldgr::Parser
- Inherits:
-
Object
- Object
- Ldgr::Parser
- Defined in:
- lib/ldgr/parser.rb
Overview
Constant Summary collapse
- FILEBASE =
Dir.home + '/.config/ledger/'
- 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)*)/
- COMMANDS =
%w(add sort tag clear open).freeze
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
-
#transactions_file ⇒ Object
Returns the value of attribute transactions_file.
Instance Method Summary collapse
-
#add ⇒ Object
Public: Adds a transaction to the transactions_file.
-
#clear ⇒ Object
Public: Runs through all uncleared transactions that are passed their effective date and offers to clear them.
-
#initialize(config: {}) ⇒ Parser
constructor
Public: Creates a new Parser object.
- #open_file(file_to_open) ⇒ Object
-
#parse ⇒ Object
Public: Kicks off the CLI.
-
#sort ⇒ Object
Public: Sorts all transactions by date.
-
#tag ⇒ Object
Public: Runs through all transactions with only Expenses set as the account and lets you enter an account name.
Constructor Details
#initialize(config: {}) ⇒ Parser
Public: Creates a new Parser object
config - A hash of config options
Examples
new(config: {currency: '¥'})
# => <ParserObject>
Returns a Parser object.
43 44 45 46 |
# File 'lib/ldgr/parser.rb', line 43 def initialize(config: {}) @transactions_file = defaults.fetch(:transactions_file) @config = defaults.merge(user_config).merge(config) end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
31 32 33 |
# File 'lib/ldgr/parser.rb', line 31 def config @config end |
#transactions_file ⇒ Object
Returns the value of attribute transactions_file.
31 32 33 |
# File 'lib/ldgr/parser.rb', line 31 def transactions_file @transactions_file end |
Instance Method Details
#add ⇒ Object
Public: Adds a transaction to the transactions_file.
Examples
add
Returns nothing.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/ldgr/parser.rb', line 85 def add error_policy = ->(key) { fail "You need to provide a value for #{key.to_s}." } transaction = Transaction.new do |t| date = String(config.fetch(:date) { |key| error_policy.call(key) }) effective = String(config.fetch(:effective) { |key| error_policy.call(key) }) t.payee = config.fetch(:payee) { |key| error_policy.call(key) } t.account = config.fetch(:account) { |key| error_policy.call(key) } t.amount = config.fetch(:amount) { |key| error_policy.call(key) } t.currency = config.fetch(:currency) { config.fetch(:currency) } t.equity = config.fetch(:equity) { config.fetch(:equity) } t.cleared = config[:cleared] ? '* ' : '' t.date = date == effective ? date : date << '=' << effective end File.open(transactions_file, 'a') { |file| file.puts transaction } end |
#clear ⇒ Object
Public: Runs through all uncleared transactions that are passed their effective date and offers to clear them.
Examples
clear
Returns nothing.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ldgr/parser.rb', line 112 def clear output = '' pattern = /((^\d{,4}-\d{,2}-\d{,2})(=\d{,4}-\d{,2}-\d{,2})?) ([^\*]+)/ count = 0 File.open(transactions_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 transaction question = ask('Do you want to clear this? ') do |q| q.default = 'No' end transaction.gsub!(pattern, "#{front} * #{back}") if question.match?(/y/i) end output << transaction end end IO.write(transactions_file, output) end |
#open_file(file_to_open) ⇒ Object
215 216 217 218 219 |
# File 'lib/ldgr/parser.rb', line 215 def open_file(file_to_open) checked_file = "#{FILEBASE}#{file_to_open}.dat" fail "#{checked_file} doesn't exist." unless Pathname(checked_file).exist? system(ENV['EDITOR'], checked_file) end |
#parse ⇒ Object
Public: Kicks off the CLI
Examples
parse
Returns nothing.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/ldgr/parser.rb', line 55 def parse setup cli = OptionParser.new do |o| o. = "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 command = String(cli.parse(ARGV, into: config)[0]) send(command) if COMMANDS.include? command end |
#sort ⇒ Object
Public: Sorts all transactions by date.
Examples
sort
Returns nothing.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/ldgr/parser.rb', line 177 def sort text = File.read(transactions_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(transactions_file, 'w') do |file| file.puts results.sort end end |
#tag ⇒ Object
Public: Runs through all transactions with only Expenses set as the account and lets you enter an account name.
Examples
tag
Returns nothing.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/ldgr/parser.rb', line 148 def tag output = '' pattern = /(^\s+Expenses[^:])\s*(¥.+)/ count = 0 previous = '' File.open(transactions_file, 'r') do |transactions| transactions.each_line do |transaction| match = pattern.match(transaction) if match count += 1 puts "\n#{previous} #{match[2]}" 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(transactions_file, output) end |