/pidgin/main: a351cbf422ed: Backport 68d162284480: facebook rost...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Wed May 7 10:22:35 EDT 2014
Changeset: a351cbf422ed20bbde373ccb9beb5337c4bfa421
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-05-07 16:22 +0200
Branch: release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/a351cbf422ed
Description:
Backport 68d162284480: facebook roster quirks
diffstat:
libpurple/protocols/jabber/Makefile.am | 2 +
libpurple/protocols/jabber/facebook_roster.c | 131 +++++++++++++++++++++++++++
libpurple/protocols/jabber/facebook_roster.h | 35 +++++++
libpurple/protocols/jabber/jabber.c | 6 +
libpurple/protocols/jabber/jabber.h | 2 +
libpurple/protocols/jabber/roster.c | 8 +
6 files changed, 184 insertions(+), 0 deletions(-)
diffs (246 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,131 @@
+/**
+ * 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"
+
+#include "internal.h"
+
+void
+jabber_facebook_roster_cleanup(JabberStream *js, xmlnode *query)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ xmlnode *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_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 = xmlnode_get_child(query, "item"); item;
+ item = xmlnode_get_next_twin(item))
+ {
+ jid = 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_buddy_alias(buddy);
+ item = xmlnode_new_child(query, "item");
+ xmlnode_set_namespace(item, xmlnode_get_namespace(query));
+ xmlnode_set_attrib(item, "jid", jid);
+ xmlnode_set_attrib(item, "subscription", "remove");
+ if (alias)
+ xmlnode_set_attrib(item, "name", alias);
+ }
+
+ g_hash_table_destroy(remove_buddies);
+}
+
+gboolean
+jabber_facebook_roster_incoming(JabberStream *js, xmlnode *item)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ const gchar *jid, *subscription;
+ gchar *jid_norm;
+ PurpleBuddy *buddy;
+ PurpleGroup *buddy_group;
+ xmlnode *group;
+ const gchar *alias;
+
+ subscription = xmlnode_get_attrib(item, "subscription");
+
+ /* Skip entries added with jabber_facebook_roster_cleanup */
+ if (g_strcmp0(subscription, "remove") == 0)
+ return TRUE;
+
+ jid = xmlnode_get_attrib(item, "jid");
+ jid_norm = g_strdup(jabber_normalize(account, jid));
+ buddy = purple_find_buddy(account, jid);
+ g_free(jid_norm);
+
+ /* Facebook forces "Facebook Friends" group */
+ while ((group = xmlnode_get_child(item, "group")) != NULL)
+ xmlnode_free(group);
+ group = xmlnode_new_child(item, "group");
+ xmlnode_set_namespace(group, xmlnode_get_namespace(item));
+
+ /* We don't have that buddy on the list, add him to the default group */
+ if (!buddy) {
+ xmlnode_insert_data(group,
+ JABBER_ROSTER_DEFAULT_GROUP, -1);
+ return TRUE;
+ }
+
+ /* Facebook forces buddy real name as alias */
+ alias = purple_buddy_get_local_buddy_alias(buddy);
+ if (alias)
+ xmlnode_set_attrib(item, "name", alias);
+
+ /* Add buddy to his group */
+ buddy_group = purple_buddy_get_group(buddy);
+ if (g_strcmp0(purple_group_get_name(buddy_group), _("Buddies")) == 0)
+ buddy_group = NULL;
+ if (buddy_group) {
+ xmlnode_insert_data(group,
+ purple_group_get_name(buddy_group), -1);
+ } else {
+ 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, xmlnode *query);
+
+/* ignores facebook roster quirks */
+gboolean
+jabber_facebook_roster_incoming(JabberStream *js, xmlnode *item);
+
+#endif /* PURPLE_XMPP_FACEBOOK_ROSTER_H_ */
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -934,6 +934,12 @@ jabber_stream_new(PurpleAccount *account
js->gc = gc;
js->fd = -1;
+ if (g_strcmp0("prpl-facebook-xmpp",
+ purple_account_get_protocol_id(account)) == 0)
+ {
+ js->server_caps |= JABBER_CAP_FACEBOOK;
+ }
+
user = g_strdup(purple_account_get_username(account));
/* jabber_id_new doesn't accept "user at domain/" as valid */
slash = strchr(user, '/');
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/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"
@@ -211,11 +212,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 = xmlnode_get_child(query, "item"); item; item = 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 = xmlnode_get_attrib(item, "subscription");
jid = xmlnode_get_attrib(item, "jid");
name = xmlnode_get_attrib(item, "name");
More information about the Commits
mailing list