LibreOffice5(85)FileURLとSystemPathの変換方法

2017-09-22

旧ブログ

t f B! P L
LibreOfficeのマクロ内ではファイルのパスはFileURLで扱われます。ファイル選択ダイアログなどから取得できるパスはOS固有のSystemPathなのでそれとの変換をしないといけません。

前の関連記事:LibreOffice5(84)Javaの例:GUIをPythonにする その9


FileURLとSystemPathを変換する3つの方法


Pythonモジュールだけを使う方法、
unohelper.pyの関数を使う方法、
FileContentProviderサービスを使う方法、
の3つの方法があります。

Pythonモジュールだけを使う方法
from urllib.parse import urlparse
from urllib.request import url2pathname
systempath = url2pathname(urlparse(fileurl).path)
これでfileurlをsystempathに変換できます。
from pathlib import Path
fileurl = Path(systempath).as_uri()
これでsystempathをfileurlに変換できます。

この方法の欠点はPython3.4以上でしかpathlibモジュールが使えないことです。

なのでこの方法はWindows版のLibreOffice5.3以下ではsystempathをfileurlに変換することはできません。

LibreOffice5.4以上であればWindows版もLinux版もバンドルPythonのバージョンは3.5.4になっているのでpathlibモジュールが使えます。

unohelper.pyの関数を使う方法
import unohelper
systempath =  unohelper.fileUrlToSystemPath(fileurl)
これでfileurlをsystempathに変換できます。
import unohelper
fileurl = unohelper.systemPathToFileUrl(systempath)
これでsystempathをfileurlに変換できます。

FileContentProviderサービスを使う方法
filecontentprovider = smgr.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", ctx)
systempath =  filecontentprovider.getSystemPathFromFileURL(fileurl)
これでfileurlをsystempathに変換できます。

smgrはサービスマネージャー、ctxはコンポーネントコンテクストを入れとかないといけません。
filecontentprovider = smgr.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", ctx)
fileurl = filecontentprovider.getFileURLFromSystemPath("", systempath)
これでsystempathをfileurlに変換できます。

WindowsとLinuxでのFileURLとSystemPath


WindowsとLinuxではそれぞれFileURLとSystemPathの形式が異なります。

例としてホームディレクトリのパスを表示します。

Windows

FileURL: file:///C:/Users/pq

SystemPath: C:\Users\pq

Linux

FileURL: file:///home/pq

SystemPath: /home/pq

FileURLはOSに関係なく共通なものと勘違いしていましたが、OSによって異なっていました。

正しくない形式を渡したときの各方法の戻り値


https://docs.google.com/spreadsheets/d/e/2PACX-1vQYwD4eS1tfwIcV1hIAJM2xj8k4Hle3JSAZnJc9dmVV07sg4FWWUpb5NnQw-TejQnRBSaWD42VRnXVE/pubhtml?gid=0&single=true

入力値を14パターン入力してその戻り値を調べました。

misc/pathconverters.py at 1b8865f21a48f3c9d9c98211def75647893aac25 · p--q/misc

このマクロで調べましたが、WindowsではLibreOfficeがクラッシュする入力値のパターンがあるのでそれを避けて二つのマクロを追加して調べました。

misc/pathconverters_forWin.py at 1b8865f21a48f3c9d9c98211def75647893aac25 · p--q/misc

misc/pathconverters_forWin2.py at 1b8865f21a48f3c9d9c98211def75647893aac25 · p--q/misc

かなり面倒な作業でした。

さあ、この表を見て何を考えるか、、、

正しい形式の値であれば、どの方法でもちゃんと値が返ってきます。

FileURLもSystemPathも、WindowsとLinuxとで互換性がないので、デフォルトパスを設定する場合はPathSubstitutionサービスかthePathSettingsシングルトンから取得するようにしたいと思います。

不正な値をどうやって弾くかについて考えます。

ユーザーからの入力されたSystemPathは、ファイル選択ダイアログ(FilePickerサービス)か、フォルダ選択ダイアログ(FolderPickerサービス)に限定して取得するようにすれば、FileURLへの変換をしてくれます。

SimpleFileAccessサービスのexists()メソッドでFileURLのパスが実存するかが確認できます。

これでSystemPathの不正な入力値を弾けると思います。

FileURLはユーザーから入力されることはなく、PathSubstitutionサービスかthePathSettingsシングルトンから得たFileURLの存在を確認して、存在しないものを弾けば、不正な値を避けることができます。

ということは不正な値が入力される想定をする必要はなさそうです。

パスを正規化する関数はLibreOffice APIにないようなので、SystemPathに変換してos.path.normpath(path)で正規化するしかなさそうです。

次の関連記事:LibreOffice5(86)拡張機能: TCU - Tree Command for UNO の作成

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