comparison libpurple/protocols/jabber/useravatar.c @ 26709:80437c891f92

Publish only 'new' xmlns of avatars and delete old. Instead of publishing our avatar to both PEP nodes, publish only to the new and delete anything at the old. We still support receiving both/either. Backward compatibility is achieved through vcard-temp:x:update.
author Paul Aurich <paul@darkrain42.org>
date Mon, 27 Apr 2009 05:49:32 +0000
parents ca421152b5d4
children a0e48796defb
comparison
equal deleted inserted replaced
26708:ca421152b5d4 26709:80437c891f92
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_add_feature("avatarmeta", NS_AVATAR_0_12_METADATA,
37 jabber_pep_namespace_only_when_pep_enabled_cb);
38 jabber_add_feature("avatardata", NS_AVATAR_0_12_DATA,
39 jabber_pep_namespace_only_when_pep_enabled_cb);
40 jabber_pep_register_handler("avatar", NS_AVATAR_0_12_METADATA, 36 jabber_pep_register_handler("avatar", NS_AVATAR_0_12_METADATA,
41 update_buddy_metadata); 37 update_buddy_metadata);
42 38
43 jabber_add_feature("urn_avatarmeta", NS_AVATAR_1_1_METADATA, 39 jabber_add_feature("urn_avatarmeta", NS_AVATAR_1_1_METADATA,
44 jabber_pep_namespace_only_when_pep_enabled_cb); 40 jabber_pep_namespace_only_when_pep_enabled_cb);
47 43
48 jabber_pep_register_handler("urn_avatar", NS_AVATAR_1_1_METADATA, 44 jabber_pep_register_handler("urn_avatar", NS_AVATAR_1_1_METADATA,
49 update_buddy_metadata); 45 update_buddy_metadata);
50 } 46 }
51 47
52 void jabber_avatar_set(JabberStream *js, PurpleStoredImage *img, const char *ns) 48 static void
49 remove_avatar_0_12_nodes(JabberStream *js)
50 {
51 jabber_pep_delete_node(js, NS_AVATAR_0_12_METADATA);
52 jabber_pep_delete_node(js, NS_AVATAR_0_12_DATA);
53 }
54
55 void jabber_avatar_set(JabberStream *js, PurpleStoredImage *img)
53 { 56 {
54 xmlnode *publish, *metadata, *item; 57 xmlnode *publish, *metadata, *item;
55 58
56 if (!js->pep) 59 if (!js->pep)
57 return; 60 return;
58 61
62 remove_avatar_0_12_nodes(js);
63
59 if (!img) { 64 if (!img) {
60 if (ns == NULL || g_str_equal(ns, NS_AVATAR_0_12_METADATA)) { 65 publish = xmlnode_new("publish");
61 /* remove the metadata */ 66 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA);
62 publish = xmlnode_new("publish"); 67
63 xmlnode_set_attrib(publish, "node", NS_AVATAR_0_12_METADATA); 68 item = xmlnode_new_child(publish, "item");
64 69 metadata = xmlnode_new_child(item, "metadata");
65 item = xmlnode_new_child(publish, "item"); 70 xmlnode_set_namespace(metadata, NS_AVATAR_1_1_METADATA);
66 metadata = xmlnode_new_child(item, "metadata"); 71
67 xmlnode_set_namespace(metadata, NS_AVATAR_0_12_METADATA); 72 /* publish */
68 73 jabber_pep_publish(js, publish);
69 xmlnode_new_child(metadata, "stop");
70 /* publish */
71 jabber_pep_publish(js, publish);
72 }
73
74 if (ns == NULL || g_str_equal(ns, NS_AVATAR_1_1_METADATA)) {
75 /* Now for the XEP-0084 v1.1 namespace, where we publish an empty
76 * metadata node instead of a <stop/> element */
77 publish = xmlnode_new("publish");
78 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA);
79
80 item = xmlnode_new_child(publish, "item");
81 metadata = xmlnode_new_child(item, "metadata");
82 xmlnode_set_namespace(metadata, NS_AVATAR_1_1_METADATA);
83
84 /* publish */
85 jabber_pep_publish(js, publish);
86 }
87 } else { 74 } else {
88 /* 75 /*
89 * TODO: This is pretty gross. The Jabber PRPL really shouldn't 76 * TODO: This is pretty gross. The Jabber PRPL really shouldn't
90 * do voodoo to try to determine the image type, height 77 * do voodoo to try to determine the image type, height
91 * and width. 78 * and width.
130 char *hash = jabber_calculate_data_sha1sum(purple_imgstore_get_data(img), 117 char *hash = jabber_calculate_data_sha1sum(purple_imgstore_get_data(img),
131 purple_imgstore_get_size(img)); 118 purple_imgstore_get_size(img));
132 char *base64avatar = purple_base64_encode(purple_imgstore_get_data(img), 119 char *base64avatar = purple_base64_encode(purple_imgstore_get_data(img),
133 purple_imgstore_get_size(img)); 120 purple_imgstore_get_size(img));
134 121
135 if (ns == NULL || g_str_equal(ns, NS_AVATAR_0_12_METADATA)) { 122 publish = xmlnode_new("publish");
136 publish = xmlnode_new("publish"); 123 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_DATA);
137 xmlnode_set_attrib(publish, "node", NS_AVATAR_0_12_DATA); 124
138 125 item = xmlnode_new_child(publish, "item");
139 item = xmlnode_new_child(publish, "item"); 126 xmlnode_set_attrib(item, "id", hash);
140 xmlnode_set_attrib(item, "id", hash); 127
141 128 data = xmlnode_new_child(item, "data");
142 data = xmlnode_new_child(item, "data"); 129 xmlnode_set_namespace(data, NS_AVATAR_1_1_DATA);
143 xmlnode_set_namespace(data, NS_AVATAR_0_12_DATA); 130
144 131 xmlnode_insert_data(data, base64avatar, -1);
145 xmlnode_insert_data(data, base64avatar, -1); 132 /* publish the avatar itself */
146 /* publish the avatar itself */ 133 jabber_pep_publish(js, publish);
147 jabber_pep_publish(js, publish);
148 }
149
150 if (ns == NULL || g_str_equal(ns, NS_AVATAR_1_1_METADATA)) {
151 publish = xmlnode_new("publish");
152 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_DATA);
153
154 item = xmlnode_new_child(publish, "item");
155 xmlnode_set_attrib(item, "id", hash);
156
157 data = xmlnode_new_child(item, "data");
158 xmlnode_set_namespace(data, NS_AVATAR_1_1_DATA);
159
160 xmlnode_insert_data(data, base64avatar, -1);
161 /* publish the avatar itself */
162 jabber_pep_publish(js, publish);
163 }
164 134
165 g_free(base64avatar); 135 g_free(base64avatar);
166 136
167 lengthstring = g_strdup_printf("%" G_GSIZE_FORMAT, 137 lengthstring = g_strdup_printf("%" G_GSIZE_FORMAT,
168 purple_imgstore_get_size(img)); 138 purple_imgstore_get_size(img));
169 widthstring = g_strdup_printf("%u", width); 139 widthstring = g_strdup_printf("%u", width);
170 heightstring = g_strdup_printf("%u", height); 140 heightstring = g_strdup_printf("%u", height);
171 141
172 if (ns == NULL || g_str_equal(ns, NS_AVATAR_0_12_METADATA)) { 142 /* publish the metadata */
173 /* next step: publish the metadata to the old namespace */ 143 publish = xmlnode_new("publish");
174 publish = xmlnode_new("publish"); 144 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA);
175 xmlnode_set_attrib(publish, "node", NS_AVATAR_0_12_METADATA); 145
176 146 item = xmlnode_new_child(publish, "item");
177 item = xmlnode_new_child(publish, "item"); 147 xmlnode_set_attrib(item, "id", hash);
178 xmlnode_set_attrib(item, "id", hash); 148
179 149 metadata = xmlnode_new_child(item, "metadata");
180 metadata = xmlnode_new_child(item, "metadata"); 150 xmlnode_set_namespace(metadata, NS_AVATAR_1_1_METADATA);
181 xmlnode_set_namespace(metadata, NS_AVATAR_0_12_METADATA); 151
182 152 info = xmlnode_new_child(metadata, "info");
183 info = xmlnode_new_child(metadata, "info"); 153 xmlnode_set_attrib(info, "id", hash);
184 xmlnode_set_attrib(info, "id", hash); 154 xmlnode_set_attrib(info, "type", "image/png");
185 xmlnode_set_attrib(info, "type", "image/png"); 155 xmlnode_set_attrib(info, "bytes", lengthstring);
186 xmlnode_set_attrib(info, "bytes", lengthstring); 156 xmlnode_set_attrib(info, "width", widthstring);
187 xmlnode_set_attrib(info, "width", widthstring); 157 xmlnode_set_attrib(info, "height", heightstring);
188 xmlnode_set_attrib(info, "height", heightstring); 158
189 /* publish the metadata */ 159 jabber_pep_publish(js, publish);
190 jabber_pep_publish(js, publish);
191 }
192
193 if (ns == NULL || g_str_equal(ns, NS_AVATAR_1_1_METADATA)) {
194 /* publish the metadata to the new namespace */
195 publish = xmlnode_new("publish");
196 xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_METADATA);
197
198 item = xmlnode_new_child(publish, "item");
199 xmlnode_set_attrib(item, "id", hash);
200
201 metadata = xmlnode_new_child(item, "metadata");
202 xmlnode_set_namespace(metadata, NS_AVATAR_1_1_METADATA);
203
204 info = xmlnode_new_child(metadata, "info");
205 xmlnode_set_attrib(info, "id", hash);
206 xmlnode_set_attrib(info, "type", "image/png");
207 xmlnode_set_attrib(info, "bytes", lengthstring);
208 xmlnode_set_attrib(info, "width", widthstring);
209 xmlnode_set_attrib(info, "height", heightstring);
210
211 jabber_pep_publish(js, publish);
212 }
213 160
214 g_free(lengthstring); 161 g_free(lengthstring);
215 g_free(widthstring); 162 g_free(widthstring);
216 g_free(heightstring); 163 g_free(heightstring);
217 g_free(hash); 164 g_free(hash);
240 187
241 ns = xmlnode_get_namespace(metadata); 188 ns = xmlnode_get_namespace(metadata);
242 if (!ns) 189 if (!ns)
243 return; 190 return;
244 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
245 /* Publish ours if it's different than the server's */ 201 /* Publish ours if it's different than the server's */
246 if (!purple_strequal(server_hash, js->initial_avatar_hash)) { 202 if (!purple_strequal(server_hash, js->initial_avatar_hash)) {
247 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account); 203 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
248 jabber_avatar_set(js, img, ns); 204 jabber_avatar_set(js, img);
249 purple_imgstore_unref(img); 205 purple_imgstore_unref(img);
250 } 206 }
251 } 207 }
252 208
253 void jabber_avatar_fetch_mine(JabberStream *js) 209 void jabber_avatar_fetch_mine(JabberStream *js)