2020年2月2日日曜日

28: 'やあ、コンソールPython UNOクライアントたち'サンプル

<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>

あなたのプログラムをLibreOffice/OpenOfficeインスタンス(または任意のUNOサーバー)に接続する、オフィスドキュメントを読み書きしたりインスタンスを操作したりするために。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Python

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、外部コンソールPythonプログラムをUNOサーバー(例えば、LibreOfficeまたはApache OpenOfficeのインスタンス)に接続する方法を知る。
ト書き
Hypothesizer 7、Objector 28A、Objector 28Bがコンピューターの前にいる。


オリエンテーション


Hypothesizer 7
この記事では、コンソールPython UNOクライアントサンプルを取得、ビルド、実行、理解します。

Objector 28B
それは結構ね、でも、シンプルにしてね。

Hypothesizer 7
...マダム、何を「シンプル」にするよう期待されてますか?サンプルですか説明ですか?

Objector 28B
すべてよ!「シンプルイズベスト」ですからね。

Hypothesizer 7
実のところ、私には疑問ですね。...認識や記述について言えば、私は正確にしようと試みます、「シンプル」にではなく。実際、正確さを犠牲にして単純化することは、諸悪の根源であるように思われます、私には。

Objector 28B
...嘘をつけとは言わなかったでしょ!

Hypothesizer 7
ああ、真実が実際にそうであるとおりの複雑さで述べられなければ、その叙述は嘘である、なぜなら、真実が真実に反してより単純であるかのように歪められているから、という点で意見が一致していると知って安心いたしました。

Objector 28B
...心の平安が得られて結構なことね!それで、サンプルはどうなの?

Hypothesizer 7
'フレキシビリティを犠牲にして近道を取る'ことを「シンプル」とお呼びでしたら、それは私の目的でないと認めざるをえません。私の目的は、最もフレキシブルで最も拡張可能な方法を示すことです。

Objector 28B
...LibreOfficeインスタンスに接続することの'フレキシビリティ'や'拡張性'なんて何のことか私には分からないわ: ただ接続するだけでしょう?

Hypothesizer 7
フレキシビリティというのは、プログラムが任意のTCP/IPソケットUNOサーバー(ローカルでもリモートでも)に接続できるかどうか、プログラムがUNOサーバーに初期???UNOオブジェクト群をオファーできるかどうか、プログラムがUNO切断を検知できるかどうかです。拡張性というのは、方法がUNOサーバー作成へ拡張できるかです。

Objector 28B
...それじゃあ、私にはどうでもよいフレキシビリティと拡張性を達成するために、不必要に複雑なサンプルを私に提示するわけね!

Hypothesizer 7
第1に、私にはどうでもよくありません、第2に、フレキシブルなものはフレキシブルでないものを兼ねます、第3に、1群のユーティリティクラスをただ一度作ればよいだけのことです。

Objector 28B
それらは、そんなフレキシビリティなんで絶対に必要としないと確信している私にとっての、不必要に複雑な方法を採用する有効なインセンティブではありませんわね!

Hypothesizer 7
仰るとおりです。

Objector 28B
それで?

Hypothesizer 7
「それで?」?...それで、ご要求のものをどこかでお見つけになられるようご幸運をお祈りいたします。

Objector 28B
...

Objector 28A
あんたのその'開始コンテキスト'てのは...一体何だ?

Hypothesizer 7
サー、その'開始コンテキスト'というのは、本記事がそこから開始して展開していくというコンテキストです。

Objector 28A
...あんた、ただの著者のくせに、不届きにもそんな要求を俺にすんのか?

Hypothesizer 7
えーと、どんな著者も、たとえ「ただの著者」でさえも、一定の知識を読者に要求します、なぜなら、赤ん坊でもその文書を理解できるなどという保証はできないからです。その要求が明示的に述べられているか否かが違うだけです。

Objector 28A
だが、その要求が法外だろうが!

Hypothesizer 7
...法外であろうがなかろうが、要求は本記事のコンテンツから論理的に決定されるのであって、私の「不届き」具合によって決定されるのではありません。お分かりのように、必要なものは必要なのです、私の態度に関係なく。お分かりのように、UNOとは何かという知識はほとんどのUNO関連記事で必要です。

Objector 28A
...親切に説明すればいいだけだろうが。

Hypothesizer 7
...全てのUNO関連記事をUNOとは何かという説明から、親切に始めるべきですか?

Objector 28A
なんでいけないんだ?

