quicken 0.0.1

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.
@@ -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
+ ^