summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-09-29 13:49:59 -0400
committerirungentoo <irungentoo@gmail.com>2014-09-29 13:49:59 -0400
commit627e4d3aa629038b0e195f2189e9826b32c9531a (patch)
treefbef1cbfe2878c6010320b012737f63b21aaf84e
parentad804855f9b70a6bab88e9ba6362f0f613f6d019 (diff)
parent118febcfeec3217bf31c5ab000b762fe27a54d2f (diff)
Merge branch 'master' of https://github.com/dubslow/toxcore
-rw-r--r--docs/Avatars.md35
-rw-r--r--testing/test_avatars.c114
2 files changed, 67 insertions, 82 deletions
diff --git a/docs/Avatars.md b/docs/Avatars.md
index 75517004..74308f02 100644
--- a/docs/Avatars.md
+++ b/docs/Avatars.md
@@ -241,18 +241,22 @@ already downloaded by other clients can be reused.
241 241
242Given the Tox data directory described in STS Draft v0.1.0: 242Given the Tox data directory described in STS Draft v0.1.0:
243 243
244 - The user avatar is stored in a file named "avatar.png". As more formats 244 - Avatars are stored in a directory called "avatars" and named
245 may be used in the future, another extensions are reserved and clients 245 as "xxxxx.png", where "xxxxx" is the complete client id (but not friend
246 should keep just one file named "avatar.*", with the data of the last 246 address!) encoded as an uppercase hexadecimal string and "png" is the
247 avatar set by the user. If the user have no avatar, no such files should 247 extension for the PNG avatar. As new image formats may be used in the
248 be kept in the data directory; 248 future, clients should ensure no other file "xxxxx.*" exists. No file
249 249 should be kept for an user who have no avatar.
250 - Friends avatars are stored in a directory called "avatars" and named 250
251 as "xxxxx.png", where "xxxxx" is the complete client id encoded as an 251 - The client's own avatar is not special and is stored like any other. This
252 uppercase hexadecimal string and "png" is the extension for the PNG 252 is partially for simplicity, and partially in anticipation of profiles.
253 avatar. As new image formats may be used in the future, clients should 253
254 ensure no other file "xxxxx.*" exists. No file should be kept for an user 254 - The avatar should be stored as its recieved, before any modifications by
255 who have no avatar. 255 the client for display purposes.
256
257 - The hash, as calculated by toxcore and passed in to the data callback,
258 should be saved in "avatars/xxxxx.hash" where "xxxxx" means the
259 same thing as for avatars. (The filename is longer than the file :) )
256 260
257 **To be discussed:** User keys are usually presented in Tox clients as 261 **To be discussed:** User keys are usually presented in Tox clients as
258 upper case strings, but lower case file names are more usual. 262 upper case strings, but lower case file names are more usual.
@@ -262,13 +266,14 @@ Example for Linux and other Unix systems, assuming an user called "gildor":
262 266
263 Tox data directory: /home/gildor/.config/tox/ 267 Tox data directory: /home/gildor/.config/tox/
264 Tox data file: /home/gildor/.config/tox/data 268 Tox data file: /home/gildor/.config/tox/data
265 Gildor's avatar: /home/gildor/.config/tox/avatar.png
266 Avatar data dir: /home/gildor/.config/tox/avatars/ 269 Avatar data dir: /home/gildor/.config/tox/avatars/
270 Gildor's avatar: /home/gildor/.config/tox/avatars/E5809EEF5F11AB29B9BDF543C05B58DDF454AB9CA176C235C7699FDC2757DC33.png
267 Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png 271 Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png
272 Elrond's hash: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.hash
268 Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png 273 Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png
274 Elladan's hash: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.hash
269 Elrohir's avatar /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.png 275 Elrohir's avatar /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.png
270 Arwen's avatar: /home/gildor/.config/tox/avatars/53686520746F6F6B20476C6F7266696E64656C277320706C6163652068657265.png 276 Elrohir's hash: /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.hash
271 Lindir's avatar: /home/gildor/.config/tox/avatars/417070735772697474656E42794D6F7274616C734C6F6F6B54686553616D652E.png
272 277
273This recommendation is partially implemented by "testing/test_avatars.c". 278This recommendation is partially implemented by "testing/test_avatars.c".
274 279
diff --git a/testing/test_avatars.c b/testing/test_avatars.c
index 55beea67..6afbac1d 100644
--- a/testing/test_avatars.c
+++ b/testing/test_avatars.c
@@ -17,17 +17,15 @@
17 * 17 *
18 * Data dir MAY have: 18 * Data dir MAY have:
19 * 19 *
20 * - A file named avatar.png. If given, the bot will publish it. Otherwise, 20 * - A directory named "avatars" with the user's avatar and cached avatars.
21 * no avatar will be set. 21 * The user avatar must be named in the format: "<uppercase user id>.png"
22 *
23 * - A directory named "avatars" with the currently cached avatars.
24 * 22 *
25 * 23 *
26 * The bot will answer to these commands: 24 * The bot will answer to these commands:
27 * 25 *
28 * !debug-on - Enable extended debug messages 26 * !debug-on - Enable extended debug messages
29 * !debug-off - Disenable extended debug messages 27 * !debug-off - Disenable extended debug messages
30 * !set-avatar - Set our avatar to the contents of the file avatar.* 28 * !set-avatar - Set our avatar from "avatars/<USERID>.png"
31 * !remove-avatar - Remove our avatar 29 * !remove-avatar - Remove our avatar
32 * 30 *
33 */ 31 */
@@ -81,13 +79,12 @@ static void debug_printf(const char *fmt, ...)
81typedef struct { 79typedef struct {
82 uint8_t format; 80 uint8_t format;
83 char *suffix; 81 char *suffix;
84 char *file_name; 82} avatar_format_data_t;
85} def_avatar_name_t;
86 83
87static const def_avatar_name_t def_avatar_names[] = { 84static const avatar_format_data_t avatar_formats[] = {
88 /* In order of preference */ 85 /* In order of preference */
89 { TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" }, 86 { TOX_AVATAR_FORMAT_PNG, "png" },
90 { TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */ 87 { TOX_AVATAR_FORMAT_NONE, NULL }, /* Must be the last one */
91}; 88};
92 89
93 90
@@ -99,9 +96,9 @@ static char *get_avatar_suffix_from_format(uint8_t format)
99{ 96{
100 int i; 97 int i;
101 98
102 for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) 99 for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++)
103 if (def_avatar_names[i].format == format) 100 if (avatar_formats[i].format == format)
104 return def_avatar_names[i].suffix; 101 return avatar_formats[i].suffix;
105 102
106 return NULL; 103 return NULL;
107} 104}
@@ -169,8 +166,8 @@ static void byte_to_hex_str(const uint8_t *buf, const size_t buflen, char *dst)
169/* Make the cache file name for a avatar of the given format for the given 166/* Make the cache file name for a avatar of the given format for the given
170 * client id. 167 * client id.
171 */ 168 */
172static int make_avatar_file_name(char *dst, size_t dst_len, 169static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir,
173 char *base_dir, uint8_t format, uint8_t *client_id) 170 const uint8_t format, uint8_t *client_id)
174{ 171{
175 char client_id_str[2 * TOX_CLIENT_ID_SIZE + 1]; 172 char client_id_str[2 * TOX_CLIENT_ID_SIZE + 1];
176 byte_to_hex_str(client_id, TOX_CLIENT_ID_SIZE, client_id_str); 173 byte_to_hex_str(client_id, TOX_CLIENT_ID_SIZE, client_id_str);
@@ -267,13 +264,13 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
267 /* This iteration is dumb and inefficient */ 264 /* This iteration is dumb and inefficient */
268 int i; 265 int i;
269 266
270 for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) { 267 for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
271 int ret = make_avatar_file_name(path, sizeof(path), base_dir, 268 int ret = make_avatar_file_name(path, sizeof(path), base_dir,
272 def_avatar_names[i].format, addr); 269 avatar_formats[i].format, addr);
273 270
274 if (ret != 0) { 271 if (ret != 0) {
275 DEBUG("Failed to create avatar path for friend #%d, format %d\n", 272 DEBUG("Failed to create avatar path for friend #%d, format %d\n",
276 friendnum, def_avatar_names[i].format); 273 friendnum, avatar_formats[i].format);
277 continue; 274 continue;
278 } 275 }
279 276
@@ -438,66 +435,49 @@ static void friend_request_cb(Tox *tox, const uint8_t *public_key,
438} 435}
439 436
440 437
441static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name_t *an) 438static void set_avatar(Tox *tox, const char *base_dir)
442{ 439{
440 uint8_t addr[TOX_FRIEND_ADDRESS_SIZE];
443 char path[PATH_MAX]; 441 char path[PATH_MAX];
444 int n = snprintf(path, sizeof(path), "%s/%s", base_dir, an->file_name); 442 uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
445 path[sizeof(path) - 1] = '\0';
446
447 if (n >= sizeof(path)) {
448 DEBUG("error: path %s too big\n", path);
449 return -1;
450 }
451
452 DEBUG("trying file %s: ", path);
453 FILE *fp = fopen(path, "rb");
454
455 if (fp != NULL) {
456 uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
457 int len = fread(buf, 1, sizeof(buf), fp);
458
459 if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
460 int r = tox_set_avatar(tox, an->format, buf, len);
461 DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
462
463 if (r == 0)
464 printf("Setting avatar file %s\n", path);
465 else
466 printf("Error setting avatar file %s\n", path);
467 } else if (len < 0) {
468 DEBUG("read error %d", len);
469 } else {
470 printf("Avatar file %s if too big (more than %d bytes)",
471 path, TOX_AVATAR_MAX_DATA_LENGTH);
472 }
473
474 fclose(fp);
475 return 0;
476 } else {
477 DEBUG("File %s not found", path);
478 }
479
480 return -1;
481}
482 443
444 tox_get_address(tox, addr);
483 445
484static void set_avatar(Tox *tox, const char *base_dir)
485{
486 int i; 446 int i;
487 447 for (i = 0; ; i++) {
488 for (i = 0; i < 4; i++) { 448 if (avatar_formats[i].format == TOX_AVATAR_FORMAT_NONE) {
489 if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
490 tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0); 449 tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
491 printf("No avatar file found, setting to NONE.\n"); 450 printf("No avatar file found, setting to NONE.\n");
492 return; 451 break;
493 } else { 452 } else {
494 if (try_avatar_file(tox, base_dir, &def_avatar_names[i]) == 0) 453 int ret = make_avatar_file_name(path, sizeof(path), base_dir,
454 avatar_formats[i].format, addr);
455 if (ret < 0) {
456 printf("Failed to generate avatar file name.\n");
457 return;
458 }
459
460 int len = load_avatar_data(path, buf);
461 if (len < 0) {
462 printf("Failed to load avatar data from file: %s\n", path);
463 continue;
464 }
465
466 if (len > TOX_AVATAR_MAX_DATA_LENGTH) {
467 printf("Avatar file %s is too big (more than %d bytes)",
468 path, TOX_AVATAR_MAX_DATA_LENGTH);
495 return; 469 return;
470 }
471
472 ret = tox_set_avatar(tox, avatar_formats[i].format, buf, len);
473 DEBUG("tox_set_avatar returned=%d", ret);
474 if (ret == 0)
475 printf("Setting avatar from %s (%d bytes).\n", path, len);
476 else
477 printf("Error setting avatar from %s.\n", path);
478 return;
496 } 479 }
497 } 480 }
498
499 /* Should be unreachable */
500 printf("UNEXPECTED CODE PATH\n");
501} 481}
502 482
503 483