# telepathy-sunshine is the GaduGadu connection manager for Telepathy # # Copyright (C) 2006-2007 Ali Sabil # Copyright (C) 2007 Johann Prieur # Copyright (C) 2010 Krzysztof Klinikowski # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import logging, hashlib import telepathy import xml.etree.ElementTree as ET from sunshine.lqsoft.pygadu.models import GaduProfile, GaduContact, GaduContactGroup from twisted.internet import reactor from sunshine.util.decorator import async from sunshine.handle import SunshineHandleFactory from sunshine.channel.contact_list import SunshineListChannel __all__ = ['SunshineGroupChannel'] logger = logging.getLogger('Sunshine.GroupChannel') class SunshineGroupChannel(SunshineListChannel): def __init__(self, connection, manager, props, object_path=None): self.__pending_add = [] self.__pending_remove = [] self.conn = connection self.groups = {} SunshineListChannel.__init__(self, connection, manager, props, object_path=object_path) self.GroupFlagsChanged(telepathy.CHANNEL_GROUP_FLAG_CAN_ADD | telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE, 0) @async def create_group(): if self._handle.group is None: name = self._handle.name for group in self.conn.profile.groups: if group.Name != name: h = hashlib.md5() h.update(name) group_xml = ET.Element("Group") ET.SubElement(group_xml, "Id").text = h.hexdigest() ET.SubElement(group_xml, "Name").text = name ET.SubElement(group_xml, "IsExpanded").text = str('True') ET.SubElement(group_xml, "IsRemovable").text = str('True') g = GaduContactGroup.from_xml(group_xml) self.conn.profile.addGroup(g) for group in self.conn.profile.groups: self.groups[group.Id] = group.Name for contact in self.conn.profile.contacts: contact_groups = ET.fromstring(contact.Groups) if contact.Groups: for group in contact_groups.getchildren(): if self.groups.has_key(group.text): if self.groups[group.text] == self._handle.group.Name: self.add_contact_to_group(self._handle.group, contact, None) create_group() def AddMembers(self, contacts, message): for contact_handle_id in contacts: contact_handle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contact_handle_id) logger.info("Adding contact %s to group %s" % (unicode(contact_handle), unicode(self._handle))) contact = contact_handle.contact group = self._handle.group self.add_contact_to_group(group, contact, contact_handle) reactor.callLater(3.0, self._conn_ref().exportContactsFile) def RemoveMembers(self, contacts, message): for contact_handle_id in contacts: contact_handle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contact_handle_id) logger.info("Removing contact %s from pending group %s" % (unicode(contact_handle), unicode(self._handle))) contact = contact_handle.contact group = self._handle.group self.delete_contact_from_group(group, contact, contact_handle) reactor.callLater(3.0, self._conn_ref().exportContactsFile) def Close(self): logger.debug("Deleting group %s" % self._handle.name) del self.conn.profile.groups[self._handle.name] @async def add_contact_to_group(self, group, contact, contact_handle): group_name = group.Name if group_name == self._handle.name: if hasattr(contact, 'uin'): contact_uin = contact.uin else: contact_uin = contact_handle.name handle = SunshineHandleFactory(self.conn, 'contact', contact_uin, None) added = set() added.add(handle) if group.Name and group.Id: is_group = False contact_groups_xml = ET.Element("Groups") if hasattr(contact, 'Groups'): contact_groups = ET.fromstring(contact.Groups) for c_group in contact_groups.getchildren(): if c_group.text == group.Id: is_group = True ET.SubElement(contact_groups_xml, "GroupId").text = c_group.text if is_group != True: ET.SubElement(contact_groups_xml, "GroupId").text = group.Id c_groups = ET.tostring(contact_groups_xml) if hasattr(contact, 'updateGroups'): contact.updateGroups(c_groups) else: self.conn.pending_contacts_to_group[contact_uin] = c_groups self.MembersChanged('', added, (), (), (), 0, telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE) logger.debug("Contact %s added to group %s" % (handle.name, group_name)) @async def delete_contact_from_group(self, group, contact, contact_handle): group_name = group.Name if group_name == self._handle.name: handle = SunshineHandleFactory(self.conn, 'contact', contact.uin, None) removed = set() removed.add(handle) contact_groups_xml = ET.Element("Groups") contact_groups = ET.fromstring(contact.Groups) if contact.Groups: for c_group in contact_groups.getchildren(): if c_group.text != group.Id: ET.SubElement(contact_groups_xml, "GroupId").text = c_group.text c_groups = ET.tostring(contact_groups_xml) contact.updateGroups(c_groups) self.MembersChanged('', (), removed, (), (), 0, telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE) logger.debug("Contact %s removed from group %s" % (handle.name, group_name))