mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
851 lines
27 KiB
C
851 lines
27 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2023-2026 Sébastien Helleu <flashcode@flashtux.org>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* This file is part of WeeChat, the extensible chat client.
|
|
*
|
|
* WeeChat is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* WeeChat is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* Build JSON messages for "api" protocol */
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <cjson/cJSON.h>
|
|
|
|
#include "../../weechat-plugin.h"
|
|
#include "../relay.h"
|
|
#include "../relay-client.h"
|
|
#include "../relay-http.h"
|
|
#include "../relay-websocket.h"
|
|
#include "relay-api.h"
|
|
#include "relay-api-msg.h"
|
|
#include "relay-api-protocol.h"
|
|
|
|
#define MSG_ADD_STR_BUF(__json_name, __string) \
|
|
cJSON_AddItemToObject( \
|
|
json, __json_name, \
|
|
cJSON_CreateString (__string));
|
|
|
|
#define MSG_ADD_STR_PTR(__json_name, __string) \
|
|
cJSON_AddItemToObject( \
|
|
json, __json_name, \
|
|
cJSON_CreateString ((__string) ? __string : ""));
|
|
|
|
#define MSG_ADD_HDATA_VAR(__json_type, __json_name, \
|
|
__var_type, __var_name) \
|
|
cJSON_AddItemToObject( \
|
|
json, __json_name, \
|
|
cJSON_Create##__json_type ( \
|
|
weechat_hdata_##__var_type (hdata, pointer, __var_name)));
|
|
|
|
#define MSG_ADD_HDATA_TIME_USEC(__json_name, \
|
|
__var_name, __var_name_usec) \
|
|
tv.tv_sec = weechat_hdata_time (hdata, pointer, __var_name); \
|
|
tv.tv_usec = weechat_hdata_integer (hdata, pointer, \
|
|
__var_name_usec); \
|
|
weechat_util_strftimeval (str_time, sizeof (str_time), \
|
|
"%@%FT%T.%fZ", &tv); \
|
|
MSG_ADD_STR_BUF(__json_name, str_time);
|
|
|
|
#define MSG_ADD_HDATA_STR(__json_name, __var_name) \
|
|
ptr_string = weechat_hdata_string (hdata, pointer, __var_name); \
|
|
MSG_ADD_STR_PTR(__json_name, ptr_string);
|
|
|
|
#define MSG_CONVERT_COLORS(__json_name, __string) \
|
|
switch (colors) \
|
|
{ \
|
|
case RELAY_API_COLORS_ANSI: \
|
|
string = weechat_hook_modifier_exec ( \
|
|
"color_encode_ansi", NULL, \
|
|
(__string) ? __string : ""); \
|
|
if (string) \
|
|
{ \
|
|
MSG_ADD_STR_PTR(__json_name, string); \
|
|
free (string); \
|
|
} \
|
|
break; \
|
|
case RELAY_API_COLORS_WEECHAT: \
|
|
MSG_ADD_STR_PTR(__json_name, __string); \
|
|
break; \
|
|
case RELAY_API_COLORS_STRIP: \
|
|
string = weechat_string_remove_color ( \
|
|
(__string) ? __string : "", NULL); \
|
|
if (string) \
|
|
{ \
|
|
MSG_ADD_STR_PTR(__json_name, string); \
|
|
free (string); \
|
|
} \
|
|
case RELAY_API_NUM_COLORS: \
|
|
break; \
|
|
}
|
|
|
|
#define MSG_ADD_HDATA_STR_COLORS(__json_name, __var_name) \
|
|
ptr_string = weechat_hdata_string (hdata, pointer, __var_name); \
|
|
MSG_CONVERT_COLORS(__json_name, ptr_string);
|
|
|
|
#define MSG_ADD_HDATA_COLOR(__json_name, __var_name) \
|
|
ptr_string = weechat_hdata_string (hdata, pointer, __var_name); \
|
|
ptr_color = (ptr_string && ptr_string[0]) ? \
|
|
weechat_color (ptr_string) : NULL; \
|
|
MSG_CONVERT_COLORS(__json_name, ptr_color);
|
|
|
|
|
|
/*
|
|
* Send JSON response to client (internal use).
|
|
*
|
|
* Return number of bytes sent to client, -1 if error.
|
|
*/
|
|
|
|
int
|
|
relay_api_msg_send_json_internal (struct t_relay_client *client,
|
|
int return_code,
|
|
const char *message,
|
|
const char *event_name,
|
|
long long event_buffer_id,
|
|
const char *headers,
|
|
const char *body_type,
|
|
cJSON *json_body)
|
|
{
|
|
cJSON *json;
|
|
char *string, *request;
|
|
int num_bytes, length;
|
|
|
|
if (!client || !message)
|
|
return -1;
|
|
|
|
num_bytes = -1;
|
|
|
|
if (client->websocket == RELAY_CLIENT_WEBSOCKET_READY)
|
|
{
|
|
/*
|
|
* with established websocket, we return JSON string instead of
|
|
* an HTTP response
|
|
*/
|
|
json = cJSON_CreateObject ();
|
|
if (json)
|
|
{
|
|
cJSON_AddItemToObject (json, "code", cJSON_CreateNumber (return_code));
|
|
cJSON_AddItemToObject (json, "message", cJSON_CreateString (message));
|
|
if (event_name)
|
|
{
|
|
cJSON_AddItemToObject (
|
|
json, "event_name",
|
|
cJSON_CreateString ((event_name) ? event_name : ""));
|
|
cJSON_AddItemToObject (
|
|
json, "buffer_id",
|
|
cJSON_CreateNumber (event_buffer_id));
|
|
}
|
|
else
|
|
{
|
|
length = weechat_asprintf (
|
|
&request,
|
|
"%s%s%s",
|
|
(client->http_req->method) ? client->http_req->method : "",
|
|
(client->http_req->method) ? " " : "",
|
|
(client->http_req->path) ? client->http_req->path : "");
|
|
if (length >= 0)
|
|
{
|
|
cJSON_AddItemToObject (json, "request",
|
|
cJSON_CreateString (request));
|
|
cJSON_AddItemToObject (
|
|
json, "request_body",
|
|
(client->http_req->body) ?
|
|
cJSON_Parse (client->http_req->body) : cJSON_CreateNull ());
|
|
free (request);
|
|
}
|
|
cJSON_AddItemToObject (
|
|
json, "request_id",
|
|
(client->http_req->id) ?
|
|
cJSON_CreateString (client->http_req->id) : cJSON_CreateNull ());
|
|
}
|
|
cJSON_AddItemToObject (
|
|
json, "body_type",
|
|
(body_type) ?
|
|
cJSON_CreateString (body_type) : cJSON_CreateNull ());
|
|
cJSON_AddItemToObject (
|
|
json, "body",
|
|
(json_body) ? json_body : cJSON_CreateNull ());
|
|
string = cJSON_PrintUnformatted (json);
|
|
num_bytes = relay_client_send (
|
|
client,
|
|
RELAY_MSG_STANDARD,
|
|
string,
|
|
(string) ? strlen (string) : 0,
|
|
NULL); /* raw_message */
|
|
free (string);
|
|
cJSON_DetachItemFromObject (json, "body");
|
|
cJSON_Delete (json);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string = (json_body) ? cJSON_PrintUnformatted (json_body) : NULL;
|
|
num_bytes = relay_http_send_json (client, return_code, message, headers,
|
|
string);
|
|
free (string);
|
|
}
|
|
|
|
return num_bytes;
|
|
}
|
|
|
|
/*
|
|
* Send JSON response to client (internal use).
|
|
*
|
|
* Return number of bytes sent to client, -1 if error.
|
|
*/
|
|
|
|
int
|
|
relay_api_msg_send_json (struct t_relay_client *client,
|
|
int return_code,
|
|
const char *message,
|
|
const char *headers,
|
|
const char *body_type,
|
|
cJSON *json_body)
|
|
{
|
|
return relay_api_msg_send_json_internal (client,
|
|
return_code,
|
|
message,
|
|
NULL, /* event_name */
|
|
-1, /* event_buffer_id */
|
|
headers,
|
|
body_type,
|
|
json_body);
|
|
}
|
|
|
|
/*
|
|
* Send JSON error to client.
|
|
*
|
|
* Return number of bytes sent to client, -1 if error.
|
|
*/
|
|
|
|
int
|
|
relay_api_msg_send_error_json (struct t_relay_client *client,
|
|
int return_code,
|
|
const char *message,
|
|
const char *headers,
|
|
const char *format, ...)
|
|
{
|
|
cJSON *json;
|
|
int num_bytes;
|
|
char *str_json;
|
|
|
|
if (!client || !message || !format)
|
|
return -1;
|
|
|
|
weechat_va_format (format);
|
|
if (!vbuffer)
|
|
return -1;
|
|
|
|
num_bytes = -1;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return -1;
|
|
|
|
cJSON_AddItemToObject (json, "error", cJSON_CreateString (vbuffer));
|
|
|
|
if (client->websocket == RELAY_CLIENT_WEBSOCKET_READY)
|
|
{
|
|
/*
|
|
* with established websocket, we return JSON string instead of
|
|
* an HTTP response
|
|
*/
|
|
num_bytes = relay_api_msg_send_json_internal (
|
|
client,
|
|
return_code,
|
|
message,
|
|
NULL, /* event_name */
|
|
-1, /* event_buffer_id */
|
|
headers,
|
|
NULL, /* body_type */
|
|
json);
|
|
}
|
|
else
|
|
{
|
|
str_json = cJSON_PrintUnformatted (json);
|
|
num_bytes = relay_http_send_json (client, return_code, message,
|
|
headers, str_json);
|
|
free (str_json);
|
|
}
|
|
|
|
cJSON_Delete (json);
|
|
free (vbuffer);
|
|
return num_bytes;
|
|
}
|
|
|
|
/*
|
|
* Send event to the client.
|
|
*
|
|
* Return number of bytes sent to client, -1 if error.
|
|
*/
|
|
|
|
int
|
|
relay_api_msg_send_event (struct t_relay_client *client,
|
|
const char *name,
|
|
long long buffer_id,
|
|
const char *body_type,
|
|
cJSON *json_body)
|
|
{
|
|
return relay_api_msg_send_json_internal (client,
|
|
RELAY_API_HTTP_0_EVENT,
|
|
name,
|
|
buffer_id,
|
|
NULL, /* headers */
|
|
body_type,
|
|
json_body);
|
|
}
|
|
|
|
/*
|
|
* Add a buffer local variable into a JSON object.
|
|
*/
|
|
|
|
void
|
|
relay_api_msg_buffer_add_local_vars_cb (void *data,
|
|
struct t_hashtable *hashtable,
|
|
const void *key,
|
|
const void *value)
|
|
{
|
|
cJSON *json;
|
|
|
|
/* make C compiler happy */
|
|
(void) hashtable;
|
|
|
|
json = (cJSON *)data;
|
|
|
|
cJSON_AddItemToObject (
|
|
json,
|
|
(const char *)key,
|
|
cJSON_CreateString ((value) ? (const char *)value : ""));
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with a buffer.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_buffer_to_json (struct t_gui_buffer *buffer,
|
|
long lines,
|
|
long lines_free,
|
|
int nicks,
|
|
enum t_relay_api_colors colors)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_buffer *pointer;
|
|
struct t_gui_lines *ptr_lines;
|
|
struct t_gui_line *ptr_line;
|
|
struct t_gui_line_data *ptr_line_data;
|
|
cJSON *json, *json_local_vars, *json_lines, *json_nicklist_root;
|
|
const char *ptr_string;
|
|
char *string;
|
|
int last_read_line_id;
|
|
|
|
hdata = relay_hdata_buffer;
|
|
pointer = buffer;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!buffer)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_VAR(Number, "id", longlong, "id");
|
|
MSG_ADD_HDATA_STR("name", "full_name");
|
|
MSG_ADD_HDATA_STR("short_name", "short_name");
|
|
MSG_ADD_HDATA_VAR(Number, "number", integer, "number");
|
|
ptr_string = weechat_buffer_get_string (buffer, "type");
|
|
if (weechat_strcmp (ptr_string, "free") == 0)
|
|
lines = lines_free;
|
|
MSG_ADD_STR_PTR("type", ptr_string);
|
|
MSG_ADD_HDATA_VAR(Bool, "hidden", integer, "hidden");
|
|
MSG_ADD_HDATA_STR_COLORS("title", "title");
|
|
MSG_ADD_HDATA_STR_COLORS("modes", "modes");
|
|
MSG_ADD_HDATA_STR_COLORS("input_prompt", "input_prompt");
|
|
MSG_ADD_HDATA_STR("input", "input_buffer");
|
|
MSG_ADD_HDATA_VAR(Number, "input_position", integer, "input_buffer_pos");
|
|
MSG_ADD_HDATA_VAR(Bool, "input_multiline", integer, "input_multiline");
|
|
MSG_ADD_HDATA_VAR(Bool, "nicklist", integer, "nicklist");
|
|
MSG_ADD_HDATA_VAR(Bool, "nicklist_case_sensitive", integer, "nicklist_case_sensitive");
|
|
MSG_ADD_HDATA_VAR(Bool, "nicklist_display_groups", integer, "nicklist_display_groups");
|
|
MSG_ADD_HDATA_VAR(Bool, "time_displayed", integer, "time_for_each_line");
|
|
|
|
/* local_variables */
|
|
json_local_vars = cJSON_CreateObject ();
|
|
if (json_local_vars)
|
|
{
|
|
weechat_hashtable_map (
|
|
weechat_hdata_pointer (hdata, buffer, "local_variables"),
|
|
&relay_api_msg_buffer_add_local_vars_cb,
|
|
json_local_vars);
|
|
cJSON_AddItemToObject (json, "local_variables", json_local_vars);
|
|
}
|
|
|
|
/* keys local to buffer */
|
|
cJSON_AddItemToObject (json, "keys", relay_api_msg_keys_to_json (buffer));
|
|
|
|
/* lines */
|
|
if (lines != 0)
|
|
{
|
|
json_lines = relay_api_msg_lines_to_json (buffer, lines, colors);
|
|
if (json_lines)
|
|
cJSON_AddItemToObject (json, "lines", json_lines);
|
|
}
|
|
last_read_line_id = -1;
|
|
ptr_lines = weechat_hdata_pointer (relay_hdata_buffer, buffer, "own_lines");
|
|
if (ptr_lines)
|
|
{
|
|
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "last_read_line");
|
|
if (ptr_line)
|
|
{
|
|
ptr_line_data = weechat_hdata_pointer (relay_hdata_line, ptr_line, "data");
|
|
if (ptr_line_data)
|
|
{
|
|
last_read_line_id = weechat_hdata_integer (relay_hdata_line_data,
|
|
ptr_line_data, "id");
|
|
}
|
|
}
|
|
}
|
|
cJSON_AddItemToObject (
|
|
json, "last_read_line_id",
|
|
cJSON_CreateNumber (last_read_line_id));
|
|
|
|
/* nicks */
|
|
if (nicks)
|
|
{
|
|
json_nicklist_root = relay_api_msg_nick_group_to_json (
|
|
weechat_hdata_pointer (hdata, buffer, "nicklist_root"),
|
|
colors);
|
|
if (json_nicklist_root)
|
|
cJSON_AddItemToObject (json, "nicklist_root", json_nicklist_root);
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with a buffer key.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_key_to_json (struct t_gui_key *key)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_key *pointer;
|
|
cJSON *json;
|
|
const char *ptr_string;
|
|
|
|
hdata = relay_hdata_key;
|
|
pointer = key;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!key)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_STR("key", "key");
|
|
MSG_ADD_HDATA_STR("command", "command");
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with an array of buffer keys.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_keys_to_json (struct t_gui_buffer *buffer)
|
|
{
|
|
cJSON *json;
|
|
struct t_gui_key *ptr_key;
|
|
|
|
json = cJSON_CreateArray ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
ptr_key = weechat_hdata_pointer (relay_hdata_buffer, buffer, "keys");
|
|
while (ptr_key)
|
|
{
|
|
cJSON_AddItemToArray (json, relay_api_msg_key_to_json (ptr_key));
|
|
ptr_key = weechat_hdata_move (relay_hdata_key, ptr_key, 1);
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with a buffer line data.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_line_data_to_json (struct t_gui_line_data *line_data,
|
|
enum t_relay_api_colors colors)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_line_data *pointer;
|
|
cJSON *json, *json_tags;
|
|
const char *ptr_string;
|
|
char *string, str_time[256], str_var[64];
|
|
int i, tags_count;
|
|
struct timeval tv;
|
|
|
|
hdata = relay_hdata_line_data;
|
|
pointer = line_data;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!line_data)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_VAR(Number, "id", integer, "id");
|
|
MSG_ADD_HDATA_VAR(Number, "y", integer, "y");
|
|
MSG_ADD_HDATA_TIME_USEC("date", "date", "date_usec");
|
|
MSG_ADD_HDATA_TIME_USEC("date_printed", "date_printed", "date_usec_printed");
|
|
MSG_ADD_HDATA_VAR(Bool, "displayed", char, "displayed");
|
|
MSG_ADD_HDATA_VAR(Bool, "highlight", char, "highlight");
|
|
MSG_ADD_HDATA_VAR(Number, "notify_level", char, "notify_level");
|
|
MSG_ADD_HDATA_STR_COLORS("prefix", "prefix");
|
|
MSG_ADD_HDATA_STR_COLORS("message", "message");
|
|
|
|
/* tags */
|
|
json_tags = cJSON_CreateArray ();
|
|
if (json_tags)
|
|
{
|
|
tags_count = weechat_hdata_integer (hdata, line_data, "tags_count");
|
|
for (i = 0; i < tags_count; i++)
|
|
{
|
|
snprintf (str_var, sizeof (str_var), "%d|tags_array", i);
|
|
cJSON_AddItemToArray (
|
|
json_tags,
|
|
cJSON_CreateString (weechat_hdata_string (hdata, line_data, str_var)));
|
|
}
|
|
}
|
|
cJSON_AddItemToObject(json, "tags", json_tags);
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with an array of buffer lines.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_lines_to_json (struct t_gui_buffer *buffer,
|
|
long lines,
|
|
enum t_relay_api_colors colors)
|
|
{
|
|
cJSON *json;
|
|
struct t_gui_lines *ptr_lines;
|
|
struct t_gui_line *ptr_line;
|
|
struct t_gui_line_data *ptr_line_data;
|
|
long i, count;
|
|
|
|
json = cJSON_CreateArray ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (lines == 0)
|
|
return json;
|
|
|
|
ptr_lines = weechat_hdata_pointer (relay_hdata_buffer, buffer, "own_lines");
|
|
if (!ptr_lines)
|
|
return json;
|
|
|
|
if (lines < 0)
|
|
{
|
|
/* search start line from the last line */
|
|
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "last_line");
|
|
if (ptr_line)
|
|
{
|
|
for (i = -1; i > lines; i--)
|
|
{
|
|
ptr_line = weechat_hdata_move (relay_hdata_line, ptr_line, -1);
|
|
if (!ptr_line)
|
|
break;
|
|
}
|
|
if (!ptr_line)
|
|
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "first_line");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "first_line");
|
|
}
|
|
|
|
if (!ptr_line)
|
|
return json;
|
|
|
|
count = 0;
|
|
while (ptr_line)
|
|
{
|
|
ptr_line_data = weechat_hdata_pointer (relay_hdata_line, ptr_line, "data");
|
|
if (ptr_line_data)
|
|
{
|
|
cJSON_AddItemToArray (
|
|
json,
|
|
relay_api_msg_line_data_to_json (ptr_line_data, colors));
|
|
}
|
|
count++;
|
|
if ((lines > 0) && (count >= lines))
|
|
break;
|
|
ptr_line = weechat_hdata_move (relay_hdata_line, ptr_line, 1);
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a nick JSON object.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_nick_to_json (struct t_gui_nick *nick,
|
|
enum t_relay_api_colors colors)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_nick *pointer;
|
|
struct t_gui_nick_group *ptr_group;
|
|
cJSON *json;
|
|
const char *ptr_string, *ptr_color;
|
|
char *string;
|
|
|
|
hdata = relay_hdata_nick;
|
|
pointer = nick;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!nick)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_VAR(Number, "id", longlong, "id");
|
|
ptr_group = weechat_hdata_pointer (relay_hdata_nick, nick, "group");
|
|
cJSON_AddItemToObject (
|
|
json, "parent_group_id",
|
|
cJSON_CreateNumber (
|
|
(ptr_group) ?
|
|
weechat_hdata_longlong (relay_hdata_nick_group, ptr_group, "id") : -1));
|
|
MSG_ADD_HDATA_STR("prefix", "prefix");
|
|
MSG_ADD_HDATA_STR("prefix_color_name", "prefix_color");
|
|
MSG_ADD_HDATA_COLOR("prefix_color", "prefix_color");
|
|
MSG_ADD_HDATA_STR("name", "name");
|
|
MSG_ADD_HDATA_STR("color_name", "color");
|
|
MSG_ADD_HDATA_COLOR("color", "color");
|
|
MSG_ADD_HDATA_VAR(Bool, "visible", integer, "visible");
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a nick group JSON object.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_nick_group_to_json (struct t_gui_nick_group *nick_group,
|
|
enum t_relay_api_colors colors)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_nick_group *pointer, *ptr_group;
|
|
struct t_gui_nick *ptr_nick;
|
|
cJSON *json, *json_groups, *json_nicks;
|
|
const char *ptr_string, *ptr_color;
|
|
char *string;
|
|
|
|
hdata = relay_hdata_nick_group;
|
|
pointer = nick_group;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!nick_group)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_VAR(Number, "id", longlong, "id");
|
|
ptr_group = weechat_hdata_pointer (relay_hdata_nick_group, nick_group, "parent");
|
|
cJSON_AddItemToObject (
|
|
json, "parent_group_id",
|
|
cJSON_CreateNumber (
|
|
(ptr_group) ?
|
|
weechat_hdata_longlong (relay_hdata_nick_group, ptr_group, "id") : -1));
|
|
MSG_ADD_HDATA_STR("name", "name");
|
|
MSG_ADD_HDATA_STR("color_name", "color");
|
|
MSG_ADD_HDATA_COLOR("color", "color");
|
|
MSG_ADD_HDATA_VAR(Bool, "visible", integer, "visible");
|
|
|
|
json_groups = cJSON_CreateArray ();
|
|
if (json_groups)
|
|
{
|
|
ptr_group = weechat_hdata_pointer (relay_hdata_nick_group, nick_group, "children");
|
|
if (ptr_group)
|
|
{
|
|
while (ptr_group)
|
|
{
|
|
cJSON_AddItemToArray (
|
|
json_groups,
|
|
relay_api_msg_nick_group_to_json (ptr_group, colors));
|
|
ptr_group = weechat_hdata_move (relay_hdata_nick_group, ptr_group, 1);
|
|
}
|
|
}
|
|
cJSON_AddItemToObject (json, "groups", json_groups);
|
|
}
|
|
|
|
json_nicks = cJSON_CreateArray ();
|
|
if (json_nicks)
|
|
{
|
|
ptr_nick = weechat_hdata_pointer (relay_hdata_nick_group, nick_group, "nicks");
|
|
if (ptr_nick)
|
|
{
|
|
while (ptr_nick)
|
|
{
|
|
cJSON_AddItemToArray (
|
|
json_nicks,
|
|
relay_api_msg_nick_to_json (ptr_nick, colors));
|
|
ptr_nick = weechat_hdata_move (relay_hdata_nick, ptr_nick, 1);
|
|
}
|
|
}
|
|
cJSON_AddItemToObject (json, "nicks", json_nicks);
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with a completion entry.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_completion_to_json (struct t_gui_completion *completion)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_completion *pointer;
|
|
struct t_gui_completion_word *word;
|
|
const char *ptr_string;
|
|
struct t_arraylist *ptr_list;
|
|
cJSON *json, *json_array;
|
|
int context, i, size;
|
|
|
|
hdata = relay_hdata_completion;
|
|
pointer = completion;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!completion)
|
|
return json;
|
|
|
|
ptr_list = weechat_hdata_pointer (relay_hdata_completion, completion, "list");
|
|
if (!ptr_list)
|
|
return json;
|
|
|
|
/* context */
|
|
context = weechat_hdata_integer (relay_hdata_completion, completion, "context");
|
|
switch (context)
|
|
{
|
|
case 0:
|
|
MSG_ADD_STR_PTR("context", "null");
|
|
break;
|
|
case 1:
|
|
MSG_ADD_STR_PTR("context", "command");
|
|
break;
|
|
case 2:
|
|
MSG_ADD_STR_PTR("context", "command_arg");
|
|
break;
|
|
default:
|
|
MSG_ADD_STR_PTR("context", "auto");
|
|
break;
|
|
}
|
|
|
|
MSG_ADD_HDATA_STR("base_word", "base_word");
|
|
MSG_ADD_HDATA_VAR(Number, "position_replace", integer, "position_replace");
|
|
MSG_ADD_HDATA_VAR(Bool, "add_space", integer, "add_space");
|
|
|
|
json_array = cJSON_CreateArray ();
|
|
size = weechat_arraylist_size (ptr_list);
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
word = (struct t_gui_completion_word *)weechat_arraylist_get (ptr_list, i);
|
|
cJSON_AddItemToArray (
|
|
json_array,
|
|
cJSON_CreateString (
|
|
weechat_hdata_string (relay_hdata_completion_word, word, "word")));
|
|
}
|
|
cJSON_AddItemToObject (json, "list", json_array);
|
|
|
|
return json;
|
|
}
|
|
|
|
/*
|
|
* Create a JSON object with a hotlist entry.
|
|
*/
|
|
|
|
cJSON *
|
|
relay_api_msg_hotlist_to_json (struct t_gui_hotlist *hotlist)
|
|
{
|
|
struct t_hdata *hdata;
|
|
struct t_gui_hotlist *pointer;
|
|
struct t_gui_buffer *buffer;
|
|
cJSON *json, *json_count;
|
|
struct timeval tv;
|
|
char str_time[256], str_key[32];
|
|
int i, array_size;
|
|
long long buffer_id;
|
|
|
|
hdata = relay_hdata_hotlist;
|
|
pointer = hotlist;
|
|
|
|
json = cJSON_CreateObject ();
|
|
if (!json)
|
|
return NULL;
|
|
|
|
if (!hotlist)
|
|
return json;
|
|
|
|
MSG_ADD_HDATA_VAR(Number, "priority", integer, "priority");
|
|
MSG_ADD_HDATA_TIME_USEC("date", "time", "time_usec");
|
|
buffer = weechat_hdata_pointer (hdata, hotlist, "buffer");
|
|
buffer_id = (buffer) ?
|
|
weechat_hdata_longlong (relay_hdata_buffer, buffer, "id") : -1;
|
|
cJSON_AddItemToObject (json, "buffer_id", cJSON_CreateNumber (buffer_id));
|
|
|
|
json_count = cJSON_CreateArray ();
|
|
if (json_count)
|
|
{
|
|
array_size = weechat_hdata_get_var_array_size (hdata, hotlist, "count");
|
|
for (i = 0; i < array_size; i++)
|
|
{
|
|
snprintf (str_key, sizeof (str_key), "%d|count", i);
|
|
cJSON_AddItemToArray (
|
|
json_count,
|
|
cJSON_CreateNumber (weechat_hdata_integer (hdata, hotlist, str_key)));
|
|
}
|
|
}
|
|
cJSON_AddItemToObject (json, "count", json_count);
|
|
|
|
return json;
|
|
}
|