#!ruby -Ku
#Windowsのプロンプトの場合は、rbファイルをSJISに変換した上で、上のオプションを「-Ks」にしてください。

# main

require 'openssl' # パスワードの暗号復号に使うので、最初に呼び出す。

@item_names = [] # アカウント情報を一意に決めるための内部名の配列
@print_names = [] # 選択画面に表示する名前の配列
@get_functions = [] # 読み出した口座情報関数取得用の配列
@make_account = [] # アカウント情報登録のための関数の配列
@login_functions = [] # ログインのみの関数の配列
@format_functions = [] # 書式を整える関数取得用の配列

# 自作ライブラリ(口座取得関数、暗号復号メソッド with openssl)読み出し。
require 'lib_a_require'
 
 
# キー入力を隠すコマンドがOS依存なのでOS判定。
case RUBY_PLATFORM.downcase
when /mswin(?!ce)|mingw|cygwin|bccwin/
  @osname = "windows"
when /linux/
  @osname ="linux"
end
 
puts "マスターパスワードを入力してください。"
key = `stty -echo;read line;stty echo; echo $line`.chomp if @osname == "linux"
key = gets.chomp if @osname == "windows" # Windowsの場合はキー入力を隠さない。

 
# パスワードファイル読み込み
# encrypt、decryptはlib_a_defaultでStringクラスに追加したメソッド
if File.exist?("account_passwd")
  enc_passes = []
  dec_passes = []
  enc_passes = open("account_passwd", "rb"){ |f| f.read }
  begin
    dec_passes = enc_passes.decrypt(key).split("\n")
  rescue
    STDERR.puts "パスワードが違います! パスワードファイルを解読できません。" if $!.to_s == 'bad decrypt'
    exit
  end
  dec_passes.map! {|l| l.split(",")}
else
  puts "パスワードファイルがありません! > ruby makepasswdfile.rb でパスワードファイルを作成してください。"
end
 
# gemsのライブラリはロードが遅いので、パスワード入力後にロード。
require 'rubygems'
 
# 作業用ブラウザインスタンス作成コマンド
# Windowsの場合はWatir+IEで動くようにしてある。Vista+IE7だt「ログインのみ」だけ対応。
# それ以降の情報取得はHTMLのオブジェクトの読み込み方の違いからか、うまく動かなかった。
# テーブル名をIndexを使わずに一意に決められる方法があれば、両方で同じように動くかもしれない。
# Windowsの場合は、パスワード入力の際に文字が隠れないという制限がある。(僕がどうやって隠すか知らないため)
if @osname == "linux"
  require 'firewatir'
  new_browser = "ff = FireWatir::Firefox.new"
elsif @osname == "windows"
  require 'watir'
  new_browser = "ff = Watir::IE.new"
end
 
account_info = Array.new(@item_names.length, false) # ログインアカウント保存用配列

# アカウント情報が登録されているかどうかのフラグの配列を設定
flags = Array.new(@item_names.length, false)
 
# lib_a_requireに登録されている関数のアカウント情報があるかどうか順番に見ていく。
# あったら、それを格納。
@item_names.each_with_index do |x, i|
  dec_passes.each do |y|
    if y[0] == x
      flags[i] = true
      account_info[i] = y
    end
  end
end
 
puts "どの口座情報を取得しますか?"
 
# 登録(関数とアカウント情報の両方)されているアカウントを順番に表示
@print_names.each_with_index do |x,i|
  print (i).to_s + "." + x + " "
  print "\n"
end
puts "a.アカウント情報登録済みのものすべて"
 
select_no = gets.chomp
 
# モード選択
# 簡易表示は取得した情報をそのまま表示させます。
# 書式を整えて表示は、口座共通のテンプレに取得したデータを流し込んで表示させます。
# ファイル出力は実装していないので、必要な場合はリダイレクションでファイルにとってください。

puts "何をしますか?"
puts "1.ログインのみ 2.簡易表示 3.書式を整えて表示(一部非対応)"
mode_no = gets.chomp
 
# 入力された値のチェック
if (mode_no != "1" && mode_no != "2" && mode_no != "3")
  puts "入力された値が間違っています! スクリプトを終了します。"
  exit
elsif mode_no == "3" && @format_functions[select_no.to_i] == false && mode_no != "a"
  puts "この口座では、書式を整えて表示のオプションは定義されていません。簡易表示を使ってください。スクリプトを終了します。"
  exit
end
 
outputs = [] # 画面表示用にデータを保存する配列

if select_no == "a" # すべて読み込み
  eval(new_browser)
  flags.each_with_index do |x,i|
    # モード3が定義されていないものはモード2で口座情報を取得する。
    mode_no_tmp = mode_no # あとで値を元に戻すため。
    if (mode_no == "3" && @format_functions[i] == false)
      mode_no = "2"
    end
 
    if x == true
      if mode_no == "1"
        func = @login_functions[i] + "(ff,account_info[" + i.to_s + "])"
        outputs = eval(func)
        # exit  テストの際、すべてログインさせる場合があるため、このexitはなしにした。
      elsif mode_no == "2"
        func = @get_functions[i] + "(ff,account_info[" + i.to_s + "])"
        outputs = eval(func)
        outputs.each {|x| x.print_table} # print_tableはArrayクラスに追加したメソッド。
        print "\n"
      elsif mode_no == "3"
        func = @get_functions[i] + "(ff,account_info[" + i.to_s + "])"
        outputs = eval(func)
        format = @format_functions[i] + "(outputs," + i.to_s + ")"
        eval(format)
        print "\n"
      end
    else
      next
    end
    mode_no = mode_no_tmp # mode_noを3から2に変えていた場合は、ここで戻す。
  end
  #Close the browser.
  eval("ff.close") # instance_evalの下にffインスタンスが置かれているため、こうしないと期待通りに動かない。

elsif select_no == "test"
  # テスト用のコードを書くところ。今はとくになし。
  eval(new_browser)
  if mode_no == "1"
    func = @login_functions[1] + "(ff,account_info[1])"
    outputs = eval(func)
    exit # ログインしたらスクリプトを終了。
  end
elsif select_no =~ /\d+/ # 個別に読み込み
  if select_no.to_i >= flags.length
    puts "指定された数値は大きすぎます。スクリプトを終了します。"
    exit
  elsif flags[select_no.to_i] == false
    puts "アカウントが登録されていません。"
    puts "> ruby makepasswdfile.rb を実行し、アカウント情報を登録してください。"
    exit
  end
 
  eval(new_browser)
  if mode_no == "1"
    func = @login_functions[select_no.to_i] + "(ff,account_info[" + select_no + "])"
    outputs = eval(func)
    exit # ログインしたらスクリプトを終了。
  elsif mode_no == "2"
    func = @get_functions[select_no.to_i] + "(ff,account_info[" + select_no + "])"
    outputs = eval(func)
    outputs.each {|x| x.print_table}
    print "\n"
  elsif mode_no == "3"
    func = @get_functions[select_no.to_i] + "(ff,account_info[" + select_no + "])"
    outputs = eval(func)
    format = @format_functions[select_no.to_i] + "(outputs," + select_no + ")"
    eval(format)
    print "\n"
  end
 
  #Close the browser.
  eval("ff.close") # evalの下にffインスタンスが置かれているため、こうしないと期待通りに動かない。

else
  puts "入力された値が間違っています! スクリプトを終了します。"
  exit
end
 
# ここまで。
 
最終更新:2009年11月28日 19:59