From ade10e0b8e5571e45cdd4800927c24597e2f7315 Mon Sep 17 00:00:00 2001 From: necoro <> Date: Sun, 12 Aug 2007 04:21:38 +0000 Subject: added listener/notify --- doc/Changelog | 2 + doc/Hooks | 7 - doc/Howto_Write_Plugins | 1 + doc/TODO | 2 + i18n/de_DE.po | 238 ++++++++++---------- i18n/messages.pot | 198 +++++++++-------- plugin.xsd | 2 +- plugins/noroot.xml | 12 -- plugins/notify.xml | 14 ++ plugins/resume_loop.xml | 4 +- portato.desktop | 2 +- portato.py | 35 ++- portato/__init__.py | 3 + portato/constants.py | 7 + portato/gui/gtk/__init__.py | 3 + portato/gui/gtk/windows.py | 111 +++++----- portato/gui/templates/portato.glade | 420 ++++++++++++++++++------------------ portato/helper.py | 17 +- portato/plistener.py | 127 +++++++++++ portato/plugin.py | 3 + portato/plugins/etc_proposals.py | 3 +- portato/plugins/noroot.py | 15 -- portato/plugins/notify.py | 23 ++ 23 files changed, 711 insertions(+), 538 deletions(-) delete mode 100644 plugins/noroot.xml create mode 100644 plugins/notify.xml create mode 100644 portato/plistener.py delete mode 100644 portato/plugins/noroot.py create mode 100644 portato/plugins/notify.py diff --git a/doc/Changelog b/doc/Changelog index 0893e48..fa48774 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,8 @@ next: - new threading model for the emerge process - minor enhancements - added splash screen +- added notifies +- added listener / launch gksu/kdesu by ourselves 0.8.1: - bugfixes diff --git a/doc/Hooks b/doc/Hooks index 43dfe3b..e0469e9 100644 --- a/doc/Hooks +++ b/doc/Hooks @@ -1,13 +1,6 @@ List of hooks currently being supported by Portato ================================================== -am_i_root ---------- -Called: When checking whether the current user is root (ie. uid == 0). -Parameters: None -Return if override: Boolean signaling whether we are root. - - emerge: ------- Called: When emerge or every other command given by e.g. the synccmd preference is being called. diff --git a/doc/Howto_Write_Plugins b/doc/Howto_Write_Plugins index 6c4f97f..9b0e375 100644 --- a/doc/Howto_Write_Plugins +++ b/doc/Howto_Write_Plugins @@ -42,6 +42,7 @@ Sample XML Notes: - If you want to specify a dependency plugin the connect tag has to be like: The other plugin we depend on . +- The "connect"-tag can be omitted. It then defaults to "". - It is possible of course to have more than one "hook" tag. - The options tag is optional. For a complete list of options, see below. diff --git a/doc/TODO b/doc/TODO index c79d0a2..e3821d7 100644 --- a/doc/TODO +++ b/doc/TODO @@ -26,6 +26,8 @@ Main Point: user preferences: - window size / location - colors and font sizes +- rotating systray icon + GTK: ---- - make oneshot better diff --git a/i18n/de_DE.po b/i18n/de_DE.po index f61b737..936b13a 100644 --- a/i18n/de_DE.po +++ b/i18n/de_DE.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Portato\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2007-08-09 20:20-0800\n" +"PO-Revision-Date: 2007-08-11 22:13-0800\n" "Last-Translator: René 'Necoro' Neumann \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -30,18 +30,18 @@ msgid "gtk-quit" msgstr "" #: portato/gui/templates/portato.glade:81 -#: portato/gui/templates/portato.glade:569 +#: portato/gui/templates/portato.glade:514 msgid "_Emerge" msgstr "_Emerge" #: portato/gui/templates/portato.glade:89 #: portato/gui/templates/portato.glade:719 -#: portato/gui/gtk/windows.py:690 +#: portato/gui/gtk/windows.py:691 msgid "E_merge" msgstr "E_merge" #: portato/gui/templates/portato.glade:104 -#: portato/gui/templates/portato.glade:578 +#: portato/gui/templates/portato.glade:523 #: portato/gui/templates/portato.glade:728 msgid "_Unmerge" msgstr "_Unmerge" @@ -112,47 +112,47 @@ msgstr "Zeige _Log" msgid "gtk-find" msgstr "" -#: portato/gui/templates/portato.glade:472 -msgid "Installed, but not in portage anymore" -msgstr "Installiert, aber nicht mehr im Portage-Tree vorhanden" - -#: portato/gui/templates/portato.glade:551 -msgid "MISSING KEYWORD" -msgstr "FEHLENDES KEYWORD" - -#: portato/gui/templates/portato.glade:590 -msgid "Re_vert" -msgstr "_Wiederherstellen" - -#: portato/gui/templates/portato.glade:602 -msgid "E_build" -msgstr "E_build" - -#: portato/gui/templates/portato.glade:628 +#: portato/gui/templates/portato.glade:461 msgid "Installed" msgstr "Installiert" -#: portato/gui/templates/portato.glade:641 -#: portato/gui/gtk/windows.py:667 -#: portato/gui/gtk/windows.py:670 -#: portato/gui/gtk/windows.py:673 -#: portato/gui/gtk/windows.py:778 -#: portato/gui/gtk/windows.py:781 -#: portato/gui/gtk/windows.py:788 -#: portato/gui/gtk/windows.py:792 +#: portato/gui/templates/portato.glade:474 +#: portato/gui/gtk/windows.py:668 +#: portato/gui/gtk/windows.py:671 +#: portato/gui/gtk/windows.py:674 +#: portato/gui/gtk/windows.py:773 +#: portato/gui/gtk/windows.py:776 +#: portato/gui/gtk/windows.py:783 +#: portato/gui/gtk/windows.py:787 msgid "Masked" msgstr "Masked" -#: portato/gui/templates/portato.glade:655 -#: portato/gui/gtk/windows.py:680 -#: portato/gui/gtk/windows.py:683 +#: portato/gui/templates/portato.glade:488 +#: portato/gui/gtk/windows.py:681 +#: portato/gui/gtk/windows.py:684 +#: portato/gui/gtk/windows.py:745 #: portato/gui/gtk/windows.py:750 -#: portato/gui/gtk/windows.py:755 msgid "Testing" msgstr "Testing" +#: portato/gui/templates/portato.glade:535 +msgid "Re_vert" +msgstr "_Wiederherstellen" + +#: portato/gui/templates/portato.glade:547 +msgid "E_build" +msgstr "E_build" + +#: portato/gui/templates/portato.glade:568 +msgid "MISSING KEYWORD" +msgstr "FEHLENDES KEYWORD" + +#: portato/gui/templates/portato.glade:647 +msgid "Installed, but not in portage anymore" +msgstr "Installiert, aber nicht mehr im Portage-Tree vorhanden" + #: portato/gui/templates/portato.glade:682 -#: portato/gui/gtk/windows.py:127 +#: portato/gui/gtk/windows.py:128 msgid "Package" msgstr "Paket" @@ -161,12 +161,12 @@ msgid "_Remove" msgstr "_Löschen" #: portato/gui/templates/portato.glade:777 -#: portato/gui/gtk/windows.py:1003 +#: portato/gui/gtk/windows.py:998 msgid "Queue" msgstr "Queue" #: portato/gui/templates/portato.glade:805 -#: portato/gui/gtk/windows.py:1100 +#: portato/gui/gtk/windows.py:1095 msgid "Console" msgstr "Konsole" @@ -220,31 +220,19 @@ msgstr "Sync-Befehl: " msgid "Sync Options" msgstr "Sync Optionen" -#: portato/gui/templates/portato.glade:1164 -msgid "File name to use, if package.use is a directory: " -msgstr "Zu benutzender Dateiname, wenn package.use ein Verzeichnis ist:" - -#: portato/gui/templates/portato.glade:1175 -msgid "Add only exact version to package.use" -msgstr "Füge nur die exakte Paketversion zu package.keywords hinzu" - -#: portato/gui/templates/portato.glade:1188 -msgid "Add only exact version to package.keywords" -msgstr "Füge nur die exakte Paketversion zu package.keywords hinzu" - -#: portato/gui/templates/portato.glade:1202 -msgid "File name to use, if package.keywords is a directory: " -msgstr "Zu benutzender Dateiname, wenn package.keywords ein Verzeichnis ist:" +#: portato/gui/templates/portato.glade:1154 +msgid "Masking Keywords" +msgstr "Masking Keywords" -#: portato/gui/templates/portato.glade:1236 -msgid "File name to use, if package.mask/package.unmask is a directory: " -msgstr "Zu benutzender Dateiname, wenn package.mask/package.unmask ein Verzeichnis ist:" +#: portato/gui/templates/portato.glade:1169 +msgid "Testing Keywords" +msgstr "Testing Keywords" -#: portato/gui/templates/portato.glade:1247 -msgid "Add only exact version to package.mask/package.unmask" -msgstr "Füge nur die exakte Paketversion zu package.mask/package.unmask hinzu" +#: portato/gui/templates/portato.glade:1184 +msgid "Use-Flags" +msgstr "Use-Flags" -#: portato/gui/templates/portato.glade:1269 +#: portato/gui/templates/portato.glade:1206 msgid "" "You may use the following placeholders:\n" "\n" @@ -258,17 +246,29 @@ msgstr "" "$(pkg): Paketname\n" "$(cat-1)/$(cat-2): erster/zweiter Teil der Kategorie" -#: portato/gui/templates/portato.glade:1295 -msgid "Use-Flags" -msgstr "Use-Flags" +#: portato/gui/templates/portato.glade:1230 +msgid "Add only exact version to package.mask/package.unmask" +msgstr "Füge nur die exakte Paketversion zu package.mask/package.unmask hinzu" -#: portato/gui/templates/portato.glade:1310 -msgid "Testing Keywords" -msgstr "Testing Keywords" +#: portato/gui/templates/portato.glade:1244 +msgid "File name to use, if package.mask/package.unmask is a directory: " +msgstr "Zu benutzender Dateiname, wenn package.mask/package.unmask ein Verzeichnis ist:" -#: portato/gui/templates/portato.glade:1325 -msgid "Masking Keywords" -msgstr "Masking Keywords" +#: portato/gui/templates/portato.glade:1278 +msgid "File name to use, if package.keywords is a directory: " +msgstr "Zu benutzender Dateiname, wenn package.keywords ein Verzeichnis ist:" + +#: portato/gui/templates/portato.glade:1289 +msgid "Add only exact version to package.keywords" +msgstr "Füge nur die exakte Paketversion zu package.keywords hinzu" + +#: portato/gui/templates/portato.glade:1302 +msgid "Add only exact version to package.use" +msgstr "Füge nur die exakte Paketversion zu package.keywords hinzu" + +#: portato/gui/templates/portato.glade:1316 +msgid "File name to use, if package.use is a directory: " +msgstr "Zu benutzender Dateiname, wenn package.use ein Verzeichnis ist:" #: portato/gui/templates/portato.glade:1342 msgid "Use Flag and Keyword Options" @@ -355,100 +355,104 @@ msgstr "Logs" msgid "Resume-loop called while process is still running!" msgstr "\"Resume-Loop\" aufgerufen, während Emerge noch lief. Bug!" -#: portato/plugins/etc_proposals.py:64 -#: portato/plugins/etc_proposals.py:76 +#: portato/plugins/etc_proposals.py:65 +#: portato/plugins/etc_proposals.py:77 msgid "Cannot start etc-proposals. No graphical frontend installed!" msgstr "Kann etc-proposals nicht starten. Kein grafisches Frontend installiert." -#: portato/plugins/etc_proposals.py:78 +#: portato/plugins/etc_proposals.py:79 msgid "Cannot start etc-proposals. Not root!" msgstr "Kann etc-proposals nicht starten. Nur root kann das!" -#: portato/gui/gtk/windows.py:72 +#: portato/plugins/notify.py:11 +msgid "Notify called while process is still running!" +msgstr "\"Notify\" aufgerufen, während Emerge noch lief." + +#: portato/gui/gtk/windows.py:73 msgid "Plugin" msgstr "Plugin" -#: portato/gui/gtk/windows.py:75 +#: portato/gui/gtk/windows.py:76 msgid "Authors" msgstr "Entwickler" -#: portato/gui/gtk/windows.py:80 -#: portato/gui/gtk/windows.py:126 -#: portato/gui/gtk/windows.py:541 +#: portato/gui/gtk/windows.py:81 +#: portato/gui/gtk/windows.py:127 +#: portato/gui/gtk/windows.py:542 msgid "Enabled" msgstr "Aktiviert" -#: portato/gui/gtk/windows.py:225 +#: portato/gui/gtk/windows.py:226 msgid "Results" msgstr "Ergebnisse" -#: portato/gui/gtk/windows.py:494 +#: portato/gui/gtk/windows.py:495 msgid "" msgstr "" -#: portato/gui/gtk/windows.py:523 +#: portato/gui/gtk/windows.py:524 msgid "This is an expanded use flag and cannot be selected" msgstr "Dies ist ein \"Expanded Use Flag\" und kann daher nicht ausgewählt werden." -#: portato/gui/gtk/windows.py:542 +#: portato/gui/gtk/windows.py:543 msgid "Flag" msgstr "Flag" -#: portato/gui/gtk/windows.py:543 +#: portato/gui/gtk/windows.py:544 msgid "Description" msgstr "Beschreibung" -#: portato/gui/gtk/windows.py:622 +#: portato/gui/gtk/windows.py:623 #, python-format msgid "Package could not be found: %s" msgstr "Paket konnte nicht gefunden werden: %s" -#: portato/gui/gtk/windows.py:693 +#: portato/gui/gtk/windows.py:694 msgid "Re_merge" msgstr "Re_merge" -#: portato/gui/gtk/windows.py:890 +#: portato/gui/gtk/windows.py:885 msgid "Creating Database" msgstr "Erstelle Datenbank" -#: portato/gui/gtk/windows.py:895 +#: portato/gui/gtk/windows.py:890 msgid "Loading Config" msgstr "Lade Konfiguration" -#: portato/gui/gtk/windows.py:906 +#: portato/gui/gtk/windows.py:901 msgid "Loading Plugins" msgstr "Lade Plugins" -#: portato/gui/gtk/windows.py:919 +#: portato/gui/gtk/windows.py:914 msgid "Finishing startup" msgstr "Erledige letzte Handgriffe :)" -#: portato/gui/gtk/windows.py:1006 +#: portato/gui/gtk/windows.py:1001 msgid "Options" msgstr "Optionen" -#: portato/gui/gtk/windows.py:1024 +#: portato/gui/gtk/windows.py:1019 msgid "Categories" msgstr "Kategorien" -#: portato/gui/gtk/windows.py:1039 +#: portato/gui/gtk/windows.py:1034 msgid "Packages" msgstr "Pakete" -#: portato/gui/gtk/windows.py:1102 +#: portato/gui/gtk/windows.py:1097 #, python-format msgid "Console (%(title)s)" msgstr "Konsole (%(title)s)" -#: portato/gui/gtk/windows.py:1154 +#: portato/gui/gtk/windows.py:1149 msgid "use flags" msgstr "Use Flags" -#: portato/gui/gtk/windows.py:1161 +#: portato/gui/gtk/windows.py:1156 msgid "masking keywords" msgstr "Masking Keywords" -#: portato/gui/gtk/__init__.py:20 +#: portato/gui/gtk/__init__.py:21 msgid "Loading Portage" msgstr "Lade Portage" @@ -587,90 +591,98 @@ msgstr "Konflikt beim Masking-Status: %s" msgid "Unrecognized line in configuration: %s" msgstr "Unbekannte Zeile in Konfiguration: %s" -#: portato/plugin.py:287 -#: portato/plugin.py:293 -#: portato/plugin.py:298 +#: portato/plugin.py:290 +#: portato/plugin.py:296 +#: portato/plugin.py:301 #, python-format msgid "%s cannot be imported." msgstr "%s kann nicht importiert werden." -#: portato/plugin.py:325 +#: portato/plugin.py:328 #, python-format msgid "Accessing hook '%(hook)s' of plugin '%(plugin)s' (before)." msgstr "Aufruf des Hooks '%(hook)s' vom Plugin '%(plugin)s'. (before)" -#: portato/plugin.py:329 +#: portato/plugin.py:332 #, python-format msgid "Overriding hook '%(hook)s' with plugin '%(plugin)s'." msgstr "Überschreibe den Hook '%(hook)s' mit Plugin '%(plugin)s'." -#: portato/plugin.py:336 +#: portato/plugin.py:339 #, python-format msgid "Accessing hook '%(hook)s' of plugin '%(plugin)s' (after)." msgstr "Aufruf des Hooks '%(hook)s' vom Plugin '%(plugin)s'. (after)" -#: portato/plugin.py:356 +#: portato/plugin.py:359 #, python-format msgid "Loading plugin '%s' failed. Invalid XML syntax." msgstr "Laden des Plugins '%s\" fehlgeschlagen: XML-Syntax-Fehler." -#: portato/plugin.py:359 +#: portato/plugin.py:362 #, python-format msgid "Loading plugin '%s' failed. Plugin does not comply with schema." msgstr "Laden des Plugins '%s\" fehlgeschlagen. Plugin erfüllt nicht das XML-Schema." -#: portato/plugin.py:388 +#: portato/plugin.py:391 #, python-format msgid "Plugin '%s' loaded." msgstr "Plugin '%s' geladen." -#: portato/plugin.py:391 +#: portato/plugin.py:394 #, python-format msgid "Loading plugin '%(plugin)s' failed: Could not import %(import)s" msgstr "Laden des Plugins '%(plugin)s\" fehlgeschlagen. Import von '%(import)s' nicht möglich." -#: portato/plugin.py:456 +#: portato/plugin.py:459 #, python-format msgid "For hook '%(hook)s' an override is already defined by plugin '%(plugin)s'!" msgstr "Das Plugin '%(plugin)s' definiert bereits einen \"Override\" fürr den Hook '%(hook)s'!" -#: portato.py:38 +#: portato/plistener.py:95 +msgid "Listener has not been started." +msgstr "Listener wurde nicht gestartet." + +#: portato.py:40 msgid "runs pychecker (should only be used by developers)" msgstr "Startet \"pychecker\". (Nur Entwickler sollten dies brauchen)." -#: portato.py:41 +#: portato.py:43 #, python-format msgid "the frontend to use - possible values are: %s [default: %%default]" msgstr "Das zu benutzende Frontend. Möglichkeiten: %s [Default: %%default]" -#: portato.py:44 +#: portato.py:46 msgid "opens the ebuild viewer instead of launching Portato" msgstr "Öffnet den Ebuild Viewer anstatt Portato zu starten" -#: portato.py:47 +#: portato.py:49 msgid "validates the given plugin xml instead of launching Portato" msgstr "Validiert die gegebene Plugin-XML. Startet nicht Portato." -#: portato.py:60 +#: portato.py:52 +msgid "do not start listener" +msgstr "Starte den Listener nicht." + +#: portato.py:65 #, python-format msgid "Unknown frontend '%(frontend)s'. Correct frontends are: %(list)s" msgstr "Unbekanntest Frontend '%(frontend)s'. Erlaubte Frontends sind: %(list)s" -#: portato.py:68 +#: portato.py:73 #, python-format msgid "'%(frontend)s' should be installed, but cannot be imported. This is definitly a bug. (%(error)s)" msgstr "'%(frontend)s' sollte installiert sein, aber das Einbinden schlug fehl. Das ist definitiv ein Bug. (%(error)s)" -#: portato.py:78 +#: portato.py:83 #, python-format msgid "Validation failed. XML syntax error: %s." msgstr "Validierung fehlgeschlagen. XML Syntax Fehler: %s." -#: portato.py:81 +#: portato.py:86 msgid "Validation failed. Does not comply with schema." msgstr "Validierung gegen das Schema fehlgeschlagen." -#: portato.py:84 +#: portato.py:89 msgid "Validation succeeded." msgstr "Validierung erfolgreich." diff --git a/i18n/messages.pot b/i18n/messages.pot index 272221d..b1efe83 100644 --- a/i18n/messages.pot +++ b/i18n/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-08-09 20:17-0700\n" +"POT-Creation-Date: 2007-08-11 22:12-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -34,17 +34,17 @@ msgid "gtk-quit" msgstr "" #: portato/gui/templates/portato.glade:81 -#: portato/gui/templates/portato.glade:569 +#: portato/gui/templates/portato.glade:514 msgid "_Emerge" msgstr "" #: portato/gui/templates/portato.glade:89 -#: portato/gui/templates/portato.glade:719 portato/gui/gtk/windows.py:690 +#: portato/gui/templates/portato.glade:719 portato/gui/gtk/windows.py:691 msgid "E_merge" msgstr "" #: portato/gui/templates/portato.glade:104 -#: portato/gui/templates/portato.glade:578 +#: portato/gui/templates/portato.glade:523 #: portato/gui/templates/portato.glade:728 msgid "_Unmerge" msgstr "" @@ -115,40 +115,40 @@ msgstr "" msgid "gtk-find" msgstr "" -#: portato/gui/templates/portato.glade:472 -msgid "Installed, but not in portage anymore" +#: portato/gui/templates/portato.glade:461 +msgid "Installed" msgstr "" -#: portato/gui/templates/portato.glade:551 -msgid "MISSING KEYWORD" +#: portato/gui/templates/portato.glade:474 portato/gui/gtk/windows.py:668 +#: portato/gui/gtk/windows.py:671 portato/gui/gtk/windows.py:674 +#: portato/gui/gtk/windows.py:773 portato/gui/gtk/windows.py:776 +#: portato/gui/gtk/windows.py:783 portato/gui/gtk/windows.py:787 +msgid "Masked" msgstr "" -#: portato/gui/templates/portato.glade:590 -msgid "Re_vert" +#: portato/gui/templates/portato.glade:488 portato/gui/gtk/windows.py:681 +#: portato/gui/gtk/windows.py:684 portato/gui/gtk/windows.py:745 +#: portato/gui/gtk/windows.py:750 +msgid "Testing" msgstr "" -#: portato/gui/templates/portato.glade:602 -msgid "E_build" +#: portato/gui/templates/portato.glade:535 +msgid "Re_vert" msgstr "" -#: portato/gui/templates/portato.glade:628 -msgid "Installed" +#: portato/gui/templates/portato.glade:547 +msgid "E_build" msgstr "" -#: portato/gui/templates/portato.glade:641 portato/gui/gtk/windows.py:667 -#: portato/gui/gtk/windows.py:670 portato/gui/gtk/windows.py:673 -#: portato/gui/gtk/windows.py:778 portato/gui/gtk/windows.py:781 -#: portato/gui/gtk/windows.py:788 portato/gui/gtk/windows.py:792 -msgid "Masked" +#: portato/gui/templates/portato.glade:568 +msgid "MISSING KEYWORD" msgstr "" -#: portato/gui/templates/portato.glade:655 portato/gui/gtk/windows.py:680 -#: portato/gui/gtk/windows.py:683 portato/gui/gtk/windows.py:750 -#: portato/gui/gtk/windows.py:755 -msgid "Testing" +#: portato/gui/templates/portato.glade:647 +msgid "Installed, but not in portage anymore" msgstr "" -#: portato/gui/templates/portato.glade:682 portato/gui/gtk/windows.py:127 +#: portato/gui/templates/portato.glade:682 portato/gui/gtk/windows.py:128 msgid "Package" msgstr "" @@ -156,11 +156,11 @@ msgstr "" msgid "_Remove" msgstr "" -#: portato/gui/templates/portato.glade:777 portato/gui/gtk/windows.py:1003 +#: portato/gui/templates/portato.glade:777 portato/gui/gtk/windows.py:998 msgid "Queue" msgstr "" -#: portato/gui/templates/portato.glade:805 portato/gui/gtk/windows.py:1100 +#: portato/gui/templates/portato.glade:805 portato/gui/gtk/windows.py:1095 msgid "Console" msgstr "" @@ -214,31 +214,19 @@ msgstr "" msgid "Sync Options" msgstr "" -#: portato/gui/templates/portato.glade:1164 -msgid "File name to use, if package.use is a directory: " -msgstr "" - -#: portato/gui/templates/portato.glade:1175 -msgid "Add only exact version to package.use" -msgstr "" - -#: portato/gui/templates/portato.glade:1188 -msgid "Add only exact version to package.keywords" -msgstr "" - -#: portato/gui/templates/portato.glade:1202 -msgid "File name to use, if package.keywords is a directory: " +#: portato/gui/templates/portato.glade:1154 +msgid "Masking Keywords" msgstr "" -#: portato/gui/templates/portato.glade:1236 -msgid "File name to use, if package.mask/package.unmask is a directory: " +#: portato/gui/templates/portato.glade:1169 +msgid "Testing Keywords" msgstr "" -#: portato/gui/templates/portato.glade:1247 -msgid "Add only exact version to package.mask/package.unmask" +#: portato/gui/templates/portato.glade:1184 +msgid "Use-Flags" msgstr "" -#: portato/gui/templates/portato.glade:1269 +#: portato/gui/templates/portato.glade:1206 msgid "" "You may use the following placeholders:\n" "\n" @@ -247,16 +235,28 @@ msgid "" "$(cat-1)/$(cat-2): first/second part of the category" msgstr "" -#: portato/gui/templates/portato.glade:1295 -msgid "Use-Flags" +#: portato/gui/templates/portato.glade:1230 +msgid "Add only exact version to package.mask/package.unmask" msgstr "" -#: portato/gui/templates/portato.glade:1310 -msgid "Testing Keywords" +#: portato/gui/templates/portato.glade:1244 +msgid "File name to use, if package.mask/package.unmask is a directory: " msgstr "" -#: portato/gui/templates/portato.glade:1325 -msgid "Masking Keywords" +#: portato/gui/templates/portato.glade:1278 +msgid "File name to use, if package.keywords is a directory: " +msgstr "" + +#: portato/gui/templates/portato.glade:1289 +msgid "Add only exact version to package.keywords" +msgstr "" + +#: portato/gui/templates/portato.glade:1302 +msgid "Add only exact version to package.use" +msgstr "" + +#: portato/gui/templates/portato.glade:1316 +msgid "File name to use, if package.use is a directory: " msgstr "" #: portato/gui/templates/portato.glade:1342 @@ -342,98 +342,102 @@ msgstr "" msgid "Resume-loop called while process is still running!" msgstr "" -#: portato/plugins/etc_proposals.py:64 portato/plugins/etc_proposals.py:76 +#: portato/plugins/etc_proposals.py:65 portato/plugins/etc_proposals.py:77 msgid "Cannot start etc-proposals. No graphical frontend installed!" msgstr "" -#: portato/plugins/etc_proposals.py:78 +#: portato/plugins/etc_proposals.py:79 msgid "Cannot start etc-proposals. Not root!" msgstr "" -#: portato/gui/gtk/windows.py:72 +#: portato/plugins/notify.py:11 +msgid "Notify called while process is still running!" +msgstr "" + +#: portato/gui/gtk/windows.py:73 msgid "Plugin" msgstr "" -#: portato/gui/gtk/windows.py:75 +#: portato/gui/gtk/windows.py:76 msgid "Authors" msgstr "" -#: portato/gui/gtk/windows.py:80 portato/gui/gtk/windows.py:126 -#: portato/gui/gtk/windows.py:541 +#: portato/gui/gtk/windows.py:81 portato/gui/gtk/windows.py:127 +#: portato/gui/gtk/windows.py:542 msgid "Enabled" msgstr "" -#: portato/gui/gtk/windows.py:225 +#: portato/gui/gtk/windows.py:226 msgid "Results" msgstr "" -#: portato/gui/gtk/windows.py:494 +#: portato/gui/gtk/windows.py:495 msgid "" msgstr "" -#: portato/gui/gtk/windows.py:523 +#: portato/gui/gtk/windows.py:524 msgid "This is an expanded use flag and cannot be selected" msgstr "" -#: portato/gui/gtk/windows.py:542 +#: portato/gui/gtk/windows.py:543 msgid "Flag" msgstr "" -#: portato/gui/gtk/windows.py:543 +#: portato/gui/gtk/windows.py:544 msgid "Description" msgstr "" -#: portato/gui/gtk/windows.py:622 +#: portato/gui/gtk/windows.py:623 #, python-format msgid "Package could not be found: %s" msgstr "" -#: portato/gui/gtk/windows.py:693 +#: portato/gui/gtk/windows.py:694 msgid "Re_merge" msgstr "" -#: portato/gui/gtk/windows.py:890 +#: portato/gui/gtk/windows.py:885 msgid "Creating Database" msgstr "" -#: portato/gui/gtk/windows.py:895 +#: portato/gui/gtk/windows.py:890 msgid "Loading Config" msgstr "" -#: portato/gui/gtk/windows.py:906 +#: portato/gui/gtk/windows.py:901 msgid "Loading Plugins" msgstr "" -#: portato/gui/gtk/windows.py:919 +#: portato/gui/gtk/windows.py:914 msgid "Finishing startup" msgstr "" -#: portato/gui/gtk/windows.py:1006 +#: portato/gui/gtk/windows.py:1001 msgid "Options" msgstr "" -#: portato/gui/gtk/windows.py:1024 +#: portato/gui/gtk/windows.py:1019 msgid "Categories" msgstr "" -#: portato/gui/gtk/windows.py:1039 +#: portato/gui/gtk/windows.py:1034 msgid "Packages" msgstr "" -#: portato/gui/gtk/windows.py:1102 +#: portato/gui/gtk/windows.py:1097 #, python-format msgid "Console (%(title)s)" msgstr "" -#: portato/gui/gtk/windows.py:1154 +#: portato/gui/gtk/windows.py:1149 msgid "use flags" msgstr "" -#: portato/gui/gtk/windows.py:1161 +#: portato/gui/gtk/windows.py:1156 msgid "masking keywords" msgstr "" -#: portato/gui/gtk/__init__.py:20 +#: portato/gui/gtk/__init__.py:21 msgid "Loading Portage" msgstr "" @@ -571,90 +575,98 @@ msgstr "" msgid "Unrecognized line in configuration: %s" msgstr "" -#: portato/plugin.py:287 portato/plugin.py:293 portato/plugin.py:298 +#: portato/plugin.py:290 portato/plugin.py:296 portato/plugin.py:301 #, python-format msgid "%s cannot be imported." msgstr "" -#: portato/plugin.py:325 +#: portato/plugin.py:328 #, python-format msgid "Accessing hook '%(hook)s' of plugin '%(plugin)s' (before)." msgstr "" -#: portato/plugin.py:329 +#: portato/plugin.py:332 #, python-format msgid "Overriding hook '%(hook)s' with plugin '%(plugin)s'." msgstr "" -#: portato/plugin.py:336 +#: portato/plugin.py:339 #, python-format msgid "Accessing hook '%(hook)s' of plugin '%(plugin)s' (after)." msgstr "" -#: portato/plugin.py:356 +#: portato/plugin.py:359 #, python-format msgid "Loading plugin '%s' failed. Invalid XML syntax." msgstr "" -#: portato/plugin.py:359 +#: portato/plugin.py:362 #, python-format msgid "Loading plugin '%s' failed. Plugin does not comply with schema." msgstr "" -#: portato/plugin.py:388 +#: portato/plugin.py:391 #, python-format msgid "Plugin '%s' loaded." msgstr "" -#: portato/plugin.py:391 +#: portato/plugin.py:394 #, python-format msgid "Loading plugin '%(plugin)s' failed: Could not import %(import)s" msgstr "" -#: portato/plugin.py:456 +#: portato/plugin.py:459 #, python-format msgid "" "For hook '%(hook)s' an override is already defined by plugin '%(plugin)s'!" msgstr "" -#: portato.py:38 +#: portato/plistener.py:95 +msgid "Listener has not been started." +msgstr "" + +#: portato.py:40 msgid "runs pychecker (should only be used by developers)" msgstr "" -#: portato.py:41 +#: portato.py:43 #, python-format msgid "the frontend to use - possible values are: %s [default: %%default]" msgstr "" -#: portato.py:44 +#: portato.py:46 msgid "opens the ebuild viewer instead of launching Portato" msgstr "" -#: portato.py:47 +#: portato.py:49 msgid "validates the given plugin xml instead of launching Portato" msgstr "" -#: portato.py:60 +#: portato.py:52 +msgid "do not start listener" +msgstr "" + +#: portato.py:65 #, python-format msgid "Unknown frontend '%(frontend)s'. Correct frontends are: %(list)s" msgstr "" -#: portato.py:68 +#: portato.py:73 #, python-format msgid "" "'%(frontend)s' should be installed, but cannot be imported. This is " "definitly a bug. (%(error)s)" msgstr "" -#: portato.py:78 +#: portato.py:83 #, python-format msgid "Validation failed. XML syntax error: %s." msgstr "" -#: portato.py:81 +#: portato.py:86 msgid "Validation failed. Does not comply with schema." msgstr "" -#: portato.py:84 +#: portato.py:89 msgid "Validation succeeded." msgstr "" diff --git a/plugin.xsd b/plugin.xsd index 7f9975b..06b22f6 100644 --- a/plugin.xsd +++ b/plugin.xsd @@ -13,7 +13,7 @@ - + diff --git a/plugins/noroot.xml b/plugins/noroot.xml deleted file mode 100644 index 850a039..0000000 --- a/plugins/noroot.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - René 'Necoro' Neumann - No Root - portato.plugins.noroot - - - - - - - diff --git a/plugins/notify.xml b/plugins/notify.xml new file mode 100644 index 0000000..8de08c8 --- /dev/null +++ b/plugins/notify.xml @@ -0,0 +1,14 @@ + + + + René 'Necoro' Neumann + Notify + gtk + + portato.plugins.notify + + + + + + diff --git a/plugins/resume_loop.xml b/plugins/resume_loop.xml index 01dca78..124d61d 100644 --- a/plugins/resume_loop.xml +++ b/plugins/resume_loop.xml @@ -5,9 +5,7 @@ portato.plugins.resume_loop - - - + * diff --git a/portato.desktop b/portato.desktop index e65eaa8..693235e 100644 --- a/portato.desktop +++ b/portato.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=Portato Icon=portato-icon -Exec=gksu -D "Portato (GTK)" -u root portato gtk +Exec=portato StartupNotify=true Type=Application Categories=Application;System;PackageManager diff --git a/portato.py b/portato.py index e318411..f90fd69 100755 --- a/portato.py +++ b/portato.py @@ -12,9 +12,11 @@ # # Written by René 'Necoro' Neumann -from portato.constants import VERSION, FRONTENDS, STD_FRONTEND, XSD_LOCATION, LOCALE_DIR, APP +from portato import listener +from portato.constants import VERSION, FRONTENDS, STD_FRONTEND, XSD_LOCATION, LOCALE_DIR, APP, SU_COMMAND from optparse import OptionParser -import sys, os +from subprocess import call +import sys, os, socket import gettext, locale def get_frontend_list (): @@ -46,6 +48,9 @@ def main (): parser.add_option("-x", "--validate", action = "store", dest = "validate", metavar="PLUGIN", help = _("validates the given plugin xml instead of launching Portato")) + parser.add_option("-L", "--no-listener", action = "store_true", dest = "nolistener", default = False, + help = _("do not start listener")) + # run parser (options, args) = parser.parse_args() @@ -83,8 +88,32 @@ def main (): else: print _("Validation succeeded.") return - else: + elif options.nolistener: + try: + # move this process into a new process group + # this is to be able to kill emerge et al w/o killing ourselves :) + os.setsid() + except OSError: + pass + listener.set_send() run() + else: # start listener and start us again in root modus + if os.fork() == 0: + listener.set_recv() + else: + additional = [] + if options.check: + additional.append("-c") + if options.frontend: + additional.extend(["-f", options.frontend]) + + try: + if os.getuid() == 0: + call([SU_COMMAND, "%s --no-listener %s" % (sys.argv[0], " ".join(additional))], env = os.environ) + else: + call([sys.argv[0], "--no-listener"]+additional, env = os.environ) + except KeyboardInterrupt: + pass if __name__ == "__main__": main() diff --git a/portato/__init__.py b/portato/__init__.py index f10b9ef..57dd691 100644 --- a/portato/__init__.py +++ b/portato/__init__.py @@ -55,3 +55,6 @@ handler.setFormatter(formatter) logging.getLogger("portatoLogger").addHandler(handler) logging.getLogger("portatoLogger").setLevel(logging.DEBUG) logging.getLogger("portatoLogger").propagate = False + +from plistener import PListener +listener = PListener() diff --git a/portato/constants.py b/portato/constants.py index c21b0a5..309b774 100644 --- a/portato/constants.py +++ b/portato/constants.py @@ -38,6 +38,10 @@ These should be set during the installation. @type FRONTENDS: string[] @var STD_FRONTEND: the frontend uses as the default, i.e. if no other one is given on the cmdline @type STD_FRONTEND: string +@var SU_COMMAND: command to execute to "su" +@type SU_COMMAND: string +@var SOCKET: path to socket for communication between listener and GUI +@type SOCKET: string """ from os.path import join as pjoin @@ -60,3 +64,6 @@ LOCALE_DIR = "i18n/" FRONTENDS = ["gtk" ,"qt"] STD_FRONTEND = "gtk" + +SU_COMMAND = "gksu -D 'Portato'" +SOCKET = "/tmp/portato.socket" diff --git a/portato/gui/gtk/__init__.py b/portato/gui/gtk/__init__.py index 0714f39..ba49652 100644 --- a/portato/gui/gtk/__init__.py +++ b/portato/gui/gtk/__init__.py @@ -12,6 +12,7 @@ from gettext import lgettext as _ +from portato import listener from exception_handling import register_ex_handler def run (): @@ -27,6 +28,8 @@ def run (): except KeyboardInterrupt: pass + listener.close() + def show_ebuild (pkg): import gtk from portato import plugin diff --git a/portato/gui/gtk/windows.py b/portato/gui/gtk/windows.py index 74f7058..f0b7f1b 100644 --- a/portato/gui/gtk/windows.py +++ b/portato/gui/gtk/windows.py @@ -20,6 +20,7 @@ from subprocess import Popen from gettext import lgettext as _ # our backend stuff +from portato import listener from portato.helper import * from portato.constants import CONFIG_LOCATION, VERSION, APP_ICON from portato.backend import flags, system @@ -335,7 +336,7 @@ class PreferenceWindow (AbstractDialog): self.cfg.set("consolefont", font, section = "GTK") self.set_console_font(font) - gtk.link_button_set_uri_hook(lambda btn, x: Popen([self.cfg.get("browserCmd", section = "GUI"), btn.get_uri()])) + gtk.link_button_set_uri_hook(lambda btn, x: listener.send_cmd([self.cfg.get("browserCmd", section = "GUI"), btn.get_uri()])) def cb_ok_clicked(self, button): """Saves, writes to config-file and closes the window.""" @@ -717,20 +718,14 @@ class PackageTable: def cb_package_emerge_clicked (self, button): """Callback for pressed emerge-button. Adds the package to the EmergeQueue.""" - if not am_i_root(): - not_root_dialog() - else: - self._update_keywords(True) - self.main.notebook.set_current_page(self.main.QUEUE_PAGE) + self._update_keywords(True) + self.main.notebook.set_current_page(self.main.QUEUE_PAGE) return True def cb_package_unmerge_clicked (self, button): """Callback for pressed unmerge-button clicked. Adds the package to the UnmergeQueue.""" - if not am_i_root(): - not_root_dialog() - else: - self._update_keywords(False) - self.main.notebook.set_current_page(self.main.QUEUE_PAGE) + self._update_keywords(False) + self.main.notebook.set_current_page(self.main.QUEUE_PAGE) return True def cb_package_ebuild_clicked(self, button): @@ -900,7 +895,7 @@ class MainWindow (Window): raise self.cfg.modify_external_configs() - gtk.link_button_set_uri_hook(lambda btn, x: Popen([self.cfg.get("browserCmd", section = "GUI"), btn.get_uri()])) + gtk.link_button_set_uri_hook(lambda btn, x: listener.send_cmd([self.cfg.get("browserCmd", section = "GUI"), btn.get_uri()])) # set plugins and plugin-menu splash(_("Loading Plugins")) @@ -1177,47 +1172,43 @@ class MainWindow (Window): return True def cb_update_clicked (self, action): - if not am_i_root(): - not_root_dialog() - else: + def __update(): - def __update(): - - def cb_idle_append (pkg, unmask): - self.queue.append(pkg.get_cpv(), unmask = unmask) - return False + def cb_idle_append (pkg, unmask): + self.queue.append(pkg.get_cpv(), unmask = unmask) + return False - def cb_idle_unmask_dialog (e, updating): - if unmask_dialog(e[0]) == gtk.RESPONSE_YES: - for pkg, old_pkg in updating: - self.queue.append(pkg.get_cpv(), unmask = True) - return False + def cb_idle_unmask_dialog (e, updating): + if unmask_dialog(e[0]) == gtk.RESPONSE_YES: + for pkg, old_pkg in updating: + self.queue.append(pkg.get_cpv(), unmask = True) + return False - def cb_idle_blocked(e): - blocked_dialog(e[0], e[1]) - self.queue.remove_children(self.queue.emergeIt) - return False + def cb_idle_blocked(e): + blocked_dialog(e[0], e[1]) + self.queue.remove_children(self.queue.emergeIt) + return False - watch = gtk.gdk.Cursor(gtk.gdk.WATCH) - self.window.window.set_cursor(watch) + watch = gtk.gdk.Cursor(gtk.gdk.WATCH) + self.window.window.set_cursor(watch) + try: + updating = system.update_world(newuse = self.cfg.get_boolean("newuse"), deep = self.cfg.get_boolean("deep")) + debug("updating list: %s --> length: %s", [(x.get_cpv(), y.get_cpv()) for x,y in updating], len(updating)) try: - updating = system.update_world(newuse = self.cfg.get_boolean("newuse"), deep = self.cfg.get_boolean("deep")) - debug("updating list: %s --> length: %s", [(x.get_cpv(), y.get_cpv()) for x,y in updating], len(updating)) try: - try: - for pkg, old_pkg in updating: - gobject.idle_add(cb_idle_append, pkg, False) - except PackageNotFoundException, e: - gobject.idle_add(cb_idle_unmask_dialog, e, updating) - - except BlockedException, e: - gobject.idle_add(cb_idle_blocked(e)) - - if len(updating): self.doUpdate = True - finally: - self.window.window.set_cursor(None) + for pkg, old_pkg in updating: + gobject.idle_add(cb_idle_append, pkg, False) + except PackageNotFoundException, e: + gobject.idle_add(cb_idle_unmask_dialog, e, updating) - GtkThread(name="Update-Thread", target=__update).start() + except BlockedException, e: + gobject.idle_add(cb_idle_blocked(e)) + + if len(updating): self.doUpdate = True + finally: + self.window.window.set_cursor(None) + + GtkThread(name="Update-Thread", target=__update).start() return True @@ -1245,26 +1236,20 @@ class MainWindow (Window): return True def cb_sync_clicked (self, action): - if not am_i_root(): - not_root_dialog() - else: - self.notebook.set_current_page(self.CONSOLE_PAGE) - cmd = self.cfg.get("syncCmd") + self.notebook.set_current_page(self.CONSOLE_PAGE) + cmd = self.cfg.get("syncCmd") - if cmd != "emerge --sync": - cmd = cmd.split() - self.queue.sync(cmd) - else: - self.queue.sync() + if cmd != "emerge --sync": + cmd = cmd.split() + self.queue.sync(cmd) + else: + self.queue.sync() def cb_save_flags_clicked (self, action): - if not am_i_root(): - not_root_dialog() - else: - flags.write_use_flags() - flags.write_testing() - flags.write_masked() - + flags.write_use_flags() + flags.write_testing() + flags.write_masked() + @Window.watch_cursor def cb_reload_clicked (self, action): """Reloads the portage settings and the database.""" diff --git a/portato/gui/templates/portato.glade b/portato/gui/templates/portato.glade index fe57c9a..77f8a8f 100644 --- a/portato/gui/templates/portato.glade +++ b/portato/gui/templates/portato.glade @@ -450,107 +450,52 @@ 5 3 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + True - + + True + True + Installed + 0 + True + + + + False + - - - 3 - 1 - 2 - GTK_EXPAND - - - - - - True - True - <b>Installed, but not in portage anymore</b> - True - - - 3 - 2 - 3 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - + True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - False - - - + True + Masked + 0 + True + - False + False + 1 - + True - False - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - - - True - - + True + Testing + 0 + True + - 1 + False + 2 - - 3 - 3 - 4 - 5 - 5 - - - - - True - GTK_JUSTIFY_CENTER - True - - - 3 - GTK_FILL - - 10 - - - - - True - True - <span foreground='red'><b>MISSING KEYWORD</b></span> - True - 3 2 @@ -617,51 +562,90 @@ - + True - 1 - True + True + <span foreground='red'><b>MISSING KEYWORD</b></span> + True + + + 3 + 2 + 3 + GTK_FILL + + + + + True + GTK_JUSTIFY_CENTER + True + + + 3 + GTK_FILL + + 10 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 - + True - True - Installed - 0 - True - + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + False + + + - False + False - + True - True - Masked - 0 - True - + False + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + True + + - False 1 - - - True - True - Testing - 0 - True - - - - False - 2 - - + + + 3 + 3 + 4 + 5 + 5 + + + + + True + True + <b>Installed, but not in portage anymore</b> + True 3 @@ -670,6 +654,22 @@ GTK_FILL + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + 3 + 1 + 2 + GTK_EXPAND + + + False @@ -1147,189 +1147,189 @@ - + True + 0 + 5 + <u><i>Masking Keywords</i></u> + True + True - 1 - 2 - 3 - 4 + 7 + 8 + 5 - + True 0 - File name to use, if package.use is a directory: + 5 + <u><i>Testing Keywords</i></u> + True True - 3 - 4 + 4 + 5 + 5 - + True - Add only exact version to package.use - 0 - True + 0 + 5 + <u><i>Use-Flags</i></u> + True + True + + + 1 + 2 + 6 + + + + + True + + + True + 0 + GTK_SHADOW_OUT + + + True + 0 + <u>You may use the following placeholders:</u> + +<i>$(cat)</i>: category +<i>$(pkg)</i>: package name +<i>$(cat-1)/$(cat-2)</i>: first/second part of the category + True + + + + + + label_item + + +