diff options
author | Dan Williams <dcbw@redhat.com> | 2007-05-14 01:34:15 (GMT) |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2007-05-14 01:34:15 (GMT) |
commit | 5e2ea16e3aaf3db3629164de786ad5083f600600 (patch) | |
tree | 2df4bff5ffae78d16707b203843e542128021e02 /services/presence/buddy.py | |
parent | 66dfd363ba7cc169ffaeafffe6c6b302c4779eeb (diff) |
Redo PS connection handling; ensure valid network connection before talking to server
Diffstat (limited to 'services/presence/buddy.py')
-rw-r--r-- | services/presence/buddy.py | 183 |
1 files changed, 12 insertions, 171 deletions
diff --git a/services/presence/buddy.py b/services/presence/buddy.py index f302b8c..200401b 100644 --- a/services/presence/buddy.py +++ b/services/presence/buddy.py @@ -22,6 +22,7 @@ import dbus import dbus.service from dbus.gobject_service import ExportedGObject from ConfigParser import ConfigParser, NoOptionError +import psutils from sugar import env, profile, util import logging @@ -132,9 +133,19 @@ class Buddy(ExportedGObject): logging.debug("Invalid init property '%s'; ignoring..." % key) del kwargs[key] + # Set icon after superclass init, because it sends DBus and GObject + # signals when set + icon_data = None + if kwargs.has_key(_PROP_ICON): + icon_data = kwargs[_PROP_ICON] + del kwargs[_PROP_ICON] + ExportedGObject.__init__(self, bus_name, self._object_path, gobject_properties=kwargs) + if icon_data: + self.props.icon = icon_data + def do_get_property(self, pspec): """Retrieve current value for the given property specifier @@ -399,176 +410,6 @@ class Buddy(ExportedGObject): except AttributeError: self._valid = False - -NM_SERVICE = 'org.freedesktop.NetworkManager' -NM_IFACE = 'org.freedesktop.NetworkManager' -NM_IFACE_DEVICES = 'org.freedesktop.NetworkManager.Devices' -NM_PATH = '/org/freedesktop/NetworkManager' - -class IP4AddressMonitor(gobject.GObject): - """This class, and direct buddy IPv4 address access, will go away quite soon""" - - __gsignals__ = { - 'address-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - __gproperties__ = { - 'address' : (str, None, None, None, gobject.PARAM_READABLE) - } - - def __init__(self): - gobject.GObject.__init__(self) - self._nm_present = False - self._matches = [] - self._addr = None - self._nm_obj = None - - sys_bus = dbus.SystemBus() - bus_object = sys_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - try: - if bus_object.GetNameOwner(NM_SERVICE, dbus_interface='org.freedesktop.DBus'): - self._nm_present = True - except dbus.DBusException: - pass - - if self._nm_present: - self._connect_to_nm() - else: - addr = self._get_address_fallback() - self._update_address(addr) - - def do_get_property(self, pspec): - if pspec.name == "address": - return self._addr - - def _update_address(self, new_addr): - if new_addr == "0.0.0.0": - new_addr = None - if new_addr == self._addr: - return - - self._addr = new_addr - logging.debug("IP4 address now '%s'" % new_addr) - self.emit('address-changed', new_addr) - - def _connect_to_nm(self): - """Connect to NM device state signals to tell when the IPv4 address changes""" - try: - sys_bus = dbus.SystemBus() - proxy = sys_bus.get_object(NM_SERVICE, NM_PATH) - self._nm_obj = dbus.Interface(proxy, NM_IFACE) - except dbus.DBusException, err: - logging.debug("Error finding NetworkManager: %s" % err) - self._nm_present = False - return - - sys_bus = dbus.SystemBus() - match = sys_bus.add_signal_receiver(self._nm_device_active_cb, - signal_name="DeviceNowActive", - dbus_interface=NM_IFACE) - self._matches.append(match) - - match = sys_bus.add_signal_receiver(self._nm_device_no_longer_active_cb, - signal_name="DeviceNoLongerActive", - dbus_interface=NM_IFACE, - named_service=NM_SERVICE) - self._matches.append(match) - - match = sys_bus.add_signal_receiver(self._nm_state_change_cb, - signal_name="StateChange", - dbus_interface=NM_IFACE, - named_service=NM_SERVICE) - self._matches.append(match) - - state = self._nm_obj.state() - if state == 3: # NM_STATE_CONNECTED - self._query_devices() - - def _device_properties_cb(self, *props): - active = props[4] - if not active: - return - act_stage = props[5] - # HACK: OLPC NM has an extra stage, so activated == 8 on OLPC - # but 7 everywhere else - if act_stage != 8 and act_stage != 7: - # not activated - return - self._update_address(props[6]) - - def _device_properties_error_cb(self, err): - logging.debug("Error querying device properties: %s" % err) - - def _query_device_properties(self, device): - sys_bus = dbus.SystemBus() - proxy = sys_bus.get_object(NM_SERVICE, device) - dev = dbus.Interface(proxy, NM_IFACE_DEVICES) - dev.getProperties(reply_handler=self._device_properties_cb, - error_handler=self._device_properties_error_cb) - - def _get_devices_cb(self, ops): - """Query each device's properties""" - for op in ops: - self._query_device_properties(op) - - def _get_devices_error_cb(self, err): - logging.debug("Error getting NetworkManager devices: %s" % err) - - def _query_devices(self): - """Query NM for a list of network devices""" - self._nm_obj.getDevices(reply_handler=self._get_devices_cb, - error_handler=self._get_devices_error_cb) - - def _nm_device_active_cb(self, device, ssid=None): - self._query_device_properties(device) - - def _nm_device_no_longer_active_cb(self, device): - self._update_address(None) - - def _nm_state_change_cb(self, new_state): - if new_state == 4: # NM_STATE_DISCONNECTED - self._update_address(None) - - def handle_name_owner_changed(self, name, old, new): - """Clear state when NM goes away""" - if name != NM_SERVICE: - return - if (old and len(old)) and (not new and not len(new)): - # NM went away - self._nm_present = False - for match in self._matches: - match.remove() - self._matches = [] - self._update_address(None) - elif (not old and not len(old)) and (new and len(new)): - # NM started up - self._nm_present = True - self._connect_to_nm() - - def _get_iface_address(self, iface): - import socket - import fcntl - import struct - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - fd = s.fileno() - SIOCGIFADDR = 0x8915 - addr = fcntl.ioctl(fd, SIOCGIFADDR, struct.pack('256s', iface[:15]))[20:24] - s.close() - return socket.inet_ntoa(addr) - - def _get_address_fallback(self): - import commands - (s, o) = commands.getstatusoutput("/sbin/route -n") - if s != 0: - return - for line in o.split('\n'): - fields = line.split(" ") - if fields[0] == "0.0.0.0": - iface = fields[len(fields) - 1] - return self._get_iface_address(iface) - return None - class GenericOwner(Buddy): """Common functionality for Local User-like objects @@ -617,7 +458,7 @@ class GenericOwner(Buddy): signal_name="NameOwnerChanged", dbus_interface="org.freedesktop.DBus") - self._ip4_addr_monitor = IP4AddressMonitor() + self._ip4_addr_monitor = psutils.IP4AddressMonitor.get_instance() self._ip4_addr_monitor.connect("address-changed", self._ip4_address_changed_cb) def _ip4_address_changed_cb(self, monitor, address): |