Como posso definir uma tecla de atalho para abrir o arquivo selecionado no nautilus?

3

Cansado de clicar com o botão direito em Abrir com para abrir um arquivo em um aplicativo específico, eu gostaria de definir um atalho para abrir um arquivo, por exemplo, Gimp. Eu não quero mudar a ação de abertura padrão embora. (Ubuntu 14.04)

O que eu tentei:

Eu configurei um atalho de teclado para executar o script abaixo para abrir o arquivo selecionado do Nautilus, no aplicativo especificado (gimp).

!/bin/sh
for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS 
do
/usr/bin/gimp "$file"
done

e ...

!/bin/sh
/usr/bin/gimp "$1"

No entanto, ele nunca pega o arquivo selecionado na janela do nautilus corretamente.

Existe uma maneira de fazer isso?

    
por Seek Truth 23.02.2017 / 21:12

2 respostas

4

NOTA : nesta resposta existem duas soluções, cada uma com seus próprios benefícios. Os usuários são encorajados a descobrir qual deles funciona melhor para seu caso específico.

Introdução

O Nautilus por si só não oferece uma maneira de definir atalhos de teclado personalizados e suas ações. Esta é a principal razão pela qual os scripts que você tentou falharam. $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS só pode ser usado via submenu de clique direito. Mas podemos explorar outra coisa para alcançar o resultado desejado - atalhos definidos nas configurações e na área de transferência do sistema.

