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

James Geboski <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: acae53caaff0dc1e7eb92420c038662cc522c518
Author:	 James Geboski <[email protected]>
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);

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.