Como criar um lançador de unidade que monitora arquivos?

11

Gostaria de criar um iniciador que faça o mesmo que o ícone da lixeira, onde diferentes listas rápidas são exibidas, dependendo da existência ou não de itens na lixeira.

Gostaria de algo como: se a pasta Aexiste, é exibida A,B,Cna lista rápida, se a pasta Anão existe, é exibida D,E,Fna lista rápida.

Rey Leonard Amorato
fonte
3
Eu já examinei isso antes, e provavelmente isso deve ser feito através do protocolo de notificação de inicialização . E definindo StartupNotify como true no arquivo .desktop. Mas não tenho certeza de lá.
Paul van Schayck,
1
Confira: wiki.ubuntu.com/Unity/LauncherAPI Tem exemplos de listas rápidas dinâmicas
Prasanth

Respostas:

3

Os seguintes trabalhos:

  1. Crie 2 arquivos: mylauncher.desktop e mylauncher.py com o conteúdo indicado abaixo.
  2. Torne o mylauncher.desktop um executável.
  3. Adicione mylauncher.desktop ao iniciador do unity.
  4. Edite nomes de pastas e localizações de pastas em mylauncher.py, conforme necessário.
  5. Execute python mylauncher.pyem segundo plano. Você precisará adicionar isso a um dos seus scripts de inicialização.

Fonte: https://wiki.ubuntu.com/Unity/LauncherAPI


Conteúdo do mylauncher.desktop:

[Desktop Entry]
Name=My Launcher
Comment=A,B,C if A else D,E,F
Exec=nautilus %U
Icon=nautilus
Terminal=false
StartupNotify=true
Type=Application
OnlyShowIn=GNOME;Unity;
Actions=;

Conteúdo do mylauncher.py:

updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.
#In Foldernames and Folderlocations, spaces shouldn't be preceded by \.
Foldernames = ["A", "B", "C", "D", "E", "F"]
Folderlocations = ["/home/prasanth/A", "/home/prasanth/B", "/home/prasanth/C", "/home/prasanth/D", "/home/prasanth/E", "/home/prasanth/F"]
#####################################

from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess

def nautilusopen(junk1, junk2, location): #Function that opens `location` in nautilus. Equivalent to `nautilus location` in bash.
    subprocess.Popen(['nautilus', "%s" % location])

launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`

#Code block A: This code block builds 6 quicklist entries, 3 for when A is found and 3 for when it isn't
QLentries = [Dbusmenu.Menuitem.new() for i in Foldernames]
for i in xrange(6):
    QLentries[i].property_set(Dbusmenu.MENUITEM_PROP_LABEL, "Goto %s" % Foldernames[i])
    QLentries[i].connect("item-activated", nautilusopen, Folderlocations[i])
    QLentries[i].property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
################

#Code block B: This code block creates 2 quicklists 1 for when A is found and 1 for when it isn't. Then it adds the first 3 quicklist entries to QLifA and the next 3 to QLifnotA
QLifA = Dbusmenu.Menuitem.new() #Quicklist if A is found
QLifnotA = Dbusmenu.Menuitem.new() #Quicklist if A is not found.
for i in xrange(3):
    QLifA.child_append(QLentries[i])
for i in xrange(3, 6):
    QLifnotA.child_append(QLentries[i])
################

#The rest of the code simply monitors the file system for A's existence and switches appropriately between QLifA and QLifnotA
prevState = None
def updateql():
    global prevState
    currentState = 'A' if os.path.exists(Folderlocations[0]) else 'notA' #currentState is 'A' if Folderlocations[0] (which is /home/prasanth/A) exists, 'notA' otherwise
    if currentState != prevState:
        if currentState == 'A':
            launcher.set_property("quicklist", QLifA)
        else:
            launcher.set_property("quicklist", QLifnotA)
        prevState = currentState
    return True

#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()

#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
    raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)

mainloop = GObject.MainLoop()

while True:
    try:
        updateql()
        signal.alarm(updateinterval)
        mainloop.run()
    except KeyboardInterrupt:
        continue

EDIT: Use o seguinte como mylauncher.py para a finalidade mencionada nos comentários. Modificar para atender às suas necessidades deve ser direto e, caso não seja mencionado nos comentários.

from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess

updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.

#Quicklist entries if already mounted:
ifMountedEntry1text = """Unmount A""" #Text shown in the quicklist menu for this entry.
ifMountedEntry1command = """unmount A""" #Bash command to execute when entry 1 is clicked. Doubt if `unmount A` will work. Modify appropriately.

ifMountedEntry2text = """Open A""" #Maybe you'll want to open A directly from the launcher. Included just so you get a hang of how this works.
ifMountedEntry2command = """nautilus A"""
#Extend as required.

#Quicklist entries if not already mounted:
ifnotMountedEntry1text = """Mount A"""
ifnotMountedEntry1command = """mount A""" #Again modify `mount A` appropriately.
#Extend as required.

#My old file monitoring should work. But in case you want to change the criteria for modifying quicklists, it is better to do the following:
filemonitoringcommand = """if [ -d /folder/to/monitor/ ]; then echo True; else echo False; fi;""" #<Bash command>/<location to script> which prints 'True' if A is mounted, 'False' otherwise.
#####################

def systemcall(junk1, junk2, command):
    os.system(command)

launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`

