diff --git a/src/tox-weechat-friend-requests.c b/src/tox-weechat-friend-requests.c index 3658b56..5e1d7c0 100644 --- a/src/tox-weechat-friend-requests.c +++ b/src/tox-weechat-friend-requests.c @@ -23,7 +23,6 @@ #include #include -#include #include "tox-weechat.h" #include "tox-weechat-identities.h" @@ -76,8 +75,7 @@ tox_weechat_friend_request_add(struct t_tox_weechat_identity *identity, void tox_weechat_friend_request_remove(struct t_tox_weechat_friend_request *request) { - struct t_tox_weechat_identity *identity = request->identity; - if (request == identity->last_friend_request) + struct t_tox_weechat_identity *identity = request->identity; if (request == identity->last_friend_request) identity->last_friend_request = request->prev_request; if (request->prev_request) @@ -123,81 +121,6 @@ tox_weechat_friend_request_with_num(struct t_tox_weechat_identity *identity, return request; } -/** - * Remove all friend requests from an identity and add new ones from the JSON - * array json_request_array. - */ -void -tox_weechat_friend_requests_load_json(struct t_tox_weechat_identity *identity, - json_t *json_request_array) -{ - identity->friend_requests = identity->last_friend_request = NULL; - identity->friend_request_count = 0; - - size_t index; - json_t *json_request; - json_array_foreach(json_request_array, index, json_request) - { - char client_id[TOX_CLIENT_ID_SIZE]; - const char *message; - - json_t *json_id = json_object_get(json_request, - tox_weechat_json_friend_request_key_client_id); - json_t *json_message = json_object_get(json_request, - tox_weechat_json_friend_request_key_message); - - tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id); - message = json_string_value(json_message); - - tox_weechat_friend_request_add(identity, - (uint8_t *)client_id, - message); - } -} - -/** - * Save all friend requests for an identity to a json array. Returns NULL on - * error. - */ -json_t * -tox_weechat_friend_requests_save_json(struct t_tox_weechat_identity *identity) -{ - json_t *friend_requests = json_array(); - if (!json_array) - return NULL; - - for (struct t_tox_weechat_friend_request *request = identity->friend_requests; - request; - request = request->next_request) - { - json_t *json_request = json_object(); - - char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1]; - tox_weechat_bin2hex(request->tox_id, TOX_CLIENT_ID_SIZE, hex_id); - - json_t *json_id = json_string(hex_id); - json_t *json_message = json_string(request->message); - - if (!json_request || !json_id || !json_message) - break; - - json_object_set(json_request, - tox_weechat_json_friend_request_key_client_id, - json_id); - json_decref(json_id); - - json_object_set(json_request, - tox_weechat_json_friend_request_key_message, - json_message); - json_decref(json_message); - - json_array_append(friend_requests, json_request); - json_decref(json_request); - } - - return friend_requests; -} - /** * Free a friend request. */ diff --git a/src/tox-weechat-identities.c b/src/tox-weechat-identities.c index b28ad3a..d583fa4 100644 --- a/src/tox-weechat-identities.c +++ b/src/tox-weechat-identities.c @@ -53,7 +53,6 @@ char *tox_weechat_bootstrap_addresses[] = { "54.199.139.199", "63.165.243.15", }; - uint16_t tox_weechat_bootstrap_ports[] = { 33445, 443, 33445, 33445, 33445, 33445, 33445, 33445, 33445, 33445, diff --git a/src/tox-weechat-json.c b/src/tox-weechat-json.c index f78417c..a35521d 100644 --- a/src/tox-weechat-json.c +++ b/src/tox-weechat-json.c @@ -23,91 +23,180 @@ #include "tox-weechat.h" #include "tox-weechat-identities.h" +#include "tox-weechat-friend-requests.h" #include "tox-weechat-utils.h" #include "tox-weechat-json.h" #define TOX_WEECHAT_JSON_CONFIG_PATH "%h/tox/data.json" -json_t *tox_weechat_json_config = NULL; - const char *tox_weechat_json_key_friend_requests = "friend_requests"; const char *tox_weechat_json_friend_request_key_client_id = "client_id"; const char *tox_weechat_json_friend_request_key_message = "message"; +/** + * Return the full path to the JSON data file. + */ char * -tox_weechat_json_config_file_path() +tox_weechat_json_data_file_path() { const char *weechat_dir = weechat_info_get("weechat_dir", NULL); return weechat_string_replace(TOX_WEECHAT_JSON_CONFIG_PATH, "%h", weechat_dir); } -void -tox_weechat_json_init() +/** + * Return the key used for an identity in the JSON data file. Must be freed. + */ +char * +tox_weechat_json_get_identity_key(struct t_tox_weechat_identity *identity) { - char *full_path = tox_weechat_json_config_file_path(); + uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; + tox_get_address(identity->tox, address); - json_error_t error; - tox_weechat_json_config = json_load_file(full_path, - 0, - &error); - free(full_path); + char *hex_id = malloc(TOX_CLIENT_ID_SIZE * 2 + 1); + tox_weechat_bin2hex(address, TOX_CLIENT_ID_SIZE, hex_id); - if (!tox_weechat_json_config) + return hex_id; +} + +/** + * Save an identity's data to a JSON object. + */ +json_t * +tox_weechat_json_identity_save(struct t_tox_weechat_identity *identity) +{ + json_t *json_data = json_object(); + json_t *friend_request_array = json_array(); + if (!json_data || !friend_request_array) + return NULL; + + for (struct t_tox_weechat_friend_request *request = identity->friend_requests; + request; + request = request->next_request) { - // TODO: read error - tox_weechat_json_config = json_object(); + char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1]; + tox_weechat_bin2hex(request->tox_id, TOX_CLIENT_ID_SIZE, hex_id); + + json_t *json_request = json_object(); + json_t *json_id = json_string(hex_id); + json_t *json_message = json_string(request->message); + if (!json_request || !json_id || !json_message) + break; + + json_object_set(json_request, + tox_weechat_json_friend_request_key_client_id, + json_id); + json_decref(json_id); + + json_object_set(json_request, + tox_weechat_json_friend_request_key_message, + json_message); + json_decref(json_message); + + json_array_append(friend_request_array, json_request); + json_decref(json_request); + } + + json_object_set(json_data, + tox_weechat_json_key_friend_requests, + friend_request_array); + json_decref(friend_request_array); + + return json_data; +} + +/** + * Load an identity's data from a JSON object. + */ +void +tox_weechat_json_identity_load(struct t_tox_weechat_identity *identity, + json_t *data) +{ + json_t *friend_request_array = json_object_get(data, tox_weechat_json_key_friend_requests); + + if (friend_request_array) + { + tox_weechat_friend_request_free_identity(identity); + + size_t index; + json_t *json_request; + json_array_foreach(friend_request_array, index, json_request) + { + char client_id[TOX_CLIENT_ID_SIZE]; + const char *message; + + json_t *json_id = json_object_get(json_request, + tox_weechat_json_friend_request_key_client_id); + json_t *json_message = json_object_get(json_request, + tox_weechat_json_friend_request_key_message); + + tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id); + message = json_string_value(json_message); + + tox_weechat_friend_request_add(identity, + (uint8_t *)client_id, + message); + } } } +/** + * Load the JSON data on disk into the in-memory identity objects. + */ +void +tox_weechat_json_load() +{ + char *full_path = tox_weechat_json_data_file_path(); + + json_error_t error; + json_t *json_data = json_load_file(full_path, 0, &error); + free(full_path); + + if (json_data) + { + for (struct t_tox_weechat_identity *identity = tox_weechat_identities; + identity; + identity = identity->next_identity) + { + char *hex_id = tox_weechat_json_get_identity_key(identity); + json_t *identity_data = json_object_get(json_data, hex_id); + + if (identity_data) + tox_weechat_json_identity_load(identity, identity_data); + } + json_decref(json_data); + } +} + +/** + * Save all in-memory data to JSON data on disk. Return 0 on success, -1 on + * error. + */ int tox_weechat_json_save() { - char *full_path = tox_weechat_json_config_file_path(); + json_t *json_data = json_object(); + if (!json_data) + return -1; - int rc = json_dump_file(tox_weechat_json_config, + for (struct t_tox_weechat_identity *identity = tox_weechat_identities; + identity; + identity = identity->next_identity) + { + char *hex_id = tox_weechat_json_get_identity_key(identity); + json_t *identity_data = tox_weechat_json_identity_save(identity); + + json_object_set(json_data, hex_id, identity_data); + json_decref(identity_data); + } + + char *full_path = tox_weechat_json_data_file_path(); + int rc = json_dump_file(json_data, full_path, 0); free(full_path); + json_decref(json_data); return rc; } -json_t * -tox_weechat_json_get_identity_object(struct t_tox_weechat_identity *identity) -{ - if (!(identity->tox)) return NULL; - - uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; - char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1]; - tox_get_address(identity->tox, address); - tox_weechat_bin2hex(address, TOX_CLIENT_ID_SIZE, hex_id); - - json_t *object = json_object_get(tox_weechat_json_config, - hex_id); - - if (object == NULL) - { - object = json_object(); - json_object_set(tox_weechat_json_config, hex_id, object); - json_decref(object); - } - - return object; -} - -int -tox_weechat_json_set_identity_object(struct t_tox_weechat_identity *identity, - json_t *object) -{ - if (!(identity->tox)) return -1; - - uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; - char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1]; - tox_get_address(identity->tox, address); - tox_weechat_bin2hex(address, TOX_CLIENT_ID_SIZE, hex_id); - - return json_object_set(tox_weechat_json_config, - hex_id, object); -} - diff --git a/src/tox-weechat-json.h b/src/tox-weechat-json.h index d7a9d53..516f89f 100644 --- a/src/tox-weechat-json.h +++ b/src/tox-weechat-json.h @@ -20,27 +20,16 @@ #ifndef TOX_WEECHAT_JSON_H #define TOX_WEECHAT_JSON_H -#include - #include "tox-weechat-identities.h" -extern json_t *tox_weechat_json_config; - extern const char *tox_weechat_json_key_friend_requests; extern const char *tox_weechat_json_friend_request_key_client_id; extern const char *tox_weechat_json_friend_request_key_message; void -tox_weechat_json_init(); +tox_weechat_json_load(); int tox_weechat_json_save(); -json_t * -tox_weechat_json_get_identity_object(struct t_tox_weechat_identity *identity); - -int -tox_weechat_json_set_identity_object(struct t_tox_weechat_identity *identity, - json_t *object); - #endif // TOX_WEECHAT_JSON_H diff --git a/src/tox-weechat.c b/src/tox-weechat.c index 95944df..37d2dde 100644 --- a/src/tox-weechat.c +++ b/src/tox-weechat.c @@ -46,10 +46,9 @@ weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]) { weechat_plugin = plugin; - tox_weechat_json_init(); - tox_weechat_config_init(); tox_weechat_config_read(); + tox_weechat_json_load(); tox_weechat_commands_init(); tox_weechat_gui_init(); tox_weechat_completion_init(); @@ -63,8 +62,8 @@ int weechat_plugin_end(struct t_weechat_plugin *plugin) { tox_weechat_config_write(); - tox_weechat_identity_free_all(); tox_weechat_json_save(); + tox_weechat_identity_free_all(); return WEECHAT_RC_OK; }