diff options
author | necoro <> | 2007-08-12 04:21:38 +0000 |
---|---|---|
committer | necoro <> | 2007-08-12 04:21:38 +0000 |
commit | ade10e0b8e5571e45cdd4800927c24597e2f7315 (patch) | |
tree | ff2d39f0366a7238366abd3c77b739996ed8937a /portato/plistener.py | |
parent | a6a5cace4864c37b7a820c89540f85069d842521 (diff) | |
download | portato-ade10e0b8e5571e45cdd4800927c24597e2f7315.tar.gz portato-ade10e0b8e5571e45cdd4800927c24597e2f7315.tar.bz2 portato-ade10e0b8e5571e45cdd4800927c24597e2f7315.zip |
added listener/notify
Diffstat (limited to 'portato/plistener.py')
-rw-r--r-- | portato/plistener.py | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/portato/plistener.py b/portato/plistener.py new file mode 100644 index 0000000..29054b2 --- /dev/null +++ b/portato/plistener.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# +# File: portato/gui/gtk/plistener.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2007 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +import socket, os +from subprocess import Popen +from gettext import lgettext as _ + +try: + import pynotify +except ImportError: + pynotify = None + +from constants import SOCKET, APP +from helper import debug, warning + +class PListener (object): + """This class handles the communication between the "listener" and the GUI. + This listener starts programs as the user while the GUI runs as root. + + @ivar _recv: listener socket + @type _recv: socket.socket + @ivar _send: sender socket + @type _send: socket.socket""" + + def set_recv (self): + self._recv = socket.socket(socket.AF_UNIX) + + try: + self._recv.bind(SOCKET) + except socket.error, e: + if int(e[0]) == 98: # already existing - delete + os.unlink(SOCKET) + self._recv.bind(SOCKET) + else: + raise + + self._recv.listen(1) + con, addr = self._recv.accept() + + while True: + try: + len = con.recv(4) + string = con.recv(int(len)) + + data = string.split("\0") + debug(data) + + if data[0] == "notify": + self.do_notify(*data[1:]) + elif data[0] == "cmd": + self.do_cmd(data[1:]) + elif data[0] == "close": + break + except KeyboardInterrupt: + pass + + con.close() + self._recv.close() + + def do_cmd (self, cmdlist): + """Starts a command as the user. + + @param cmdlist: list of command (options) + @type cmdlist: string[]""" + + Popen(cmdlist) + + def do_notify(self, base, descr, icon, urgency): + """Displays a notify. + This will do nothing if pynotify is not present and/or root is running the listener.""" + + if pynotify and not os.getuid == 0: + if not pynotify.is_initted(): + pynotify.init(APP) + + n = pynotify.Notification(base, descr, icon) + n.set_urgency(int(urgency)) + n.show() + + def set_send (self): + self._send = socket.socket(socket.AF_UNIX) + try: + self._send.connect(SOCKET) + except socket.error, e: + if e[0] in [111, 2]: # can't connect + warning(_("Listener has not been started.")) + self._send = None + else: + raise + + def __send (self, string): + self._send.sendall("%4d" % len(string)) + self._send.sendall(string) + + def send_notify (self, base = "", descr = "", icon = "", urgency = None): + if self._send is None: + self.do_notify(base, descr, icon, urgency) + else: + string = "\0".join(["notify", base, descr, icon]) + + if urgency is not None: + string += "\0%d" % urgency + else: + string += "\0" + + self.__send(string) + + def send_cmd (self, cmdlist): + if self._send is None: + self.do_cmd(cmdlist) + else: + self.__send("\0".join(["cmd"] +cmdlist)) + + def close (self): + if self._send is not None: + self.__send("close") + self._send.close() + os.unlink(SOCKET) |