LibreOffice5(12)PythonでLibreOfficeのバージョン番号を得る方法

前の関連記事:LibreOffice5(11)unoinsp.py:自作IDLへの対応


LibreOfficeのバージョン番号を得るという簡単にできそうなことがなかなかわかりませんでした。GetSolarVersion - LibreOfficeを活用したい方々へをようやく見つけて解決への糸口を掴みました。

BasicにあるGetSolarVersion関数の代わりを考える


GetSolarVersionを検索するとGetSolarVersion Function [Runtime] - LibreOffice Helpがみつかりました。(the solar technologyとLibreOfficeとはどういうご関係?)

BasicではこのGetSolarVersion関数でLibreOfficeのバージョンが得られるようです。

PythonではどうなのかLibreOffice: Main Pageでいろいろな単語で検索してみましたがLibreOfficeのバージョンを返すメソッドは見つけられませんでした。

仕方なくせっせとGetSolarVersionで検索した結果をみていくと[RESUELTO] Identificar Apache OpenOffice o LibreOffice (Ver Tema) • Apache OpenOffice: Foro oficial de la comunidadに行き着きました。

スペイン語で書いてあるのでChromeで翻訳してみると問題は解決したようです。

回答のリンク先のeasydev/tools.py at master · UniversoLibreMexicoAC/easydevを使えば解決しそうです。

EasyDev はソースがPythonなのでいろいろ勉強になりそう


Welcome to EasyDev’s documentation! — EasyDev 2.0.0 documentation

先のリンク先はこのEasyDevのソースの一部になります。

easydev/release-notes_en.txtをみると2015.8.15の安定版1.0.0から始まっています。

easydev/filesにあるoxtファイルを拡張機能マネージャーに登録するとBasicでいろいろ便利なことができるようです。

でもソースはPythonで書いてありますので参考になりそうです。

ドキュメントも充実していますが、実行結果が載っていないので実行してみないと何が返ってくるのかがわかりません。

EasyDev_v2.4.1.oxtファイルを拡張機能マネージャーに登録してみました。


Python2.4.1と書いてあるようにみえますが、ソースはPython3系のようです。


EasyDev_v2.4.1.oxtファイルを拡張機能マネージャーに登録するとLibreOffice BasicのマイマクロフォルダにEasyDevのマクロの例が追加されていました。

スタートセンターでToolsのShowInfoPCを実行するとフリーズしてしまいましたが、Writerで実行するとPCの情報が順番にメッセージボックスにでてきました。

EasyDevのバージョン。
OSの名前。
アプリケーションの名前。
アプリケーションのバージョン。
画面サイズ。


ログインユーザー名、コンピューター名、OS名、マシンタイプ、CPU名、プラットフォーム名。

PythonでLibreOfficeのバージョン番号を得る方法


EasyDevのtools.pyを参考にPythonのオートメーションでLibreOfficeのバージョン番号を得てみます。
#!/opt/libreoffice5.0/program/python
# -*- coding: utf-8 -*-
import uno
from com.sun.star.beans import PropertyValue
def get_info():
    ctx = XSCRIPTCONTEXT.getComponentContext()
    cp = ctx.getServiceManager().createInstanceWithContext('com.sun.star.configuration.ConfigurationProvider', ctx)
    node = PropertyValue()
    node.Name = 'nodepath'
    node.Value = 'org.openoffice.Setup/Product'
    ca = cp.createInstanceWithArguments('com.sun.star.configuration.ConfigurationAccess', (node,))
    data = ca.getPropertyValue('ooSetupVersion')
    print("LibreOfficeのバージョン: " + data)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    get_info()
このget_LO_info.pyで LibreOfficeのバージョン: 5.0 が出力されました。

7行目でcom.sun.star.configuration.ConfigurationProviderサービスをcreateInstanceWithContext()でインスタンス化しています。

ConfigurationProviderの継承図をみるとConfigurationProviderサービスはcom.sun.star.lang.XMultiServiceFactoryインターフェイスをもっています。

