mizuho_bank 0.1.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 kimoto
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,18 @@
1
+ = mizuho_bank
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2011 kimoto. See LICENSE for details.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,238 @@
1
+ # encoding: utf-8
2
+ require 'mechanize'
3
+ require 'kconv'
4
+ require 'logger'
5
+ require 'retry-handler'
6
+
7
+ class MizuhoBank
8
+ TOP_URL = "https://web.ib.mizuhobank.co.jp/servlet/mib?xtr=Emf00000"
9
+ CACHEFLOW_URL = '/servlet/mib?xtr=Emf04000&NLS=JP'
10
+
11
+ attr_reader :info
12
+
13
+ def initialize(keiyaku_no, password, aikotoba_dict={}, logger=nil, &block)
14
+ @agent = nil
15
+ @logger = Logger.new(nil)
16
+ @logger = logger unless logger.nil?
17
+
18
+ if login(keiyaku_no, password, aikotoba_dict)
19
+ block.call(self) if block_given?
20
+ end
21
+ self
22
+ end
23
+
24
+ def login(keiyaku_no, password, aikotoba_dict={})
25
+ @login_result = false
26
+ Proc.new do
27
+ @agent = Mechanize.new{ |agent|
28
+ agent.user_agent_alias = "Windows IE 7"
29
+ }
30
+
31
+ auth_keiyaku_no(keiyaku_no)
32
+
33
+ while true
34
+ page_id = what_is_this_page?
35
+ @logger.info "page: #{page_id.inspect}"
36
+
37
+ case page_id
38
+ when :auth_keiyaku_no
39
+ auth_keiyaku_no(keiyaku_no)
40
+ when :auth_aikotoba
41
+ aikotoba_theme = extract_aikotoba_theme
42
+ aikotoba_answer = aikotoba_dict[aikotoba_theme]
43
+ auth_aikotoba(aikotoba_theme, aikotoba_answer)
44
+ when :auth_password
45
+ auth_password(password)
46
+ when :logout_fail_info
47
+ raise "Logout fail info page!!"
48
+ when :unknown
49
+ @logger.info "unknown page reached: #{@agent.page.title}"
50
+ @login_result = true
51
+
52
+ @info = load_bank_page(@agent.page.body.toutf8)
53
+ go_cacheflow_page
54
+ @info.main_account = load_cacheflow_page(@agent.page.body.toutf8)
55
+ break
56
+ when :not_connection
57
+ @logger.info "not connection"
58
+ end
59
+ end
60
+ end.retry(:logger => @logger, :accept_exception => StandardError, :wait => 5, :max => 5)
61
+ @login_result
62
+ end
63
+
64
+ private
65
+ # 契約者番号の認証ページ処理
66
+ def is_auth_keiyaku_no_page?
67
+ @agent.page.body.toutf8.include? "お客さま番号を入力し、「次へ」ボタンを"
68
+ end
69
+
70
+ def auth_keiyaku_no(keiyaku_no)
71
+ @logger.info "auth_keiyaku_no: #{keiyaku_no}"
72
+ @agent.get(TOP_URL){ |page| # ページ取得
73
+ unless is_auth_keiyaku_no_page?
74
+ raise "not keiyakusya no page error"
75
+ end
76
+
77
+ page.form_with(:name => 'FORM1'){ |f|
78
+ f.field_with(:name => 'KeiyakuNo').value = keiyaku_no.tosjis
79
+ f.click_button
80
+ }
81
+ }
82
+ end
83
+
84
+ # 合言葉入力画面であるかどうか
85
+ def is_auth_aikotoba_page?
86
+ @agent.page.body.toutf8.include? "合言葉確認"
87
+ end
88
+
89
+ def extract_aikotoba_theme
90
+ unless is_auth_aikotoba_page?
91
+ raise "not aikotoba page error"
92
+ end
93
+
94
+ aikotoba_theme = Nokogiri(@agent.page.body.toutf8).search("center > :nth-child(7) > :nth-child(2) > td > div").last.text
95
+ end
96
+
97
+ def auth_aikotoba(aikotoba_theme, aikotoba)
98
+ @logger.info "auth_aikotoba: #{aikotoba_theme} => #{aikotoba}"
99
+ @agent.page.form_with(:name => 'FORM1'){ |f|
100
+ f.field_with(:name => 'rskAns').value = aikotoba.tosjis
101
+ f.click_button
102
+ }
103
+ end
104
+
105
+ def is_auth_password_page?
106
+ @agent.page.body.toutf8.include? "ご登録いただいている画像を確認のうえ、ログインパスワードを半角英数字で入力し"
107
+ end
108
+
109
+ def is_logout_fail_info_page?
110
+ @agent.page.body.toutf8.include? "ログインできませんでした。前回の操作で正しくログアウトされていない可能性があります。"
111
+ end
112
+
113
+ def auth_password(password)
114
+ @agent.page.form_with(:name => 'FORM1'){ |f|
115
+ f.field_with(:name => 'Anshu1No').value = password.tosjis
116
+ f.click_button
117
+ }
118
+ end
119
+
120
+ def what_is_this_page?
121
+ if @agent.page.nil? or @agent.page.body.nil?
122
+ return :not_connection
123
+ end
124
+
125
+ if is_auth_aikotoba_page?
126
+ return :auth_aikotoba
127
+ elsif is_logout_fail_info_page?
128
+ return :logout_fail_info
129
+ elsif is_auth_password_page?
130
+ return :auth_password
131
+ elsif is_auth_keiyaku_no_page?
132
+ return :auth_keiyaku_no
133
+ else
134
+ return :unknown
135
+ end
136
+ end
137
+
138
+ def load_bank_page(page_data)
139
+ doc = Nokogiri(page_data)
140
+ content = doc.search("#bodycontent > div > table")[4]
141
+
142
+ info = MizuhoDirectInfo.new
143
+ info.username = content.search("tr > td > table > tr > td > div > b")[0].text.gsub(/さまの$/, "")
144
+ info.last_logined_at = content.search("tr > td > table > tr > td > div > b")[2].text
145
+ info.mailaddr = content.search("tr > td > table > tr > td > div > b")[4].text
146
+
147
+ account = MizuhoAccount.new
148
+ account.name = content.search("tr").search("./td/table")[2].search("table > tr")[3].search("table > tr > td > div")[1].text.toutf8.strip
149
+ account.deal_type = content.search("tr").search("./td/table")[2].search("table > tr")[3].search("table > tr > td > div")[3].text.toutf8.strip
150
+ account.number = content.search("tr").search("./td/table")[2].search("table > tr")[3].search("table > tr > td > div")[5].text.toutf8.strip
151
+ account.money = content.search("tr").search("./td/table")[2].search("table > tr")[3].search("table > tr > td > div")[7].text.toutf8.strip
152
+ account.usable_money = content.search("tr").search("./td/table")[2].search("table > tr")[3].search("table > tr > td > div")[9].text.toutf8.strip
153
+
154
+ info.latest_cache_flows = []
155
+ info.main_account = account
156
+
157
+ records = content.search("tr").search("./td/table")[2].search("./tr/td/table/tr")[6].search("table > tr > td > div")
158
+ 10.times{ |n|
159
+ i = (n + 1) * 4
160
+
161
+ cacheflow = MizuhoCacheFlow.new
162
+ cacheflow.date = records[i+0].text.toutf8.strip
163
+ cacheflow.money_in = records[i+1].text.toutf8.strip
164
+ cacheflow.money_out = records[i+2].text.toutf8.strip
165
+ cacheflow.summary = records[i+3].text.toutf8.strip
166
+ info.latest_cache_flows << cacheflow
167
+ }
168
+ info
169
+ end
170
+
171
+ def load_cacheflow_page(data)
172
+ content = Nokogiri(data).search("#bodycontent > div > table")[4]
173
+
174
+ account = MizuhoAccount.new
175
+ account.name = content.search("./tr/td/table/tr/td/table/tr")[1].search("./td/table/tr/td/table/tr/td/div")[1].text.toutf8.strip
176
+ account.deal_type = content.search("./tr/td/table/tr/td/table/tr")[1].search("./td/table/tr/td/table/tr/td/div")[3].text.toutf8.strip
177
+ account.number = content.search("./tr/td/table/tr/td/table/tr")[1].search("./td/table/tr/td/table/tr/td/div")[5].text.toutf8.strip
178
+ account.money = content.search("./tr/td/table/tr/td/table/tr")[1].search("./td/table/tr/td/table/tr/td/div")[7].text.toutf8.strip
179
+ account.usable_money = content.search("./tr/td/table/tr/td/table/tr")[1].search("./td/table/tr/td/table/tr/td/div")[9].text.toutf8.strip
180
+
181
+ account.cache_flows = []
182
+ flows = content.search("./tr/td/table/tr/td/table/tr")[4].search("./td/table/tr/td/table/tr/td/div").map(&:text).map(&:toutf8).map(&:strip)
183
+ (flows.size / 4 - 1).times{ |n|
184
+ i = (n + 1) * 4
185
+ cf = MizuhoCacheFlow.new
186
+ (cf.date, cf.money_in, cf.money_out, cf.summary) = [flows[i], flows[i+1], flows[i+2], flows[i+3]]
187
+ account.cache_flows << cf
188
+ }
189
+
190
+ account
191
+ end
192
+
193
+ def go_cacheflow_page
194
+ @agent.get(CACHEFLOW_URL)
195
+ @agent.page.form_with(:name => 'FORM1'){ |f|
196
+ f.field_with(:name => 'SelAcct'){ |list|
197
+ list.options.first.select
198
+ }
199
+ f.field_with(:name => 'INQUIRY_MONTH_TYPE'){ |list|
200
+ list.options.each{ |opt|
201
+ if opt.value == "BEFORE_LASTMONTH"
202
+ opt.select
203
+ end
204
+ }
205
+ }
206
+ f.click_button
207
+ }
208
+ end
209
+
210
+ class MizuhoDirectInfo
211
+ attr_accessor :username
212
+ attr_accessor :mailaddr
213
+ attr_accessor :last_logined_at
214
+ attr_accessor :informations # reserved
215
+ attr_accessor :main_account
216
+ attr_accessor :latest_cache_flows
217
+ end
218
+
219
+ class MizuhoCacheFlow
220
+ attr_accessor :date
221
+ attr_accessor :value
222
+ attr_accessor :summary
223
+
224
+ attr_accessor :money_in
225
+ attr_accessor :money_out
226
+ end
227
+
228
+ class MizuhoAccount
229
+ attr_accessor :name # 店名
230
+ attr_accessor :deal_type # 取引種類
231
+ attr_accessor :number # 口座番号
232
+ attr_accessor :money # 残高
233
+ attr_accessor :usable_money # お引き出し可能残高
234
+ attr_accessor :cache_flows # C/F明細
235
+ end
236
+ end
237
+
238
+
@@ -0,0 +1,19 @@
1
+ みずほ銀行ウェブサイトから口座残高を取得するスクリプト
2
+
3
+ 2009年頃に正しく動作していることを確認しているのですが、現在は不明
4
+ たぶんUI変わってるだろうし無理
5
+
6
+ 暇を見つけて今後修正していく予定なので一応githubにアップ
7
+
8
+ __
9
+ ちなみに当時の使い方は
10
+ 1. Firefoxでみずほ銀行ウェブサイトにログイン
11
+ 2. ./bin/cookie.plでfirefoxのsqlite3データベースからcookie情報を取得
12
+ 3. そのcookie情報を元に、mizuho.rbを実行って感じです
13
+ -------------------
14
+ MizuhoBank.start(pit['username'], pit['password'], pit['aikotoba1'], pit['aikotoba2']){ |bank|
15
+ p bank.money
16
+ }
17
+ -------------------
18
+ とすると標準出力に、口座残高が出力される
19
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class MizuhoBankTest < Test::Unit::TestCase
4
+ should true do
5
+ true
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'mizuho_bank'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mizuho_bank
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - kimoto
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-11-25 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thoughtbot-shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ description: Mizuho Bank (Mizuho Direct) Ruby Interface
34
+ email: sub+peerler@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - LICENSE
41
+ - README.rdoc
42
+ files:
43
+ - VERSION
44
+ - lib/mizuho_bank.rb
45
+ - readme.txt
46
+ - LICENSE
47
+ - README.rdoc
48
+ - test/test_helper.rb
49
+ - test/mizuho_bank_test.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/kimoto/mizuho_bank
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.3.7
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Mizuho Bank (Mizuho Direct) Ruby Interface
82
+ test_files:
83
+ - test/test_helper.rb
84
+ - test/mizuho_bank_test.rb