web-dev-qa-db-ja.com

最近使用したファイルの動的なアプリケーション固有のクイックリストをUnityランチャーに追加するにはどうすればよいですか?

ランチャーの動的なクイックリストを使用して、LibreOfficeから最近使用したドキュメントにアクセスするのは素晴らしい機能です。 カスタムstaticクイックリストの作成方法に関する経験がかなりあります があります。

しかし、loで最近使用されたドキュメントのdynamicクイックリストを構築する方法について建設的な方向性を与える可能性のある人はいますか?

Ubuntu wikiには、pythonまたはvalaを使用してクイックリストを作成する方法に関する 非常に簡単な説明 があります。私は2つのどちらにも経験がなく、動的なクイックリスト用の包括的なサンプルスクリプトを見つけられませんでした。したがって、私はそれを実装するためのいくつかの簡単な方法、またはすでにそれを見て/見た人を探しています。

4
joaoal

動的な「最近使用した」セクションをアプリケーションのランチャーに追加する

fullアプリケーションと前述のdynamic quicklist -entriesの統合は、おそらくアプリケーションのfrom insideで行う必要があります。結局のところ、使用されるファイルに関する最も直接的な情報は、アプリケーション自体から取得されます。

ただし、ソースコードの編集は私たちが行っていることの範囲外であるため、これを行うのは道のりではありません。

それでは何?

それは、「外部」からより柔軟で一般的な方法でさえ、ほぼ同じ結果を達成できないという意味ではありません。必要なすべての情報は、動的に更新されるファイル~/.local/share/recently-used.xbelで利用できます。このファイルから、開いているファイルの完全な履歴、対応する日付と時刻の情報、使用されたアプリケーションを取得できます。

さらに、dynamically更新されたセクションをランチャーに追加することは、「従来の」(静的)セクションの一部として非常にうまく行うことができます。ソリューションの鍵は、システムに目立った負担をかけることなく、上記のアクションを処理するプロセスを作成することです。
質問の リンク で述べたように、変更を追跡して指示を渡すには、とにかくsomeバックグラウンドプロセスが必要になります。

以下のスクリプトは、まさにそれを行っています。

ソリューション;背景スクリプト

以下のスクリプト内の値は、LibreOfficeとそのドキュメント専用に設定されています。編集せずに、LibreOffice-Writerlauncherに最近使用した-セクションを追加するために使用できます。 LibreOfficeモジュールのいずれかによって開かれた、最後に使用された10個のドキュメントが表示されます。

ただし、このソリューションを使用すると、.desktop内の/usr/share/applicationsファイルを使用してmany applicatiosnに「最近使用した」セクションを追加できます。ファイル~/.local/share/recently-used.xbelGtkに関連しているため、Gtkウィンドウを持つアプリケーションが最も可能性の高い候補になります(つまり、アプリケーションがファイルを開いて編集する場合)。さらに、表示するファイルの数は任意です。

見た目

ソリューションは、Unityランチャーのターゲットランチャーにセクションを追加し、最近使用した任意の数のファイルを表示します。例:

  • 最後の7つのファイルを表示します。

    enter image description here

  • または最後の10ファイル:

    enter image description here

  • ただし、同じ簡単さで、geditランチャーに動的セクションを与え、geditで開いた最後の7つのファイルを表示できます(下の画像を参照)

使い方

