/soc/2015/jgeboski/facebook: acae53caaff0: facebook: periodicall...

James Geboski jgeboski at gmail.com
Wed Aug 12 18:55:49 EDT 2015


Changeset: acae53caaff0dc1e7eb92420c038662cc522c518
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-12 18:55 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/acae53caaff0

Description:

facebook: periodically refetch the contact list for updates

diffstat:

 libpurple/protocols/facebook/api.h      |   2 +-
 libpurple/protocols/facebook/data.c     |  38 +++++++++++++++
 libpurple/protocols/facebook/data.h     |   7 ++
 libpurple/protocols/facebook/facebook.c |  80 ++++++++++++++++++++++++++++++--
 4 files changed, 120 insertions(+), 7 deletions(-)

diffs (255 lines):

diff --git a/libpurple/protocols/facebook/api.h b/libpurple/protocols/facebook/api.h
--- a/libpurple/protocols/facebook/api.h
+++ b/libpurple/protocols/facebook/api.h
@@ -39,7 +39,7 @@
 #define FB_API_KEY     "256002347743983"
 #define FB_API_SECRET  "374e60f8b9bb6b8cbb30f78030438895"
 
-#define FB_API_CONTACTS_COUNT  200
+#define FB_API_CONTACTS_COUNT  500
 
 #define FB_API_URL_AUTH     FB_API_BHOST "/method/auth.login"
 #define FB_API_URL_GQL      FB_API_GHOST "/graphql"
diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c
--- a/libpurple/protocols/facebook/data.c
+++ b/libpurple/protocols/facebook/data.c
@@ -35,6 +35,7 @@ struct _FbDataPrivate
 	GQueue *msgs;
 	GHashTable *icons;
 	GHashTable *icona;