LibreOffice(14)デベロッパーガイド2 サービスマネジャとファクトリーではサービスをインスタンス化するときはXMultiServiceFactoryインターフェイスではなく、今後はコンテクストを伝搬できるXMultiComponentFactoryインターフェイスを使ったほうがよいと学習しました。

ConfigurationProviderサービスは複数のインターフェイスをもつold-style serviceなのでXMultiComponentFactoryインターフェイスではなくXMultiServiceFactoryインターフェイスを継承している、と思ったのですがConfigurationProviderの解説を読んでみてもよくわかりませんでした。

ConfigurationProviderの解説はConfigurationProviderサービスのインスタンス化するときのcreateInstanceWithContextAndArguments() とcreateInstanceWithArguments()について書いてあります。(createInstanceWithContextAndArgumentsは誤植で正確にはcreateInstanceWithArgumentsAndContext ですね。)

引数なしでインスタンス化するとデフォルト値が採用されるようです。

11行目でConfigurationProviderのcreateInstanceWithContext()メソッドでnodepathをorg.openoffice.Setup/Productに設定したPropertyValue()を引数にしてcom.sun.star.configuration.ConfigurationAccessサービスをインスタンス化しています。

12行目で.ConfigurationAccessサービスがもっているcom.sun.star.beans.XPropertySetインターフェイスのgetPropertyValue()メソッドでプロパティ名ooSetupVersionを引数にしてその値5.0を得ています。

LibreOfficeのバージョン番号は/opt/libreoffice5.0/share/registry/main.xcdに書いてある


ノードパスとかプロパティ名は一体どうやって知ればいいのかAPIリファレンスを読んでもわからなかったので調べてみたところOOoBasic/Generic/Configurations - ...?にちゃんと書いてありました。

以前にもこの記事は読んだことがあるのですがそのときは理解できなかったのですがようやく理解できるようになりました。

これらのサービスは/opt/libreoffice5.0/share/registryにあるxcdファイルの内容を読み込んでいるのでした。

xcdファイルはxmlで書いてあるのでChromeで開いてしばらく待っていると見やすく整形してくれます。

上記のget_LO_info.pyで設定したノードパスのorg.openoffice.Setup/Productは、パッケージ名org.openoffice、コンポーネント名Setupでコンポーネントフルパスorg.openoffice.Setupの下層にあるProductノードに至るパスになります。

そしてgetPropertyValue()メソッドでooSetupVersionの値を得ています。
<oor:component-data xmlns:install="http://openoffice.org/2004/installation" oor:name="Setup" oor:package="org.openoffice">
    <node oor:name="Product">
        <prop oor:name="ooName">
            <value>LibreOffice</value>
        </prop>
        <prop oor:name="ooSetupVersion">
            <value>5.0</value>
        </prop>
        <prop oor:name="ooSetupVersionAboutBox">
            <value>5.0.3.2</value>
        </prop>
        <prop oor:name="ooSetupVersionAboutBoxSuffix">
            <value/>
        </prop>
        <prop oor:name="ooVendor">
            <value>The Document Foundation</value>
        </prop>
        <prop oor:name="ooSetupExtension">
            <value>.3.2</value>
        </prop>
        <prop oor:name="ooXMLFileFormatVersion">
            <value>1.0</value>
        </prop>
        <prop oor:name="ooXMLFileFormatName">
            <value>OpenOffice.org</value>
        </prop>
        <prop oor:name="ooOpenSourceContext">
            <value>1</value>
        </prop>
    </node>
/opt/libreoffice5.0/share/registry/main.xcdにooSetupVersionの部分を見つけました。

LibreOfficeのインストールパスを得たい


