/pidgin/main: 68d162284480: XMPP: adjust facebook roster quirks
Tomasz Wasilczyk
twasilczyk at pidgin.im
Wed May 7 09:54:56 EDT 2014
Changeset: 68d162284480d3158697c68f3021dbd242dd19f6
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-05-07 15:54 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/68d162284480
Description:
XMPP: adjust facebook roster quirks
diffstat:
libpurple/protocols/jabber/Makefile.am | 2 +
libpurple/protocols/jabber/facebook_roster.c | 130 +++++++++++++++++++++++++++
libpurple/protocols/jabber/facebook_roster.h | 35 +++++++
libpurple/protocols/jabber/jabber.h | 2 +
libpurple/protocols/jabber/libfacebook.c | 19 +++-
libpurple/protocols/jabber/roster.c | 8 +
6 files changed, 195 insertions(+), 1 deletions(-)
diffs (265 lines):
diff --git a/libpurple/protocols/jabber/Makefile.am b/libpurple/protocols/jabber/Makefile.am
--- a/libpurple/protocols/jabber/Makefile.am
+++ b/libpurple/protocols/jabber/Makefile.am
@@ -27,6 +27,8 @@ JABBERSOURCES = \
data.h \
disco.c \
disco.h \
+ facebook_roster.c \
+ facebook_roster.h \
google/gmail.c \
google/gmail.h \
google/google.c \
diff --git a/libpurple/protocols/jabber/facebook_roster.c b/libpurple/protocols/jabber/facebook_roster.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/jabber/facebook_roster.c
@@ -0,0 +1,130 @@
+/**
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "facebook_roster.h"
+
+#include "roster.h"
+
+void
+jabber_facebook_roster_cleanup(JabberStream *js, PurpleXmlNode *query)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ PurpleXmlNode *item;
+ GSList *local_buddies;
+ GHashTable *remove_buddies;
+ GHashTableIter it;
+ PurpleBuddy *buddy;
+ const gchar *jid;
+
+ /* mark all local buddies as "to be removed" */
+ remove_buddies = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+ local_buddies = purple_blist_find_buddies(account, NULL);
+ for (; local_buddies; local_buddies = g_slist_delete_link(
+ local_buddies, local_buddies))
+ {
+ buddy = local_buddies->data;
+
+ g_hash_table_insert(remove_buddies, g_strdup(jabber_normalize(
+ account, purple_buddy_get_name(buddy))), buddy);
+ }
+
+ /* un-mark all remote buddies */
+ for (item = purple_xmlnode_get_child(query, "item"); item;
+ item = purple_xmlnode_get_next_twin(item))
+ {
+ jid = purple_xmlnode_get_attrib(item, "jid");
+
+ g_hash_table_remove(remove_buddies,
+ jabber_normalize(account, jid));
+ }
+
+ /* remove all not-remote buddies */
+ g_hash_table_iter_init(&it, remove_buddies);
+ while (g_hash_table_iter_next(&it, (gpointer*)&jid, (gpointer*)&buddy)) {
+ const gchar *alias = purple_buddy_get_local_alias(buddy);
+ item = purple_xmlnode_new_child(query, "item");
+ purple_xmlnode_set_namespace(item,
+ purple_xmlnode_get_namespace(query));
+ purple_xmlnode_set_attrib(item, "jid", jid);
+ purple_xmlnode_set_attrib(item, "subscription", "remove");
+ if (alias)
+ purple_xmlnode_set_attrib(item, "name", alias);
+ }
+
+ g_hash_table_destroy(remove_buddies);
+}
+
+gboolean
+jabber_facebook_roster_incoming(JabberStream *js, PurpleXmlNode *item)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ const gchar *jid, *subscription;
+ gchar *jid_norm;
+ PurpleBuddy *buddy;
+ PurpleGroup *buddy_group;
+ PurpleXmlNode *group;
+ const gchar *alias;
+
+ subscription = purple_xmlnode_get_attrib(item, "subscription");
+
+ /* Skip entries added with jabber_facebook_roster_cleanup */
+ if (g_strcmp0(subscription, "remove") == 0)
+ return TRUE;
+
+ jid = purple_xmlnode_get_attrib(item, "jid");
+ jid_norm = g_strdup(jabber_normalize(account, jid));
+ buddy = purple_blist_find_buddy(account, jid);
+ g_free(jid_norm);
+
+ /* Facebook forces "Facebook Friends" group */
+ while ((group = purple_xmlnode_get_child(item, "group")) != NULL)
+ purple_xmlnode_free(group);
+ group = purple_xmlnode_new_child(item, "group");
+ purple_xmlnode_set_namespace(group, purple_xmlnode_get_namespace(item));
+
+ /* We don't have that buddy on the list, add him to the default group */
+ if (!buddy) {
+ purple_xmlnode_insert_data(group,
+ JABBER_ROSTER_DEFAULT_GROUP, -1);
+ return TRUE;
+ }
+
+ /* Facebook forces buddy real name as alias */
+ alias = purple_buddy_get_local_alias(buddy);
+ if (alias)
+ purple_xmlnode_set_attrib(item, "name", alias);
+
+ /* Add buddy to his group */
+ buddy_group = purple_buddy_get_group(buddy);
+ if (buddy_group == purple_blist_get_default_group())
+ buddy_group = NULL;
+ if (buddy_group) {
+ purple_xmlnode_insert_data(group,
+ purple_group_get_name(buddy_group), -1);
+ } else {
+ purple_xmlnode_insert_data(group,
+ JABBER_ROSTER_DEFAULT_GROUP, -1);
+ }
+
+ return TRUE;
+}
diff --git a/libpurple/protocols/jabber/facebook_roster.h b/libpurple/protocols/jabber/facebook_roster.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/jabber/facebook_roster.h
@@ -0,0 +1,35 @@
+/**
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+#ifndef PURPLE_XMPP_FACEBOOK_ROSTER_H_
+#define PURPLE_XMPP_FACEBOOK_ROSTER_H_
+
+#include "jabber.h"
+
+/* removes deleted buddies from the list */
+void
+jabber_facebook_roster_cleanup(JabberStream *js, PurpleXmlNode *query);
+
+/* ignores facebook roster quirks */
+gboolean
+jabber_facebook_roster_incoming(JabberStream *js, PurpleXmlNode *item);
+
+#endif /* PURPLE_XMPP_FACEBOOK_ROSTER_H_ */
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -49,6 +49,8 @@ typedef enum {
JABBER_CAP_ITEMS = 1 << 14,
JABBER_CAP_ROSTER_VERSIONING = 1 << 15,
+ JABBER_CAP_FACEBOOK = 1 << 16,
+
JABBER_CAP_RETRIEVED = 1 << 31
} JabberCapabilities;
diff --git a/libpurple/protocols/jabber/libfacebook.c b/libpurple/protocols/jabber/libfacebook.c
--- a/libpurple/protocols/jabber/libfacebook.c
+++ b/libpurple/protocols/jabber/libfacebook.c
@@ -55,6 +55,23 @@ facebook_list_icon(PurpleAccount *a, Pur
return "facebook";
}
+static void
+facebook_login(PurpleAccount *account)
+{
+ PurpleConnection *gc;
+ JabberStream *js;
+
+ jabber_login(account);
+
+ gc = purple_account_get_connection(account);
+ js = purple_connection_get_protocol_data(gc);
+
+ if (!js)
+ return;
+
+ js->server_caps |= JABBER_CAP_FACEBOOK;
+}
+
static PurplePlugin *my_protocol = NULL;
static PurplePluginProtocolInfo prpl_info =
@@ -76,7 +93,7 @@ static PurplePluginProtocolInfo prpl_inf
jabber_blist_node_menu, /* blist_node_menu */
jabber_chat_info, /* chat_info */
jabber_chat_info_defaults, /* chat_info_defaults */
- jabber_login, /* login */
+ facebook_login, /* login */
jabber_close, /* close */
jabber_message_send_im, /* send_im */
jabber_set_info, /* set_info */
diff --git a/libpurple/protocols/jabber/roster.c b/libpurple/protocols/jabber/roster.c
--- a/libpurple/protocols/jabber/roster.c
+++ b/libpurple/protocols/jabber/roster.c
@@ -27,6 +27,7 @@
#include "buddy.h"
#include "chat.h"
+#include "facebook_roster.h"
#include "google/google.h"
#include "google/google_roster.h"
#include "presence.h"
@@ -215,11 +216,18 @@ void jabber_roster_parse(JabberStream *j
js->currently_parsing_roster_push = TRUE;
+ if (js->server_caps & JABBER_CAP_FACEBOOK)
+ jabber_facebook_roster_cleanup(js, query);
+
for(item = purple_xmlnode_get_child(query, "item"); item; item = purple_xmlnode_get_next_twin(item))
{
const char *jid, *name, *subscription, *ask;
JabberBuddy *jb;
+ if (js->server_caps & JABBER_CAP_FACEBOOK)
+ if (!jabber_facebook_roster_incoming(js, item))
+ continue;
+
subscription = purple_xmlnode_get_attrib(item, "subscription");
jid = purple_xmlnode_get_attrib(item, "jid");
name = purple_xmlnode_get_attrib(item, "name");
More information about the Commits
mailing list