pingアプリの結果を逐次表示

昨日の実装だとpingの終了を待たないと結果が表示されないので、逐次表示されるように修正してみた。

作ってみる

構成
ping2/
- main.py
- static/
  - favicon.png
  - jquery-1.4.2.min.js
  - test.css
  - test.js
- templates/
  - index.html
index.html
$def with (host)
<html>
  <head>
    <title>home</title>
    <link rel="icon" type="image/png" href="/static/favicon.png"/>
    <link rel="stylesheet" type="text/css" href="/static/test.css"/>
    <script type="text/javascript" src="/static/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="/static/test.js"></script>
  </head>
  <body>
    <input id="id_host" type="text" value="$host">
    <a href="javascript:void(0)" onclick="doping()">ping</a>
    <div id="result">
    </div>
  </body>
</html>
test.css
body {
    background-color: lightyellow;
    font: 8pt tahoma;
}
div#result {
    background-color: silver;
    font: 10pt "MS UIGothic";
    width: 500px;
    height: 300px;
    padding: 4px;
}
iframe {
    width: 100%;
    height: 100%;
}
main.py
# -*- coding: utf-8 -*-

import web
import os
import time
from subprocess import *

urls = (
    r'^/ping$', 'ping',
    r'^/.*$', 'index',
    )

app = web.application(urls, globals(), autoreload = True)
render = web.template.render('templates/')

class index:
    def GET(self):
        return render.index(host = 'localhost')

class ping:
    def GET(self):
        web.header('Content-type', 'text/plain')
        i = web.input()
        conv = Popen('ping '+i.host, stdout=PIPE)
        while True:
            x = conv.stdout.readline()
            if not x: break
            x = x.rstrip() + '\n'
            yield x

if __name__ == '__main__':
    web.webapi.internalerror = web.debugerror
    app.run()
test.js
function doping()
{
    $("#result").html(
        "<iframe frameborder='no' src='/ping?host="+$("#id_host").val()+"'></iframe>"
    );
    return false;
}

実行してみる

  • こんな感じ。

    あ、見た目は同じかw

まとめ

  • ついでにfaviconとtemplateをやってみた。
  • 逐次表示するにはyieldを使えば良い。ただし、ヘッダで明示的にtext/plainにしておかないと受信完了まで待ってしまう。
  • firefoxchromeは挙動が同じになるんだけど、IE(7)だけ思ったように動作しない。うーん、なんでだろ?
  • 実用的に考えるとpingの出力をログファイルにリダイレクトしておいて、iframeで定期的にリロードする方が良いかも。