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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: def2132cbd39a44c0aece86b0ffa5f47c1be645e
4
- data.tar.gz: 0d8b5e4458577817812a7f35dc62a0afc9e696e2
3
+ metadata.gz: cf1d814fe911f299cf58401c3b36734e29a172f1
4
+ data.tar.gz: 9130495690de1f73cfa3570a6e3386f38df86830
5
5
  SHA512:
6
- metadata.gz: 836a0e77e93157362465452ff7ff2760c1a2bee8c5181cbe2a850e2229caf7bdc75b986f87465f61a5c8d34ae66e942985341d3d80d3eb6941e68d79f3217bcd
7
- data.tar.gz: 1065704ac1fba78cf115cd9406ddf18eb0bf93650d61fee2439b93e1d691fc304637d9742ae88e37050a472297466a375d76fc41261a9a8398a6015a0017328d
6
+ metadata.gz: b7c3e23f96983cd79844ba37524f1b843a1dbba230198cf813b83c7c65a076506fb2c66ab663dee0970db2d42e1d3e0b03adf41ee163d08f3b38dbb163c373a6
7
+ data.tar.gz: d74ab72db15d54bc0bfe548369ec9a8b3903760bc09fbc16340a6f64c929a69d595c4840900e8a425996bc580e5924321ece84b10d3e033b193b066f2520f7c2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reckon (0.4.3)
4
+ reckon (0.4.4)
5
5
  chronic (>= 0.3.0)
6
6
  fastercsv (>= 1.5.1)
7
7
  highline (>= 1.5.2)
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
  ```
@@ -4,12 +4,13 @@ require 'yaml'
4
4
 
5
5
  module Reckon
6
6
  class App
7
- VERSION = "Reckon 0.4.3"
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
- tokenize(data).each do |token|
69
- tokens[token] ||= {}
70
- tokens[token][account] ||= 0
71
- tokens[token][account] += 1
72
- accounts[account] += 1
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 = weighted_account_match( row ).map! { |a| a[:account] }
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])
@@ -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.3"
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}
@@ -5,9 +5,11 @@ Income:
5
5
  Expenses:
6
6
  Bank:
7
7
  - 'Comission'
8
- - 'MasterCard'
8
+ - /mastercard/i
9
9
  Rent:
10
10
  - '0011223344' # Landlord bank number
11
+ Websites:
12
+ - /web/i
11
13
  Books:
12
14
  - 'Book'
13
15
  '[Internal:Transfer]': # Virtual account
@@ -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.3
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-08-16 00:00:00.000000000 Z
12
+ date: 2015-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec