2011年12月12日月曜日

wsgiref を使ってpythonで書いた HTTPサーバで画像をアップロード


結構大変だったのでメモ。参考文献は忘れたのでパス。
HTTPでアクセスできるサーバを、 wsgiref というモジュールで書きました。

以下のプログラムどっかでを実行して、
http://localhost:8080 にブラウザからアクセスすると、フォームが現れます。
ブラウザから画像を選択 -> サーバがカレントディレクトリに aaa.png という名前で保存します。

import cgi, StringIO
from wsgiref import simple_server
import numpy, Image

class Selector(object):
    def __init__(self, table, notfound = None):
        tmp = sorted(table, key=lambda x:len(x), reverse=True)
        table = [(x, table[x]) for x in tmp]
        self.table = table # url table
        if notfound:
            self.notfound = notfound # when not found

    def __call__(self, environ, start_response):
        name = "SCRIPT_NAME"
        info = "PATH_INFO"

        scriptname = environ.get(name, "")
        pathinfo = environ.get(info, "")

        for p, app in self.table:
            print p, pathinfo
            if p == "" or p =="/" or pathinfo.startswith(p):
                print app
                return app(environ, start_response)

        if pathinfo == p or pathinfo.startswith(p) and pathinfo[len(p)] == "/":
            scriptname = scriptname + p
            pathinfo = pathinfo[len(p):]
            environ[name] = scriptname
            environ[info] = pathinfo
            return app(environ, start_response)

        return self.notfound(environ, start_response)

    def notfound(self, environ, start_response):
        start_response('404 Not Found', [('Content-type', 'text/html')])
        fp = StringIO.StringIO()
        fp.write(r"""<html><header><title>Not Found</title></header>
<body> 
<H1> URL not found. </H1>
<ul>
""")
        for entry in self.table:
            fp.write(r"<li/> %s %s" % (entry[0], entry[1]))
        fp.write(r"</ul></body></html>")
        fp.seek(0)
        
        return fp

def imageupload(environ, start_response):
    try:
        clen = int(environ["CONTENT_LENGTH"])
    except:
        clen = 0

    f = cgi.FieldStorage(fp=environ["wsgi.input"], 
                         environ=environ, 
                         keep_blank_values=True)
    handle = open("aaa.png", "wb")
    handle.write(f["filename"].file.read())
    handle.close()


    fp = StringIO.StringIO()
    fp.write(r"<html><body> environmental variables <dl>")

    for key in sorted(environ.keys()):
        fp.write(r"<dt>%s</dt><dd>%s</dd>" % (key, environ[key]))
    fp.write(r"</dl></body></html>")
    fp.seek(0)
    
    start_response("200 OK", [("Content-type", "text/html")])
    return fp

def showtop(environ, start_response):
    start_response("200 OK", [("Content-type", "text/html")])
    return r"""<html><body> 
imageupload 
<form action="/image" enctype="multipart/form-data" method="post">
<input type="file" name="filename"><input type="submit" value="Upload">
</form>
</body></html>"""

if __name__ == '__main__':
    application = Selector({"/":showtop, "/image":imageupload})
    srv = simple_server.make_server('', 8080, application)
    srv.serve_forever()

2 件のコメント:

  1. Good info. Lucky me I came across your site by accident (stumbleupon). I have book-marked it for later!

    返信削除
  2. Thanks for the marvelous posting! I genuinely enjoyed reading it, you will be a great author. I will make certain to bookmark your blog and will often come back later in life. I want to encourage you continue your great job, have a nice day!

    返信削除