it-swarm-es.com

¿Cómo puedo agregar una lista rápida dinámica, específica de la aplicación para los archivos usados ​​recientemente al Unity Launcher?

Sería una característica increíble acceder a documentos usados ​​recientemente desde LibreOffice con una lista rápida dinámica en el iniciador. Hay bastante experiencia sobre cómo crear listas personalizadas estáticas listas rápidas .

Pero, ¿hay alguien por ahí que pueda dar una orientación constructiva sobre cómo construir una lista rápida dinámica para documentos usados ​​recientemente en lo?

El wiki de Ubuntu tiene un descripción muy breve sobre cómo crear listas rápidas con python o vala. No tengo experiencia en ninguno de los dos y no encontré scripts de ejemplo completos para listas rápidas dinámicas. Por lo tanto, estoy buscando una forma más fácil de implementarlo o alguien que ya lo haya hecho/visto.

4
joaoal

Agregar una sección dinámica "utilizada recientemente" al iniciador de una aplicación

La integración completa de una aplicación con la mencionada lista dinámica dinámica probablemente deba realizarse desde el interior de la aplicación. Después de todo, la información más directa sobre los archivos usados ​​proviene de la aplicación misma.

Sin embargo, dado que editar el código fuente está fuera del alcance de lo que estamos haciendo, ese no sería el camino a seguir.

¿Entonces qué?

Eso no significa que no podamos lograr exactamente el mismo resultado, tal vez incluso de una manera más flexible y general, desde "afuera". Toda la información que necesitamos está disponible en el archivo actualizado dinámicamente: _~/.local/share/recently-used.xbel_, del cual podemos recuperar el historial completo de los archivos abiertos, la información de fecha y hora correspondiente y la aplicación que se utilizó.

Además, agregar una sección actualizada dinámicamente a un lanzador puede hacerse muy bien como parte de la sección "tradicional" (estática). La clave de la solución es crear un proceso que se encargue de las acciones anteriores sin agregar una carga notable a su sistema.
Como se menciona en el enlace de la pregunta, de todos modos se necesitaría algún proceso de fondo para realizar un seguimiento de los cambios y pasar las instrucciones .

El siguiente script está haciendo exactamente eso.

La solución; un guión de fondo

Los valores en el script a continuación se establecen específicamente para LibreOffice y sus documentos. Sin ninguna edición, se puede usar para agregar una sección recientemente utilizada al lanzador _LibreOffice-Writer_. Mostrará los últimos 10 documentos utilizados, abiertos por cualquiera de los módulos LibreOffice.

Sin embargo, la solución se puede usar para agregar una sección de "uso reciente" a muchas aplicaciones con un archivo _.desktop_ en _/usr/share/applications_. Dado que el archivo _~/.local/share/recently-used.xbel_ está relacionado con Gtk, lo más probable es que las aplicaciones con una ventana Gtk sean nuestros candidatos potenciales (es decir, si la aplicación abre y edita archivos). Además, el número de archivos para mostrar es arbitrario.

Cómo se ve

La solución agrega una sección al iniciador de destino en el iniciador de Unity, que muestra un número arbitrario de archivos usados ​​recientemente, por ejemplo:

  • muestra los últimos siete archivos:

    enter image description here

  • o los últimos diez archivos:

    enter image description here

  • Sin embargo, con la misma facilidad, podemos darle al lanzador gedit una sección dinámica, que muestra los últimos siete archivos, abiertos con gedit (ver imagen más abajo)

Cómo utilizar

Suponiendo que tiene LibreOffice preinstalado (la versión descargada no tiene un archivo _.desktop_ de referencia en _/usr/share/applications_ que necesita el script, pero en otro lugar, mencione si necesita configurar la versión LO descargada por separado)

  1. Copie el script a continuación en un archivo vacío, guárdelo como _dynamic_recent.py_ Para LibreOffice, el nombre del proceso es soffice, ya configurado correctamente en el script.

    _#!/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. En la sección principal del script, puede establecer una serie de opciones:

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

    La mayoría de las opciones hablan por sí solas, si desea agregar la sección dinámica al lanzador _LO-Writer_, deje todo como está. De lo contrario, configure el iniciador apropiado.

  3. Prueba: ejecute el script ejecutándose desde una terminal:

    _python3 /path/to/dynamic_recent.py
    _
  4. El script copió el archivo global _.desktop_ a _~/.local/share/applications_ (en este caso _~/.local/share/applications/libreoffice-writer.desktop_). Arrastre la copia local al iniciador (de lo contrario, deberá cerrar sesión/iniciar sesión).

  5. Si todo funciona bien, agréguelo a Aplicaciones de inicio: Tablero> Aplicaciones de inicio> Agregar. Agrega el comando:

    _python3 /path/to/dynamic_recent.py
    _

Para usarlo en otras aplicaciones

Como se mencionó, puede usar fácilmente el script para agregar una sección dinámica "utilizada recientemente" a los iniciadores de otras aplicaciones. Para hacerlo, vea la configuración de ejemplo gedit para la sección de encabezado del script:

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

Cómo funciona

  • El script revisa periódicamente el archivo _~/.local/share/recently-used.xbel_ para encontrar archivos coincidentes, abiertos con LibreOffice (nombre de proceso: soffice)

    Utiliza un algoritmo bastante rápido para hacerlo, "disparando" a través del archivo en una sola pasada, para recuperar las líneas necesarias (dos por "registro"). El resultado es que el script tiene muy poco jugo.

  • Una vez que las líneas relevantes se recuperan del archivo, las líneas se ordenan por fecha/hora, creando un "top ten" (o cualquier otro número) de los archivos usados ​​más recientemente de la aplicación correspondiente.

  • SOLO si se cambia esta lista, el archivo _.desktop_ se actualiza.

Pude notar ni medir ninguna carga adicional en mi sistema, ejecutando el script en segundo plano.

Probado el 14.04/15.10

Cómo restaurar el lanzador original

Simplemente elimine la copia local del iniciador en _~/.local/share/applications_

Notas

  • En caso de que use nity Quicklist Editor para editar sus lanzadores (listas rápidas), debe evitar editar los lanzadores con una sección actualizada dinámicamente del "último uso" de esta respuesta. Las ediciones que realice con el Editor de lista rápida se sobrescribirán instantáneamente con el script.

  • Puede editar su lista rápida manualmente, pero asegúrese de agregar un nuevo elemento antes (en el lado izquierdo de) _divider1_ en la línea _Actions=_ -

    _Actions=Window;Document;_ divisor1 _;aap.sh;Todo;pscript_2.py;currdate;bulkmail_llJacob;verhaal;test doc;_

    Todos los elementos a la derecha de _divider1_ pertenecen a la sección actualizada dinámicamente.


Edición mayor

Se hicieron algunas mejoras importantes:

  1. El script ahora solo verifica el archivo _.xbel_ mientras se ejecuta la aplicación de destino (ya que no habrá cambios en la lista utilizada recientemente si la aplicación no se ejecuta). El script ya tenía poco contenido, pero ahora, solo vigilar si se ejecuta la aplicación, significa aún menos para su sistema.
  2. En 15.04+, resulta que el archivo _.xbel_ tenía dobles menciones de nuevos archivos; uno con y otro sin extensión. El efecto de eso ahora se elimina.

4
Jacob Vlijm