/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