+	guint syncev;
 };
 
 static const gchar *fb_props_strs[] = {
@@ -54,6 +55,10 @@ fb_data_dispose(GObject *obj)
 {
 	FbDataPrivate *priv = FB_DATA(obj)->priv;
 
+	if (priv->syncev > 0) {
+		purple_timeout_remove(priv->syncev);
+	}
+
 	if (G_LIKELY(priv->api != NULL)) {
 		g_object_unref(priv->api);
 	}
@@ -205,6 +210,39 @@ fb_data_save(FbData *fata)
 	g_free(dup);
 }
 
+void
+fb_data_add_sync_timeout(FbData *fata, guint minutes, GSourceFunc func,
+                         gpointer data)
+{
+	FbDataPrivate *priv;
+
+	g_return_if_fail(FB_IS_DATA(fata));
+	priv = fata->priv;
+
+	if (priv->syncev > 0) {
+		purple_timeout_remove(priv->syncev);
+	}
+
+	minutes *= 60;
+	priv->syncev = purple_timeout_add_seconds(minutes, func, data);
+}
+
+void
+fb_data_clear_sync_timeout(FbData *fata, gboolean remove)
+{
+	FbDataPrivate *priv;
+
+	g_return_if_fail(FB_IS_DATA(fata));
+	priv = fata->priv;
+	g_return_if_fail(priv->syncev > 0);
+
+	if (remove) {
+		purple_timeout_remove(priv->syncev);
+	}
+
+	priv->syncev = 0;
+}
+
 FbApi *
 fb_data_get_api(FbData *fata)
 {
diff --git a/libpurple/protocols/facebook/data.h b/libpurple/protocols/facebook/data.h
--- a/libpurple/protocols/facebook/data.h
+++ b/libpurple/protocols/facebook/data.h
@@ -78,6 +78,13 @@ fb_data_load(FbData *fata);
 void
 fb_data_save(FbData *fata);
 
+void
+fb_data_add_sync_timeout(FbData *fata, guint minutes, GSourceFunc func,
+                         gpointer data);
+
+void
+fb_data_clear_sync_timeout(FbData *fata, gboolean remove);
+
 FbApi *
 fb_data_get_api(FbData *fata);
 
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -59,15 +59,17 @@ static PurpleProtocol *fb_protocol = NUL
 static void
 fb_cb_api_messages(FbApi *api, GSList *msgs, gpointer data);
 
-static void
-fb_buddy_add_nonfriend(PurpleAccount *acct, FbApiUser *user)
+static PurpleGroup *
+fb_get_group(gboolean friend)
 {
-	gchar uid[FB_ID_STRMAX];
 	PurpleBlistNode *n;
 	PurpleBlistNode *node;
-	PurpleBuddy *bdy;
 	PurpleGroup *grp;
 
+	if (friend) {
+		return purple_blist_get_default_group();
+	}
+
 	grp = purple_blist_find_group(_("Facebook Non-Friends"));
 
 	if (G_UNLIKELY(grp == NULL)) {
@@ -86,8 +88,20 @@ fb_buddy_add_nonfriend(PurpleAccount *ac
 		purple_blist_node_set_bool(node, "collapsed", TRUE);
 	}
 
+	return grp;
+}
+
+static void
+fb_buddy_add_nonfriend(PurpleAccount *acct, FbApiUser *user)
+{
+	gchar uid[FB_ID_STRMAX];
+	PurpleBlistNode *node;
+	PurpleBuddy *bdy;
+	PurpleGroup *grp;
+
 	FB_ID_TO_STR(user->uid, uid);
 	bdy = purple_buddy_new(acct, uid, NULL);
+	grp = fb_get_group(FALSE);
 	node = PURPLE_BLIST_NODE(bdy);
 
 	purple_blist_node_set_transient(node, TRUE);
@@ -187,6 +201,18 @@ fb_cb_api_contact(FbApi *api, FbApiUser 
 	}
 }
 
+static gboolean
+fb_cb_sync_contacts(gpointer data)
+{
+	FbApi *api;
+	FbData *fata = data;
+
+	api = fb_data_get_api(fata);
+	fb_data_clear_sync_timeout(fata, FALSE);
+	fb_api_contacts(api);
+	return FALSE;
+}
+
 static void
 fb_cb_api_contacts(FbApi *api, GSList *users, gboolean complete, gpointer data)
 {
@@ -196,6 +222,9 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 	FbData *fata = data;
 	FbId muid;
 	gchar uid[FB_ID_STRMAX];
+	gint sync;
+	gpointer bata;
+	GSList *buddies;
 	GSList *l;
 	GValue val = G_VALUE_INIT;
 	PurpleAccount *acct;
@@ -203,13 +232,15 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 	PurpleConnection *gc;
 	PurpleConnectionState state;
 	PurpleGroup *grp;
+	PurpleGroup *grpn;
 	PurpleStatus *status;
 	PurpleStatusPrimitive pstat;
 	PurpleStatusType *type;
 
 	gc = fb_data_get_connection(fata);
 	acct = purple_connection_get_account(gc);
-	grp = purple_blist_get_default_group();
+	grp = fb_get_group(TRUE);
+	grpn = fb_get_group(FALSE);
 	alias = purple_account_get_private_alias(acct);
 	state = purple_connection_get_state(gc);
 
@@ -233,11 +264,17 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 
 		bdy = purple_blist_find_buddy(acct, uid);
 
+		if (purple_buddy_get_group(bdy) == grpn) {
+			purple_blist_remove_buddy(bdy);
+			bdy = NULL;
+		}
+
 		if (bdy == NULL) {
 			bdy = purple_buddy_new(acct, uid, NULL);
 			purple_blist_add_buddy(bdy, NULL, grp, NULL);
 		}
 
+		purple_buddy_set_protocol_data(bdy, GINT_TO_POINTER(TRUE));
 		purple_buddy_set_server_alias(bdy, user->name);
 		csum = purple_buddy_icons_get_checksum_for_user(bdy);
 
@@ -249,7 +286,25 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 
 	fb_data_icon_queue(fata);
 
-	if (complete && (state != PURPLE_CONNECTION_CONNECTED)) {
+	if (!complete) {
+		return;
+	}
+
+	buddies = purple_blist_find_buddies(acct, NULL);
+
+	while (buddies != NULL) {
+		bdy = buddies->data;
+		bata = purple_buddy_get_protocol_data(bdy);
+		buddies = g_slist_delete_link(buddies, buddies);
+
+		if (GPOINTER_TO_INT(bata)) {
+			purple_buddy_set_protocol_data(bdy, NULL);
+		} else if (purple_buddy_get_group(bdy) != grpn) {
+			purple_blist_remove_buddy(bdy);
+		}
+	}
+
+	if (state != PURPLE_CONNECTION_CONNECTED) {
 		status = purple_account_get_active_status(acct);
 		type = purple_status_get_status_type(status);
 		pstat = purple_status_type_get_primitive(type);
@@ -257,6 +312,15 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 		purple_connection_update_progress(gc, _("Connecting"), 3, 4);
 		fb_api_connect(api, pstat == PURPLE_STATUS_INVISIBLE);
 	}
+
+	sync = purple_account_get_int(acct, "sync-interval", 30);
+
+	if (sync < 5) {
+		purple_account_set_int(acct, "sync-interval", 5);
+		sync = 5;
+	}
+
+	fb_data_add_sync_timeout(fata, sync, fb_cb_sync_contacts, fata);
 }
 
 static void
@@ -1171,6 +1235,10 @@ facebook_protocol_init(PurpleProtocol *p
 	protocol->name    = "Facebook";
 	protocol->options = OPT_PROTO_CHAT_TOPIC;
 
+	opt = purple_account_option_int_new(_("Buddy list sync interval"),
+	                                    "sync-interval", 30);
+	opts = g_list_prepend(opts, opt);
+
 	opt = purple_account_option_bool_new(_("Mark messages as read"),
 	                                     "mark-read", TRUE);
 	opts = g_list_prepend(opts, opt);



More information about the Commits mailing list