LibreOffice(55)WSGIでブラウザに結果を出力する

ラベル: ,

前の関連記事:LibreOffice(54)サービス属性、インターフェイス属性、メソッドも枝付きで出力


Python(1)WSGI:PythonからWSGIアプリでウェブブラウザに結果を出力するでやったWSGIサーバからWSGIアプリを呼び出してobjinsp()の結果をブラウザに出力します。

WSGIアプリに引数を渡す方法がよくわからないの外のスコープからデータを渡す

from wsgiref.simple_server import make_server
import webbrowser
def run():
    port = 8000  # サーバが受け付けるポート番号を設定。
    httpd = make_server("", port, app)  # appへの接続を受け付けるWSGIサーバを生成。
    url = "http://localhost:{}".format(port)  # 出力先のurlを取得。
    webbrowser.open_new_tab(url)  # デフォルトのブラウザでurlを開く。
    httpd.handle_request()  # リクエストを1回だけ受け付けたらサーバを終了させる。
def app(environ, start_response):  # WSGIアプリ。evironは必須WSGI変数を含む辞書。
    start_response("200 OK", [("Content-Type", "text/html; charset=utf-8")])  # start_responseは2つの必須固定引数statusとresponse_headers(タプル)、他にexc_infoを含む。
    html = '<a href="http://knzm.readthedocs.org/en/latest/pep-3333-ja.html">WSGIの仕様書の日本語訳</a>'  # 出力するhtml。
    return [html.encode()]  # htmlをバイト列に変換してWSGIサーバに渡す。
run()
Python(1)WSGI:PythonからWSGIアプリでウェブブラウザに結果を出力するの最後にやったこのコードを組み込もうと思うのですが、ブラウザに出力する内容を入れた11行目の変数htmlを関数appの外から渡す方法をどうしたものかと思いました。

app(environ, start_response)の引数を勝手に増やしてもできるのかもしれませんが、このあたりの仕組みがよく理解できていないのでそれは挑戦せずに外のスコープからhtmlを渡すことにしました。

このままではグローバルスコープから渡すことになるのでまずはすべてをクラスのスコープに入れることにします。

ということでまずはobjinsp()をクラスにします。

objinsp()のクラス化はLibreOffice(51)クラスにすると関数の引数が減らせたで以前やりました。

このときのobjinsp()は再帰関数とか二分木のことを知らない頃だったのでサブルチンの関数が多用していました。

それをクラス化することによってサブルチンの関数の引数をクラスのデータ属性で渡すようにしたのでサブルチンの関数の引数を減らせました。

今のobjinsp()はサブルチンの関数はないので今回はクラスのデータ属性にするのはapp()に渡すhtmlだけになります。

objinsp()でprint()するものをリストにいれてそのリストをapp()へ渡して出力しようと思ったのですが、app()からyieldで返すとブラウザに返されるのでobjinsp()の内容をapp()で実行することにしました。

libreoffice55.py

うーん。yieldで返すとprint()と違って改行がつきませんね。

しかもスペースもhtmlにすると消えてしまうようです。

ということでやっぱり最初に考えたとおりに一旦出力するものはリストに収納してからどうするか考えることにします。

WSGIアプリに結果を渡すのではなく、処理対象のUNOオブジェクトを渡してobjinsp()で処理していた内容はWSGIアプリで実行するままにしています。

libreoffice55.py

print()で出力していたものをリストlst_htmlに取得して、最後に半角スペースと改行のHTMLタグをつけてWSGIサーバに返しています。

出力を確認したブラウザはFirefox 31.0です。

ブラウザで等幅フォントを使うように<tt>~</tt>タグを使っています。

プロポーショナルフォントでは右揃えがうまくいきませんでした。

LibreOfficeのマクロとして実行するとエラーがでる


PyCharmから実行するオートメーションですと結構時間がかかります。

ところがLibreOfficeのマクロで実行すると一瞬で結果が返ります。

LibreOffice(5)PythonでLibreOfficeが動く仕組み:UNOでみたようにLibreOfficeのAPIを使うたびにソケット接続を介するのでそれが律速段階になっているようです。

でもマクロでWSGIサーバを起動するとエラーが出てきます。

        server.handle_request()  # リクエストを1回だけ受け付けたらサーバを終了させる。
ここでひっかかっていますね。

ブラウザには結果はちゃんと出力されますが、ブラウザのタブが「接続中...」のままになったままです。

LibreOfficeを再起動しないでそのまま今度はオートメーションでこのlibreoffice55()を実行すると、以下のエラーがでてきてWSGIサーバを起動できません。

OSError: [WinError 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。

この問題を解決しないとマクロからウェブブラウザに結果を出力する手段が使えませんね。

server.serve_forever()にしてもダメですね。

マクロからWSGIサーバを起動すること自体が問題なのかもと思いましたが、マルチスレッドにするとエラーダイアログがでませんでした。

Python(3)WSGI:ウェブページからshutdown()メソッドでWSGIサーバを停止させるで使ったのをマクロで呼び出せるようにしたのがwsgi3.pyです。

これをマクロで実行するとエラーはでてきません。

ただし実行できるのは1回だけです。

2回目以降は<class 'OSError'>: [WinError 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。、とでてきて実行できません。

LibreOfficeを再起動するとまた実行できるようになります。

ポート番号を変更するとLibreOfficeを再起動しなくても実行できました。

参考にしたサイト


HTMLタグ/テキスト・フォントタグ/等幅文字にする - TAG index Webサイト
<tt>~</tt>で等幅フォントを指定可能。

次の関連記事:LibreOffice(56)htmlをファイルに保存してブラウザに結果を出力する

PR

0 件のコメント:

コメントを投稿