diff options
Diffstat (limited to 'sugar/chat/BuddyList.py')
-rw-r--r-- | sugar/chat/BuddyList.py | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/sugar/chat/BuddyList.py b/sugar/chat/BuddyList.py new file mode 100644 index 0000000..d35fa84 --- /dev/null +++ b/sugar/chat/BuddyList.py @@ -0,0 +1,121 @@ +# -*- tab-width: 4; indent-tabs-mode: t -*- + +import presence +import avahi + +ACTION_BUDDY_ADDED = "added" +ACTION_BUDDY_REMOVED = "removed" + + +class Buddy(object): + def __init__(self, nick, realname, servicename, host, address, port, key=None): + self._nick = nick + self._realname = realname + self._servicename = servicename + self._key = key + self._host = host + self._address = str(address) + self._port = int(port) + self._chat = None + + def set_chat(self, chat): + self._chat = chat + + def chat(self): + return self._chat + + def nick(self): + return self._nick + + def realname(self): + return self._realname + + def servicename(self): + return self._servicename + + def host(self): + return self._host + + def address(self): + return self._address + + def port(self): + return self._port + + def key(self): + return self._key + +class BuddyList(object): + """ Manage a list of buddies """ + + def __init__(self, servicename): + self._listeners = [] + self._buddies = {} + self._servicename = servicename + self._pdiscovery = presence.PresenceDiscovery() + self._pdiscovery.add_service_listener(self._on_service_change) + + def start(self): + self._pdiscovery.start() + + def add_buddy_listener(self, listener): + self._listeners.append(listener) + + def _add_buddy(self, host, address, port, servicename, data): + # Ignore ourselves + if servicename == self._servicename: + return + + if len(data) > 0 and 'name' in data.keys(): + buddy = self._find_buddy_by_service_name(servicename) + if not buddy: + buddy = Buddy(data['name'], data['realname'], servicename, host, address, port) + self._buddies[data['name']] = buddy + self._notify_listeners(ACTION_BUDDY_ADDED, buddy) + + def _remove_buddy(self, buddy): + nick = buddy.nick() + self._notify_listeners(ACTION_BUDDY_REMOVED, buddy) + del self._buddies[nick] + + def _find_buddy_by_service_name(self, servicename): + for buddy in self._buddies.values(): + if buddy.servicename() == servicename: + return buddy + return None + + def find_buddy_by_address(self, address): + for buddy_name in self._buddies.keys(): + buddy = self._buddies[buddy_name] + if buddy.address() == address: + return buddy + return None + + def _notify_listeners(self, action, buddy): + for listener in self._listeners: + listener(action, buddy) + + def _on_service_change(self, action, interface, protocol, name, stype, domain, flags): + if stype != presence.OLPC_CHAT_SERVICE: + return + if action == presence.ACTION_SERVICE_NEW: + self._pdiscovery.resolve_service(interface, protocol, name, stype, domain, self._on_service_resolved) + elif action == presence.ACTION_SERVICE_REMOVED: + buddy = self._find_buddy_by_service_name(name) + if buddy: + self._remove_buddy(buddy) + + def _pair_to_dict(self, l): + res = {} + for el in l: + tmp = el.split('=', 1) + if len(tmp) > 1: + res[tmp[0]] = tmp[1] + else: + res[tmp[0]] = '' + return res + + def _on_service_resolved(self, interface, protocol, name, stype, domain, host, aprotocol, address, port, txt, flags): + data = self._pair_to_dict(avahi.txt_array_to_string_array(txt)) + self._add_buddy(host, address, port, name, data) + |