Hypothesizer 7
なぜなら、読者にとってとても苛立たしいことになるからです: 私なら言うでしょう、「それはもう知ってるよ!同じことを繰り返すな!」。...それは親切ですか?

Objector 28A
...


本体


0: 注釈


Hypothesizer 7
ご注意いただきたいのですが、本サンプルプログラムは、Python 3.6以降のみが対象です。

実のところ、以前の記事でご紹介したWindows用開発環境は、もっと古いPythonのものなので、現在Windowsでは本サンプルはそのままでは動きません、残念ながら。

Objector 28A
...バージョン3.6の何が特別なんだ?

Hypothesizer 7
そのバージョンは、変数タイプアノテーション機能をサポートしています。

Objector 28A
はあ?そんな機能はゴミだ: Python的じゃない!

Hypothesizer 7
「Python的じゃない」...、それがどうかしましたか?

Objector 28A
「それがどうか」?!「それがどうか」と言ったか?!

Hypothesizer 7
申しました...、それがどうかしましたか?

Objector 28A
「それがどうか」?!どういう意味だ?!

Hypothesizer 7
つまり、私は、自分のコードのメンテナンス性はとても大事にしていますが、自分のコードの「Python的」性ですか?...どうでもいいです。

Objector 28A
...

Hypothesizer 7
とにかく、ソースファイル群から変数タイプアノテーションを取り除いて、ビルドスクリプトによって自動的に呼び出される静的型チェックをバイパスすれば、サンプルは多分問題なく動作するでしょう。

Objector 28A
「バイパス」だと?どうやって?

Hypothesizer 7
静的型チェックは呼び出されるのは、'commonTasks.gradle'ファイル内で'i_pythonCompileTask'タスク(これが静的型チェックを行ないます)が'i_pythonCheckTypesTask'タスクに依存しているからです。したがって、ただその依存性を取り除けばよいだけです、多分。

Objector 28A
...


1: コンソールPython UNOクライアントサンプルを取得してビルドする


Hypothesizer 7
ここに、コンソールPython UNOクライアントサンプルがあります。このシリーズに挙げられている任意のサンプルプロジェクトをビルドする方法は過去の記事に記載されています。

Objector 28A
「ビルド」?Pythonプログラムはビルドする必要ないだろうが?

Hypothesizer 7
ありません、しかし、私のビルドシステムは、'mypy'による静的タイプチェックを行ない、'mypy'スタブ群を作成し、明示的にソースファイル群をコンパイルします。

Objector 28A
どうでもいいが。

Hypothesizer 7
ZIPファイルを展開した後、'hiConsolePythonUnoClients'がサンプルプログラムのプロジェクトディレクトリであり、他の2つのディレクトリは様々なプロジェクトから共通に使われるプロジェクトのものです。

開発環境を構築する方法は、過去の記事(Linux用はこちらで Windows用はこちら)で説明されています。

ト書き
Hypothesizer 7はターミナルを開いてサンプルプロジェクトをビルドする。


2: サンプルプログラムを実行する


Hypothesizer 7
サンプルプログラムを実行する前に、LibreOfficeまたはApache OpenOfficeのインスタンスを、クライアントからのコネクションを受け付ける状態で開始しておかなければなりません(その方法は、過去の記事で知ることができます)。

ト書き
Hypothesizer 7は、LibreOfficeのインスタンスをポート番号'2002'で開始する。

Hypothesizer 7
サンプルプログラムは、カレントディレクトリをサンプルプロジェクトディレクトリに位置させ、ファイルURLを環境に合わせて、以下のようにして実行できます。

@bash ソースコード
gradle i_executePythonExecutableFileTask -Pc_mainModuleName="theBiasPlanet.hiConsolePythonUnoClients.programs.HiConsolePythonUnoClients" -Pc_commandLineArguments="socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext file://${HOME}/myData/development/hiConsolePythonUnoClients/execution/HiConsolePythonUnoClientsTests.odt"

ト書き
Hypothesizer 7は、カレントディレクトリをサンプルプロジェクトディレクトリに位置させて、上記コマンドをターミナルで実行する。Writer文書がオープンし、その後、すぐにクローズする。

Objector 28A
...ドキュメントはディスプレイ上にどうしても表示されてしまうのか?

Hypothesizer 7
いいえ。意図的にディスプレイに表示しています、サンプルプログラムがオフィスインスタンスへの接続に成功したことをデモンストレーションするために。

Objector 28A
それならいい。

