LBP-1820のステータスを一括取得

20数台のプリンタのステータスを取得したいのが、エラーに悩まされたりして解決に時間が掛かった。
 
頭を悩ませていたのが「Timeout::Error」って奴。
 
参考にしたのがこのあたり。

  def lprlist
    @page_title = "プリンタの状態"
    
    ip_ary = ["192.168.1.200","192.168.1.201","192.168.1.202"]
              
    @printers = Array.new
    require 'ping'
    count = 0
    ip_ary.each{|host_name|
      if Ping.pingecho(host_name, timeout = 5, "80")
        @printers[count] = lpr_state(count, ip_ary[count])
        count += 1
      end
    }
  end
  def lpr_state(id, ip)
    #LBP-1820用
    require 'net/http'
    Net::HTTP.version_1_2   # おまじない
    $proxy_addr = 'proxy_address'
    $proxy_port = 80
    
    lpr = Array.new
    lpr[0] = id
    lpr[1] = "http://"+ip
    begin
    http = Net::HTTP::Proxy($proxy_addr, $proxy_port).new( ip )
    http.open_timeout = 5
    http.read_timeout = 10
    http.start do
      response = http.get('/dev/dev_env.shtml')
      find_flag = 0
      response.body.toutf8.each{|l|
        #ホスト名を取得する
        if /izm/ =~ l
          s = l.index("izm")
          e = l.index("</b>")
          lpr[3] = l.slice(s,e-s)
        end
        #総印刷ページ数を取得する
        if find_flag == 1
          s =  l.index("<td>")
          e =  l.rindex("</td>")
          lpr[2] = l.slice(s+4..e-1)
          break
        end
        find_flag = 1 if /総印刷ページ数/ =~ l.toutf8
      }

      #用紙の状態を表す画像のURLを取得する。
      response = http.get('/dev/dev_stat.shtml')
      response.body.toutf8.each{|l|
      if /cassette/ =~ l
        s = l.index("image")
        e = l.index("gif")
        lpr[4] = "http://"+ip+"/cab/image/"+l.slice(s+6,e-s-3)
      end
      }
      #デバイスの状態を取得する
      find_flag = 0
      response.body.toutf8.each{|l|
      if find_flag == 1
        s = l.index("><b>")
        e = l.index("/b>")
        lpr[5] = l.slice(s+4..e-2)
        break
      end
      find_flag = 1 if /デバイス状態/ =~ l.toutf8
      }
    end
    rescue 
      puts "exception on HTTP: StandardError #{$!}"
    rescue Timeout::Error
      puts "exception on HTTP: TimeoutError"
    rescue Exception
      puts "exception on HTTP: #{$!}"
    end
    return lpr
  end

他にも試したのがこれら。

  • Hashにパラメータを入れてリダイレクト(URLがアホみたいになった!)
  • Tempfile.rbを使った(意味が無かった)
  • ファイルを作った(意味が無かった)

どれもTimeout::Errorには対処できなかった。
 

失敗作

失敗昨を残してみる。

tempfile版

tempfileを作成する場所の指定する必要があった。

  @printers = Array.new
  @lprcount = params[:count].nil? ? 0 : params[:count].to_i
    require "tempfile"
    @printers = Array.new
    if params[:count].nil?
      @lprcount = 0
      temp = Tempfile.new("lprlist",RAILS_ROOT+'/tmp')
      pp "temp dir", temp.path
    else
      @lprcount = params[:count].to_i
      #tempを読み込んで、@priに書き出す
      if FileTest.exist?(RAILS_ROOT+'/tmp'+'/lprlist')
        pp "find lprlist"
      pp "temp dir", temp.path
        temp.open
        pp "temp open"
        tmpcount = 0
        temp.each{|line|
          line.split(/,/).each{|lpr|
            pp "lpr",lpr
          }
        }
      end
    end
    
    strlpr = ""
    3.times {
      if ip_ary[@lprcount].nil?
        break
      end
      lprary = lpr_state(@lprcount+1, ip_ary[@lprcount])
      @printers[@lprcount]=lprary
      strlpr = lprary[0].to_s+","+lprary[1]+","+lprary[2]+","+lprary[3]+","+lprary[4]+","+lprary[5]
      temp.puts strlpr
      @lprcount += 1
    }
    temp.close

GCって直ぐに消えちゃうのね・・・

 

個別ファイル版

Timeoutの問題に気づかせてくれた、ある意味いい奴。

    require "socket"
    usrfile = RAILS_ROOT+"/tmp/lpr/"+Socket.gethostname
    
    unless File.file?(usrfile)
      #ファイルが存在しているの?無かったら作る
      File.open(usrfile,"w"){|file|}
    else
      #タイムスタンプが古かったら内容を消す
      File.open(usrfile,"w"){} if File.mtime(usrfile).to_date < Date.today.to_date
      
      #ファイルを1行ずつ読み込んで、表示用に書き出す
      @printers = Array.new
      File.open(usrfile){|file|
        while line = file.gets
          @printers << line.split(/::/)
        end
      }
      @lprcount = params[:count].nil? ? 0 : params[:count].to_i
      
      #ファイルに書き込む&表示用にも書き込む
      3.times {
        strlpr = ""
        break if ip_ary[@lprcount].nil?
        @printers[@lprcount] = lpr_state(@lprcount+1, ip_ary[@lprcount])
        strlpr = @printers[@lprcount].join("::")
        File.open(usrfile, "a"){|file| file.puts strlpr }
        @lprcount += 1
      }
  end

ちゃんと検証していないから、意図通りに動かない部分もある。