AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 747420
Accepted
joaoal
joaoal
Asked: 2016-03-19 02:23:18 +0800 CST2016-03-19 02:23:18 +0800 CST 2016-03-19 02:23:18 +0800 CST

如何将最近使用的文件的动态、特定于应用程序的快速列表添加到 Unity Launcher?

  • 772

使用启动器中的动态快速列表从 LibreOffice 访问最近使用的文档将是一个很棒的功能。关于如何创建自定义静态快速列表有相当多的经验。

但是,有没有人可以就如何为lo 中最近使用的文档构建动态快速列表提供一些建设性的指导?

Ubuntu wiki对如何使用 python 或 vala 创建快速列表有一个非常简短的描述。我对这两种方法都没有经验,也没有找到用于动态快速列表的综合示例脚本。因此,我正在寻找一些更简单的方法来实现它或已经完成/看过它的人。

unity
  • 1 1 个回答
  • 899 Views

1 个回答

  • Voted
  1. Best Answer
    Jacob Vlijm
    2016-03-20T04:22:36+08:002016-03-20T04:22:36+08:00

    将动态“最近使用”部分添加到应用程序的启动器

    应用程序与上述动态快速列表条目的完全集成很可能需要从应用程序内部完成。毕竟,关于已用文件的最直接信息来自应用程序本身。

    但是,由于编辑源代码超出了我们的工作范围,所以这不是我们要走的路。

    然后呢?

    这并不意味着我们不能从“外部”获得几乎完全相同的结果,甚至可能以更灵活和通用的方式。我们需要的所有信息都在动态更新的文件中:~/.local/share/recently-used.xbel,我们可以从中检索打开文件的完整历史记录、相应的日期和时间信息以及使用的应用程序。

    此外,将动态更新的部分添加到启动器中可以很好地作为“传统”(静态)部分的一部分来完成。解决方案的关键是创建一个处理上述操作的进程,而不会给您的系统增加明显的负担。
    如问题链接中所述,无论如何都需要一些后台进程来跟踪更改并传递说明。

    下面的脚本几乎就是这样做的。

    解决方案; 后台脚本

    下面脚本中的值是专门为LibreOffice它的文档设置的。无需任何编辑,它可用于将最近使用的 - 部分添加到LibreOffice-Writer启动器。它将显示由任何LibreOffice-modules 打开的最后 10 个使用的文档。

    但是,该解决方案可用于将“最近使用”部分添加到许多应用程序中,其中.desktop包含/usr/share/applications. 由于文件~/.local/share/recently-used.xbel是Gtk相关的,因此带有Gtk窗口的应用程序很可能是我们的潜在候选者(即,如果应用程序打开并编辑文件)。此外,要显示的文件数量是任意的。

    它看起来如何

    该解决方案在 Unity 启动器的目标启动器中添加一个部分,显示任意数量的最近使用的文件,例如:

    • 显示最后七个文件:

      在此处输入图像描述

    • 或最后十个文件:

      在此处输入图像描述

    • 然而,同样容易,我们可以给gedit启动器一个动态部分,显示最后七个文件,打开gedit(见下图)

    如何使用

    假设您预装了 LibreOffice(下载的版本没有脚本需要的引用.desktop文件/usr/share/applications,但在其他地方,如果您需要设置单独下载的 LO 版本,请提及)

    1. 将下面的脚本复制到一个空文件中,另存为dynamic_recent.py For 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. 在脚本的 head 部分,您可以设置许多选项:

      # --- 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. 如果一切正常,请将其添加到启动应用程序:Dash > Startup Applications > Add。添加命令:

      python3 /path/to/dynamic_recent.py
      

    在其他应用程序上使用它

    如前所述,您可以轻松地使用脚本将动态“最近使用”部分添加到其他应用程序的启动器。为此,请参阅gedit脚本 head 部分的示例设置:

    # --- 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"
    

    在此处输入图像描述

    这个怎么运作

    • 该脚本定期查看文件~/.local/share/recently-used.xbel以查找匹配的文件,使用LibreOffice(processname: soffice)打开

      它使用一种非常快速的算法来执行此操作,一次通过文件“拍摄”,以检索所需的行(每个“记录”两个)。结果是脚本的果汁非常低。

    • 一旦从文件中检索到相关行,这些行就会按日期/时间排序,从而创建相应应用程序最近使用的文件的“前十名”(或任何其他数量)。

    • 仅当此列表更改时,.desktop文件才会更新。

    在后台运行脚本时,我无法注意到或测量系统的任何额外负载。

    在 14.04 / 15.10 测试

    如何恢复原始启动器

    只需删除启动器的本地副本~/.local/share/applications

    笔记

    • 如果您使用Unity Quicklist Editor编辑启动器(快速列表),则应避免使用此答案中动态更新的“上次使用”部分编辑启动器。您使用快速列表编辑器所做的编辑将立即被脚本覆盖。

    • 您可以手动编辑您的快速列表,但请确保在- 行之前(左侧)添加新项目divider1Actions=

      Actions=Window;Document;分频器1;aap.sh;Todo;pscript_2.py;currdate;bulkmail_llJacob;verhaal;test doc;

      右侧的所有项目都divider1属于动态更新的部分。


    主要编辑

    刚刚进行了一些重大改进:

    1. 该脚本现在仅在目标应用程序运行时检查.xbel文件(因为如果应用程序未运行,则最近使用的列表不会发生更改)。该脚本的果汁已经很低,但现在,只关注应用程序是否运行,对您的系统意味着更少。
    2. 在 15.04+ 中,该.xbel文件两次提到了新文件;一个有扩展名,一个没有扩展名。现在已经消除了这种影响。

    • 3

相关问题

  • 如何将 Web 应用程序放入 Unity Launcher?

  • Ubuntu 上网本 10.10 中没有 Alt+F2?

  • Unity 中的 gnome-do 样式键盘快捷键

  • 在哪里提交 Unity 的错误/愿望清单?

  • Unity 启动器——它可以作为单独的包提供吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve