syrup 0.0.3 → 0.0.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.
- data/.gitignore +8 -7
- data/.rspec +2 -2
- data/CHANGELOG.rdoc +8 -2
- data/Gemfile +4 -4
- data/README.rdoc +46 -46
- data/Rakefile +8 -8
- data/TODO.rdoc +12 -12
- data/lib/syrup/account.rb +142 -143
- data/lib/syrup/information_missing_error.rb +8 -8
- data/lib/syrup/institutions/institution_base.rb +142 -142
- data/lib/syrup/institutions/uccu.rb +135 -0
- data/lib/syrup/institutions/zions_bank.rb +175 -175
- data/lib/syrup/transaction.rb +19 -19
- data/lib/syrup/version.rb +3 -3
- data/lib/syrup.rb +46 -46
- data/spec/spec_helper.rb +15 -15
- data/spec/syrup/account_spec.rb +52 -52
- data/spec/syrup/institutions/institution_base_spec.rb +119 -119
- data/spec/syrup/institutions/uccu_spec.rb +45 -0
- data/spec/syrup/institutions/zions_bank_spec.rb +40 -40
- data/spec/syrup/syrup_spec.rb +40 -40
- data/spec/syrup/transaction_spec.rb +20 -20
- data/syrup.gemspec +26 -26
- metadata +60 -42
data/.gitignore
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
*.swp
|
2
|
-
**/*.swp
|
3
|
-
*.gem
|
4
|
-
.bundle
|
5
|
-
Gemfile.lock
|
6
|
-
pkg/*
|
7
|
-
doc/*
|
1
|
+
*.swp
|
2
|
+
**/*.swp
|
3
|
+
*.gem
|
4
|
+
.bundle
|
5
|
+
Gemfile.lock
|
6
|
+
pkg/*
|
7
|
+
doc/*
|
8
|
+
.DS_Store
|
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
--color
|
2
|
-
--format documentation
|
1
|
+
--color
|
2
|
+
--format documentation
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
-
0.0.
|
2
|
-
|
1
|
+
0.0.3 (Jun 29, 2011)
|
2
|
+
|
3
|
+
* removed activesupport dependency in favor of multi_json
|
4
|
+
* ZionsBank now populates balance information while fetching transactions
|
5
|
+
* Account only tries to populate itself if the data being requested isn't there
|
6
|
+
|
7
|
+
0.0.1
|
8
|
+
|
3
9
|
* initial release
|
data/Gemfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
source "http://rubygems.org"
|
2
|
-
|
3
|
-
# Specify your gem's dependencies in syrup.gemspec
|
4
|
-
gemspec
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in syrup.gemspec
|
4
|
+
gemspec
|
data/README.rdoc
CHANGED
@@ -1,46 +1,46 @@
|
|
1
|
-
= Syrup
|
2
|
-
|
3
|
-
Syrup helps you to extract bank account information and transactions.
|
4
|
-
|
5
|
-
== Usage
|
6
|
-
|
7
|
-
# Setup an instance of the bank
|
8
|
-
zions_bank = Syrup.setup_institution('zions_bank') do |config|
|
9
|
-
config.username = 'user'
|
10
|
-
config.password = 'pass'
|
11
|
-
config.secret_questions = {'What is your secret question?' => "I don't know"}
|
12
|
-
end
|
13
|
-
|
14
|
-
# List accounts
|
15
|
-
zions_bank.accounts.each do |account|
|
16
|
-
puts "#{account.name} (#{account.current_balance}) # => "Checking (100.0)"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Get transactions
|
20
|
-
account = zions_bank.find_account_by_id 123456
|
21
|
-
transactions = account.find_transactions(Date.today - 30) # => an array of Transactions from the last 30 days
|
22
|
-
transactions = account.find_transactions(Date.parse('2011-01-01'), Date.parse('2011-02-01') - 1) # => an array of Transactions from the month of January
|
23
|
-
|
24
|
-
== Installation
|
25
|
-
|
26
|
-
The latest version of Syrup can be installed with Rubygems:
|
27
|
-
|
28
|
-
[sudo] gem install "syrup"
|
29
|
-
|
30
|
-
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
31
|
-
|
32
|
-
gem "syrup"
|
33
|
-
|
34
|
-
In <b>Rails 2</b>, add this to your environment.rb file.
|
35
|
-
|
36
|
-
config.gem "syrup"
|
37
|
-
|
38
|
-
== Supported Institutions
|
39
|
-
|
40
|
-
Currently, only Zions Bank[http://zionsbank.com] is supported. I will be
|
41
|
-
implementing UCCU, USAA, and Wells Fargo (probably in that order). If you would
|
42
|
-
like support for a different bank, you have two options:
|
43
|
-
|
44
|
-
1. Get me the credentials to log into an account with that bank (you'd have to
|
45
|
-
trust me).
|
46
|
-
2. Implement it yourself and submit a pull request. See {Adding Support For Another Institution}[https://github.com/dontangg/syrup/wiki/Adding-Support-For-Another-Institution]
|
1
|
+
= Syrup
|
2
|
+
|
3
|
+
Syrup helps you to extract bank account information and transactions.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
# Setup an instance of the bank
|
8
|
+
zions_bank = Syrup.setup_institution('zions_bank') do |config|
|
9
|
+
config.username = 'user'
|
10
|
+
config.password = 'pass'
|
11
|
+
config.secret_questions = {'What is your secret question?' => "I don't know"}
|
12
|
+
end
|
13
|
+
|
14
|
+
# List accounts
|
15
|
+
zions_bank.accounts.each do |account|
|
16
|
+
puts "#{account.name} (#{account.current_balance}) # => "Checking (100.0)"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get transactions
|
20
|
+
account = zions_bank.find_account_by_id 123456
|
21
|
+
transactions = account.find_transactions(Date.today - 30) # => an array of Transactions from the last 30 days
|
22
|
+
transactions = account.find_transactions(Date.parse('2011-01-01'), Date.parse('2011-02-01') - 1) # => an array of Transactions from the month of January
|
23
|
+
|
24
|
+
== Installation
|
25
|
+
|
26
|
+
The latest version of Syrup can be installed with Rubygems:
|
27
|
+
|
28
|
+
[sudo] gem install "syrup"
|
29
|
+
|
30
|
+
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
31
|
+
|
32
|
+
gem "syrup"
|
33
|
+
|
34
|
+
In <b>Rails 2</b>, add this to your environment.rb file.
|
35
|
+
|
36
|
+
config.gem "syrup"
|
37
|
+
|
38
|
+
== Supported Institutions
|
39
|
+
|
40
|
+
Currently, only {Zions Bank}[http://zionsbank.com] is supported. I will be
|
41
|
+
implementing UCCU, USAA, and Wells Fargo (probably in that order). If you would
|
42
|
+
like support for a different bank, you have two options:
|
43
|
+
|
44
|
+
1. Get me the credentials to log into an account with that bank (you'd have to
|
45
|
+
trust me).
|
46
|
+
2. Implement it yourself and submit a pull request. See {Adding Support For Another Institution}[https://github.com/dontangg/syrup/wiki/Adding-Support-For-Another-Institution]
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
|
4
|
-
Bundler::GemHelper.install_tasks
|
5
|
-
|
6
|
-
desc "Run tests"
|
7
|
-
RSpec::Core::RakeTask.new
|
8
|
-
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
desc "Run tests"
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
9
|
task :default => :spec
|
data/TODO.rdoc
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
Make sure that mechanize validates SSL certificates
|
3
|
-
|
4
|
-
When getting transactions
|
5
|
-
* populate as many variables on Account as you can (eg. current_balance, etc.)
|
6
|
-
|
7
|
-
Tests
|
8
|
-
* Add generic tests to test institution implementations
|
9
|
-
* Add tests to test Zions Bank without storing username, password, etc.
|
10
|
-
|
11
|
-
Documentation
|
12
|
-
* Improve GitHub wiki documentation
|
1
|
+
|
2
|
+
Make sure that mechanize validates SSL certificates
|
3
|
+
|
4
|
+
When getting transactions
|
5
|
+
* populate as many variables on Account as you can (eg. current_balance, etc.)
|
6
|
+
|
7
|
+
Tests
|
8
|
+
* Add generic tests to test institution implementations
|
9
|
+
* Add tests to test Zions Bank without storing username, password, etc.
|
10
|
+
|
11
|
+
Documentation
|
12
|
+
* Improve GitHub wiki documentation
|
data/lib/syrup/account.rb
CHANGED
@@ -1,144 +1,143 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
|
-
module Syrup
|
4
|
-
# An account contains all the information related to the account. Information
|
5
|
-
# is loaded lazily so that you can use an account to get transactions without
|
6
|
-
# incurring the cost of getting any account information.
|
7
|
-
class Account
|
8
|
-
##
|
9
|
-
# :attr_reader: name
|
10
|
-
# Gets the name of the account (eg. "Don's Checking").
|
11
|
-
|
12
|
-
##
|
13
|
-
# :attr_reader: type
|
14
|
-
# Gets the type of account. Currently, the only valid types are :deposit and :credit.
|
15
|
-
|
16
|
-
##
|
17
|
-
# :attr_reader: account_number
|
18
|
-
|
19
|
-
##
|
20
|
-
# :attr_reader: available_balance
|
21
|
-
|
22
|
-
##
|
23
|
-
# :attr_reader: current_balance
|
24
|
-
|
25
|
-
##
|
26
|
-
# :attr_reader: prior_day_balance
|
27
|
-
|
28
|
-
##
|
29
|
-
# :attr_reader: populated?
|
30
|
-
|
31
|
-
##
|
32
|
-
# :attr_writer: populated
|
33
|
-
|
34
|
-
##
|
35
|
-
# :attr_reader: valid?
|
36
|
-
# Since account information is lazily loaded, the validity of this account isn't immediately
|
37
|
-
# known. Once this account has been populated, this will return true if the account is a
|
38
|
-
# valid account, nil otherwise. Calling this method causes the account to attempt to be populated.
|
39
|
-
|
40
|
-
##
|
41
|
-
# :attr_writer: valid
|
42
|
-
|
43
|
-
#
|
44
|
-
attr_accessor :id
|
45
|
-
attr_writer :name, :type, :account_number, :current_balance, :available_balance, :prior_day_balance
|
46
|
-
|
47
|
-
|
48
|
-
def name
|
49
|
-
populate unless @name
|
50
|
-
@name
|
51
|
-
end
|
52
|
-
|
53
|
-
def type
|
54
|
-
populate unless @type
|
55
|
-
@type
|
56
|
-
end
|
57
|
-
|
58
|
-
def account_number
|
59
|
-
populate unless @account_number
|
60
|
-
@account_number
|
61
|
-
end
|
62
|
-
|
63
|
-
def current_balance
|
64
|
-
populate unless @current_balance
|
65
|
-
@current_balance
|
66
|
-
end
|
67
|
-
|
68
|
-
def available_balance
|
69
|
-
populate unless @available_balance
|
70
|
-
@available_balance
|
71
|
-
end
|
72
|
-
|
73
|
-
def prior_day_balance
|
74
|
-
populate unless @prior_day_balance
|
75
|
-
@prior_day_balance
|
76
|
-
end
|
77
|
-
|
78
|
-
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
79
|
-
# attributes (pass a hash with key names matching the associated attribute names).
|
80
|
-
def initialize(attr_hash = nil)
|
81
|
-
if attr_hash
|
82
|
-
attr_hash.each do |k, v|
|
83
|
-
instance_variable_set "@#{k}", v
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
@cached_transactions = []
|
88
|
-
end
|
89
|
-
|
90
|
-
def populated?
|
91
|
-
@populated
|
92
|
-
end
|
93
|
-
|
94
|
-
def populated=(value)
|
95
|
-
@populated = value
|
96
|
-
end
|
97
|
-
|
98
|
-
# Populates this account with all of its information
|
99
|
-
def populate
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
#
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Syrup
|
4
|
+
# An account contains all the information related to the account. Information
|
5
|
+
# is loaded lazily so that you can use an account to get transactions without
|
6
|
+
# incurring the cost of getting any account information.
|
7
|
+
class Account
|
8
|
+
##
|
9
|
+
# :attr_reader: name
|
10
|
+
# Gets the name of the account (eg. "Don's Checking").
|
11
|
+
|
12
|
+
##
|
13
|
+
# :attr_reader: type
|
14
|
+
# Gets the type of account. Currently, the only valid types are :deposit and :credit.
|
15
|
+
|
16
|
+
##
|
17
|
+
# :attr_reader: account_number
|
18
|
+
|
19
|
+
##
|
20
|
+
# :attr_reader: available_balance
|
21
|
+
|
22
|
+
##
|
23
|
+
# :attr_reader: current_balance
|
24
|
+
|
25
|
+
##
|
26
|
+
# :attr_reader: prior_day_balance
|
27
|
+
|
28
|
+
##
|
29
|
+
# :attr_reader: populated?
|
30
|
+
|
31
|
+
##
|
32
|
+
# :attr_writer: populated
|
33
|
+
|
34
|
+
##
|
35
|
+
# :attr_reader: valid?
|
36
|
+
# Since account information is lazily loaded, the validity of this account isn't immediately
|
37
|
+
# known. Once this account has been populated, this will return true if the account is a
|
38
|
+
# valid account, nil otherwise. Calling this method causes the account to attempt to be populated.
|
39
|
+
|
40
|
+
##
|
41
|
+
# :attr_writer: valid
|
42
|
+
|
43
|
+
#
|
44
|
+
attr_accessor :id
|
45
|
+
attr_writer :name, :type, :account_number, :current_balance, :available_balance, :prior_day_balance
|
46
|
+
|
47
|
+
|
48
|
+
def name
|
49
|
+
populate unless @name
|
50
|
+
@name
|
51
|
+
end
|
52
|
+
|
53
|
+
def type
|
54
|
+
populate unless @type
|
55
|
+
@type
|
56
|
+
end
|
57
|
+
|
58
|
+
def account_number
|
59
|
+
populate unless @account_number
|
60
|
+
@account_number
|
61
|
+
end
|
62
|
+
|
63
|
+
def current_balance
|
64
|
+
populate unless @current_balance
|
65
|
+
@current_balance
|
66
|
+
end
|
67
|
+
|
68
|
+
def available_balance
|
69
|
+
populate unless @available_balance
|
70
|
+
@available_balance
|
71
|
+
end
|
72
|
+
|
73
|
+
def prior_day_balance
|
74
|
+
populate unless @prior_day_balance
|
75
|
+
@prior_day_balance
|
76
|
+
end
|
77
|
+
|
78
|
+
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
79
|
+
# attributes (pass a hash with key names matching the associated attribute names).
|
80
|
+
def initialize(attr_hash = nil)
|
81
|
+
if attr_hash
|
82
|
+
attr_hash.each do |k, v|
|
83
|
+
instance_variable_set "@#{k}", v
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@cached_transactions = []
|
88
|
+
end
|
89
|
+
|
90
|
+
def populated?
|
91
|
+
@populated
|
92
|
+
end
|
93
|
+
|
94
|
+
def populated=(value)
|
95
|
+
@populated = value
|
96
|
+
end
|
97
|
+
|
98
|
+
# Populates this account with all of its information
|
99
|
+
def populate
|
100
|
+
unless populated? || @institution.nil?
|
101
|
+
raise "The account id must not be nil when populating an account" if id.nil?
|
102
|
+
@institution.populate_account(id)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Tests equality of this account with another account. Accounts are considered equal
|
107
|
+
# if they have the same id.
|
108
|
+
def ==(other_account)
|
109
|
+
other_account.id == self.id && other_account.is_a?(Account)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns an array of transactions from this account for the supplied date range.
|
113
|
+
def find_transactions(starting_at, ending_at = Date.today)
|
114
|
+
return [] if starting_at > ending_at
|
115
|
+
|
116
|
+
@institution.fetch_transactions(self.id, starting_at, ending_at)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Merges this account information with another account. The other account's information
|
120
|
+
# overrides this account's.
|
121
|
+
def merge!(account_with_info)
|
122
|
+
if account_with_info
|
123
|
+
account_with_info.instance_variables.each do |filled_var|
|
124
|
+
self.instance_variable_set(filled_var, account_with_info.instance_variable_get(filled_var))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
130
|
+
def valid?
|
131
|
+
if @valid.nil?
|
132
|
+
populate
|
133
|
+
@valid = populated?
|
134
|
+
end
|
135
|
+
@valid
|
136
|
+
end
|
137
|
+
|
138
|
+
def valid=(validity)
|
139
|
+
@valid = validity
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
144
143
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
module Syrup
|
2
|
-
# This error is raised when the information supplied was invalid or incorrect.
|
3
|
-
# Here are some example situations:
|
4
|
-
#
|
5
|
-
# * A username/password wasn't supplied.
|
6
|
-
# * The password supplied didn't work.
|
7
|
-
class InformationMissingError < StandardError
|
8
|
-
end
|
1
|
+
module Syrup
|
2
|
+
# This error is raised when the information supplied was invalid or incorrect.
|
3
|
+
# Here are some example situations:
|
4
|
+
#
|
5
|
+
# * A username/password wasn't supplied.
|
6
|
+
# * The password supplied didn't work.
|
7
|
+
class InformationMissingError < StandardError
|
8
|
+
end
|
9
9
|
end
|