Hypothesizer 7
Officeインスタンスがリモートホストにいる場合は、ホスト名を'localhost'から変更すればよいです、勿論、ファイアウォールが通信をブロックしなければですが。

ご注意いただきたいのですが、Windowsでは、'${HOME}'は'/E:/home/tanichida'のようになります。


3: サンプルプログラムを理解する


Hypothesizer 7
コンソールPython UNOクライアントサンプルの説明は、コンソールJavaUNOクライアントサンプルのそれとほとんど同じであって、その過去記事内の一部の記述とほとんど同じ記述をここで行なうことなく、その過去記事の一部のサブセクションを引用して、違いだけを示します。


3-1: プロジェクト群構造


Hypothesizer 7
3つのプロジェクト、'coreUtilitiesToBeDisclosed'、'unoUtilitiesToBeDisclosed'、'hiConsolePythonUnoClients'があります。'coreUtilitiesToBeDisclosed'には、あらゆる種類のプロジェクトで共用されるように想定されているユーティリティコードが含まれています。'unoUtilitiesToBeDisclosed'には、UNOプログラムのプロジェクト群で共用されるように想定されているユーティリティコードが含まれています。'hiConsolePythonUnoClientsは、サンプルプロジェクトです。

サンプルプログラムは、'unoUtilitiesToBeDisclosed'をただ使う以外のことはあまり行なわないので、私たちの外部コンソールPythonプログラムをUNOサーバーに接続させる方法を学ぶには、'unoUtilitiesToBeDisclosed'プロジェクトの中身を見る必要があります。


3-2: 当ユーティリティプロジェクト群を使用してUNOサーバーに接続した後にしなければならないこと


Hypothesizer 7
当ユーティリティプロジェクト群を万が一そのままご使用になるという場合のために、当ユーティリティプロジェクト群を使用してUNOサーバーにコネクトした後にしなければならないことを見ておきましょう。

実際には、Pythonユーティリティクラス・インターフェイス群の構造はJavaユーティリティクラス・インターフェイス群のそれに準拠しているため、以前の記事のこのサブセクションの記述が、そのまま当てはまります。


3-3: UNOオブジェクト群コンテキストのラッパー


Hypothesizer 7
'unoUtilitiesToBeDisclosed'プロジェクトの'theBiasPlanet.unoUtilities.connectionsHandling.UnoObjectsContext'クラスは、UNOオブジェクト群コンテキストのラッパーです。

このラッパーについての以前の記事のこのサブセクションの記述が、そのまま、ここに当てはまります。


3-4: ローカルUNOオブジェクト群コンテキストを生成する(ブートストラッピング)


Hypothesizer 7
'ブートストラッピング'のコンセプトについての以前の記事のこのサブセクションの記述は、ここに当てはまりますが、ローカルUNOオブジェクト群コンテキストを生成する方法は、Pythonでは異なります。

以下が、ローカルUNOオブジェクト群コンテキストを生成する方法です、'theBiasPlanet.unoUtilities.programsHandling.UnoProcessEnvironment'クラスのコンストラクターに見られるとおり。

@Python ソースコード
import uno
from com.sun.star.uno import XComponentContext

			l_originalLocalObjectsContext: XComponentContext = uno.getComponentContext ()


3-5: UNOサーバーに接続する


Hypothesizer 7
UNOサーバーに接続することについての以前の記事のこのサブセクションの記述が、ここに当てはまります。


3-6: コネクションを切断する


Hypothesizer 7
コネクションを切断することについての以前の記事のこのサブセクションの記述が、そのまま、ここに当てはまります。


4: オフィスインスタンスに接続する、より単純な方法があるが...


Hypothesizer 7
実は、オフィスインスタンスに接続する、より単純な方法があります、しかし、その方法にはいくつか制限があり、それらは、ある種のケースにおいて致命的です。

以前の記事のこのセクションの議論が、ここに、そのまま、当てはまります。


5: 結びとその先


Hypothesizer 7
これで、コンソールPython UNOクライアントから、任意のUNOサーバーにコネクトすることができます。

当サンプルを'コンソール'クライアントと特に断わったのは、GUI Python UNOクライアントサンプルを将来の記事で紹介するからです。

GUI Python UNOクライアントは、UNO上、コンソールPython UNOクライアントと違う必要がないように思われるかもしれませんが、1つ違いがあります。UNOクライアントが長い間動作し続けると想定されるため、UNOサーバーまたはネットワークによって引き起こされるコネクション切断を検知することがより適切となります。


参考資料


<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>