/soc/2015/jgeboski/facebook: 5ba291680ac4: facebook: compare che...

James Geboski jgeboski at gmail.com
Sat Jun 6 02:19:51 EDT 2015


Changeset: 5ba291680ac4ff9b996d7ab75254519a5f35cfc8
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-06-06 02:13 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/5ba291680ac4

Description:

facebook: compare checksums before fetching icons

diffstat:

 libpurple/protocols/facebook/api.c      |   27 +++-
 libpurple/protocols/facebook/api.h      |    1 +
 libpurple/protocols/facebook/facebook.c |   22 ++-
 libpurple/protocols/facebook/http.c     |  227 +++++++++++++++++++++++++++++++-
 libpurple/protocols/facebook/http.h     |   45 ++++++
 5 files changed, 311 insertions(+), 11 deletions(-)

diffs (truncated from 500 to 300 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -965,12 +965,20 @@ fb_api_auth(FbApi *api, const gchar *use
 }
 
 static void
+fb_api_cb_contacts_free(FbApiUser *user)
+{
+	g_free(user->csum);
+	g_free(user);
+}
+
+static void
 fb_api_cb_contacts(PurpleHttpConnection *con, PurpleHttpResponse *res,
                    gpointer data)
 {
 	const gchar *str;
 	FbApi *api = data;
 	FbApiUser user;
+	FbHttpParams *params;
 	GError *err = NULL;
 	GList *elms = NULL;
 	GList *l;
@@ -987,12 +995,23 @@ fb_api_cb_contacts(PurpleHttpConnection 
 		return;
 	}
 
+	params = fb_http_params_new_parse("http://www.google.com/index.php?text=hello%20world#world", TRUE);
+	fb_http_params_free(params);
+
+	params = fb_http_params_new_parse("http://www.google.com/?text=hi", TRUE);
+	fb_http_params_free(params);
+
+	params = fb_http_params_new_parse("text=hello%20world", FALSE);
+	fb_http_params_free(params);
+
 	arr = fb_json_node_get_arr(root, expr, &err);
 	FB_API_ERROR_CHK(api, err, goto finish);
 	elms = json_array_get_elements(arr);
 
 	for (l = elms; l != NULL; l = l->next) {
 		node = l->data;
+		memset(&user, 0, sizeof user);
+
 		str = fb_json_node_get_str(node, "$.represented_profile.id",
 		                           &err);
 		FB_API_ERROR_CHK(api, err, goto finish);
@@ -1008,6 +1027,12 @@ fb_api_cb_contacts(PurpleHttpConnection 
 		FB_API_ERROR_CHK(api, err, goto finish);
 		user.icon = str;
 
+		params = fb_http_params_new_parse(user.icon, TRUE);
+		str = fb_http_params_get_str(params, "oh", &err);
+		user.csum = g_strdup(str);
+		fb_http_params_free(params);
+		FB_API_ERROR_CHK(api, err, goto finish);
+
 		mptr = g_memdup(&user, sizeof user);
 		users = g_slist_prepend(users, mptr);
 	}
@@ -1016,7 +1041,7 @@ fb_api_cb_contacts(PurpleHttpConnection 
 
 finish:
 	g_list_free(elms);
-	g_slist_free_full(users, g_free);
+	g_slist_free_full(users, (GDestroyNotify) fb_api_cb_contacts_free);
 	json_node_free(root);
 }
 
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
@@ -129,6 +129,7 @@ struct _FbApiUser
 	FbId uid;
 	const gchar *name;
 	const gchar *icon;
+	gchar *csum;
 };
 
 struct _FbApiHttpInfo
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
@@ -166,15 +166,18 @@ static void
 fb_cb_icon_fetch(PurpleHttpConnection *con, PurpleHttpResponse *res,
                  gpointer data)
 {
+	const gchar *csum;
 	const gchar *name;
 	const gchar *str;
 	FbApi *api;
+	FbHttpParams *params;
 	GError *err;
 	gsize size;
 	guchar *idata;
 	PurpleAccount *acct;
 	PurpleBuddy *bdy = data;
 	PurpleConnection *gc;
+	PurpleHttpRequest *req;
 
 	acct = purple_buddy_get_account(bdy);
 	gc = purple_account_get_connection(acct);
@@ -186,17 +189,24 @@ fb_cb_icon_fetch(PurpleHttpConnection *c
 		return;
 	}
 
+	req = purple_http_conn_get_request(con);
+	str = purple_http_request_get_url(req);
+	params = fb_http_params_new_parse(str, TRUE);
+	csum = fb_http_params_get_str(params, "oh", &err);
+
 	name = purple_buddy_get_name(bdy);
 	str = purple_http_response_get_data(res, &size);
+	idata = g_memdup(str, size);
 
-	idata = g_memdup(str, size);
-	purple_buddy_icons_set_for_user(acct, name, idata, size, NULL);
+	purple_buddy_icons_set_for_user(acct, name, idata, size, csum);
+	fb_http_params_free(params);
 }
 
 static void
 fb_cb_api_contacts(FbApi *api, GSList *users, gpointer data)
 {
 	const gchar *alias;
+	const gchar *csum;
 	FbApiUser *user;
 	FbId muid;
 	gchar uid[FB_ID_STRMAX];
@@ -234,9 +244,15 @@ fb_cb_api_contacts(FbApi *api, GSList *u
 		if (bdy == NULL) {
 			bdy = purple_buddy_new(acct, uid, user->name);
 			purple_blist_add_buddy(bdy, NULL, grp, NULL);
+			purple_http_get(gc, fb_cb_icon_fetch, bdy, user->icon);
+			continue;
 		}
 
-		purple_http_get(gc, fb_cb_icon_fetch, bdy, user->icon);
+		csum = purple_buddy_icons_get_checksum_for_user(bdy);
+
+		if (!purple_strequal(csum, user->csum)) {
+			purple_http_get(gc, fb_cb_icon_fetch, bdy, user->icon);
+		}
 	}
 
 	purple_connection_update_progress(gc, _("Connecting"), 3, 4);
diff --git a/libpurple/protocols/facebook/http.c b/libpurple/protocols/facebook/http.c
--- a/libpurple/protocols/facebook/http.c
+++ b/libpurple/protocols/facebook/http.c
@@ -19,6 +19,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "internal.h"
+
+#include <string.h>
+
 #include "http.h"
 
 GQuark
@@ -55,6 +59,68 @@ fb_http_params_new(void)
         return g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 }
 
+FbHttpParams *
+fb_http_params_new_parse(const gchar *data, gboolean isurl)
+{
+	const gchar *tail;
+	gchar *key;
+	gchar **ps;
+	gchar *val;
+	guint i;
+	FbHttpParams *params;
+
+	params = fb_http_params_new();
+
+	if (data == NULL) {
+		return params;
+	}
+
+	if (isurl) {
+		data = strchr(data, '?');
+
+		if (data++ == NULL) {
+			return params;
+		}
+
+		tail = strchr(data, '#');
+
+		if (tail != NULL) {
+			data = g_strndup(data, tail - data);
+		} else {
+			data = g_strdup(data);
+		}
+	}
+
+	ps = g_strsplit(data, "&", 0);
+
+	for (i = 0; ps[i] != NULL; i++) {
+		key = ps[i];
+		val = strchr(ps[i], '=');
+
+		if (val == NULL) {
+			continue;
+		}
+
+		*(val++) = 0;
+		key = g_uri_unescape_string(key, NULL);
+		val = g_uri_unescape_string(val, NULL);
+		g_hash_table_replace(params, key, val);
+	}
+
+	if (isurl) {
+		g_free((gchar*) data);
+	}
+
+	g_strfreev(ps);
+	return params;
+}
+
+void
+fb_http_params_free(FbHttpParams *params)
+{
+	g_hash_table_destroy(params);
+}
+
 gchar *
 fb_http_params_close(FbHttpParams *params, gsize *size)
 {
@@ -85,12 +151,159 @@ fb_http_params_close(FbHttpParams *param
 		*size = ret->len;
 	}
 
-	g_hash_table_destroy(params);
+	fb_http_params_free(params);
 	return g_string_free(ret, FALSE);
 }
 
+static const gchar *
+fb_http_params_get(FbHttpParams *params, const gchar *name, GError **error)
+{
+	const gchar *ret;
+
+	ret = g_hash_table_lookup(params, name);
+
+	if (ret == NULL) {
+		g_set_error(error, FB_HTTP_ERROR, FB_HTTP_ERROR_NOMATCH,
+		            _("No matches for %s"), name);
+		return NULL;
+	}
+
+	return ret;
+}
+
+gboolean
+fb_http_params_get_bool(FbHttpParams *params, const gchar *name,
+                        GError **error)
+{
+	const gchar *val;
+
+	val = fb_http_params_get(params, name, error);
+
+	if (val == NULL) {
+		return FALSE;
+	}
+
+	return g_ascii_strcasecmp(val, "TRUE") == 0;
+}
+
+gdouble
+fb_http_params_get_dbl(FbHttpParams *params, const gchar *name,
+                       GError **error)
+{
+	const gchar *val;
+
+	val = fb_http_params_get(params, name, error);
+
+	if (val == NULL) {
+		return 0.0;
+	}
+
+	return g_ascii_strtod(val, NULL);
+}
+
+gint64
+fb_http_params_get_int(FbHttpParams *params, const gchar *name,
+                       GError **error)
+{
+	const gchar *val;
+
+	val = fb_http_params_get(params, name, error);
+
+	if (val == NULL) {
+		return 0;
+	}
+
+	return g_ascii_strtoll(val, NULL, 10);
+}
+



More information about the Commits mailing list