reckon 0.4.3 → 0.4.4
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/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/lib/reckon/app.rb +35 -10
- data/reckon.gemspec +1 -1
- data/spec/data_fixtures/tokens.yaml +3 -1
- data/spec/reckon/app_spec.rb +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf1d814fe911f299cf58401c3b36734e29a172f1
|
4
|
+
data.tar.gz: 9130495690de1f73cfa3570a6e3386f38df86830
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7c3e23f96983cd79844ba37524f1b843a1dbba230198cf813b83c7c65a076506fb2c66ab663dee0970db2d42e1d3e0b03adf41ee163d08f3b38dbb163c373a6
|
7
|
+
data.tar.gz: d74ab72db15d54bc0bfe548369ec9a8b3903760bc09fbc16340a6f64c929a69d595c4840900e8a425996bc580e5924321ece84b10d3e033b193b066f2520f7c2
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -90,6 +90,8 @@ Expenses:
|
|
90
90
|
- 'MasterCard'
|
91
91
|
Rent:
|
92
92
|
- '0011223344' # Landlord bank number
|
93
|
+
Hosting:
|
94
|
+
- /hosting/i # This regexp will catch descriptions such as WebHosting or filehosting
|
93
95
|
'[Internal:Transfer]': # Virtual account
|
94
96
|
- '4433221100' # Your own account number
|
95
97
|
```
|
data/lib/reckon/app.rb
CHANGED
@@ -4,12 +4,13 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
module Reckon
|
6
6
|
class App
|
7
|
-
VERSION = "Reckon 0.4.
|
8
|
-
attr_accessor :options, :accounts, :tokens, :seen, :csv_parser
|
7
|
+
VERSION = "Reckon 0.4.4"
|
8
|
+
attr_accessor :options, :accounts, :tokens, :seen, :csv_parser, :regexps
|
9
9
|
|
10
10
|
def initialize(options = {})
|
11
11
|
self.options = options
|
12
12
|
self.tokens = {}
|
13
|
+
self.regexps = {}
|
13
14
|
self.accounts = {}
|
14
15
|
self.seen = {}
|
15
16
|
self.options[:currency] ||= '$'
|
@@ -54,7 +55,7 @@ module Reckon
|
|
54
55
|
if options[:account_tokens_file]
|
55
56
|
fail "#{options[:account_tokens_file]} doesn't exist!" unless File.exists?(options[:account_tokens_file])
|
56
57
|
extract_account_tokens(YAML.load_file(options[:account_tokens_file])).each do |account, tokens|
|
57
|
-
tokens.each { |t| learn_about_account(account, t) }
|
58
|
+
tokens.each { |t| learn_about_account(account, t, true) }
|
58
59
|
end
|
59
60
|
end
|
60
61
|
return unless options[:existing_ledger_file]
|
@@ -63,13 +64,27 @@ module Reckon
|
|
63
64
|
learn_from(ledger_data)
|
64
65
|
end
|
65
66
|
|
66
|
-
def learn_about_account(account, data)
|
67
|
+
def learn_about_account(account, data, parse_regexps = false)
|
67
68
|
accounts[account] ||= 0
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
if parse_regexps && data.start_with?('/')
|
70
|
+
# https://github.com/tenderlove/psych/blob/master/lib/psych/visitors/to_ruby.rb
|
71
|
+
match = data.match(/^\/(.*)\/([ix]*)$/m)
|
72
|
+
fail "failed to parse regexp #{data}" unless match
|
73
|
+
options = 0
|
74
|
+
(match[2] || '').split('').each do |option|
|
75
|
+
case option
|
76
|
+
when 'x' then options |= Regexp::EXTENDED
|
77
|
+
when 'i' then options |= Regexp::IGNORECASE
|
78
|
+
end
|
79
|
+
end
|
80
|
+
regexps[Regexp.new(match[1], options)] = account
|
81
|
+
else
|
82
|
+
tokenize(data).each do |token|
|
83
|
+
tokens[token] ||= {}
|
84
|
+
tokens[token][account] ||= 0
|
85
|
+
tokens[token][account] += 1
|
86
|
+
accounts[account] += 1
|
87
|
+
end
|
73
88
|
end
|
74
89
|
end
|
75
90
|
|
@@ -92,7 +107,8 @@ module Reckon
|
|
92
107
|
seen_anything_new = true
|
93
108
|
end
|
94
109
|
|
95
|
-
possible_answers =
|
110
|
+
possible_answers = most_specific_regexp_match(row)
|
111
|
+
possible_answers = weighted_account_match( row ).map! { |a| a[:account] } if possible_answers.empty?
|
96
112
|
|
97
113
|
ledger = if row[:money] > 0
|
98
114
|
if options[:unattended]
|
@@ -151,6 +167,15 @@ module Reckon
|
|
151
167
|
options[:output_file].flush
|
152
168
|
end
|
153
169
|
|
170
|
+
def most_specific_regexp_match( row )
|
171
|
+
matches = regexps.map { |regexp, account|
|
172
|
+
if match = regexp.match(row[:description])
|
173
|
+
[account, match[0]]
|
174
|
+
end
|
175
|
+
}.compact
|
176
|
+
matches.sort_by! { |account, matched_text| matched_text.length }.map(&:first)
|
177
|
+
end
|
178
|
+
|
154
179
|
# Weigh accounts by how well they match the row
|
155
180
|
def weighted_account_match( row )
|
156
181
|
query_tokens = tokenize(row[:description])
|
data/reckon.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = %q{reckon}
|
6
|
-
s.version = "0.4.
|
6
|
+
s.version = "0.4.4"
|
7
7
|
s.authors = ["Andrew Cantino", "BlackEdder"]
|
8
8
|
s.email = %q{andrew@iterationlabs.com}
|
9
9
|
s.homepage = %q{https://github.com/cantino/reckon}
|
data/spec/reckon/app_spec.rb
CHANGED
@@ -62,13 +62,14 @@ describe Reckon::App do
|
|
62
62
|
@output_file.string.scan('Expenses:Books').count.should == 1
|
63
63
|
end
|
64
64
|
|
65
|
-
it 'should learn from an account tokens file' do
|
65
|
+
it 'should learn from an account tokens file and parse regexps' do
|
66
66
|
@chase = Reckon::App.new(:string => BANK_CSV,
|
67
67
|
:unattended => true,
|
68
68
|
:output_file => @output_file,
|
69
69
|
:account_tokens_file => 'spec/data_fixtures/tokens.yaml')
|
70
70
|
@chase.walk_backwards
|
71
71
|
@output_file.string.scan('Expenses:Books').count.should == 1
|
72
|
+
@output_file.string.scan('Expenses:Websites').count.should == 2
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reckon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Cantino
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|