ウェブサイト検索

nautilus-pythonを使ったNautilus拡張機能の書き方


Nautilus(「ファイル」としても知られています)は、GNOMEデスクトップ環境のデフォルトのファイルマネージャーです。以前のチュートリアルでは、Nautilusのコンテキストメニューからカスタムスクリプトを作成して呼び出す方法を見ました。この機能は非常に便利ですが、いくつかの制限があります。私たちのお気に入りのLinuxディストリビューションにnautilus-pythonパッケージをインストールし、わずか数行のPythonコードを書くことで、これらの制限を克服し、適切なNautilus拡張機能を作成できます。

このチュートリアルでは、Pythonとnautilus-pythonパッケージによって提供されるバインディングを使用して、Nautilus拡張機能を書き方を学びます。

このチュートリアルでは、あなたは学びます:

  • 最も使用されているLinuxディストリビューションのいくつかにnautilus-pythonをインストールする方法
  • ナイタリスAPIの仕組み
  • PythonでNautilus拡張機能を作成する方法

「プロパティ」拡張を作成する

別の例を見てみましょう。今回は、epubファイルのプロパティセクションに追加の「タブ」を提供する拡張機能を作成します。このスペースを利用して、いくつかの書籍メタデータを表示します。

"""
Add a Nautilus property page to epub files to display book metadata.

Author: Egidio Docile
"""

from gi.repository import GObject, Gtk, Nautilus
from urllib.parse import urlparse, unquote

import epub_meta


class EpubMetadataPropertyPageProvider(GObject.GObject, Nautilus.PropertyPageProvider):

    def _get_epub_metadata(self, file):
        file_path = unquote(urlparse(file.get_uri()).path)
        
        return epub_meta.get_epub_metadata(file_path)


    def get_property_pages(self, files):
        if len(files) != 1:
            return

        file = files[0]
        if file.get_mime_type() != 'application/epub+zip':
            return ()

        metadata = self._get_epub_metadata(file)

        property_label = Gtk.Label('Epub Metadata')
        property_label.show()
        
        grid = Gtk.Grid()
        grid.props.margin_left = 50
        grid.props.margin_top = 20
        
        for row, key in enumerate(['authors', 'publisher', 'title']):
            val = ",".join(metadata[key]) if isinstance(metadata[key], list) else metadata[key] 
            grid.attach(Gtk.Label(f'{key.capitalize()}: ', xalign=1), 0, row, 1, 1)
            grid.attach(Gtk.Label(val, xalign=0), 1, row, 1, 1)
        
        grid.show_all()

        page = Nautilus.PropertyPage(
                    name="epub_metadata",
                    label=property_label,
                    page=grid)

        return page,

この例では、gi.repository から Gtk モジュールもインポートしたことがわかります。これは、電子書籍のメタデータを整理して表示するためにグリッドコンテナを作成するために行いました。

get_property_pagesメソッドは、EpubMetadataPropertyPageProviderクラスで実装されており、Nautilus.PropertyPageProvider基本クラスから継承されています。このメソッドは、選択されたファイルを表すFileInfoオブジェクトのリストを単一の引数として受け取り、関連するNautilusセクションに追加されるべきPropertyPageオブジェクトのリストを返します。

メソッド本体で最初に行ったことは、1つのファイルだけが選択されているかどうかをテストすることでした。なぜなら、私たちの拡張機能は一度に1つのファイルだけで動作するようにしたいからです。ユーザーが複数のファイルを選択した場合は、前の例と同様に、空のタプルを返します。

1つのファイルだけが選択されている場合、MIMEタイプをチェックしてそれがepubであることを確認し、最終的にそのメタデータ(著者、出版社、タイトル)を取得します。データを表示するために、Gtk.Gridオブジェクトを作成し、Gtk.Labelオブジェクトを使用してテキストを表示しました。

最後に、Nautilus.PropertyPageオブジェクトを作成し、それを唯一の要素として含むタプルを返しました。これで、epubファイルを右クリックし、Nautilusのコンテキストメニューで「プロパティ」を選択すると、「Epubメタデータ」という追加のプロパティタブが表示されるはずです。:

ここではウィジェットをどのように作成したかを詳細に説明していません。なぜなら、これは実装の詳細だと考えているからです(そして、洗練されるべきです)。この文脈で重要なのは、拡張機能の作成における主要なロジックを理解することです。

列の拡張を作成する

私たちの第三および最後の例では、「カラム」拡張を作成します。この拡張は、Nautilusの「リスト」ビューに8進数形式で表示されたファイルのパーミッションを含む新しいカラムを追加します。ここに考えられる実装があります。

"""
Add a column containing the file permissions in octal notation
to the Nautilus list view.

Author: Egidio Docile
"""

import os
from urllib.parse import unquote, urlparse

from gi.repository import GObject, Nautilus


class OctalPermissionsInfoProvider(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
    def get_columns(self):
        column = Nautilus.Column(
            name="file_permissions_octal",
            attribute="file_permissions_octal",
            label="Permissions (octal)",
            description="The octal file permissions"
        )

        return column,

    def update_file_info(self, file):
        file_path = unquote(urlparse(file.get_uri()).path)
        octal_permissions = oct(os.stat(file_path).st_mode)[-3:]
        file.add_string_attribute('file_permissions_octal', octal_permissions)

この例では、私たちの拡張は、GObject.GObjectから通常通り継承し、さらに2つの基底クラスであるNautilus.ColumnProviderとNautilus.InfoProviderからも継承しているOctalPermissionsInfoProviderクラスによって表されています。

前者については、Nautilusに追加すべき列のリストを返す必要があるget_columnsメソッドを実装しました。メソッドの本体では、Nautilus.Columnオブジェクトとして表される1つの列だけを作成し、それをタプルの唯一の要素として返しました。

Nautilus.Columnオブジェクトを作成するために、私たちはそのコンストラクタに4つの文字列を引数として渡しました。最初のもの、nameは列の識別子として使用されます。2つ目のattributeは、列に表示される属性の名前です(file_permissions_octal属性は、update_file_infoメソッドでファイルを表すFileInfoオブジェクトに追加されます)。3番目の引数、labelは、列ヘッダーとしてユーザーに表示されるテキストであり、最後のdescriptionは列の説明です。

update_file_info メソッドは Nautilus.InfoProvider 基底クラスから継承されています。このメソッドは、単一の FileInfo オブジェクトを引数として受け取ります。私たちの実装では、ファイルの権限を取得し、それを八進数形式に変換しました。そして、add_string_attribute メソッドを使用してオブジェクトに追加した file_permissions_octal 属性の値として結果を設定しました。

ナウティルスの「リスト」ビューで追加の列がどのように表示されるかは次のとおりです(列がデフォルトで表示されていない場合は、列のヘッダーを右クリックして、列メニューの関連エントリーをチェックしてください):

結論

このチュートリアルでは、nautilus-pythonパッケージが提供するバインディングを使用して、PythonでNautilus拡張機能を作成する方法を学びました。最も使用されているLinuxディストリビューションのいくつかにパッケージをインストールする方法を見て、Nautilus APIを確認し、いくつかの拡張機能を例として作成しました。Nautilus 3.0 APIの詳細については、以下のドキュメントを参照してください。また、nautilus-pythonの開発を追跡するには、GitLabでプロジェクトをフォローできます。

関連記事: