/soc/2015/jgeboski/facebook: 5ba291680ac4: facebook: compare che...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 5ba291680ac4ff9b996d7ab75254519a5f35cfc8 Author: James Geboski <[email protected]> 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); +} +