[Telepathy-commits] [telepathy-gabble/master] Extract handling other MUC presences to a function

Will Thompson will.thompson at collabora.co.uk
Sun Feb 1 08:58:57 PST 2009


---
 src/muc-channel.c |  360 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 188 insertions(+), 172 deletions(-)

diff --git a/src/muc-channel.c b/src/muc-channel.c
index 1c79d42..544646d 100644
--- a/src/muc-channel.c
+++ b/src/muc-channel.c
@@ -1897,6 +1897,191 @@ handle_unavailable_presence_update (GabbleMucChannel *chan,
     tp_handle_unref (contact_handles, actor);
 }
 
+static void
+handle_presence_update (GabbleMucChannel *chan,
+                        TpHandleRepoIface *contact_handles,
+                        TpHandle handle,
+                        TpIntSet *handle_singleton,
+                        LmMessageNode *item_node,
+                        const gchar *status_code)
+{
+  GabbleMucChannelPrivate *priv = GABBLE_MUC_CHANNEL_GET_PRIVATE (chan);
+  TpGroupMixin *mixin = TP_GROUP_MIXIN (chan);
+  TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
+  const gchar *owner_jid = lm_message_node_get_attribute (item_node, "jid");
+
+  if (!tp_handle_set_is_member (mixin->members, handle))
+    {
+      TpHandle owner_handle = 0;
+
+      if (owner_jid != NULL)
+        {
+          owner_handle = tp_handle_ensure (contact_handles, owner_jid,
+              GUINT_TO_POINTER (GABBLE_JID_GLOBAL), NULL);
+
+          if (owner_handle == 0)
+            DEBUG ("Invalid owner handle '%s', treating as no owner",
+                owner_jid);
+        }
+
+      if (handle == mixin->self_handle &&
+          owner_handle != conn->self_handle)
+        {
+          /* We know that in XEP-0045 compliant MUCs, nobody else can have
+           * the nick we tried to use - the service MUST reject us
+           * with code 409/"conflict" in this case. So, if someone in the
+           * room has the nick we want, it's us.
+           *
+           * If the MUC service fails to comply with this requirement,
+           * we get hopelessly confused, but this isn't a regression
+           * (we always would have done).
+           *
+           * FIXME: we ought to respect the 110 and 210 status codes
+           * too, so we can detect MUCs renaming us - otherwise the
+           * presence aggregator will never stop
+           */
+          DEBUG ("Overriding ownership of channel-specific handle %u "
+              "from %u to %u because I know it's mine",
+              mixin->self_handle, owner_handle, conn->self_handle);
+
+          if (owner_handle != 0)
+            tp_handle_unref (contact_handles, owner_handle);
+
+          tp_handle_ref (contact_handles, conn->self_handle);
+          owner_handle = conn->self_handle;
+        }
+
+      if (priv->initial_state_aggregator == NULL)
+        {
+          /* we've already had the initial batch of presence stanzas */
+          tp_group_mixin_add_handle_owner ((GObject *) chan, handle,
+              owner_handle);
+          tp_group_mixin_change_members ((GObject *) chan, "",
+              handle_singleton, NULL, NULL, NULL, 0, 0);
+        }
+      else
+        {
+          /* aggregate this presence */
+          tp_handle_set_add (priv->initial_state_aggregator->members,
+              handle);
+
+          g_hash_table_insert (priv->initial_state_aggregator->owner_map,
+              GUINT_TO_POINTER (handle), GUINT_TO_POINTER (owner_handle));
+
+          if (owner_handle != 0)
+            tp_handle_set_add (priv->initial_state_aggregator->owners,
+                owner_handle);
+
+          /* Do not emit one signal per presence. Instead, get all
+           * presences, and add them in priv->initial_state_aggregator.
+           * When we get the last presence, emit the signal. The last
+           * presence is ourselves. */
+          if (handle == mixin->self_handle)
+            {
+              /* Add all handle owners in a single operation */
+              tp_group_mixin_add_handle_owners ((GObject *) chan,
+                  priv->initial_state_aggregator->owner_map);
+
+              /* Change all presences in a single operation */
+              tp_group_mixin_change_members ((GObject *) chan, "",
+                  tp_handle_set_peek (
+                      priv->initial_state_aggregator->members),
+                  NULL, NULL, NULL, 0, 0);
+
+              initial_state_aggregator_free (
+                  priv->initial_state_aggregator);
+              priv->initial_state_aggregator = NULL;
+            }
+        }
+
+      if (owner_handle != 0)
+        {
+          if (handle != mixin->self_handle)
+            {
+              /* If at least one other handle in the channel has an owner,
+               * the HANDLE_OWNERS_NOT_AVAILABLE flag should be removed.
+               */
+              tp_group_mixin_change_flags ((GObject *) chan, 0,
+                  TP_CHANNEL_GROUP_FLAG_HANDLE_OWNERS_NOT_AVAILABLE);
+            }
+
+          g_signal_emit (chan, signals[CONTACT_JOIN], 0, owner_handle);
+
+          tp_handle_unref (contact_handles, owner_handle);
+        }
+
+      if (handle == mixin->self_handle)
+        {
+          g_object_set (chan, "state", MUC_STATE_JOINED, NULL);
+        }
+    }
+
+  if (handle == mixin->self_handle)
+    {
+      const gchar *role, *affil;
+      GabbleMucRole new_role;
+      GabbleMucAffiliation new_affil;
+
+      /* accept newly-created room settings before we send anything
+       * below which queryies them. */
+      if (status_code && strcmp (status_code, "201") == 0)
+        {
+          LmMessage *msg;
+          LmMessageNode *node;
+          GError *error = NULL;
+
+          msg = lm_message_new_with_sub_type (priv->jid,
+              LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
+
+          node = lm_message_node_add_child (msg->node, "query", NULL);
+          lm_message_node_set_attribute (node, "xmlns", NS_MUC_OWNER);
+
+          node = lm_message_node_add_child (node, "x", NULL);
+          lm_message_node_set_attributes (node,
+                                          "xmlns", NS_X_DATA,
+                                          "type", "submit",
+                                          NULL);
+
+          if (!_gabble_connection_send_with_reply (priv->conn, msg,
+                room_created_submit_reply_cb, G_OBJECT (chan), NULL,
+                &error))
+            {
+              DEBUG ("failed to send submit message: %s",
+                  error->message);
+              g_error_free (error);
+
+              lm_message_unref (msg);
+              close_channel (chan, NULL, TRUE, 0,
+                  TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
+
+              return;
+            }
+
+          lm_message_unref (msg);
+        }
+
+      /* Update room properties */
+      room_properties_update (chan);
+
+      /* update permissions after requesting new properties so that if we
+       * become an owner, we get our configuration form reply after the
+       * discovery reply, so we know whether there is a description
+       * property before we try and decide whether we can write to it. */
+      role = lm_message_node_get_attribute (item_node, "role");
+      affil = lm_message_node_get_attribute (item_node, "affiliation");
+      new_role = get_role_from_string (role);
+      new_affil = get_affiliation_from_string (affil);
+
+      if (new_role != priv->self_role || new_affil != priv->self_affil)
+        {
+          priv->self_role = new_role;
+          priv->self_affil = new_affil;
+
+          update_permissions (chan);
+        }
+    }
+}
+
 /**
  * _gabble_muc_channel_member_presence_updated
  */
@@ -1912,7 +2097,7 @@ _gabble_muc_channel_member_presence_updated (GabbleMucChannel *chan,
   TpIntSet *set;
   TpGroupMixin *mixin;
   LmMessageNode *node;
-  const gchar *affil, *role, *owner_jid, *status_code;
+  const gchar *status_code;
   TpHandleRepoIface *contact_handles;
 
   DEBUG ("called");
@@ -1937,182 +2122,14 @@ _gabble_muc_channel_member_presence_updated (GabbleMucChannel *chan,
       status_code = NULL;
     }
 
-  role = lm_message_node_get_attribute (item_node, "role");
-  affil = lm_message_node_get_attribute (item_node, "affiliation");
-  owner_jid = lm_message_node_get_attribute (item_node, "jid");
-
   /* update channel members according to presence */
   set = tp_intset_new ();
   tp_intset_add (set, handle);
 
   if (lm_message_get_sub_type (message) != LM_MESSAGE_SUB_TYPE_UNAVAILABLE)
     {
-      if (!tp_handle_set_is_member (mixin->members, handle))
-        {
-          TpHandle owner_handle = 0;
-
-          if (owner_jid != NULL)
-            {
-              owner_handle = tp_handle_ensure (contact_handles, owner_jid,
-                  GUINT_TO_POINTER (GABBLE_JID_GLOBAL), NULL);
-
-              if (owner_handle == 0)
-                DEBUG ("Invalid owner handle '%s', treating as no owner",
-                    owner_jid);
-            }
-
-          if (handle == mixin->self_handle &&
-              owner_handle != conn->self_handle)
-            {
-              /* We know that in XEP-0045 compliant MUCs, nobody else can have
-               * the nick we tried to use - the service MUST reject us
-               * with code 409/"conflict" in this case. So, if someone in the
-               * room has the nick we want, it's us.
-               *
-               * If the MUC service fails to comply with this requirement,
-               * we get hopelessly confused, but this isn't a regression
-               * (we always would have done).
-               *
-               * FIXME: we ought to respect the 110 and 210 status codes
-               * too, so we can detect MUCs renaming us - otherwise the
-               * presence aggregator will never stop
-               */
-              DEBUG ("Overriding ownership of channel-specific handle %u "
-                  "from %u to %u because I know it's mine",
-                  mixin->self_handle, owner_handle, conn->self_handle);
-
-              if (owner_handle != 0)
-                tp_handle_unref (contact_handles, owner_handle);
-
-              tp_handle_ref (contact_handles, conn->self_handle);
-              owner_handle = conn->self_handle;
-            }
-
-          if (priv->initial_state_aggregator == NULL)
-            {
-              /* we've already had the initial batch of presence stanzas */
-              tp_group_mixin_add_handle_owner ((GObject *) chan, handle,
-                  owner_handle);
-              tp_group_mixin_change_members ((GObject *) chan, "", set, NULL,
-                                              NULL, NULL, 0, 0);
-            }
-          else
-            {
-              /* aggregate this presence */
-              tp_handle_set_add (priv->initial_state_aggregator->members,
-                  handle);
-
-              g_hash_table_insert (priv->initial_state_aggregator->owner_map,
-                  GUINT_TO_POINTER (handle), GUINT_TO_POINTER (owner_handle));
-
-              if (owner_handle != 0)
-                tp_handle_set_add (priv->initial_state_aggregator->owners,
-                    owner_handle);
-
-              /* Do not emit one signal per presence. Instead, get all
-               * presences, and add them in priv->initial_state_aggregator.
-               * When we get the last presence, emit the signal. The last
-               * presence is ourselves. */
-              if (handle == mixin->self_handle)
-                {
-                  /* Add all handle owners in a single operation */
-                  tp_group_mixin_add_handle_owners ((GObject *) chan,
-                      priv->initial_state_aggregator->owner_map);
-
-                  /* Change all presences in a single operation */
-                  tp_group_mixin_change_members ((GObject *) chan, "",
-                      tp_handle_set_peek (
-                          priv->initial_state_aggregator->members),
-                      NULL, NULL, NULL, 0, 0);
-
-                  initial_state_aggregator_free (
-                      priv->initial_state_aggregator);
-                  priv->initial_state_aggregator = NULL;
-                }
-            }
-
-          if (owner_handle != 0)
-            {
-              if (handle != mixin->self_handle)
-                {
-                  /* If at least one other handle in the channel has an owner,
-                   * the HANDLE_OWNERS_NOT_AVAILABLE flag should be removed.
-                   */
-                  tp_group_mixin_change_flags ((GObject *) chan, 0,
-                      TP_CHANNEL_GROUP_FLAG_HANDLE_OWNERS_NOT_AVAILABLE);
-                }
-
-              g_signal_emit (chan, signals[CONTACT_JOIN], 0, owner_handle);
-
-              tp_handle_unref (contact_handles, owner_handle);
-            }
-
-          if (handle == mixin->self_handle)
-            {
-              g_object_set (chan, "state", MUC_STATE_JOINED, NULL);
-            }
-        }
-
-      if (handle == mixin->self_handle)
-        {
-          GabbleMucRole new_role;
-          GabbleMucAffiliation new_affil;
-
-          /* accept newly-created room settings before we send anything
-           * below which queryies them. */
-          if (status_code && strcmp (status_code, "201") == 0)
-            {
-              LmMessage *msg;
-              GError *error = NULL;
-
-              msg = lm_message_new_with_sub_type (priv->jid,
-                  LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
-
-              node = lm_message_node_add_child (msg->node, "query", NULL);
-              lm_message_node_set_attribute (node, "xmlns", NS_MUC_OWNER);
-
-              node = lm_message_node_add_child (node, "x", NULL);
-              lm_message_node_set_attributes (node,
-                                              "xmlns", NS_X_DATA,
-                                              "type", "submit",
-                                              NULL);
-
-              if (!_gabble_connection_send_with_reply (priv->conn, msg,
-                    room_created_submit_reply_cb, G_OBJECT (chan), NULL,
-                    &error))
-                {
-                  DEBUG ("failed to send submit message: %s",
-                      error->message);
-                  g_error_free (error);
-
-                  lm_message_unref (msg);
-                  close_channel (chan, NULL, TRUE, 0,
-                      TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
-
-                  goto OUT;
-                }
-
-              lm_message_unref (msg);
-            }
-
-          /* Update room properties */
-          room_properties_update (chan);
-
-          /* update permissions after requesting new properties so that if we
-           * become an owner, we get our configuration form reply after the
-           * discovery reply, so we know whether there is a description
-           * property before we try and decide whether we can write to it. */
-          new_role = get_role_from_string (role);
-          new_affil = get_affiliation_from_string (affil);
-
-          if (new_role != priv->self_role || new_affil != priv->self_affil)
-            {
-              priv->self_role = new_role;
-              priv->self_affil = new_affil;
-
-              update_permissions (chan);
-            }
-        }
+      handle_presence_update (chan, contact_handles, handle, set, item_node,
+          status_code);
     }
   else
     {
@@ -2120,7 +2137,6 @@ _gabble_muc_channel_member_presence_updated (GabbleMucChannel *chan,
           set, item_node, status_code);
     }
 
-OUT:
   tp_intset_destroy (set);
 }
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list