cpw.darkrain42.xmpp.avatars: d70cdd1f: Only (re)publish XMPP avatars at login i...
paul at darkrain42.org
paul at darkrain42.org
Fri Jan 23 22:28:23 EST 2009
-----------------------------------------------------------------
Revision: d70cdd1fd161f70a868170d8a72eadfbecfc966c
Ancestor: fd812d7a888de06f4277dce064bfc552b7e9069a
Author: paul at darkrain42.org
Date: 2009-01-21T20:16:22
Branch: im.pidgin.cpw.darkrain42.xmpp.avatars
URL: http://d.pidgin.im/viewmtn/revision/info/d70cdd1fd161f70a868170d8a72eadfbecfc966c
Modified files:
libpurple/protocols/jabber/buddy.c
libpurple/protocols/jabber/disco.c
libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/useravatar.c
libpurple/protocols/jabber/useravatar.h
ChangeLog:
Only (re)publish XMPP avatars at login if the server's avatar differs
As part of this, no longer rely on the vcard for determining a need to
publish the XEP-0084 avatar; explicitly fetch and compare it.
Closes #7734.
References #7732. That patch needs updating to apply on top of this.
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/buddy.c bfb50b6e9b69360d541061f6c9c9be615dbd6167
+++ libpurple/protocols/jabber/buddy.c 8035cd1a1fe864b3e7ac970164fb60d44ae5df30
@@ -472,7 +472,6 @@ void jabber_set_info(PurpleConnection *g
enc = purple_base64_encode(avatar_data, avatar_len);
js->avatar_hash = jabber_calculate_data_sha1sum(avatar_data, avatar_len);
-
xmlnode_insert_data(binval, enc, -1);
g_free(enc);
} else if (vc_node) {
@@ -494,7 +493,7 @@ void jabber_set_buddy_icon(PurpleConnect
{
PurplePresence *gpresence;
PurpleStatus *status;
-
+
jabber_avatar_set(gc->proto_data, img);
/* vCard avatars do not have an image type requirement so update our
* vCard avatar regardless of image type for those poor older clients
@@ -1046,9 +1045,9 @@ static void jabber_vcard_save_mine(Jabbe
static void jabber_vcard_save_mine(JabberStream *js, xmlnode *packet, gpointer data)
{
- xmlnode *vcard;
- char *txt;
- PurpleStoredImage *img;
+ xmlnode *vcard, *photo, *binval;
+ char *txt, *vcard_hash = NULL;
+ const char *current_hash;
if((vcard = xmlnode_get_child(packet, "vCard")) ||
(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp")))
@@ -1063,10 +1062,33 @@ static void jabber_vcard_save_mine(Jabbe
js->vcard_fetched = TRUE;
- if(NULL != (img = purple_buddy_icons_find_account_icon(js->gc->account))) {
- jabber_set_buddy_icon(js->gc, img);
- purple_imgstore_unref(img);
+ if (vcard && (photo = xmlnode_get_child(vcard, "PHOTO")) &&
+ (binval = xmlnode_get_child(photo, "BINVAL"))) {
+ gsize size;
+ char *bintext = xmlnode_get_data(binval);
+ guchar *data = purple_base64_decode(bintext, &size);
+ g_free(bintext);
+
+ if (data) {
+ vcard_hash = jabber_calculate_data_sha1sum(data, size);
+ g_free(data);
+ }
}
+
+ current_hash = purple_account_get_string(js->gc->account,
+ "prpl-jabber_icon_checksum", "");
+
+ /* Republish our vcard if the photo is different than the server's */
+ if ((!vcard_hash && current_hash[0] != '\0') ||
+ (vcard_hash && strcmp(vcard_hash, current_hash))) {
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ jabber_set_info(js->gc, purple_account_get_user_info(account));
+ } else if (current_hash != '\0') {
+ /* Our photo is in the vcard, so advertise vcard-temp updates */
+ js->avatar_hash = g_strdup(current_hash);
+ }
+
+ g_free(vcard_hash);
}
void jabber_vcard_fetch_mine(JabberStream *js)
============================================================
--- libpurple/protocols/jabber/disco.c 15e05aeaa2b1e64bc8b77794391c734d82691a3e
+++ libpurple/protocols/jabber/disco.c 1b4fb320eab75766adc1065f181c914419739d07
@@ -23,17 +23,17 @@
#include "prefs.h"
#include "debug.h"
+#include "adhoccommands.h"
#include "buddy.h"
+#include "disco.h"
#include "google.h"
#include "iq.h"
-#include "disco.h"
#include "jabber.h"
+#include "pep.h"
#include "presence.h"
#include "roster.h"
-#include "pep.h"
-#include "adhoccommands.h"
+#include "useravatar.h"
-
struct _jabber_disco_info_cb_data {
gpointer data;
JabberDiscoInfoCallback *callback;
@@ -341,6 +341,8 @@ jabber_disco_finish_server_info_result_c
const char *ft_proxies;
jabber_vcard_fetch_mine(js);
+ if (js->pep)
+ jabber_avatar_fetch_mine(js);
if (!(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) {
/* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */
============================================================
--- libpurple/protocols/jabber/jabber.c 61d4248bdb4e553fe1766ca4a68d5259c747c729
+++ libpurple/protocols/jabber/jabber.c f760dfac5be739853e2e2c76e815d620fd570ab5
@@ -28,6 +28,7 @@
#include "conversation.h"
#include "debug.h"
#include "dnssrv.h"
+#include "imgstore.h"
#include "message.h"
#include "notify.h"
#include "pluginpref.h"
@@ -701,6 +702,7 @@ jabber_login(PurpleAccount *account)
const char *connect_server = purple_account_get_string(account,
"connect_server", "");
JabberStream *js;
+ PurpleStoredImage *image;
JabberBuddy *my_jb = NULL;
gc->flags |= PURPLE_CONNECTION_HTML |
@@ -736,7 +738,19 @@ jabber_login(PurpleAccount *account)
_("Invalid XMPP ID. Domain must be set."));
return;
}
-
+
+ /* This account setting is used to determine if we should re-sync our avatar to the
+ * server at login. */
+ if ((image = purple_buddy_icons_find_account_icon(account))) {
+ char *checksum = jabber_calculate_data_sha1sum(purple_imgstore_get_data(image),
+ purple_imgstore_get_size(image));
+ purple_account_set_string(account, "prpl-jabber_icon_checksum", checksum);
+ g_free(checksum);
+ purple_imgstore_unref(image);
+ } else {
+ purple_account_set_string(account, "prpl-jabber_icon_checksum", "");
+ }
+
if((my_jb = jabber_buddy_find(js, purple_account_get_username(account), TRUE)))
my_jb->subscription |= JABBER_SUB_BOTH;
============================================================
--- libpurple/protocols/jabber/useravatar.c 3f6d2ed2616945ff8dfa2aca1db8c7f7810cf7ab
+++ libpurple/protocols/jabber/useravatar.c 40323527451da4237806afade17a7ebd7329604d
@@ -158,6 +158,37 @@ void jabber_avatar_set(JabberStream *js,
}
}
+static void
+do_got_own_avatar_cb(JabberStream *js, const char *from, xmlnode *items)
+{
+ xmlnode *item = NULL, *metadata = NULL, *info = NULL;
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ const char *current_hash = purple_account_get_string(account, "prpl-jabber_icon_checksum", "");
+ const char *server_hash = NULL;
+
+ if ((item = xmlnode_get_child(items, "item")) &&
+ (metadata = xmlnode_get_child(item, "metadata")) &&
+ (info = xmlnode_get_child(metadata, "info"))) {
+ server_hash = xmlnode_get_attrib(info, "id");
+ }
+
+ /* Publish ours if it's different than the server's */
+ if ((!server_hash && current_hash[0] != '\0') ||
+ (server_hash && strcmp(server_hash, current_hash))) {
+ PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
+ jabber_avatar_set(js, img);
+ purple_imgstore_unref(img);
+ }
+}
+
+void jabber_avatar_fetch_mine(JabberStream *js)
+{
+ char *jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain);
+ jabber_pep_request_item(js, jid, AVATARNAMESPACEMETA, NULL,
+ do_got_own_avatar_cb);
+ g_free(jid);
+}
+
typedef struct _JabberBuddyAvatarUpdateURLInfo {
JabberStream *js;
char *from;
============================================================
--- libpurple/protocols/jabber/useravatar.h e28754135ef2cec4c7804278d58f8dec2a1b92b2
+++ libpurple/protocols/jabber/useravatar.h 1d2a306daafa10e1dfaf55383bd41257505e2477
@@ -25,10 +25,13 @@
#define _PURPLE_JABBER_USERAVATAR_H_
#include "jabber.h"
+#include "imgstore.h"
/* Implementation of XEP-0084 */
void jabber_avatar_init(void);
void jabber_avatar_set(JabberStream *js, PurpleStoredImage *img);
+void jabber_avatar_fetch_mine(JabberStream *js);
+
#endif /* _PURPLE_JABBER_USERAVATAR_H_ */
More information about the Commits
mailing list