Jak stworzyć program uruchamiający Unity, który monitoruje pliki?


11

Chciałbym utworzyć program uruchamiający, który robi to samo co ikona kosza, w którym wyświetlane są różne listy szybkiego wyboru w zależności od tego, czy w koszu znajdują się elementy.

Chciałbym coś takiego: jeśli folder Aistnieje, pokaż A,B,Cna szybkiej liście, jeśli folder Anie istnieje, pokaż D,E,Fna szybkiej liście.


3
Zaglądałem już wcześniej i prawdopodobnie należy to zrobić za pomocą protokołu powiadomień startowych . I ustawiając wartość StartupNotify na true w pliku .desktop. Ale nie jestem tego pewien.
Paul van Schayck

1
Sprawdź: wiki.ubuntu.com/Unity/LauncherAPI Zawiera przykłady dynamicznych list szybkiego dostępu
S Prasanth

Odpowiedzi:


3

Następujące prace:

  1. Utwórz 2 pliki: mylauncher.desktop i mylauncher.py z zawartością podaną poniżej.
  2. Ustaw mylauncher.desktop jako plik wykonywalny.
  3. Dodaj mylauncher.desktop do programu uruchamiającego unity.
  4. W razie potrzeby edytuj nazwy folderów i lokalizacje folderów w mylauncher.py.
  5. Uruchom python mylauncher.pyw tle. Musisz dodać to do jednego ze swoich skryptów startowych.

Źródło: https://wiki.ubuntu.com/Unity/LauncherAPI


Zawartość 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=;

Zawartość 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

EDYCJA: Użyj następującego jako mylauncher.py do celów wymienionych w komentarzach. Modyfikacja dostosowana do twoich potrzeb powinna być prosta i na wypadek, gdyby nie wspomniano o tym w komentarzach.

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

Próbowałem tego, ale to nie działa dla mnie. Szybka lista się nie zmienia. Używam 64-bitowego systemu Ubuntu 12.10.
Rey Leonard Amorato,

Używam 12,04 32-bitowych. Skrypt Pythona powinien zostać uruchomiony PO dodaniu ikony programu uruchamiającego do programu uruchamiającego.
S Prasanth

Wykonaj następujące czynności: 1) Umieść mylauncher.desktop w ~ / .local / share / applications 2) Naciśnij super-klawisz i wyszukaj „My Launcher”. 3) Przeciągnij ikonę programu uruchamiającego, która pojawi się na program uruchamiający Unity. 4) Uruchom skrypt Pythona. To powinno działać.
S Prasanth

@ReyLeonardAmorato Jestem po prostu ciekawy. Zadziałało?
S Prasanth

Cześć. Niestety nie mogłem ostatnio znaleźć czasu na przejście do trybu online, ale Twoja najnowsza metoda działała dla mnie. Jednak to, czego chciałem, różni się nieco od tego, co robi skrypt. Chciałbym monitorować lokalizację folderu (skrypt już to robi), a jeśli folder „A” istnieje, pokaż „odmontuj” na szybkiej liście. W przeciwnym razie pokaż „mount”. Nie mam wiedzy na temat skryptowania w języku Python, więc nie mam pojęcia, jak zmodyfikować podany skrypt. Byłoby wspaniale, gdybyś mógł pomóc w tym ostatnim kawałku.
Rey Leonard Amorato
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.