quicken 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Daniel Lopes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = quicken
2
+
3
+ This gem was created with the purpoise to import QIF files in a real project. The kind of QIF files that we need import doesn't
4
+ match the official specification of QIF format, so I only support the fields that are important to my project. If you need
5
+ full support of QIF format or adjustments to fit your needs please fork the project and send a pull request to me.
6
+
7
+ == Note on Patches/Pull Requests
8
+
9
+ * Fork the project.
10
+ * Make your feature addition or bug fix.
11
+ * Add tests for it. This is important so I don't break it in a
12
+ future version unintentionally.
13
+ * Commit, do not mess with rakefile, version, or history.
14
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
15
+ * Send me a pull request. Bonus points for topic branches.
16
+
17
+ == Copyright
18
+
19
+ Copyright (c) 2010 Daniel Lopes. See LICENSE for details.
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "quicken"
8
+ gem.summary = %Q{simple QIF parser}
9
+ gem.description = %Q{QIF (Quicken Interchange Format) parser}
10
+ gem.email = "danielvlopes@gmail.com"
11
+ gem.homepage = "http://github.com/danielvlopes/quicken"
12
+ gem.authors = ["Daniel Lopes"]
13
+ gem.add_development_dependency "rspec", ">= 1.3.0"
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'spec/rake/spectask'
21
+ Spec::Rake::SpecTask.new(:spec) do |spec|
22
+ spec.libs << 'lib' << 'spec'
23
+ spec.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.rcov = true
30
+ end
31
+
32
+ task :spec => :check_dependencies
33
+
34
+ task :default => :spec
35
+
36
+ require 'rake/rdoctask'
37
+ Rake::RDocTask.new do |rdoc|
38
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
39
+
40
+ rdoc.rdoc_dir = 'rdoc'
41
+ rdoc.title = "quicken #{version}"
42
+ rdoc.rdoc_files.include('README*')
43
+ rdoc.rdoc_files.include('lib/**/*.rb')
44
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,7 @@
1
+ module Quicken
2
+ autoload :Spec, 'quicken/spec'
3
+ autoload :Foundation, 'quicken/foundation'
4
+ autoload :Account, 'quicken/account'
5
+ autoload :Transaction, 'quicken/transaction'
6
+ autoload :Parser, 'quicken/parser'
7
+ end
@@ -0,0 +1,11 @@
1
+ module Quicken
2
+ class Account < Foundation
3
+ accessors_for_spec Quicken::Spec::ACCOUNT
4
+
5
+ def ==(another)
6
+ self.number == another.number &&
7
+ self.type == another.type
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module Quicken
2
+ class Foundation
3
+
4
+ def self.accessors_for_spec(spec)
5
+ spec.each do |key, item|
6
+ instance_eval do
7
+ attr_accessor key.to_sym
8
+ end
9
+ end
10
+ end
11
+
12
+ def initialize(attrs={})
13
+ attrs.each do |key, value|
14
+ begin
15
+ send("#{key}=", value)
16
+ rescue
17
+ next
18
+ end
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,65 @@
1
+ module Quicken
2
+
3
+ class Parser
4
+ attr_accessor :file, :date_format, :transactions, :account
5
+
6
+ def initialize(file, date_format=nil)
7
+ @date_format = date_format
8
+ @file = file
9
+ @transactions_attrs = []
10
+ @account_attrs = {}
11
+ end
12
+
13
+ def parse!
14
+ section = nil
15
+
16
+ File.foreach(@file) do |line|
17
+ if line =~ /^\!(\S+)/
18
+ section = extract_section($1)
19
+ next
20
+ end
21
+
22
+ (section == :account) ? parse_account(line) : parse_transactions(line)
23
+ end
24
+
25
+ build_objects
26
+ self
27
+ end
28
+
29
+ private
30
+
31
+ def build_objects
32
+ @account = Quicken::Account.new(@account_attrs) unless @account_attrs.empty?
33
+ @transactions = @transactions_attrs.collect do |t|
34
+ t.merge!({:date_format=>@date_format}) unless @date_format.nil?
35
+ Quicken::Transaction.new(t)
36
+ end
37
+ end
38
+
39
+ def parse_transactions(line)
40
+ Quicken::Spec::TRANSACTION.each do |spec, rule|
41
+ if line =~ /^\^/
42
+ @transactions_attrs << @transaction unless @transaction.nil?
43
+ @transaction = nil
44
+ elsif line =~ rule
45
+ @transaction ||= {}
46
+ @transaction.merge!({ spec => $1.chomp })
47
+ end
48
+ end
49
+ end
50
+
51
+ def parse_account(line)
52
+ Quicken::Spec::ACCOUNT.each do |spec, rule|
53
+ next unless line =~ rule
54
+ @account_attrs.merge!({ spec => $1 })
55
+ break
56
+ end
57
+ end
58
+
59
+ def extract_section(section)
60
+ section.gsub("Type:","").downcase.to_sym
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,30 @@
1
+ module Quicken
2
+ module Spec
3
+ ACCOUNT = {
4
+ :number => /^N(.+)/,
5
+ :type => /^T(.+)/
6
+ }
7
+
8
+ TRANSACTION = {
9
+ :number => /^N(.+)/,
10
+ :amount => /^T(.+)/,
11
+ :date => /^D(.+)/,
12
+ :memo => /^M(.+)/,
13
+ :cleared => /^C(.+)/,
14
+ :payee => /^P(.+)/,
15
+ :address => /^A(.+)/,
16
+ :category => /^L(.+)/,
17
+ :flag => /^F(.+)/,
18
+ :investment => /^N(.+)/,
19
+ :investment_security => /^Y(.+)/,
20
+ :investment_price => /^I(.+)/,
21
+ :investment_shares_quantity => /^Q(.+)/,
22
+ :investment_commission => /^O(.+)/,
23
+ :split_category => /^S(.+)/,
24
+ :split_memo => /^E(.+)/,
25
+ :split_percentage => /^\%(.+)/,
26
+ :split_or_investment_amount => /^\$(.+)/
27
+ }
28
+
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'bigdecimal'
2
+
3
+ module Quicken
4
+
5
+ class Transaction < Foundation
6
+ accessors_for_spec Quicken::Spec::TRANSACTION
7
+
8
+ def initialize(attrs)
9
+ @date_format = attrs.delete(:date_format) || [:month,:day,:year]
10
+ super(attrs)
11
+ end
12
+
13
+ def date=(value)
14
+ parts = extract_date_parts(value)
15
+ @date = Date.parse("#{parts[:year]}-#{parts[:month]}-#{parts[:day]}", true)
16
+ end
17
+
18
+ %w(amount investment_price investment_shares_quantity
19
+ investment_commission split_or_investment_amount).each do |method|
20
+ define_method "#{method}=" do |value|
21
+ instance_variable_set("@#{method}", BigDecimal.new(value.delete(",")))
22
+ end
23
+ end
24
+
25
+ private
26
+ def extract_date_parts(date)
27
+ parts = date.match(/(\d+)[\/|\-](\d+)[\/|\-|'](\d+)/)[1..3]
28
+ result = {}
29
+ @date_format.each_with_index { |v, i| result.merge!({ v => parts[i] }) }
30
+ result
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,75 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{quicken}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Daniel Lopes"]
12
+ s.date = %q{2010-05-25}
13
+ s.description = %q{QIF (Quicken Interchange Format) parser}
14
+ s.email = %q{danielvlopes@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/quicken.rb",
27
+ "lib/quicken/account.rb",
28
+ "lib/quicken/foundation.rb",
29
+ "lib/quicken/parser.rb",
30
+ "lib/quicken/spec.rb",
31
+ "lib/quicken/transaction.rb",
32
+ "quicken.gemspec",
33
+ "spec/fixtures/bco_real.qif",
34
+ "spec/fixtures/default.qif",
35
+ "spec/fixtures/ms_money.qif",
36
+ "spec/quicken/account_spec.rb",
37
+ "spec/quicken/foundation_spec.rb",
38
+ "spec/quicken/parser_spec.rb",
39
+ "spec/quicken/spec_spec.rb",
40
+ "spec/quicken/transaction_spec.rb",
41
+ "spec/spec.opts",
42
+ "spec/spec_helper.rb",
43
+ "spec/support/macros/foundation_macro.rb",
44
+ "spec/support/matchers/money_matcher.rb"
45
+ ]
46
+ s.homepage = %q{http://github.com/danielvlopes/quicken}
47
+ s.rdoc_options = ["--charset=UTF-8"]
48
+ s.require_paths = ["lib"]
49
+ s.rubygems_version = %q{1.3.6}
50
+ s.summary = %q{simple QIF parser}
51
+ s.test_files = [
52
+ "spec/quicken/account_spec.rb",
53
+ "spec/quicken/foundation_spec.rb",
54
+ "spec/quicken/parser_spec.rb",
55
+ "spec/quicken/spec_spec.rb",
56
+ "spec/quicken/transaction_spec.rb",
57
+ "spec/spec_helper.rb",
58
+ "spec/support/macros/foundation_macro.rb",
59
+ "spec/support/matchers/money_matcher.rb"
60
+ ]
61
+
62
+ if s.respond_to? :specification_version then
63
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
64
+ s.specification_version = 3
65
+
66
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
67
+ s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
68
+ else
69
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
70
+ end
71
+ else
72
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
73
+ end
74
+ end
75
+
@@ -0,0 +1,50 @@
1
+ !Account
2
+ N0833_5710633
3
+ TBank
4
+ ^
5
+ !Type:Bank
6
+ D19/04/10
7
+ T6960.00
8
+ N0002593
9
+ MTED 790.234.526-15
10
+ ^
11
+ D19/04/10
12
+ T-45.98
13
+ N0001223
14
+ MCOMPRA VISA ELECTRON
15
+ ^
16
+ D19/04/10
17
+ T-100.00
18
+ N0000021
19
+ MSAQUE BANCO24H
20
+ ^
21
+ D19/04/10
22
+ T-2.86
23
+ N0002236
24
+ MTRANSF.P/ TANIA FIGUEIRED
25
+ ^
26
+ D23/04/10
27
+ T-54.16
28
+ N0001223
29
+ MCOMPRA VISA ELECTRON
30
+ ^
31
+ D12/05/10
32
+ T3.31
33
+ N0002313
34
+ MJUROS POUPANCA
35
+ ^
36
+ D12/05/10
37
+ T0.22
38
+ N0002464
39
+ MCORRECAO POUPANCA
40
+ ^
41
+ D17/05/10
42
+ T-24.90
43
+ N0001223
44
+ MCOMPRA VISA ELECTRON
45
+ ^
46
+ D17/05/10
47
+ T-400.00
48
+ N0000132
49
+ MSAQUE COM CARTAO
50
+ ^
@@ -0,0 +1,26 @@
1
+
2
+ !Account
3
+ N0833_5710633
4
+ TBank
5
+ ^
6
+ !Type:Bank
7
+ D04/19/10
8
+ T6960.00
9
+ N0002593
10
+ MTED 790.234.526-15
11
+ ^
12
+ D04/19/10
13
+ T-45.98
14
+ N0001223
15
+ MCOMPRA VISA ELECTRON
16
+ ^
17
+ D04/19/10
18
+ T-100.00
19
+ N0000021
20
+ MSAQUE BANCO24H
21
+ ^
22
+ D04/19/10
23
+ T-2.86
24
+ N0002236
25
+ MTransferência Tânia
26
+ ^