1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-26 12:56:37 +02:00

relay/api: close obsolete buffers when reconnecting to the remote

This closes all buffers that exist locally but not on the remote any more,
after reconnecting to the remote.
This commit is contained in:
Sébastien Helleu
2024-08-09 18:08:31 +02:00
parent e5b6eab2f6
commit 6e775e4768
4 changed files with 116 additions and 10 deletions
+2 -1
View File
@@ -62,7 +62,8 @@
- relay/api: fix timezone of dates sent to clients ([#2151](https://github.com/weechat/weechat/issues/2151))
- relay/api: clear lines and nicklist on all remote buffers upon successful connection to the remote ([#2161](https://github.com/weechat/weechat/issues/2161))
- relay/api: fix buffers synchronization with existing buffers that have been renamed on remote in the meanwhile ([#2169](https://github.com/weechat/weechat/issues/2169))
- relay/api: do not reset input text on existing buffers when reconnecting to remote
- relay/api: do not reset input text on existing buffers when reconnecting to the remote
- relay/api: close obsolete buffers when reconnecting to the remote
- relay/api: fix "body_type" returned when lines or nicks of a buffer are requested
- relay/api: fix read of one buffer line
- relay: fix websocket permessage-deflate extension when the client doesn't send the max window bits parameters ([#1549](https://github.com/weechat/weechat/issues/1549))
@@ -732,6 +732,91 @@ relay_remote_event_remove_localvar_cb (void *data,
}
}
/*
* Initial sync of buffers: remove any remote buffer that is not received
* from the remote (case of buffers still present after a previous connection
* to the remove).
*/
void
relay_remote_event_initial_sync_buffers (struct t_relay_remote_event *event)
{
struct t_gui_buffer *ptr_buffer;
struct t_arraylist *remote_buffers;
struct t_hashtable *buffers_id;
const char *ptr_name, *ptr_id;
char str_id[64];
cJSON *json_buffer, *json_obj;
long long id;
int i, list_size;
if (!event->remote)
return;
/* build a list of existing buffers for the remote */
remote_buffers = weechat_arraylist_new (32, 0, 0,
NULL, NULL, NULL, NULL);
if (!remote_buffers)
{
relay_remote_network_disconnect (event->remote);
return;
}
ptr_buffer = weechat_hdata_get_list (relay_hdata_buffer, "gui_buffers");
while (ptr_buffer)
{
ptr_name = weechat_buffer_get_string (ptr_buffer, "localvar_relay_remote");
if (ptr_name && (weechat_strcmp (ptr_name, event->remote->name) == 0))
{
weechat_arraylist_add (remote_buffers, ptr_buffer);
}
ptr_buffer = weechat_hdata_move (relay_hdata_buffer, ptr_buffer, 1);
}
/* build a list of remote buffers ids received in JSON */
buffers_id = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL,
NULL);
if (!buffers_id)
{
weechat_arraylist_free (remote_buffers);
relay_remote_network_disconnect (event->remote);
return;
}
if (event->json && cJSON_IsArray (event->json))
{
cJSON_ArrayForEach (json_buffer, event->json)
{
JSON_GET_NUM(json_buffer, id, -1);
snprintf (str_id, sizeof (str_id), "%lld", id);
weechat_hashtable_set (buffers_id, str_id, NULL);
}
}
/* close any remote buffer that was not received in JSON */
list_size = weechat_arraylist_size (remote_buffers);
for (i = 0; i < list_size; i++)
{
ptr_buffer = (struct t_gui_buffer *)weechat_arraylist_get (remote_buffers, i);
if (!weechat_hdata_check_pointer (
relay_hdata_buffer,
weechat_hdata_get_list (relay_hdata_buffer, "gui_buffers"),
ptr_buffer))
{
continue;
}
ptr_id = weechat_buffer_get_string (ptr_buffer, "localvar_relay_remote_id");
if (ptr_id && !weechat_hashtable_has_key (buffers_id, ptr_id))
{
weechat_buffer_close (ptr_buffer);
}
}
weechat_arraylist_free (remote_buffers);
weechat_hashtable_free (buffers_id);
}
/*
* Callback for a buffer event or response to GET /api/buffers.
*/
@@ -1052,13 +1137,14 @@ RELAY_REMOTE_EVENT_CALLBACK(version)
}
relay_remote_event_clear_buffers (event->remote);
event->remote->version_ok = 1;
snprintf (request, sizeof (request),
"{\"request\": \"GET /api/buffers?"
"lines=-%d"
"&nicks=true"
"&colors=weechat"
"\"}",
weechat_config_integer (relay_config_api_remote_get_lines));
snprintf (
request, sizeof (request),
"{"
"\"request\": "
"\"GET /api/buffers?lines=-%d&nicks=true&colors=weechat\", "
"\"request_id\": \"" RELAY_REMOTE_EVENT_ID_INITIAL_SYNC "\""
"}",
weechat_config_integer (relay_config_api_remote_get_lines));
relay_remote_network_send (event->remote, RELAY_MSG_STANDARD,
request, strlen (request));
}
@@ -1108,7 +1194,7 @@ void
relay_remote_event_recv (struct t_relay_remote *remote, const char *data)
{
cJSON *json, *json_body, *json_obj;
const char *body_type, *event_name;
const char *body_type, *event_name, *request_id;
long long buffer_id;
int i, rc, code;
struct t_relay_remote_event_cb event_cb[] = {
@@ -1149,6 +1235,7 @@ relay_remote_event_recv (struct t_relay_remote *remote, const char *data)
JSON_GET_NUM(json, code, -1);
JSON_GET_STR(json, body_type);
JSON_GET_STR(json, request_id);
json_body = cJSON_GetObjectItem (json, "body");
if (!body_type && ((code == 200) || (code == 204)))
@@ -1187,6 +1274,13 @@ relay_remote_event_recv (struct t_relay_remote *remote, const char *data)
if (callback)
{
event.json = json_body;
if ((weechat_strcmp (body_type, "buffers") == 0)
&& (weechat_strcmp (request_id,
RELAY_REMOTE_EVENT_ID_INITIAL_SYNC) == 0))
{
relay_remote_event_initial_sync_buffers (&event);
}
rc = WEECHAT_RC_OK;
if (cJSON_IsArray (json_body))
{
@@ -1198,7 +1292,6 @@ relay_remote_event_recv (struct t_relay_remote *remote, const char *data)
}
else
{
event.json = json_body;
rc = (callback) (&event);
}
if (rc == WEECHAT_RC_ERROR)
@@ -20,6 +20,8 @@
#ifndef WEECHAT_PLUGIN_RELAY_REMOTE_EVENT_H
#define WEECHAT_PLUGIN_RELAY_REMOTE_EVENT_H
#define RELAY_REMOTE_EVENT_ID_INITIAL_SYNC "initial_sync"
#define RELAY_REMOTE_EVENT_CALLBACK(__body_type) \
int \
relay_remote_event_cb_##__body_type ( \
@@ -185,6 +185,16 @@ TEST(RelayRemoteEvent, RemoveLocalVarCb)
/* TODO: write tests */
}
/*
* Tests functions:
* relay_remote_event_initial_sync_buffers
*/
TEST(RelayRemoteEvent, InitialSyncBuffers)
{
/* TODO: write tests */
}
/*
* Tests functions:
* relay_remote_event_cb_buffer