LibreOfficeがプレインストールされていると仮定します(ダウンロードしたバージョンには、スクリプトで必要な.desktopに参照/usr/share/applicationsファイルがありませんが、別の場所に、別途セットアップする必要がある場合は、ダウンロードしたLOバージョン)

  1. 以下のスクリプトを空のファイルにコピーし、dynamic_recent.pyとして保存します。LibreOfficeの場合、プロセス名はsofficeであり、既にスクリプトに正しく設定されています。

    #!/usr/bin/env python3
    import subprocess
    import os
    import time
    import shutil
    
    # --- set the number of docs to show in recently used
    n = 7
    # --- set the process name of the targeted application
    application = "soffice"
    #--- ONLY change the value below into "xdg-open" if you do not use LO preinstalled
    #    else the value should be the same as in application = (above)
    open_cmd = "soffice"
    # --- set the targeted .desktop file (e.g. "gedit.desktop")
    target = "libreoffice-writer.desktop"
    
    # --- don't change anything below
    home = os.environ["HOME"]+"/.local/share"
    loc = home+"/applications/"+target
    recdata = home+"/recently-used.xbel"
    
    def runs(app):
        try:
            # see if the application is running
            app = subprocess.check_output(["pgrep", app]).decode("utf-8")
        except subprocess.CalledProcessError:
            return False
        else:
            return True
    
    def get_lines():
        # retrieve information from the records:
        # -> get bookmark line *if* the application is in the exec= line
        with open(recdata) as infile:
            db = []
            for l in infile:
                if '<bookmark href="file://' in l:
                    sub = l
                Elif 'exec="&apos;'+application in l:
                    db.append(sub)
        # fix bug in xbel -file in 15.04
        relevant = [l.split('="') for l in set(db) if all([not "/tmp" in l, "." in l])]
        relevant = [[it[1][7:-7], it[-2][:-10]] for it in relevant]
        relevant.sort(key=lambda x: x[1])
        return [item[0].replace("%20", " ") for item in relevant[::-1][:n]]
    
    def create_section(line):
        # create shortcut section
        name = line.split("/")[-1]
        return [[
            "[Desktop Action "+name+"]",
            "Name="+name,
            "Exec="+open_cmd+" '"+line+"'",
            "\n",
            ], name]
    
    def setup_dirs():
        # copy the global .desktop file to /usr/share/applications/
        glo = "/usr/share/applications/"+target
        if not os.path.exists(loc):
            shutil.copy(glo,loc)
    
    def edit_launcher(newdyn, target, actionlist):
        # read the current .desktop file
        ql = [list(item) for item in list(enumerate(open(loc).read().splitlines()))]
        # find the Actions= line
        currlinks = [l for l in ql if "Actions=" in l[1]]
        # split the line (if it exists)  by the divider as delimiter 
        linkline = currlinks[0][1].split("divider1")[0] if currlinks else None
        # define the shortcut sections, belonging to the dynamic section (below the divider)
        lowersection = [l for l in ql if "[Desktop Action divider1]" in l]
        # compose the new Actions= line
        addlinks = (";").join(actionlist) + ";"
        if linkline:
            newlinks = linkline + addlinks
            ql[currlinks[0][0]][1] = newlinks
            # get rid of the "dynamic" section  
            ql = ql[:lowersection[0][0]] if lowersection else ql
            # define the new file
            ql = [it[1] for it in ql]+newdyn
            with open(loc, "wt") as out:
                for l in ql:
                    out.write(l+"\n")
        else:
            newlinks = "Acrions="+addlinks
    
    setup_dirs()
    lines1 = []
    
    while True:
        time.sleep(2)
        # if the application does not run, no need for a check of .xbel
        if runs(application):
            lines2 = get_lines()
            # (only) if the list of recently used changed: edit the quicklist
            if lines1 != lines2:
                actionlist = ["divider1"]
                newdyn = [
                    "[Desktop Action divider1]",
                    "Name=" + 37*".",
                    "\n",
                    ]
                for line in lines2:
                    data = create_section(line)
                    actionlist.append(data[1])
                    section = data[0]
                    for l in section:
                        newdyn.append(l)
                edit_launcher(newdyn, target, actionlist)           
            lines1 = lines2
    
  2. スクリプトのヘッドセクションでは、いくつかのオプションを設定できます。

    # --- set the number of docs to show in recently used
    n = 7
    # --- set the process name of the targeted application
    application = "soffice"
    #--- ONLY change the value below into "xdg-open" if you do not use LO preinstalled
    #    else the value should be the same as in application = (above)
    open_cmd = "soffice"
    # --- set the targeted .desktop file (e.g. "gedit.desktop")
    target = "libreoffice-writer.desktop"
    

    動的セクションをLO-Writerランチャーに追加する場合は、ほとんどのオプションが自明です。すべてをそのままにしておきます。そうでない場合は、適切なランチャーを設定します。

  3. ターミナルから実行して、スクリプトをテスト実行します。

    python3 /path/to/dynamic_recent.py
    
  4. スクリプトは、グローバル.desktopファイルを~/.local/share/applications(この場合は~/.local/share/applications/libreoffice-writer.desktop)にコピーしました。ローカルコピーをランチャーにドラッグします(そうでない場合は、ログアウト/ログインする必要があります)。

  5. すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加。コマンドを追加します。

    python3 /path/to/dynamic_recent.py
    

他のアプリケーションで使用するには

前述のように、スクリプトを使用して、「最近使用した」動的セクションを他のアプリケーションのランチャーに簡単に追加できます。これを行うには、スクリプトのheadセクションのgeditサンプル設定を参照してください。

# --- set the number of docs to show in recently used
n = 7
# --- set the process name of the targeted application
application = "gedit"
#--- ONLY change the value below into "xdg-open" if you do not use LO preinstalled
#    else the value should be the same as in application = (above)
open_cmd = "gedit"
# --- set the targeted .desktop file (e.g. "gedit.desktop")
target = "gedit.desktop"

enter image description here

使い方

  • スクリプトは定期的にファイル~/.local/share/recently-used.xbelを調べて、LibreOffice(プロセス名:soffice)で開かれた一致するファイルを見つけます。

    これは非常に高速なアルゴリズムを使用して、単一パスでファイルを「撮影」し、必要な行(「レコード」ごとに2行)を取得します。その結果、スクリプトのジュースは非常に少なくなります。

  • 関連する行がファイルから取得されると、行は日付/時刻でソートされ、対応するアプリケーションの最近使用したファイルの「トップ10」(またはその他の数)が作成されます。

  • ONLYこのリストが変更されると、.desktopファイルが更新されます。

バックグラウンドでスクリプトを実行して、システムへの追加の負荷に気付き、測定することができました。

14.04/15.10でテスト済み

元のランチャーを復元する方法

~/.local/share/applicationsでランチャーのローカルコピーを削除するだけです

ノート

  • nity Quicklist Editor を使用してランチャー(クイックリスト)を編集する場合、この回答から動的に更新される「最終使用」セクションでランチャーを編集しないでください。 QUicklist Editorで行った編集は、すぐにスクリプトによって上書きされます。

  • クイックリストは手動で編集できますが、必ず新しい項目を追加してくださいbefore(の左側)divider1-行のActions=

    Actions=Window;Document;divider1;aap.sh;Todo;pscript_2.py;currdate;bulkmail_llJacob;verhaal;test doc;

    すべての項目右側 of divider1は、動的に更新されるセクションに属します。


主な編集

いくつかの大きな改善が行われました:

  1. 現在、スクリプトはonlyターゲットアプリケーションの実行中に.xbelファイルをチェックします(アプリケーションが実行されない場合、最近使用したリストに変更がないため)。このスクリプトは既にジュースが不足していましたが、今では、アプリケーションが実行されている場合にのみ注意を払うだけで、システムにとってはさらに意味がありません。
  2. 15.04以降では、.xbelファイルに新しいファイルが二重に記載されていました。 1つは拡張あり、もう1つは拡張なしです。その影響は除去されました。

4
Jacob Vlijm