#Quicklist if already mounted:
QLifMounted = Dbusmenu.Menuitem.new()

ifMountedEntry1 = Dbusmenu.Menuitem.new()
ifMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry1text) #Sets the text shown in the quicklist menu for this entry.
ifMountedEntry1.connect("item-activated", systemcall, ifMountedEntry1command) #Sets the corresponding bash command.
ifMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry1) #Adds the first entry to the quicklist

ifMountedEntry2 = Dbusmenu.Menuitem.new()
ifMountedEntry2.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry2text)
ifMountedEntry2.connect("item-activated", systemcall, ifMountedEntry2command)
ifMountedEntry2.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry2)
#Extend as required.

#Quicklist if not already mounted:
QLifnotMounted = Dbusmenu.Menuitem.new()

ifnotMountedEntry1 = Dbusmenu.Menuitem.new()
ifnotMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifnotMountedEntry1text)
ifnotMountedEntry1.connect("item-activated", systemcall, ifnotMountedEntry1command)
ifnotMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifnotMounted.child_append(ifnotMountedEntry1)
#Extend as required.

#The rest of the code uses `filemonitoringcommand` to monitor the filesystem and dynamically modifies (or rather switches between) quicklists.
prevState = None
def updateql():
    global prevState
    currentState = 'True' in os.popen(filemonitoringcommand).read()
    if currentState != prevState:
        if currentState == True:
            launcher.set_property("quicklist", QLifMounted) #If already mounted, sets QLifMounted as the quicklist.
        else:
            launcher.set_property("quicklist", QLifnotMounted) #Otherwise sets QLifnotMounted as the quicklist.
        prevState = currentState
    return True

#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()

#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
    raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)

mainloop = GObject.MainLoop()

while True:
    try:
        updateql()
        signal.alarm(updateinterval)
        mainloop.run()
    except KeyboardInterrupt:
        continue
S Prasanth
fonte
Eu tentei isso, mas não funciona para mim. A lista rápida não muda. Estou usando o ubuntu 12.10 de 64 bits.
Rey Leonard Amorato
Estou usando o 12.04 de 32 bits. O script python deve ser executado APÓS adicionar o ícone do iniciador ao iniciador.
S Prasanth
Faça o seguinte.1) Coloque mylauncher.desktop em ~ / .local / share / applications 2) Pressione a tecla super e procure por 'My Launcher'. 3) Arraste o ícone do iniciador que aparece no iniciador do Unity. 4) Execute o script python. Isso deve funcionar.
S Prasanth
@ReyLeonardAmorato Estou apenas curioso. Funcionou?
S Prasanth
Oi. Desculpe, mas não encontrei tempo para ficar on-line ultimamente, mas seu método mais recente funcionou para mim. No entanto, o que eu queria é um pouco diferente do que o script faz. Gostaria de monitorar o local de uma pasta (o script já faz isso) e, se a pasta 'A' existir, mostrar 'desmontar' na lista rápida. Mostrar 'montar' caso contrário. Não tenho conhecimento de scripts python, portanto, não tenho idéia de como modificar o script que você forneceu. Seria ótimo se você pudesse ajudar com este bit final.
Rey Leonard Amorato 13/03