O Nautilus é construído em algo conhecido como kit de ferramentas Gtk. É uma extensa biblioteca para criação de aplicativos gráficos e, entre outras coisas, possui utilitários para fazer interface com a área de transferência do sistema. O Nautilus, sendo um gerenciador de arquivos, é especial no fato de gerar uma lista de URIs (na forma file:///home/user/Pictures/encoded%image%name.png ) para a área de transferência (o que não é um fato bem conhecido para a maioria dos usuários, e eu aprendi bem recentemente . Aparentemente, é assim que os gerenciadores de arquivos da GUI copiam arquivos.

Podemos explorar esse fato copiando o URI do arquivo (ou, para ser exato, a lista de URIs; mesmo se houver apenas um, o padrão é uma lista). Então podemos passar essa lista para gimp . As duas soluções apresentadas abaixo operam exatamente nessa ideia.

Raciocínio para 2 soluções:

Eu pessoalmente considero a solução # 1 como a preferida. Ele depende de pressionar primeiro o atalho de cópia e, em seguida, o atalho do script - que são dois atalhos de teclado -, mas tem vantagem em ter menos dependências. É uma abordagem mais manual, mas bastante decente. Ele usa os.execlp call, que substituirá o processo do script pelo Gimp, agindo como meramente um trampolim para Gimp . É uma prática frequente em scripts e programação de sistema usar exec family of functions

A segunda solução foi escrita porque Jacob Vlijm mencionou nos comentários que para ele a função execlp não funcionava, por qualquer motivo. Acho isso muito estranho porque o execlp pertence ao módulo padrão os para python, que é um dos módulos instalados padrão. Além disso, subprocess.Popen() padroniza para exec() família de funções; da documentação de subprocess :

On POSIX, with shell=False (default): In this case, the Popen class uses os.execvp() to execute the child program. args should normally be a sequence. A string will be treated as a sequence with the string as the only item (the program to execute).

(Nota "No POSIX" significa "SO compatível com POSIX"; o Ubuntu é compatível com POSIX)

Assim, não parece um problema com uma função em si, mas com o sistema do usuário. No entanto, eu escrevi segundo roteiro. Esse usa o módulo subprocess e depende de xdotool , que basicamente automatiza pressionando o atalho Ctrl + C para você e, em seguida, inicia o Gimp. Eu pessoalmente não gosto muito deste, já que ele requer um item adicional para ser instalado, mas tem a vantagem de precisar apenas de um atalho de teclado.

A ideia, no entanto, é a mesma. Ainda usamos ferramentas Gtk para consultar o conteúdo da área de transferência e, em cada caso, os scripts devem estar vinculados a um atalho.

Solução # 1, dois atalhos, dependências mínimas

Uso: selecione o arquivo e pressione Ctrl + C para copiar primeiro o arquivo, depois pressione o atalho que você atribuiu a este script. A função execlp substituirá o processo do script por gimp .

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from os import execlp
from time import sleep
from urllib.parse import unquote
import signal
import threading
import subprocess

uris = None

def autoquit():
    global uris
    #sleep(0.5)
    while not uris:
       # allow sufficient time to obtain uris
       sleep(2)
       pass
    Gtk.main_quit()

def get_clipboard_contents():
    global uris
    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    tr = threading.Thread(target=autoquit)
    tr.daemon = True
    tr.start()
    uris = clip.wait_for_uris()
    Gtk.main()
    return [unquote(i).replace('file://','')
           for i in uris]
def main():
    signal.signal(signal.SIGINT,signal.SIG_DFL)
    files = get_clipboard_contents()
    print(files)
    args = ['gimp'] + files
    execlp('gimp',*args)

if __name__ == '__main__': main()

Solução # 2: atalho único, dependência xdotool

O uso deste script é mais simples: selecione o (s) arquivo (s) no Nautilus e pressione o atalho de teclado. OBSERVAÇÃO : você deve ter xdotool instalado para que isso funcione, use sudo apt-get install xdotool .

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from subprocess import Popen,STDOUT
from time import sleep
from urllib.parse import unquote
import sys

def unquote_uri(*args):
    uris = args[-2]
    unquoted_args = [ str(unquote(i).replace('file://',''))
                      for i in uris]
    with open('/dev/null','w') as dev_null:
        proc = Popen(['gimp',*unquoted_args],stdout=dev_null,stderr=STDOUT)
    Gtk.main_quit()


def main():
    # NOTE: xdotool is REQUIRED for this to work
    Popen(['xdotool','key','Ctrl+c'])
    sleep(0.5)
    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    clip.request_uris(unquote_uri, None)
    Gtk.main()

if __name__ == '__main__': main()

Configurando o atalho

Em ambos os casos, você precisa ter um script vinculado a um atalho. Abrir configurações do sistema - > Teclado - > Atalhos - > Personalizadas. Clique no botão + . Dê caminho completo (!) Para arquivar como comando. Por exemplo, /home/User_Name/bin/clipboard_launch.py

Atribua o atalho para ser algo sensato. Por exemplo, como estamos chamando o Gimp, eu atribuí meu script a Ctrl + Super + G .

    
por Sergiy Kolodyazhnyy 23.02.2017 / 21:37
2

Abrindo o arquivo selecionado em um aplicativo específico a partir de um atalho

Inspirado no conceito de @Serg (+1), uma abordagem diferente sobre como implementá-lo:

O script

#!/usr/bin/env python3
import subprocess
import pyperclip

subprocess.call(["xdotool", "key", "Control_L+c"])
subprocess.Popen(["gimp", pyperclip.paste()])

Como usar

  1. O script precisa de pyperclip e xdotool (para xdotool- less usage, consulte as notas):

    • para 16.04 +:

      sudo apt-get install python3-pyperclip xdotool
      
    • para 14.04:

      sudo apt-get install python3-pip xdotool
      sudo pip3 install pyperclip
      
  2. Copie o script em um arquivo vazio, salve-o como open_ingimp.py

  3. Adicione a uma tecla de atalho: Escolha: Configurações do sistema > "Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:

    python3 /path/to/open_ingimp.py
    

É isso. Agora selecione um documento válido e pressione a tecla de atalho. O arquivo será aberto em Gimp .

Explicação

  • Ao pressionar Ctrl + C , enquanto um arquivo é selecionado, o caminho para o arquivo é copiado para a área de transferência. Estamos simulando isso com:

    subprocess.call(["xdotool", "key", "Control_L+c"])
    
  • Acontece que o módulo python pyperclip simplesmente produz o caminho, retirado de file:// ao usar pyperclip.paste() (isso não será literalmente colado, mas disponibilizará o caminho dentro do script).
  • Então, tudo o que precisamos para fazer o script é executar o comando para abrir o arquivo com gimp .

    subprocess.Popen(["gimp", pyperclip.paste()])
    

Notas

  • Se pressionar Ctrl + C antes de pressionar o atalho para abrir o arquivo no Gimp for aceitável, poderíamos até encurtar o script para quase um one-liner:

    #!/usr/bin/env python3
    import subprocess
    import pyperclip
    
    subprocess.Popen(["gimp", pyperclip.paste()])
    

    Isso tornaria desnecessária a instalação de xdotool .

  • Poderíamos vestir / refinar o script um pouco para funcionar apenas com extensões definidas ou fazer com que o aplicativo seja submetido a um argumento. Apenas mencione.

  • Poderíamos até definir várias opções: abrir o tipo de arquivo A com o aplicativo 1, o tipo de arquivo B com o aplicativo2, sem mexer nos aplicativos padrão para abrir o arquivo ou mexer nas opções de clique com o botão direito.

por Jacob Vlijm 25.02.2017 / 08:10