Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/useravatar.c @ 26874:76de9455154c
Drop support for XEP-0084 v0.12 and publish a <stop/> instead of deleting the node.
It causes problems (see note about ejabberd 2.0.0) and backward-compatibility
should be achievable in most cases via vcard-temp:x:update.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 03 May 2009 06:45:38 +0000 |
parents | a0e48796defb |
children | afc3ec89e83b |
comparison
equal
deleted
inserted
replaced
26873:5872d1bc546f | 26874:76de9455154c |
---|---|
31 | 31 |
32 static void update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items); | 32 static void update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items); |
33 | 33 |
34 void jabber_avatar_init(void) | 34 void jabber_avatar_init(void) |
35 { | 35 { |
36 jabber_pep_register_handler(NS_AVATAR_0_12_METADATA, | |
37 update_buddy_metadata); | |
38 | |
39 jabber_add_feature(NS_AVATAR_1_1_METADATA, | 36 jabber_add_feature(NS_AVATAR_1_1_METADATA, |
40 jabber_pep_namespace_only_when_pep_enabled_cb); | 37 jabber_pep_namespace_only_when_pep_enabled_cb); |
41 jabber_add_feature(NS_AVATAR_1_1_DATA, | 38 jabber_add_feature(NS_AVATAR_1_1_DATA, |
42 jabber_pep_namespace_only_when_pep_enabled_cb); | 39 jabber_pep_namespace_only_when_pep_enabled_cb); |
43 | 40 |
46 } | 43 } |
47 | 44 |
48 static void | 45 static void |
49 remove_avatar_0_12_nodes(JabberStream *js) | 46 remove_avatar_0_12_nodes(JabberStream *js) |
50 { | 47 { |
48 /* Publish an empty avatar according to the XEP-0084 v0.12 semantics */ | |
49 xmlnode *publish, *item, *metadata; | |
50 /* publish the metadata */ | |
51 publish = xmlnode_new("publish"); | |
52 xmlnode_set_attrib(publish, "node", NS_AVATAR_0_12_METADATA); | |
53 | |
54 item = xmlnode_new_child(publish, "item"); | |
55 xmlnode_set_attrib(item, "id", "stop"); | |
56 | |
57 metadata = xmlnode_new_child(item, "metadata"); | |
58 xmlnode_set_namespace(metadata, NS_AVATAR_0_12_METADATA); | |
59 | |
60 xmlnode_new_child(metadata, "stop"); | |
61 | |
62 /* publish */ | |
63 jabber_pep_publish(js, publish); | |
64 | |
65 /* | |
66 * This causes ejabberd 2.0.0 to RST our connection unceremoniously, | |
67 * so disable it for now (we publish a <stop/> to the metadata node | |
68 * instead. | |
69 */ | |
70 #if 0 | |
51 jabber_pep_delete_node(js, NS_AVATAR_0_12_METADATA); | 71 jabber_pep_delete_node(js, NS_AVATAR_0_12_METADATA); |
52 jabber_pep_delete_node(js, NS_AVATAR_0_12_DATA); | 72 jabber_pep_delete_node(js, NS_AVATAR_0_12_DATA); |
73 #endif | |
53 } | 74 } |
54 | 75 |
55 void jabber_avatar_set(JabberStream *js, PurpleStoredImage *img) | 76 void jabber_avatar_set(JabberStream *js, PurpleStoredImage *img) |
56 { | 77 { |
57 xmlnode *publish, *metadata, *item; | 78 xmlnode *publish, *metadata, *item; |
58 | 79 |
59 if (!js->pep) | 80 if (!js->pep) |
60 return; | 81 return; |
61 | 82 |
83 /* Hmmm, not sure if this is worth the traffic, but meh */ | |
62 remove_avatar_0_12_nodes(js); | 84 remove_avatar_0_12_nodes(js); |
63 | 85 |
64 if (!img) { | 86 if (!img) { |
65 publish = xmlnode_new("publish"); | 87 publish = xmlnode_new("publish"); |
66 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA); | 88 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA); |
167 } | 189 } |
168 } | 190 } |
169 } | 191 } |
170 | 192 |
171 static void | 193 static void |
194 do_got_own_avatar_0_12_cb(JabberStream *js, const char *from, xmlnode *items) | |
195 { | |
196 if (items) | |
197 /* It wasn't an error (i.e. 'item-not-found') */ | |
198 remove_avatar_0_12_nodes(js); | |
199 } | |
200 | |
201 static void | |
172 do_got_own_avatar_cb(JabberStream *js, const char *from, xmlnode *items) | 202 do_got_own_avatar_cb(JabberStream *js, const char *from, xmlnode *items) |
173 { | 203 { |
174 xmlnode *item = NULL, *metadata = NULL, *info = NULL; | 204 xmlnode *item = NULL, *metadata = NULL, *info = NULL; |
175 PurpleAccount *account = purple_connection_get_account(js->gc); | 205 PurpleAccount *account = purple_connection_get_account(js->gc); |
176 const char *server_hash = NULL; | 206 const char *server_hash = NULL; |
177 const char *ns; | 207 |
178 | 208 if (items && (item = xmlnode_get_child(items, "item")) && |
179 if ((item = xmlnode_get_child(items, "item")) && | |
180 (metadata = xmlnode_get_child(item, "metadata")) && | 209 (metadata = xmlnode_get_child(item, "metadata")) && |
181 (info = xmlnode_get_child(metadata, "info"))) { | 210 (info = xmlnode_get_child(metadata, "info"))) { |
182 server_hash = xmlnode_get_attrib(info, "id"); | 211 server_hash = xmlnode_get_attrib(info, "id"); |
183 } | 212 } |
184 | 213 |
185 if (!metadata) | 214 if (items && !metadata) |
186 return; | 215 return; |
187 | |
188 ns = xmlnode_get_namespace(metadata); | |
189 if (!ns) | |
190 return; | |
191 | |
192 /* | |
193 * We no longer publish avatars to the older namespace. If there is one | |
194 * there, delete it. | |
195 */ | |
196 if (g_str_equal(ns, NS_AVATAR_0_12_METADATA) && server_hash) { | |
197 remove_avatar_0_12_nodes(js); | |
198 return; | |
199 } | |
200 | 216 |
201 /* Publish ours if it's different than the server's */ | 217 /* Publish ours if it's different than the server's */ |
202 if (!purple_strequal(server_hash, js->initial_avatar_hash)) { | 218 if (!purple_strequal(server_hash, js->initial_avatar_hash)) { |
203 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account); | 219 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account); |
204 jabber_avatar_set(js, img); | 220 jabber_avatar_set(js, img); |
208 | 224 |
209 void jabber_avatar_fetch_mine(JabberStream *js) | 225 void jabber_avatar_fetch_mine(JabberStream *js) |
210 { | 226 { |
211 char *jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); | 227 char *jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); |
212 jabber_pep_request_item(js, jid, NS_AVATAR_0_12_METADATA, NULL, | 228 jabber_pep_request_item(js, jid, NS_AVATAR_0_12_METADATA, NULL, |
213 do_got_own_avatar_cb); | 229 do_got_own_avatar_0_12_cb); |
214 jabber_pep_request_item(js, jid, NS_AVATAR_1_1_METADATA, NULL, | 230 jabber_pep_request_item(js, jid, NS_AVATAR_1_1_METADATA, NULL, |
215 do_got_own_avatar_cb); | 231 do_got_own_avatar_cb); |
216 g_free(jid); | 232 g_free(jid); |
217 } | 233 } |
218 | 234 |
245 | 261 |
246 static void | 262 static void |
247 do_buddy_avatar_update_data(JabberStream *js, const char *from, xmlnode *items) | 263 do_buddy_avatar_update_data(JabberStream *js, const char *from, xmlnode *items) |
248 { | 264 { |
249 xmlnode *item, *data; | 265 xmlnode *item, *data; |
250 const char *checksum, *ns; | 266 const char *checksum; |
251 char *b64data; | 267 char *b64data; |
252 void *img; | 268 void *img; |
253 size_t size; | 269 size_t size; |
254 if(!items) | 270 if(!items) |
255 return; | 271 return; |
260 | 276 |
261 data = xmlnode_get_child(item, "data"); | 277 data = xmlnode_get_child(item, "data"); |
262 if(!data) | 278 if(!data) |
263 return; | 279 return; |
264 | 280 |
265 ns = xmlnode_get_namespace(data); | |
266 /* Make sure the namespace is one of the two valid possibilities */ | |
267 if (!ns || (!g_str_equal(ns, NS_AVATAR_0_12_DATA) && | |
268 !g_str_equal(ns, NS_AVATAR_1_1_DATA))) | |
269 return; | |
270 | |
271 checksum = xmlnode_get_attrib(item,"id"); | 281 checksum = xmlnode_get_attrib(item,"id"); |
272 if(!checksum) | 282 if(!checksum) |
273 return; | 283 return; |
274 | 284 |
275 b64data = xmlnode_get_data(data); | 285 b64data = xmlnode_get_data(data); |
288 | 298 |
289 static void | 299 static void |
290 update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items) | 300 update_buddy_metadata(JabberStream *js, const char *from, xmlnode *items) |
291 { | 301 { |
292 PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(js->gc), from); | 302 PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(js->gc), from); |
293 const char *checksum, *ns; | 303 const char *checksum; |
294 xmlnode *item, *metadata; | 304 xmlnode *item, *metadata; |
295 if(!buddy) | 305 if(!buddy) |
296 return; | 306 return; |
297 | 307 |
298 if (!items) | 308 if (!items) |
304 | 314 |
305 metadata = xmlnode_get_child(item, "metadata"); | 315 metadata = xmlnode_get_child(item, "metadata"); |
306 if(!metadata) | 316 if(!metadata) |
307 return; | 317 return; |
308 | 318 |
309 ns = xmlnode_get_namespace(metadata); | |
310 /* Make sure the namespace is one of the two valid possibilities */ | |
311 if (!ns || (!g_str_equal(ns, NS_AVATAR_0_12_METADATA) && | |
312 !g_str_equal(ns, NS_AVATAR_1_1_METADATA))) | |
313 return; | |
314 | |
315 checksum = purple_buddy_icons_get_checksum_for_user(buddy); | 319 checksum = purple_buddy_icons_get_checksum_for_user(buddy); |
316 | 320 |
317 /* check if we have received a stop */ | 321 /* <stop/> was the pre-v1.1 method of publishing an empty avatar */ |
318 if(xmlnode_get_child(metadata, "stop")) { | 322 if(xmlnode_get_child(metadata, "stop")) { |
319 purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL); | 323 purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL); |
320 } else { | 324 } else { |
321 xmlnode *info, *goodinfo = NULL; | 325 xmlnode *info, *goodinfo = NULL; |
322 gboolean has_children = FALSE; | 326 gboolean has_children = FALSE; |
345 const char *url = xmlnode_get_attrib(goodinfo, "url"); | 349 const char *url = xmlnode_get_attrib(goodinfo, "url"); |
346 const char *id = xmlnode_get_attrib(goodinfo,"id"); | 350 const char *id = xmlnode_get_attrib(goodinfo,"id"); |
347 | 351 |
348 /* the avatar might either be stored in a pep node, or on a HTTP(S) URL */ | 352 /* the avatar might either be stored in a pep node, or on a HTTP(S) URL */ |
349 if(!url) { | 353 if(!url) { |
350 const char *data_ns; | 354 jabber_pep_request_item(js, from, NS_AVATAR_1_1_DATA, id, |
351 data_ns = (g_str_equal(ns, NS_AVATAR_0_12_METADATA) ? | |
352 NS_AVATAR_0_12_DATA : NS_AVATAR_1_1_DATA); | |
353 jabber_pep_request_item(js, from, data_ns, id, | |
354 do_buddy_avatar_update_data); | 355 do_buddy_avatar_update_data); |
355 } else { | 356 } else { |
356 PurpleUtilFetchUrlData *url_data; | 357 PurpleUtilFetchUrlData *url_data; |
357 JabberBuddyAvatarUpdateURLInfo *info = g_new0(JabberBuddyAvatarUpdateURLInfo, 1); | 358 JabberBuddyAvatarUpdateURLInfo *info = g_new0(JabberBuddyAvatarUpdateURLInfo, 1); |
358 info->js = js; | 359 info->js = js; |