This commit is contained in:
irungentoo 2014-09-29 13:49:59 -04:00
commit 627e4d3aa6
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
2 changed files with 68 additions and 83 deletions

View File

@ -241,18 +241,22 @@ already downloaded by other clients can be reused.
Given the Tox data directory described in STS Draft v0.1.0:
- The user avatar is stored in a file named "avatar.png". As more formats
may be used in the future, another extensions are reserved and clients
should keep just one file named "avatar.*", with the data of the last
avatar set by the user. If the user have no avatar, no such files should
be kept in the data directory;
- Avatars are stored in a directory called "avatars" and named
as "xxxxx.png", where "xxxxx" is the complete client id (but not friend
address!) encoded as an uppercase hexadecimal string and "png" is the
extension for the PNG avatar. As new image formats may be used in the
future, clients should ensure no other file "xxxxx.*" exists. No file
should be kept for an user who have no avatar.
- Friends avatars are stored in a directory called "avatars" and named
as "xxxxx.png", where "xxxxx" is the complete client id encoded as an
uppercase hexadecimal string and "png" is the extension for the PNG
avatar. As new image formats may be used in the future, clients should
ensure no other file "xxxxx.*" exists. No file should be kept for an user
who have no avatar.
- The client's own avatar is not special and is stored like any other. This
is partially for simplicity, and partially in anticipation of profiles.
- The avatar should be stored as its recieved, before any modifications by
the client for display purposes.
- The hash, as calculated by toxcore and passed in to the data callback,
should be saved in "avatars/xxxxx.hash" where "xxxxx" means the
same thing as for avatars. (The filename is longer than the file :) )
**To be discussed:** User keys are usually presented in Tox clients as
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":
Tox data directory: /home/gildor/.config/tox/
Tox data file: /home/gildor/.config/tox/data
Gildor's avatar: /home/gildor/.config/tox/avatar.png
Avatar data dir: /home/gildor/.config/tox/avatars/
Gildor's avatar: /home/gildor/.config/tox/avatars/E5809EEF5F11AB29B9BDF543C05B58DDF454AB9CA176C235C7699FDC2757DC33.png
Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png
Elrond's hash: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.hash
Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png
Elladan's hash: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.hash
Elrohir's avatar /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.png
Arwen's avatar: /home/gildor/.config/tox/avatars/53686520746F6F6B20476C6F7266696E64656C277320706C6163652068657265.png
Lindir's avatar: /home/gildor/.config/tox/avatars/417070735772697474656E42794D6F7274616C734C6F6F6B54686553616D652E.png
Elrohir's hash: /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.hash
This recommendation is partially implemented by "testing/test_avatars.c".

View File

@ -17,17 +17,15 @@
*
* Data dir MAY have:
*
* - A file named avatar.png. If given, the bot will publish it. Otherwise,
* no avatar will be set.
*
* - A directory named "avatars" with the currently cached avatars.
* - A directory named "avatars" with the user's avatar and cached avatars.
* The user avatar must be named in the format: "<uppercase user id>.png"
*
*
* The bot will answer to these commands:
*
* !debug-on - Enable extended debug messages
* !debug-off - Disenable extended debug messages
* !set-avatar - Set our avatar to the contents of the file avatar.*
* !set-avatar - Set our avatar from "avatars/<USERID>.png"
* !remove-avatar - Remove our avatar
*
*/
@ -81,13 +79,12 @@ static void debug_printf(const char *fmt, ...)
typedef struct {
uint8_t format;
char *suffix;
char *file_name;
} def_avatar_name_t;
} avatar_format_data_t;
static const def_avatar_name_t def_avatar_names[] = {
static const avatar_format_data_t avatar_formats[] = {
/* In order of preference */
{ TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
{ TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */
{ TOX_AVATAR_FORMAT_PNG, "png" },
{ TOX_AVATAR_FORMAT_NONE, NULL }, /* Must be the last one */
};
@ -99,9 +96,9 @@ static char *get_avatar_suffix_from_format(uint8_t format)
{
int i;
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++)
if (def_avatar_names[i].format == format)
return def_avatar_names[i].suffix;
for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++)
if (avatar_formats[i].format == format)
return avatar_formats[i].suffix;
return NULL;
}
@ -169,8 +166,8 @@ static void byte_to_hex_str(const uint8_t *buf, const size_t buflen, char *dst)
/* Make the cache file name for a avatar of the given format for the given
* client id.
*/
static int make_avatar_file_name(char *dst, size_t dst_len,
char *base_dir, uint8_t format, uint8_t *client_id)
static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir,
const uint8_t format, uint8_t *client_id)
{
char client_id_str[2 * TOX_CLIENT_ID_SIZE + 1];
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)
/* This iteration is dumb and inefficient */
int i;
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
def_avatar_names[i].format, addr);
avatar_formats[i].format, addr);
if (ret != 0) {
DEBUG("Failed to create avatar path for friend #%d, format %d\n",
friendnum, def_avatar_names[i].format);
friendnum, avatar_formats[i].format);
continue;
}
@ -438,66 +435,49 @@ static void friend_request_cb(Tox *tox, const uint8_t *public_key,
}
static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name_t *an)
{
char path[PATH_MAX];
int n = snprintf(path, sizeof(path), "%s/%s", base_dir, an->file_name);
path[sizeof(path) - 1] = '\0';
if (n >= sizeof(path)) {
DEBUG("error: path %s too big\n", path);
return -1;
}
DEBUG("trying file %s: ", path);
FILE *fp = fopen(path, "rb");
if (fp != NULL) {
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
int len = fread(buf, 1, sizeof(buf), fp);
if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
int r = tox_set_avatar(tox, an->format, buf, len);
DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
if (r == 0)
printf("Setting avatar file %s\n", path);
else
printf("Error setting avatar file %s\n", path);
} else if (len < 0) {
DEBUG("read error %d", len);
} else {
printf("Avatar file %s if too big (more than %d bytes)",
path, TOX_AVATAR_MAX_DATA_LENGTH);
}
fclose(fp);
return 0;
} else {
DEBUG("File %s not found", path);
}
return -1;
}
static void set_avatar(Tox *tox, const char *base_dir)
{
int i;
uint8_t addr[TOX_FRIEND_ADDRESS_SIZE];
char path[PATH_MAX];
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
for (i = 0; i < 4; i++) {
if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
tox_get_address(tox, addr);
int i;
for (i = 0; ; i++) {
if (avatar_formats[i].format == TOX_AVATAR_FORMAT_NONE) {
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
printf("No avatar file found, setting to NONE.\n");
return;
break;
} else {
if (try_avatar_file(tox, base_dir, &def_avatar_names[i]) == 0)
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
avatar_formats[i].format, addr);
if (ret < 0) {
printf("Failed to generate avatar file name.\n");
return;
}
int len = load_avatar_data(path, buf);
if (len < 0) {
printf("Failed to load avatar data from file: %s\n", path);
continue;
}
if (len > TOX_AVATAR_MAX_DATA_LENGTH) {
printf("Avatar file %s is too big (more than %d bytes)",
path, TOX_AVATAR_MAX_DATA_LENGTH);
return;
}
ret = tox_set_avatar(tox, avatar_formats[i].format, buf, len);
DEBUG("tox_set_avatar returned=%d", ret);
if (ret == 0)
printf("Setting avatar from %s (%d bytes).\n", path, len);
else
printf("Error setting avatar from %s.\n", path);
return;
}
}
/* Should be unreachable */
printf("UNEXPECTED CODE PATH\n");
}