commerce-bank-client 1.0.0
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/Manifest +8 -0
- data/README.markdown +15 -0
- data/Rakefile +16 -0
- data/commerce-bank-client.gemspec +33 -0
- data/lib/commercebank/monkey.rb +64 -0
- data/lib/commercebank.rb +232 -0
- data/test/commerce_bank_client_test.rb +6 -0
- data/test/monkeypatch_test.rb +11 -0
- data/test/test_helper.rb +10 -0
- data.tar.gz.sig +2 -0
- metadata +106 -0
- metadata.gz.sig +0 -0
data/Manifest
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
commerce-bank-client
|
2
|
+
====================
|
3
|
+
|
4
|
+
A Ruby client library for the Commerce Bank website (https://banking.commercebank.com).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
gem install commerce-bank-client
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
require "rubygems"
|
13
|
+
require "commercebank"
|
14
|
+
|
15
|
+
cb = CommerceBank.new
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new("commerce-bank-client", "1.0.0") do |p|
|
6
|
+
|
7
|
+
p.description = "An interface to the Commerce Bank website (https://banking.commercebank.com)."
|
8
|
+
p.url = "http://github.com/alexmchale/commerce-bank-client"
|
9
|
+
p.author = "Alex McHale"
|
10
|
+
p.email = "alexmchale@gmail.com"
|
11
|
+
p.ignore_pattern = %w( tmp/* script/* )
|
12
|
+
p.runtime_dependencies = []
|
13
|
+
p.development_dependencies = []
|
14
|
+
p.require_signed = true
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{commerce-bank-client}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Alex McHale"]
|
9
|
+
s.cert_chain = ["/home/alexmchale/.ssh/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2010-09-02}
|
11
|
+
s.description = %q{An interface to the Commerce Bank website (https://banking.commercebank.com).}
|
12
|
+
s.email = %q{alexmchale@gmail.com}
|
13
|
+
s.extra_rdoc_files = ["README.markdown", "lib/commercebank.rb", "lib/commercebank/monkey.rb"]
|
14
|
+
s.files = ["Manifest", "README.markdown", "Rakefile", "lib/commercebank.rb", "lib/commercebank/monkey.rb", "test/commerce_bank_client_test.rb", "test/monkeypatch_test.rb", "test/test_helper.rb", "commerce-bank-client.gemspec"]
|
15
|
+
s.homepage = %q{http://github.com/alexmchale/commerce-bank-client}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Commerce-bank-client", "--main", "README.markdown"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{commerce-bank-client}
|
19
|
+
s.rubygems_version = %q{1.3.7}
|
20
|
+
s.signing_key = %q{/home/alexmchale/.ssh/gem-private_key.pem}
|
21
|
+
s.summary = %q{An interface to the Commerce Bank website (https://banking.commercebank.com).}
|
22
|
+
s.test_files = ["test/test_helper.rb", "test/monkeypatch_test.rb", "test/commerce_bank_client_test.rb"]
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 3
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
29
|
+
else
|
30
|
+
end
|
31
|
+
else
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pp'
|
3
|
+
require 'andand'
|
4
|
+
require 'cgi'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
class Array
|
8
|
+
def binary
|
9
|
+
map {|e| yield(e) ? [e, nil] : [nil, e]}.transpose.map {|a| a.compact}
|
10
|
+
end
|
11
|
+
|
12
|
+
def paramify
|
13
|
+
hash = Hash.new
|
14
|
+
|
15
|
+
hash.merge! pop if last.kind_of? Hash
|
16
|
+
each {|e| hash[e] = true}
|
17
|
+
|
18
|
+
hash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Object
|
23
|
+
def to_cents
|
24
|
+
(to_s.gsub(/[^-.0-9]/, '').to_f * 100).to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_dollars(*options)
|
28
|
+
options = options.paramify
|
29
|
+
|
30
|
+
plus = options[:show_plus] ? '+' : ''
|
31
|
+
minus = options[:hide_minus] ? '' : '-'
|
32
|
+
sign = to_i >= 0 ? plus : minus
|
33
|
+
|
34
|
+
("%s%0.2f" % [ sign, to_i.abs / 100.0 ]).commify
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Date
|
39
|
+
def days_in_month
|
40
|
+
(Date.parse("12/31/#{strftime("%Y")}") << (12 - month)).day
|
41
|
+
end
|
42
|
+
|
43
|
+
def last_sunday
|
44
|
+
d = self
|
45
|
+
d -= 1 until d.wday == 0
|
46
|
+
d
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Hash
|
51
|
+
def to_url
|
52
|
+
map {|key, value| "#{CGI.escape key.to_s}=#{CGI.escape value.to_s}"}.join "&"
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_cookie
|
56
|
+
map {|key, value| "#{key}=#{value}"}.join('; ')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class String
|
61
|
+
def commify
|
62
|
+
reverse.gsub(/(\d\d\d)(?=\d)/, '\1,').reverse
|
63
|
+
end
|
64
|
+
end
|
data/lib/commercebank.rb
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'hpricot'
|
5
|
+
require 'andand'
|
6
|
+
require 'cgi'
|
7
|
+
require 'yaml'
|
8
|
+
require 'time'
|
9
|
+
require 'date'
|
10
|
+
require 'json'
|
11
|
+
require 'htmlentities'
|
12
|
+
require 'gmail'
|
13
|
+
require 'appconfig'
|
14
|
+
require 'commercebank/monkey.rb'
|
15
|
+
|
16
|
+
class Fixnum
|
17
|
+
def days; 24 * hours; end
|
18
|
+
def hours; 60 * minutes; end
|
19
|
+
def minutes; 60 * seconds; end
|
20
|
+
def seconds; self; end
|
21
|
+
end
|
22
|
+
|
23
|
+
class WebClient
|
24
|
+
attr_reader :fields, :cookies
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@cookies = Hash.new
|
28
|
+
@http = Net::HTTP.new('banking.commercebank.com', 443)
|
29
|
+
@http.use_ssl = true
|
30
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(path, form = nil)
|
34
|
+
response = @http.get(path, header)
|
35
|
+
add_cookies(response)
|
36
|
+
@fields = (form && get_form(response.body, form)) || Hash.new
|
37
|
+
response
|
38
|
+
end
|
39
|
+
|
40
|
+
def post(path, form = nil)
|
41
|
+
response = @http.post(path, @fields.to_url, header)
|
42
|
+
add_cookies(response)
|
43
|
+
@fields = (form && get_form(response.body, form)) || Hash.new
|
44
|
+
response
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def header
|
50
|
+
{ 'Cookie' => @cookies.to_cookie }
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_form(body, name)
|
54
|
+
Hpricot.buffer_size = 262144
|
55
|
+
doc = Hpricot.parse(body)
|
56
|
+
form = (doc/"##{name}").first
|
57
|
+
raise "could not find form #{name}" unless form
|
58
|
+
fields = Hash[*((form/"input").map {|e| [ e.attributes['name'], e.attributes['value'] ]}.flatten)]
|
59
|
+
fields['TestJavaScript'] = 'OK'
|
60
|
+
fields
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_cookies(response)
|
64
|
+
CGI::Cookie.parse(response.header['set-cookie']).each do |key, value|
|
65
|
+
@cookies[key] = value.first
|
66
|
+
end
|
67
|
+
|
68
|
+
@cookies.delete 'path'
|
69
|
+
@cookies.delete 'expires'
|
70
|
+
|
71
|
+
self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class CommerceBank
|
76
|
+
attr_reader :pending, :register, :current, :available
|
77
|
+
|
78
|
+
def initialize
|
79
|
+
@config = AppConfig.new('~/.commerce.yaml')
|
80
|
+
|
81
|
+
client = WebClient.new
|
82
|
+
|
83
|
+
client.get('/')
|
84
|
+
|
85
|
+
client.get('/CBI/login.aspx', 'MAINFORM')
|
86
|
+
|
87
|
+
client.fields['txtUserID'] = @config.get('username')
|
88
|
+
response = client.post('/CBI/login.aspx', 'MAINFORM')
|
89
|
+
|
90
|
+
# If a question was asked, answer it then get the password page.
|
91
|
+
question = response.body.scan(/Your security question: (.*?)<\/td>/i).first.andand.first
|
92
|
+
if question
|
93
|
+
client.fields['txtChallengeAnswer'] = @config.get(question)
|
94
|
+
client.fields['saveComputer'] = 'rdoBindDeviceNo'
|
95
|
+
response = client.post('/CBI/login.aspx', 'MAINFORM')
|
96
|
+
end
|
97
|
+
|
98
|
+
raise "could not reach the password page" unless client.fields['__EVENTTARGET'] == 'btnLogin'
|
99
|
+
|
100
|
+
client.fields['txtPassword'] = @config.get('password')
|
101
|
+
response = client.post('/CBI/login.aspx')
|
102
|
+
|
103
|
+
response = client.get('/CBI/Accounts/CBI/Activity.aspx', 'MAINFORM')
|
104
|
+
(@current, @available) = parse_balance(response.body)
|
105
|
+
@pending = parse_pending(response.body)
|
106
|
+
|
107
|
+
client.fields['Anthem_UpdatePage'] = 'true'
|
108
|
+
client.fields['txtFilterFromDate:textBox'] = (Time.now - 30.days).strftime('%m/%d/%Y')
|
109
|
+
client.fields['txtFilterToDate:textBox'] = Time.now.strftime('%m/%d/%Y')
|
110
|
+
response = client.post('/CBI/Accounts/CBI/Activity.aspx?Anthem_CallBack=true')
|
111
|
+
|
112
|
+
raw_data = JSON.parse(response.body)
|
113
|
+
@register = parse_register(raw_data['controls']['pnlPosted'])
|
114
|
+
|
115
|
+
@register.each do |entry|
|
116
|
+
entry[:images].map! do |image_url|
|
117
|
+
url = "https://banking.commercebank.com/CBI/Accounts/CBI/#{image_url[:url]}"
|
118
|
+
client.get(url).andand.body
|
119
|
+
end
|
120
|
+
entry[:images].compact!
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def daily_summary
|
125
|
+
today, yesterday, this_week, last_week = [], [], [], []
|
126
|
+
|
127
|
+
register.each do |entry|
|
128
|
+
if entry[:date] == Date.today then today << entry
|
129
|
+
elsif entry[:date] == (Date.today - 1) then yesterday << entry
|
130
|
+
elsif entry[:date] >= Date.today.last_sunday then this_week << entry
|
131
|
+
elsif entry[:date] >= (Date.today.last_sunday - 1).last_sunday then last_week << entry
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
yield 'Pending', @pending
|
136
|
+
yield 'Today', today
|
137
|
+
yield 'Yesterday', yesterday
|
138
|
+
yield 'This Week', this_week
|
139
|
+
yield 'Last Week', last_week
|
140
|
+
end
|
141
|
+
|
142
|
+
def monthly_summary(day_in_month = (Date.today - Date.today.day))
|
143
|
+
first_of_month = day_in_month - day_in_month.day + 1
|
144
|
+
last_of_month = first_of_month + day_in_month.days_in_month - 1
|
145
|
+
|
146
|
+
entries = register.find_all {|entry| entry[:date] >= first_of_month && entry[:date] <= last_of_month}
|
147
|
+
|
148
|
+
yield day_in_month.strftime('%B'), entries
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def parse_balance(body)
|
154
|
+
Hpricot.buffer_size = 262144
|
155
|
+
doc = Hpricot.parse(body)
|
156
|
+
summaryRows = doc/"table.summaryTable"/"tr"
|
157
|
+
current = (summaryRows[3]/"td")[1].inner_html.to_cents
|
158
|
+
available = (summaryRows[4]/"td")[1].inner_html.to_cents
|
159
|
+
[current, available]
|
160
|
+
end
|
161
|
+
|
162
|
+
def parse_pending(body)
|
163
|
+
Hpricot.buffer_size = 262144
|
164
|
+
doc = Hpricot.parse(body)
|
165
|
+
coder = HTMLEntities.new
|
166
|
+
|
167
|
+
(doc/"#grdMemoPosted"/"tr").map do |e|
|
168
|
+
next nil unless (e['class'] == 'item' || e['class'] == 'alternatingItem')
|
169
|
+
|
170
|
+
values = (e/"td").map {|e1| coder.decode(e1.inner_html.strip)}
|
171
|
+
|
172
|
+
debit = values[2].to_cents
|
173
|
+
credit = values[3].to_cents
|
174
|
+
delta = credit - debit
|
175
|
+
|
176
|
+
{ :date => parse_date(values[0]),
|
177
|
+
:destination => values[1],
|
178
|
+
:delta => delta,
|
179
|
+
:debit => debit,
|
180
|
+
:credit => credit }
|
181
|
+
end.compact
|
182
|
+
end
|
183
|
+
|
184
|
+
def parse_register(body)
|
185
|
+
Hpricot.buffer_size = 262144
|
186
|
+
doc = Hpricot.parse(body)
|
187
|
+
coder = HTMLEntities.new
|
188
|
+
(doc/"#grdHistory"/"tr").map do |e|
|
189
|
+
next nil unless [ 'item', 'alternatingitem' ].include? e['class'].to_s.downcase
|
190
|
+
|
191
|
+
anchor = e.at("a")
|
192
|
+
values = (e/"td").map {|e1| e1.inner_html}
|
193
|
+
date = parse_date(values[0])
|
194
|
+
check = values[1].strip
|
195
|
+
debit = values[3].to_cents
|
196
|
+
credit = values[4].to_cents
|
197
|
+
delta = credit - debit
|
198
|
+
total = values[5].scan(/\$[\d,]+\.\d\d/).first.to_cents
|
199
|
+
|
200
|
+
images = (e/"a").find_all do |e1|
|
201
|
+
e1['target'].to_s.downcase == 'checkimage'
|
202
|
+
end.map do |e1|
|
203
|
+
{ :url => e1['href'], :title => e1.inner_html.strip }
|
204
|
+
end
|
205
|
+
|
206
|
+
{
|
207
|
+
:destination => coder.decode(anchor.inner_html.strip),
|
208
|
+
:url => anchor['href'],
|
209
|
+
:date => date,
|
210
|
+
:check => check,
|
211
|
+
:images => images,
|
212
|
+
:delta => delta,
|
213
|
+
:debit => debit,
|
214
|
+
:credit => credit,
|
215
|
+
:total => total
|
216
|
+
}
|
217
|
+
end.compact
|
218
|
+
end
|
219
|
+
|
220
|
+
def parse_date(date_string)
|
221
|
+
(month, day, year) = date_string.scan(/(\d+)\/(\d+)\/(\d+)/).first
|
222
|
+
return nil unless month && day && year
|
223
|
+
|
224
|
+
month = month.to_i
|
225
|
+
day = day.to_i
|
226
|
+
year = year.to_i
|
227
|
+
year += 2000 if year < 100
|
228
|
+
|
229
|
+
Date.parse("%04d-%02d-%02d" % [ year, month, day ])
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MonkeyPatchTest < Test::Unit::TestCase
|
4
|
+
should "convert a hash to a valid url parameter string" do
|
5
|
+
h1 = { :foo => 1, :bar => 2, :baz => 3 }
|
6
|
+
assert_equal h1.to_url, 'foo=1&bar=2&baz=3'
|
7
|
+
|
8
|
+
h2 = { :foo => "What's up Doc", :bar => "1" }
|
9
|
+
assert_equal h2.to_url, "foo=What%27s+up+Doc&bar=1"
|
10
|
+
end
|
11
|
+
end
|
data/test/test_helper.rb
ADDED
data.tar.gz.sig
ADDED
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: commerce-bank-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alex McHale
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain:
|
17
|
+
- |
|
18
|
+
-----BEGIN CERTIFICATE-----
|
19
|
+
MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDAphbGV4
|
20
|
+
bWNoYWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
|
21
|
+
b20wHhcNMTAwODMxMTQ1NjExWhcNMTEwODMxMTQ1NjExWjBBMRMwEQYDVQQDDAph
|
22
|
+
bGV4bWNoYWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
|
23
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIUoy5sx2lmVzR
|
24
|
+
higIWdA6zFNSt1eibOVF0nCptQ2BejzefTmfhpgwWKDX9FvGdF213WBwxIGJFP0c
|
25
|
+
yOJTOoTgKQwQd6zCSoeNgNNHrXwbd42OKfHBTN1+DvNVoK9mLB659fUJ5CoCqNLU
|
26
|
+
FI6RtILyZVH/Hja8nnHJrfGjJ0aWSRueVuO/06QmKvm19EJEVbTSd/DwAbJTYrQD
|
27
|
+
6snqEY+64mcx8gvF2aCmGXKSpLqnTedsr3/16cd1rkHw7dZqbzyKc1uZaQL+giwp
|
28
|
+
Ijyn2SdMV+OKTf6xe/aL22aW/Z2b+tjQO8elB+/cz5kOlAkhtN3ENjf2e3H3UZSs
|
29
|
+
r+JQgRSdAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
30
|
+
BBS84ERhhfvntDfJzJe0/by+aeVeqDANBgkqhkiG9w0BAQUFAAOCAQEAFZRn7kGl
|
31
|
+
gvITFgcLlGAWNwYTfDiXm+8xjNXCyFLP2YgZvzNmP9HtzxnJHG9pk1tvAzKVgGQB
|
32
|
+
w+yPgHA9ASVnNP8/YifMVQtRkOYvmYiK+ynLTgqn3cCod0Q4mWcZ3mTsVfAqGxAZ
|
33
|
+
fyoyfn4C+7Ks6j3k7yXzcKoAi4w0RiHYUrNQAOFzkahHaovvophs88nIgq/HNSY6
|
34
|
+
tgs+JaGdLZUsgj0TZpzELi4d6iFDD44D/pAKN8VIpSlcbyKXkIyQa/NrKOTSie7u
|
35
|
+
AH5EvwIudku4RjdH363cTYX1xZ69LjcwrUpDrCJbG9jNK8icMoAOTEw0huZYvGRC
|
36
|
+
qyGdKMrvQEbACA==
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
|
39
|
+
date: 2010-09-02 00:00:00 +00:00
|
40
|
+
default_executable:
|
41
|
+
dependencies: []
|
42
|
+
|
43
|
+
description: An interface to the Commerce Bank website (https://banking.commercebank.com).
|
44
|
+
email: alexmchale@gmail.com
|
45
|
+
executables: []
|
46
|
+
|
47
|
+
extensions: []
|
48
|
+
|
49
|
+
extra_rdoc_files:
|
50
|
+
- README.markdown
|
51
|
+
- lib/commercebank.rb
|
52
|
+
- lib/commercebank/monkey.rb
|
53
|
+
files:
|
54
|
+
- Manifest
|
55
|
+
- README.markdown
|
56
|
+
- Rakefile
|
57
|
+
- lib/commercebank.rb
|
58
|
+
- lib/commercebank/monkey.rb
|
59
|
+
- test/commerce_bank_client_test.rb
|
60
|
+
- test/monkeypatch_test.rb
|
61
|
+
- test/test_helper.rb
|
62
|
+
- commerce-bank-client.gemspec
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: http://github.com/alexmchale/commerce-bank-client
|
65
|
+
licenses: []
|
66
|
+
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options:
|
69
|
+
- --line-numbers
|
70
|
+
- --inline-source
|
71
|
+
- --title
|
72
|
+
- Commerce-bank-client
|
73
|
+
- --main
|
74
|
+
- README.markdown
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 11
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 2
|
95
|
+
version: "1.2"
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project: commerce-bank-client
|
99
|
+
rubygems_version: 1.3.7
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: An interface to the Commerce Bank website (https://banking.commercebank.com).
|
103
|
+
test_files:
|
104
|
+
- test/test_helper.rb
|
105
|
+
- test/monkeypatch_test.rb
|
106
|
+
- test/commerce_bank_client_test.rb
|
metadata.gz.sig
ADDED
Binary file
|