Last active
October 31, 2015 08:13
-
-
Save komiyake/89472df5eb366b6f23a0 to your computer and use it in GitHub Desktop.
大学生協(https://mp.seikyou.jp/mypage/) の購買履歴をMoneyForwardに投げる.nkfコマンド必要です
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# coding: utf-8 | |
require 'mechanize' | |
require 'openssl' | |
require 'nokogiri' | |
require 'io/console' | |
class MoneyForward | |
def initialize | |
@agent = Mechanize.new{|a| a.ssl_version, a.verify_mode = "SSLv23", OpenSSL::SSL::VERIFY_NONE} | |
@login_url = 'https://moneyforward.com/users/sign_in' | |
@base_url = 'https://moneyforward.com/' | |
end | |
def login | |
begin | |
puts "Login MoneyForward..." | |
print "ID: " | |
id = STDIN.gets.chomp | |
print "Pass: " | |
pass = STDIN.noecho(&:gets).chomp | |
puts "" | |
@agent.get(@login_url) do |page| | |
page.form_with(:id => 'new_sign_in_session_service') do |form| | |
form.field_with(:name => "sign_in_session_service[email]").value = id | |
form.field_with(:name => "sign_in_session_service[password]").value = pass | |
end.click_button | |
end | |
sleep 1 | |
if not login? | |
puts "ログインに失敗しました" | |
end | |
end while not login? | |
end | |
def login? | |
return !@agent.page.search("//a[@href=\"/users/sign_out\"]").empty? | |
end | |
def add_history(payment) | |
@agent.get("https://moneyforward.com/") | |
sleep 1 | |
payment.output | |
@agent.page.form_with(:id => "js-cf-manual-payment-entry-form") do |form| | |
form["user_asset_act[large_category_id]"] = "11" | |
form["user_asset_act[middle_category_id]"] = "42" | |
form.field_with(:name => "user_asset_act[sub_account_id_hash]").option_with(:value => @payment_account[0]).click | |
form.field_with(:id => "js-cf-manual-payment-entry-amount").value = payment.price | |
form["user_asset_act[updated_at]"] = payment.day.year.to_s + "/" + payment.day.month.to_s + "/" + payment.day.day.to_s | |
form["user_asset_act[content]"] = payment.product | |
end.click_button | |
sleep 1 | |
end | |
# アカウントの最終更新日時を調べる | |
def get_last_payment_date | |
account_name = select_account()[1] | |
@agent.get("https://moneyforward.com/") | |
sleep 1 | |
@agent.page.links.find{|e| account_name.include?(e.text)}.click | |
sleep 1.5 | |
date = @agent.page.search("//td[@class=\"date form-switch-td\"]/div[@class=\"noform\"]/span").first.text.to_s | |
date = date.split("(")[0].split("/") | |
day = Time.gm(Time.now.year, date[0].to_i, date[1].to_i, 0, 0, 0) | |
if Time.now < day | |
day.year = day.year-1 | |
end | |
day | |
end | |
# 登録されている財布から支払元を選択 | |
def select_account | |
accounts = [] | |
key = [] | |
@agent.get("https://moneyforward.com/") | |
sleep 1 | |
@agent.page.form_with(:id => "js-cf-manual-payment-entry-form") do |form| | |
form.field_with(:name => "user_asset_act[sub_account_id_hash]") do |select| | |
select.options.each do |option| | |
accounts << option.text.to_s | |
key << option.value.to_s | |
end | |
end | |
end | |
while true | |
for i in 1..accounts.size-1 | |
puts i.to_s + " " + accounts[i-1].to_s | |
end | |
print "どの支出元を使用しますか?: " | |
num = STDIN.gets.chomp.to_i | |
if 0 < num and num < accounts.size | |
break | |
else | |
puts "正しい数値を入力してください" | |
end | |
end | |
@payment_account = [key[num-1].to_s, accounts[num-1].to_s] | |
@payment_account | |
end | |
end | |
class Payment | |
attr_accessor :day, :place, :product, :point, :price | |
def initialize(data) | |
data = data.split(",") | |
date = data[0].split("(")[0].split("/") | |
@day = Time.gm(Time.now.year, date[0].to_i, date[1].to_i, 0, 0, 0) | |
if Time.now < day | |
day.year = day.year-1 | |
end | |
@place = data[1] | |
@product = data[2] | |
@point = data[3] | |
@price = data[4] | |
end | |
def output | |
print "#{@day.month.to_s+ "/" + @day.day.to_s} @#{@place} : #{@product} #{@price}\n" | |
end | |
end | |
class Seikyo | |
def initialize | |
@agent = Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE} | |
@login_url = 'https://mp.seikyou.jp/mypage/Static.init.do' | |
end | |
def login | |
begin | |
puts "Login SEIKYO..." | |
print "ID: " | |
id = STDIN.gets.chomp | |
print "Pass: " | |
pass = STDIN.noecho(&:gets).chomp | |
puts "" | |
@agent.get(@login_url) do |page| | |
page.form_with(:name => 'loginForm') do |form| | |
form.field_with(:name => "loginId").value = id | |
form.field_with(:name => "password").value = pass | |
end.click_button | |
end | |
sleep 1 | |
if not login? | |
puts "ログインに失敗しました" | |
end | |
end while not login? | |
end | |
def login? | |
return !@agent.page.search("//img[@alt=\"ログイン中\"]").empty? | |
end | |
# 文字コードの問題でcvsファイルが読み込めないので,nkfコマンドでUTF-8に直している | |
def analysis_cvs(file_name) | |
payments = [] | |
system("nkf -w --overwrite " + file_name) | |
day = "" | |
File.open(file_name) do |file| | |
file_str = file.read | |
day = file_str.split("\n")[0].split(":")[1].gsub!("\r", "") | |
file_str.split("\n").slice!(2..file_str.split("\n").size()-1).each do |data| | |
data.gsub!("\"", "") | |
payments << Payment.new(data) | |
end | |
end | |
print day + " の購買履歴の取得に成功しました\n" | |
File.delete file_name | |
payments | |
end | |
# 2ヶ月分の購買履歴をとってくる | |
def get_payment_history | |
puts "購買履歴の取得をします..." | |
form = @agent.page.form("menuForm") | |
form.id = "ALL_HISTORY" | |
form.action = "/mypage/Menu.change.do" + "?pageNm=" + "ALL_HISTORY" | |
@agent.submit(form) | |
sleep 1 | |
file_name = create_file_name() | |
form = @agent.page.form("AllHistoryFormCsvDownload") | |
@agent.submit(form).save_as(file_name) | |
payments = analysis_cvs(file_name) | |
@agent.get("https://mp.seikyou.jp/mypage/Menu.change.do") | |
sleep 1 | |
form = @agent.page.form("menuForm") | |
form.id = "ALL_HISTORY" | |
form.action = "/mypage/Menu.change.do" + "?pageNm=" + "ALL_HISTORY" | |
@agent.submit(form) | |
sleep 1 | |
form = @agent.page.form_with(:name => "AllHistoryFormChangeDate") | |
form.field_with(:name => "rirekiDate").options.first.select | |
@agent.submit(form) | |
sleep 1 | |
file_name = create_file_name() | |
form = @agent.page.form("AllHistoryFormCsvDownload") | |
@agent.submit(form).save_as(file_name) | |
payments = payments + analysis_cvs(file_name) | |
payments | |
end | |
def create_file_name | |
begin | |
file_name = (0...8).map{ (65 + rand(26)).chr }.join | |
end while File.exist? file_name | |
file_name | |
end | |
end | |
def main | |
seikyo = Seikyo.new | |
seikyo.login | |
payments = seikyo.get_payment_history | |
moneyforward = MoneyForward.new | |
moneyforward.login | |
last_payment_date = moneyforward.get_last_payment_date | |
payments.delete_if {|payment| payment.day <= last_payment_date} | |
puts "追加されていない支払いが " + payments.size.to_s + " 件あります." | |
payments.each do |payment| | |
moneyforward.add_history(payment) | |
end | |
puts "終了します" | |
end | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
カテゴリーは今のところ「食費」->「外食」で固定になっています