~ubuntu-branches/ubuntu/oneiric/cairo-dock-plug-ins/oneiric-updates

« back to all changes in this revision

Viewing changes to Status-Notifier/watcher/status-notifier-watcher.py

  • Committer: Kees Cook
  • Date: 2011-08-11 23:17:39 UTC
  • mfrom: (20.1.1 cairo-dock-plug-ins)
  • Revision ID: kees@outflux.net-20110811231739-cteedan51tmdg77v
Tags: 2.4.0~0beta2-0ubuntu1
releasing version 2.4.0~0beta2-0ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
#
 
3
# Author: Fabrice Rey
 
4
# License: GPL-3
 
5
#
 
6
# Developped as a part of Cairo-Dock, but usable as a stand-alone systray daemon.
 
7
# The code follows the same logic as the KDE watcher, to ensure a complete compatibility.
 
8
 
 
9
import sys
 
10
import glib
 
11
import gobject
 
12
import dbus, dbus.service
 
13
from dbus.mainloop.glib import DBusGMainLoop
 
14
 
 
15
class SNWatcher(dbus.service.Object):
 
16
        bus_name_str = 'org.kde.StatusNotifierWatcher'
 
17
        bus_obj_str  = '/StatusNotifierWatcher'
 
18
        bus_iface_str = 'org.kde.StatusNotifierWatcher'
 
19
        items_list = []  # array of service+path
 
20
        hosts_list = []  # array of services
 
21
        
 
22
        def __init__(self):
 
23
                DBusGMainLoop(set_as_default=True)
 
24
                try: 
 
25
                        self.bus = dbus.SessionBus()
 
26
                        bus_name = dbus.service.BusName (self.bus_name_str, self.bus)
 
27
                        print "registered a watcher:",bus_name
 
28
                        dbus.service.Object.__init__(self, bus_name, self.bus_obj_str)
 
29
                except Exception, exception:
 
30
                        print 'Could not open dbus. Uncaught exception.'
 
31
                        return
 
32
                
 
33
                bus_object = self.bus.get_object(dbus.BUS_DAEMON_NAME, dbus.BUS_DAEMON_PATH)
 
34
                self.main = dbus.Interface(bus_object, dbus.BUS_DAEMON_IFACE)
 
35
                self.main.connect_to_signal("NameOwnerChanged", self.on_name_owner_changed)
 
36
                
 
37
                self.loop = gobject.MainLoop()
 
38
                self.loop.run()
 
39
        
 
40
        def on_name_owner_changed(self, service, prev_owner, new_owner):
 
41
                print "name_owner_changed: %s; %s; %s" % (service, prev_owner, new_owner)
 
42
                if (new_owner == '' and not service.startswith(':')):  # a service has disappear from the bus, check if it was an item or a host.
 
43
                        # search amongst the items.
 
44
                        match = service+'/'
 
45
                        print "  search for ",match
 
46
                        to_be_removed=[]
 
47
                        for it in self.items_list:
 
48
                                print "  check for ",it
 
49
                                if (it.startswith(match)):  # it[0:len(match)] == match
 
50
                                        print "    match!"
 
51
                                        to_be_removed.append(it)
 
52
                        for it in to_be_removed:
 
53
                                self.items_list.remove (it)
 
54
                                self.StatusNotifierItemUnregistered(it)
 
55
 
 
56
                        # search amongst the hosts.
 
57
                        to_be_removed=[]
 
58
                        for it in self.hosts_list:
 
59
                                if (it == service):
 
60
                                        to_be_removed.append(it)
 
61
                        for it in to_be_removed:
 
62
                                self.hosts_list.remove (it)
 
63
                                self.StatusNotifierHostUnregistered()
 
64
                
 
65
        ### methods ###
 
66
        
 
67
        @dbus.service.method(dbus_interface = bus_iface_str, in_signature = 's', out_signature = None)
 
68
        def RegisterStatusNotifierHost(self, service):
 
69
                if (self.hosts_list.count (service) == 0):  # if not already listed
 
70
                        self.hosts_list.append (service)
 
71
                        self.StatusNotifierHostRegistered()
 
72
                print 'hosts:',self.hosts_list
 
73
                sys.stdout.flush()
 
74
        
 
75
        @dbus.service.method(dbus_interface = bus_iface_str, in_signature = 's', out_signature = None, sender_keyword='sender')
 
76
        def RegisterStatusNotifierItem(self, serviceOrPath, sender=None):
 
77
                # build the item id: service + path
 
78
                if (serviceOrPath[0] == '/'):
 
79
                        service = sender
 
80
                        path = serviceOrPath
 
81
                else:
 
82
                        service = serviceOrPath
 
83
                        path = "/StatusNotifierItem"
 
84
                
 
85
                itemId = service + path
 
86
                # keep track of this new item, and emit the 'new' signal.
 
87
                if (self.items_list.count (itemId) == 0):  # if not already listed
 
88
                        self.items_list.append (itemId)
 
89
                        self.StatusNotifierItemRegistered (itemId)
 
90
        
 
91
        ### Properties ###
 
92
        
 
93
        @dbus.service.method(dbus_interface = dbus.PROPERTIES_IFACE, in_signature = 'ss', out_signature = 'v')
 
94
        def Get(self, interface, property):
 
95
                if interface == 'org.kde.StatusNotifierWatcher':
 
96
                        if property == 'RegisteredStatusNotifierItems':
 
97
                                print "items: ",self.items_list
 
98
                                if (len (self.items_list) != 0):
 
99
                                        return self.items_list
 
100
                                else:  # too bad! dbus-python can't encode the GValue if 'items_list' is None or [].
 
101
                                        return ['']  # so we return a empty string; hopefuly the host will skip this invalid value.
 
102
                        elif property == 'HasStatusNotifierHostRegistered':
 
103
                                return (len (self.hosts_list) != 0)
 
104
                        elif property == 'ProtocolVersion':
 
105
                                return 0
 
106
        
 
107
        ### Signals ###
 
108
        
 
109
        @dbus.service.signal(dbus_interface=bus_name_str, signature='s')
 
110
        def StatusNotifierItemRegistered(self, service):
 
111
                print "%s registered" % (service)
 
112
                sys.stdout.flush()
 
113
        
 
114
        @dbus.service.signal(dbus_interface=bus_name_str, signature='s')
 
115
        def StatusNotifierItemUnregistered(self, service):
 
116
                print "%s unregistered" % (service)
 
117
                sys.stdout.flush()
 
118
        
 
119
        @dbus.service.signal(dbus_interface=bus_name_str, signature=None)
 
120
        def StatusNotifierHostRegistered(self):
 
121
                print "a host has been registered"
 
122
                sys.stdout.flush()
 
123
        
 
124
        @dbus.service.signal(dbus_interface=bus_name_str, signature=None)
 
125
        def StatusNotifierHostUnregistered(self):
 
126
                print "a host has been unregistered"
 
127
                sys.stdout.flush()
 
128
        
 
129
        
 
130
if __name__ == '__main__':
 
131
        SNWatcher()