/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