是否有指示器可以快速访问最近使用的文件?

ors*_*iro 6 indicator unity files software-recommendation system-tray

我正在寻找一个托盘图标指示器 - 单击该图标时 - 向我显示我最近使用的文件列表。这将是快速访问这些文件的好方法。

Jac*_*ijm 7

在面板中有您最近使用的文件

使用下面的脚本,您可以在面板中拥有任意数量的最近使用过的项目,例如 6 个项目:

在此处输入图片说明

...或 20 项:

在此处输入图片说明

...取决于您的设置。

这个怎么运作

设置存在两个项目:

  1. 一个图标,命名(准确地) recent.png
  2. 一个脚本

两者都需要在同一个文件夹中。之后,只需运行脚本。

如何设置

可能,您需要安装python3-gi

sudo apt-get install python3-gi
Run Code Online (Sandbox Code Playgroud)

然后:

  1. 将下面的脚本复制到一个空文件中,另存为 recused.py

    sudo apt-get install python3-gi
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在脚本的 head 部分,设置要显示的项目数:

    #!/usr/bin/env python3
    import signal
    import gi
    gi.require_version('Gtk', '3.0')
    gi.require_version('AppIndicator3', '0.1')
    from gi.repository import Gtk, AppIndicator3, GObject
    import time
    from threading import Thread
    import os
    import subprocess
    
    # --- set the number of recently used files to appear below
    n = 20
    # ---
    
    home = os.environ["HOME"]
    recdata = os.path.join(home, ".local/share/recently-used.xbel")
    currpath = os.path.dirname(os.path.realpath(__file__))
    
    class Indicator():
        def __init__(self):
            self.app = 'show_recent'
            iconpath = os.path.join(currpath, "recent.png")
            self.indicator = AppIndicator3.Indicator.new(
                self.app, iconpath,
                AppIndicator3.IndicatorCategory.OTHER)
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
            self.indicator.set_menu(self.create_menu())
            # the thread:
            self.update = Thread(target=self.check_recent)
            # daemonize the thread to make the indicator stopable
            self.update.setDaemon(True)
            self.update.start()
    
        def get_files(self):
            # create the list of recently used files
            used = [l for l in open(recdata) if \
                    all([
                        '<bookmark href="file://' in l,
                        not "/tmp" in l,
                        "." in l,
                         ])]
            relevant = [l.split('="') for l in set(used)]
            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_menu(self):
            # creates the (initial) menu
            self.menu = Gtk.Menu()
            # separator
            menu_sep = Gtk.SeparatorMenuItem()
            self.menu.append(menu_sep)
            # item_quit.show() 
            self.menu.show_all()
            return self.menu
    
        def open_file(self, *args):
            # opens the file with the default application
            index = self.menu.get_children().index(self.menu.get_active())
            selection = self.menu_items2[index]
            subprocess.Popen(["xdg-open", selection])
    
        def set_new(self):
            # update the list, appearing in the menu
            for i in self.menu.get_children():
                self.menu.remove(i)
            for file in self.menu_items2:
                sub = Gtk.MenuItem(file)
                self.menu.append(sub)
                sub.connect('activate', self.open_file)
            # separator
            menu_sep = Gtk.SeparatorMenuItem()
            self.menu.append(menu_sep)
            # quit
            item_quit = Gtk.MenuItem('Quit')
            item_quit.connect('activate', self.stop)
            self.menu.append(item_quit)
            self.menu.show_all()
    
        def check_recent(self):
            self.menu_items1 = []
            while True:
                time.sleep(3)
                self.menu_items2 = self.get_files()
                if self.menu_items2 != self.menu_items1:
                    GObject.idle_add(
                        self.set_new, 
                        priority=GObject.PRIORITY_DEFAULT
                        )
                self.menu_items1 = self.menu_items2
    
        def stop(self, source):
            Gtk.main_quit()
    
    Indicator()
    # this is where we call GObject.threads_init()
    GObject.threads_init()
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    Gtk.main()
    
    Run Code Online (Sandbox Code Playgroud)
  3. 同一个文件夹中,将下面的图标保存为(完全正确)recent.png

    在此处输入图片说明

    (右键单击它-> 另存为)

  4. 通过以下命令测试运行脚本:

    python3 /path/to/recused.py
    
    Run Code Online (Sandbox Code Playgroud)
  5. 如果一切正常,请添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

    /bin/bash -c "sleep 15 && python3 /path/to/recused.py"
    
    Run Code Online (Sandbox Code Playgroud)

笔记

  • 此脚本基于之前的答案,以防您对替代方案感兴趣,无论是特定应用程序的替代方案,还是使用定期更新的.desktop文件。
  • 该脚本在 16.04 上进行了测试,但也适用于早期版本。
  • 由于recently-used.xbel文件中的错误,有时一个文件被提及两次;一次有,一次没有扩展。我通过过滤掉后者解决了这个问题。结果是没有扩展名的文件不会出现在列表中。如果这是一个问题,请告诉我,我们可以尝试在这种情况下找到另一个解决方案。
  • 如果文件不存在(不再存在),则指标只是(显然)不会打开该文件。最有可能的是,我会对脚本进行更多润色,以从recently-used.xbel文件中过滤掉那些过时的条目。

解释

许多应用程序,编辑文件和使用 Gtk 窗口,跟踪文件中打开的文件:~/.local/share/recently-used.xbel. “记录”包括日期和时间、应用程序和打开的文件。

该脚本读取.xbel文件,按日期/时间对项目进行排序,包括指标菜单中的前 n 个(取决于您的设置)文件。菜单按原样每 3 秒更新一次(仅在必要时)。随后,选择项目时,将使用该命令打开文件:

xdg-open <file>
Run Code Online (Sandbox Code Playgroud)

因此,所选文件将使用默认应用程序打开。很有可能确保文件是使用上次打开的实际应用程序打开的。然而,这需要更复杂的解析。我会将其添加为 Launchpad 上计划的 ppa 版本的一个选项。

选项窗口也是如此,可以设置一些选项,例如要显示的文件数量等。

笔记

该指标现在合并与一些其他的东西这一项