(2017.4.3追記。なんとos.environ["UNO_PATH"]でインストールパスが簡単に得られました。officehelper.pyに書いてありました。)
(2017.8.18追記。os.environ["UNO_PATH"]はWindows10ではKeyがないと言われてダメでした。
configpath = ctx.getByName('/singletons/com.sun.star.util.thePathSettings').getPropertyValue("Config")  # file:///opt/libreoffice5.2/program/../share/configが返る。
configpath = unohelper.fileUrlToSystemPath(configpath)  # /opt/libreoffice5.2/program/../share/configが返る。
uno_path = os.path.join(configpath, "..", "..", "program")  # /opt/libreoffice5.2/program/../share/config/../../programが返る。
uno_path = os.path.normpath(uno_path)  # /opt/libreoffice5.2/programが返る。
これでWindowsでもインストールパスが取得できました。)
(2017.8.25追記。$(prog)で取得する方法がよいと思います。LibreOffice5(74)PathSubstitutionサービスで既定値を取得する参照。)

main.xcdをみるとooNameを小文字にしてooSetupVersionをくっつけるとインストールフォルダ名になります。

$(insturl)という変数をみつけたのでそれの値を得られないかorg.openoffice.Office.Common/Path/Currentをノードパスにしてプロパティ名Configの値を得てみましたが、オートメーションやマクロ、拡張機能いずれでも$(insturl)/share/configというのが返ってきただけなのでこの方法は断念しました。
#!/opt/libreoffice5.0/program/python
# -*- coding: utf-8 -*-
import platform
import uno
from com.sun.star.beans import PropertyValue
def get_info():
    ctx = XSCRIPTCONTEXT.getComponentContext()
    cp = ctx.getServiceManager().createInstanceWithContext('com.sun.star.configuration.ConfigurationProvider', ctx)
    node = PropertyValue()
    node.Name = 'nodepath'
    node.Value = 'org.openoffice.Setup/Product'  # libreoffice5.0/share/registry/main.xcd内のノードパス。
    ca = cp.createInstanceWithArguments('com.sun.star.configuration.ConfigurationAccess', (node,))
    o_name = ca.getPropertyValue('ooName')  # ooNameプロパティからLibreOfficeの名前を得る。
    o_setupversion = ca.getPropertyValue('ooSetupVersion')  # ooSetupVersionからLibreOfficeのメジャーバージョンとマイナーバージョンの番号を得る。
    os = platform.system()  # OS名を得る。
    if os == "Linux": path = "/opt/"  # LinuxのときのLibreOfficeのインストール先フォルダ。
    print("LibreOfficeのインストールパス: " + path + o_name.lower() + o_setupversion)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    get_info()
これでLinuxでのLibreOfficeのインストールパスが返ってきました。

(2017.4.2追記。ただし/optは決め打ちしています。)

LibreOfficeのインストールパス: /opt/libreoffice5.0

開発版のLibreOfficeの名前はLibreOfficeDevが返ってくるので開発版でも使えます。

Developer's Guide Examplesに載っているConfiguration Management examplesというJavaの例を実行してみましたがなにやらたくさんプロパティが設定されたようなコマンドがたくさん流れて終わりましたが何がどうなったのかよくわかりませんでした。

参考にしたサイト


GetSolarVersion - LibreOfficeを活用したい方々へ
LibreOfficeのメジャー、マイナー、バグフィクスのバージョン番号を三桁で返すBasicの関数。

GetSolarVersion Function [Runtime] - LibreOffice Help
GetSolarVersion()関数の使用例。

[RESUELTO] Identificar Apache OpenOffice o LibreOffice (Ver Tema) • Apache OpenOffice: Foro oficial de la comunidad
LibreOfficeのバージョン番号をPythonで得るQ&A。スペイン語なのでChromeで翻訳して読みました。

easydev/tools.py at master · UniversoLibreMexicoAC/easydev
上記のQ&AでリンクされているLibreOfficeのバージョン番号をPythonで得る部分。

Welcome to EasyDev’s documentation! — EasyDev 2.0.0 documentation
LibreOfficeに関するBasicのツール集。ソースはPythonで書いてあります。

LibreOffice: Main Page
LibreOffice APIリファレンス。

OOoBasic/Generic/Configurations - ...?
OpenOfficeの設定値を得る方法。

LibreOffice 4.5 SDK - Developer's Guide Examples
設定値を得るJavaの例。

次の関連記事:LibreOffice5(13)unoinsp.py:IDL名から継承図を出力する

PR

0 件のコメント:

コメントを投稿