[Telepathy-commits] [telepathy-pinocchio/master] re-create groups at Connect type, based on groups found in the contacts list

Travis Reitter travis.reitter at collabora.co.uk
Thu Aug 14 22:29:49 PDT 2008


---
 bin/pinocchio-ctl                 |    4 --
 pinocchio/channel/contact_list.py |   20 +++++++++
 pinocchio/connection/__init__.py  |   24 ++++++++++-
 pinocchio/server/__init__.py      |   83 ++++++++++++++++++++++++++++++++-----
 4 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/bin/pinocchio-ctl b/bin/pinocchio-ctl
index 26a5dd9..5276274 100755
--- a/bin/pinocchio-ctl
+++ b/bin/pinocchio-ctl
@@ -158,10 +158,6 @@ def connection_get_opened(bus, manager, params, opts):
         connection.self_opened = True
 
     if connection.GetStatus() == tp.constants.CONNECTION_STATUS_DISCONNECTED:
-        # tell the back-end to use any provided alternate contacts file
-        if opts['contacts-file']:
-            connection.set_contacts_file(opts['contacts-file'])
-
         connection.Connect()
 
     return (connection, connection.service_name,
diff --git a/pinocchio/channel/contact_list.py b/pinocchio/channel/contact_list.py
index ba620ec..4627e66 100644
--- a/pinocchio/channel/contact_list.py
+++ b/pinocchio/channel/contact_list.py
@@ -124,6 +124,26 @@ class Group(tp.server.ChannelTypeContactList, tp.server.ChannelInterfaceGroup):
         self._connection = connection
         self.account_id = account_id
 
+        contacts_disk = pin.server.StoredGroup(connection, channel_handle_obj)
+
+        handles_initial = contacts_disk.get_handle_objs()
+        for handle_obj in handles_initial:
+            connection._handles[tp.constants.HANDLE_TYPE_CONTACT,
+                                handle_obj.get_id()] = handle_obj
+
+        # send initial member list as any other list change
+        # this stores these HandleContact objects in self._members
+        self.MembersChanged('', handles_initial, (), (), (), 0,
+                            tp.constants.CHANNEL_GROUP_CHANGE_REASON_NONE)
+
+
+        handle_ids = [h.get_id() for h in handles_initial]
+        # announce the presence of our new contacts
+        connection.RequestPresence(handle_ids)
+
+        # announce avatars for contacts with avatars
+        connection.RequestAvatars(handle_ids)
+
         # declare our group capabilities
         self.GroupFlagsChanged(tp.constants.CHANNEL_GROUP_FLAG_CAN_ADD |
                                tp.constants.CHANNEL_GROUP_FLAG_CAN_REMOVE, 0)
diff --git a/pinocchio/connection/__init__.py b/pinocchio/connection/__init__.py
index 0c2ff26..9c03720 100644
--- a/pinocchio/connection/__init__.py
+++ b/pinocchio/connection/__init__.py
@@ -83,6 +83,19 @@ class Connection(tp.server.Connection,
                                         tp.constants.HANDLE_TYPE_LIST,
                                         handle.get_id(), True)
 
+        # XXX: this is kinda hacky, since we have to re-parse the file later
+        # create all Groups listed in the contacts file
+        group_names = pin.server.contacts_file_get_groups(self)
+        for group_name in group_names:
+            handle = tp.server.Handle(self.get_handle_id(),
+                                      tp.constants.HANDLE_TYPE_GROUP,
+                                      group_name)
+            self._handles[handle.get_type(), handle.get_id()] = handle
+
+            self._channel_get_or_create(tp.interfaces.CHANNEL_TYPE_CONTACT_LIST,
+                                        tp.constants.HANDLE_TYPE_GROUP,
+                                        handle.get_id(), True)
+
     def Disconnect(self):
         """Request connection tear-down."""
 
@@ -117,6 +130,9 @@ class Connection(tp.server.Connection,
         channel = self._channel_get_or_create (channel_type, handle_type,
                                                handle, suppress_handler)
 
+        # TODO: optimize here by only saving if a channel was created
+        self.save()
+
         return channel._object_path
 
     @dbus.service.method(tp.interfaces.CONNECTION, in_signature='uas',
@@ -353,6 +369,12 @@ class Connection(tp.server.Connection,
         account_id = self.get_account_id()
         filename = pin.common.get_contacts_file_abs(account_id,
                                                     pin.common.PREFIX_SAVED)
-        file = open(filename, 'w+')
+
+        # make sure the parent directories exist
+        parent_dir = os.path.dirname(filename)
+        if not os.path.isdir(parent_dir):
+            os.makedirs(parent_dir)
+
+        file = open(filename, 'w')
         file.write(xml_doc.toxml(encoding='utf-8'))
         file.close()
diff --git a/pinocchio/server/__init__.py b/pinocchio/server/__init__.py
index f7b473e..e5da1c1 100644
--- a/pinocchio/server/__init__.py
+++ b/pinocchio/server/__init__.py
@@ -26,6 +26,32 @@ import telepathy as tp
 
 import pinocchio as pin
 
+def contacts_file_get_groups(connection):
+    """Returns a set of the groups mentioned in the contacts file.
+
+    Arguments:
+    connection -- the initialized (though not necessarily opened) connection
+    """
+    try:
+        contacts_file = open(connection._contacts_file, 'rU')
+    except:
+        print 'Could not open contact list file ', connection._contacts_file
+        raise
+
+    group_names = set()
+
+    contacts_xml = minidom.parse(contacts_file)
+    contacts_file.close()
+
+    roster = contacts_xml.getElementsByTagName('roster')[0]
+    groups_lists = roster.getElementsByTagName('groups')
+    for groups_list in groups_lists:
+        groups = groups_list.getElementsByTagName('group')
+        for group in groups:
+            group_names.add(group.firstChild.data)
+        
+    return group_names
+
 class HandleContact(tp.server.Handle):
     """
     Full-fledged Contact wrapper of Telepathy Handle object.
@@ -182,12 +208,16 @@ class HandleContact(tp.server.Handle):
 
         return contact_xml
 
-class StoredContactList:
-    def __init__(self, connection, channel_handle_obj):
+class StoredList:
+    def __init__(self, connection, channel_handle_obj, list_tag_name,
+                 list_item_tag_name):
+        # FIXME: update this
         """
         Arguments:
         connection -- connection this StoredContactList corresponds to
         channel_handle_obj -- handle object of the channel this list maps to
+        list_tag_name -- name of the list-enclosing tag (eg, "contact_lists")
+        list_item_tag_name -- name of the list item tag (eg, "list")
 
         Exceptions:
         IOError -- failed to read contact list file
@@ -195,6 +225,8 @@ class StoredContactList:
         """
         self.connection = connection
         self.channel_handle_obj = channel_handle_obj
+        self.list_tag_name = list_tag_name
+        self.list_item_tag_name = list_item_tag_name
 
         try:
             contacts_file = open(self.connection._contacts_file, 'rU')
@@ -206,8 +238,8 @@ class StoredContactList:
         contacts_xml = minidom.parse(contacts_file)
         contacts_file.close()
 
-        list = contacts_xml.getElementsByTagName('roster')[0]
-        contacts = list.getElementsByTagName('contact')
+        roster = contacts_xml.getElementsByTagName('roster')[0]
+        contacts = roster.getElementsByTagName('contact')
 
         channel_name = self.channel_handle_obj.get_name()
 
@@ -215,15 +247,16 @@ class StoredContactList:
         for contact in contacts:
             # if contact has a
             #
-            # <contact_lists>
-            #     <list>channel_name</list>
-            # </contact_lists>
+            # <[list_tag_name]>
+            #     <[list_item_tag_name]>channel_name</[list_item_tag_name]>
+            # </[list_tag_name]>
             #
             # entry, it's a member of this list
-            contact_lists_tag = contact.getElementsByTagName('contact_lists')[0]
-            lists = contact.getElementsByTagName('list')
-            for list in lists:
-                if list.firstChild.data == channel_name:
+            stored_lists_tag = contact.getElementsByTagName(list_tag_name)[0]
+            stored_lists = stored_lists_tag.getElementsByTagName(
+                                                            list_item_tag_name)
+            for stored_list in stored_lists:
+                if stored_list.firstChild.data == channel_name:
                     handle_contact = self.contact_xml_to_handle(contact,
                                                                 connection)
 
@@ -313,3 +346,31 @@ class StoredContactList:
         contacts_file.write(xml_contents.encode('utf-8'))
 
         contacts_file.close()
+
+class StoredContactList(StoredList):
+    def __init__(self, connection, channel_handle_obj):
+        """
+        Arguments:
+        connection -- connection this StoredContactList corresponds to
+        channel_handle_obj -- handle object of the channel this list maps to
+
+        Exceptions:
+        IOError -- failed to read contact list file
+        IndexError -- contact list file parsing failed
+        """
+        StoredList.__init__(self, connection, channel_handle_obj,
+                            'contact_lists', 'list')
+
+class StoredGroup(StoredList):
+    def __init__(self, connection, channel_handle_obj):
+        """
+        Arguments:
+        connection -- connection this StoredGroup corresponds to
+        channel_handle_obj -- handle object of the channel this list maps to
+
+        Exceptions:
+        IOError -- failed to read contact list file
+        IndexError -- contact list file parsing failed
+        """
+        StoredList.__init__(self, connection, channel_handle_obj,
+                            'groups', 'group')
-- 
1.5.6.3




More information about the Telepathy-commits mailing list