Skip to content

Commit 9bf88de

Browse files
committed
feature: /ignore command
Like it's already implemented in irc plugin, this commit adds the /ignore command. Now you can filter messages in group chats to not be shown, based on a part of Tox ID. The ignore list of IDs is manageable in this way: [tox] /ignore list add <ID part> del <ID part> ommit messages from people with certain Tox IDs list: show the list of ignores add: add an ID to the list del: delete an ID from the list
1 parent fe55894 commit 9bf88de

File tree

9 files changed

+285
-7
lines changed

9 files changed

+285
-7
lines changed

src/twc-chat.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,51 @@ twc_chat_search_buffer(struct t_gui_buffer *buffer)
280280
return NULL;
281281
}
282282

283+
/**
284+
* Set a prefix to a nickname in the nicklist of a chat.
285+
*/
286+
void
287+
twc_chat_update_prefix(struct t_twc_chat *chat, const char *id,
288+
const char *prefix, const char *prefix_color)
289+
{
290+
struct t_gui_nick_group *ptr_group = NULL;
291+
struct t_gui_nick *ptr_nick = NULL;
292+
293+
weechat_nicklist_get_next_item(chat->buffer, &ptr_group, &ptr_nick);
294+
while (ptr_group || ptr_nick)
295+
{
296+
if (ptr_nick)
297+
{
298+
const char *name_field = weechat_nicklist_nick_get_string(
299+
chat->buffer, ptr_nick, "name");
300+
if (!weechat_strncasecmp(id, name_field + sizeof(char), strlen(id)))
301+
{
302+
weechat_nicklist_nick_set(chat->buffer, ptr_nick,
303+
"prefix", prefix);
304+
weechat_nicklist_nick_set(chat->buffer, ptr_nick,
305+
"prefix_color", prefix_color);
306+
weechat_nicklist_nick_set(chat->buffer, ptr_nick, "color",
307+
"default");
308+
return;
309+
}
310+
}
311+
weechat_nicklist_get_next_item(chat->buffer, &ptr_group, &ptr_nick);
312+
}
313+
}
314+
315+
/**
316+
* Update prefix for a certain nickname structure pointer.
317+
*/
318+
void
319+
twc_chat_update_prefix_by_nick(struct t_gui_buffer *buffer,
320+
struct t_gui_nick *nick, const char *prefix,
321+
const char *prefix_color)
322+
{
323+
weechat_nicklist_nick_set(buffer, nick, "prefix", prefix);
324+
weechat_nicklist_nick_set(buffer, nick, "prefix_color", prefix_color);
325+
weechat_nicklist_nick_set(buffer, nick, "color", "default");
326+
}
327+
283328
/**
284329
* Print a chat message to a chat's buffer.
285330
*/

src/twc-chat.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ twc_chat_search_group(struct t_twc_profile *profile, int32_t group_number,
5656
struct t_twc_chat *
5757
twc_chat_search_buffer(struct t_gui_buffer *target_buffer);
5858

59+
void
60+
twc_chat_update_prefix(struct t_twc_chat *chat, const char *id,
61+
const char *prefix, const char *prefix_color);
62+
63+
void
64+
twc_chat_update_prefix_by_nick(struct t_gui_buffer *buffer,
65+
struct t_gui_nick *nick, const char *prefix,
66+
const char *prefix_color);
67+
5968
enum t_twc_rc
6069
twc_chat_set_logging(struct t_twc_chat const *const chat, bool logging);
6170

src/twc-commands.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,102 @@ twc_input_complete(const void *pointer, void *data, struct t_gui_buffer *buffer,
13811381
}
13821382
return WEECHAT_RC_OK;
13831383
}
1384+
/**
1385+
* Update a certain nick's prefix in all opened group chats
1386+
*/
1387+
void
1388+
twc_name_prefix_in_groupchats(struct t_twc_profile *profile, const char *id,
1389+
const char *prefix, const char *prefix_color)
1390+
{
1391+
struct t_twc_list_item *item;
1392+
struct t_twc_chat *chat;
1393+
size_t index;
1394+
twc_list_foreach (profile->chats, index, item)
1395+
{
1396+
chat = (struct t_twc_chat *)(item->chat);
1397+
if ((chat->group_number) >= 0)
1398+
{
1399+
twc_chat_update_prefix(chat, id, prefix, prefix_color);
1400+
}
1401+
}
1402+
}
1403+
1404+
/**
1405+
* Command /ignore callback.
1406+
*/
1407+
int
1408+
twc_cmd_ignore(const void *pointer, void *data, struct t_gui_buffer *buffer,
1409+
int argc, char **argv, char **argv_eol)
1410+
{
1411+
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
1412+
TWC_CHECK_PROFILE(profile);
1413+
TWC_CHECK_PROFILE_LOADED(profile);
1414+
1415+
/* list ignores */
1416+
if ((argc == 1) ||
1417+
((argc == 2) && (weechat_strcasecmp(argv[1], "list") == 0)))
1418+
{
1419+
if (!weechat_list_size(profile->ignores))
1420+
{
1421+
weechat_printf(profile->buffer, "ignore list is empty");
1422+
return WEECHAT_RC_OK;
1423+
}
1424+
weechat_printf(profile->buffer, "ignore list:");
1425+
size_t i = 0;
1426+
struct t_weelist_item *item;
1427+
for (item = weechat_list_get(profile->ignores, 0); item;
1428+
item = weechat_list_next(item))
1429+
{
1430+
weechat_printf(profile->buffer, " [%d] %s", i,
1431+
weechat_list_string(item));
1432+
i++;
1433+
}
1434+
return WEECHAT_RC_OK;
1435+
}
1436+
/* add ignore */
1437+
1438+
const char *id = argv_eol[2];
1439+
struct t_weelist_item *item;
1440+
item = weechat_list_casesearch(profile->ignores, id);
1441+
1442+
if (weechat_strcasecmp(argv[1], "add") == 0)
1443+
{
1444+
WEECHAT_COMMAND_MIN_ARGS(3, "add");
1445+
if (!item)
1446+
{
1447+
weechat_list_add(profile->ignores, id, WEECHAT_LIST_POS_END, NULL);
1448+
weechat_printf(profile->buffer,
1449+
"%sID '%s' has been added to the ignore list",
1450+
weechat_prefix("action"), id);
1451+
twc_name_prefix_in_groupchats(profile, id, "-", "yellow");
1452+
}
1453+
else
1454+
weechat_printf(profile->buffer,
1455+
"%sID '%s' is already in the ignore list",
1456+
weechat_prefix("error"), id);
1457+
return WEECHAT_RC_OK;
1458+
}
1459+
1460+
/* delete ignore */
1461+
if (weechat_strcasecmp(argv[1], "del") == 0)
1462+
{
1463+
WEECHAT_COMMAND_MIN_ARGS(3, "del");
1464+
if (item)
1465+
{
1466+
weechat_list_remove(profile->ignores, item);
1467+
weechat_printf(profile->buffer,
1468+
"%sID '%s' has been deleted from the ignore list",
1469+
weechat_prefix("action"), id);
1470+
twc_name_prefix_in_groupchats(profile, id, " ", "default");
1471+
}
1472+
else
1473+
weechat_printf(profile->buffer,
1474+
"%sthere's no ID '%s' in the ignore list",
1475+
weechat_prefix("error"), id);
1476+
return WEECHAT_RC_OK;
1477+
}
1478+
return WEECHAT_RC_ERROR;
1479+
}
13841480

13851481
/**
13861482
* Register Tox-WeeChat commands.
@@ -1519,4 +1615,16 @@ twc_commands_init()
15191615
"%(filename)"
15201616
" || %(tox_friend_name)|%(tox_friend_tox_id) %(filename)",
15211617
twc_cmd_send, NULL, NULL);
1618+
weechat_hook_command("ignore",
1619+
"ommit messages from people with certain Tox IDs",
1620+
"list"
1621+
" || add <ID part>"
1622+
" || del <ID part>",
1623+
"list: show the list of ignores\n"
1624+
"add: add an ID to the list\n"
1625+
"del: delete an ID from the list\n",
1626+
"list"
1627+
" || add %*"
1628+
" || del %*",
1629+
twc_cmd_ignore, NULL, NULL);
15221630
}

src/twc-config.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct t_config_file *twc_config_file = NULL;
3535
struct t_config_section *twc_config_section_look = NULL;
3636
struct t_config_section *twc_config_section_profile = NULL;
3737
struct t_config_section *twc_config_section_profile_default = NULL;
38+
struct t_config_section *twc_config_section_ignore = NULL;
3839

3940
struct t_config_option *twc_config_friend_request_message;
4041
struct t_config_option *twc_config_short_id_size;
@@ -207,6 +208,80 @@ twc_config_profile_change_callback(const void *pointer, void *data,
207208
}
208209
}
209210

211+
/*
212+
* Reads ignore option from configuration file.
213+
*
214+
* Returns:
215+
* 1: OK
216+
* 0: error
217+
*/
218+
int
219+
twc_config_ignore_read_callback(const void *pointer, void *data,
220+
struct t_config_file *config_file,
221+
struct t_config_section *section,
222+
const char *option_name, const char *value)
223+
{
224+
/* make C compiler happy */
225+
(void)pointer;
226+
(void)data;
227+
(void)config_file;
228+
(void)section;
229+
if (option_name)
230+
{
231+
char *profile_name = strrchr(option_name, '.');
232+
if (profile_name)
233+
{
234+
profile_name = strndup(option_name,
235+
(profile_name - option_name) / sizeof(char));
236+
struct t_twc_profile *profile =
237+
twc_profile_search_name(profile_name);
238+
if (profile)
239+
{
240+
weechat_list_add(profile->ignores, value, WEECHAT_LIST_POS_END,
241+
NULL);
242+
}
243+
free(profile_name);
244+
}
245+
}
246+
return 1;
247+
}
248+
249+
/*
250+
* Writes ignore section in tox configuration file.
251+
*/
252+
int
253+
twc_config_ignore_write_callback(const void *pointer, void *data,
254+
struct t_config_file *config_file,
255+
const char *section_name)
256+
{
257+
/* make C compiler happy */
258+
(void)pointer;
259+
(void)data;
260+
261+
if (!weechat_config_write_line(config_file, section_name, NULL))
262+
return WEECHAT_CONFIG_WRITE_ERROR;
263+
264+
struct t_twc_list_item *item;
265+
size_t index;
266+
twc_list_foreach (twc_profiles, index, item)
267+
{
268+
size_t option_name_len =
269+
strlen(item->profile->name) + strlen(".ignore") + 1;
270+
char option_name[option_name_len];
271+
snprintf(option_name, option_name_len - 1, "%s.ignore",
272+
item->profile->name);
273+
struct t_weelist_item *ignore_item;
274+
for (ignore_item = weechat_list_get(item->profile->ignores, 0);
275+
ignore_item; ignore_item = weechat_list_next(ignore_item))
276+
{
277+
if (!weechat_config_write_line(config_file, option_name,
278+
weechat_list_string(ignore_item)))
279+
return WEECHAT_CONFIG_WRITE_ERROR;
280+
}
281+
}
282+
return WEECHAT_CONFIG_WRITE_OK;
283+
}
284+
210285
/**
211286
* Create a new option for a profile. Returns NULL if an error occurs.
212287
*/
@@ -351,6 +426,12 @@ twc_config_init()
351426
twc_config_file, "profile_default", 0, 0, NULL, NULL, NULL, NULL, NULL,
352427
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
353428

429+
twc_config_section_ignore = weechat_config_new_section(
430+
twc_config_file, "ignore", 0, 0, twc_config_ignore_read_callback, NULL,
431+
NULL, twc_config_ignore_write_callback, NULL, NULL,
432+
twc_config_ignore_write_callback, NULL, NULL, NULL, NULL, NULL, NULL,
433+
NULL, NULL);
434+
354435
for (int i = 0; i < TWC_PROFILE_NUM_OPTIONS; ++i)
355436
{
356437
twc_config_profile_default[i] =

src/twc-profile.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ twc_profile_new(const char *name)
166166
profile->tox_online = false;
167167

168168
profile->chats = twc_list_new();
169+
profile->ignores = weechat_list_new();
169170
profile->friend_requests = twc_list_new();
170171
profile->group_chat_invites = twc_list_new();
171172
profile->message_queues = weechat_hashtable_new(
@@ -247,10 +248,10 @@ twc_tox_new_print_error(struct t_twc_profile *profile,
247248
weechat_prefix("error"), options->proxy_host);
248249
break;
249250
case TOX_ERR_NEW_PROXY_BAD_PORT:
250-
weechat_printf(profile->buffer,
251-
"%scould not load Tox (invalid proxy port: \"%"
252-
PRIu16 "\")",
253-
weechat_prefix("error"), options->proxy_port);
251+
weechat_printf(
252+
profile->buffer,
253+
"%scould not load Tox (invalid proxy port: \"%" PRIu16 "\")",
254+
weechat_prefix("error"), options->proxy_port);
254255
break;
255256
case TOX_ERR_NEW_PROXY_NOT_FOUND:
256257
weechat_printf(
@@ -698,6 +699,8 @@ twc_profile_free(struct t_twc_profile *profile)
698699

699700
/* free things */
700701
twc_chat_free_list(profile->chats);
702+
weechat_list_remove_all(profile->ignores);
703+
weechat_list_free(profile->ignores);
701704
twc_friend_request_free_list(profile->friend_requests);
702705
twc_group_chat_invite_free_list(profile->group_chat_invites);
703706
twc_tfer_free(profile->tfer);

src/twc-profile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct t_twc_profile
5959
struct t_hook *tox_do_timer;
6060

6161
struct t_twc_list *chats;
62+
struct t_weelist *ignores;
6263
struct t_twc_list *friend_requests;
6364
struct t_twc_list *group_chat_invites;
6465
struct t_hashtable *message_queues;

src/twc-tox-callbacks.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,18 @@ twc_handle_group_message(Tox *tox, int32_t group_number, int32_t peer_number,
408408
bool rc;
409409
struct t_twc_profile *profile = data;
410410

411+
char *short_id =
412+
twc_get_peer_id_short(profile->tox, group_number, peer_number);
413+
if (twc_is_id_ignored(profile, short_id))
414+
{
415+
free(short_id);
416+
return;
417+
}
411418
struct t_twc_chat *chat =
412419
twc_chat_search_group(profile, group_number, true);
413420

414421
char *myname = twc_get_self_name_nt(profile->tox);
415422
char *name = twc_get_peer_name_nt(profile->tox, group_number, peer_number);
416-
char *short_id =
417-
twc_get_peer_id_short(profile->tox, group_number, peer_number);
418423
char *full_name = twc_get_peer_name_prefixed(short_id, name);
419424
char *tags = "notify_message";
420425
char *message_nt = twc_null_terminate(message, length);
@@ -526,6 +531,12 @@ twc_group_peer_list_changed_callback(Tox *tox, uint32_t group_number,
526531
char *full_name = twc_get_peer_name_prefixed(short_id, name);
527532
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group,
528533
full_name, NULL, NULL, NULL, 1);
534+
nick = weechat_nicklist_search_nick(
535+
chat->buffer, chat->nicklist_group, full_name);
536+
bool ignored = twc_is_id_ignored(profile, short_id);
537+
twc_chat_update_prefix_by_nick(chat->buffer, nick,
538+
ignored ? "-" : " ",
539+
ignored ? "yellow" : "default");
529540
weechat_printf(
530541
chat->buffer, "%s%s just joined the group chat",
531542
weechat_prefix("join"),

src/twc-utils.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,23 @@ twc_get_next_completion(struct t_weelist *completion_list,
276276
return comp;
277277
}
278278

279+
/**
280+
* Checks if an ID is ignored.
281+
*/
282+
bool
283+
twc_is_id_ignored(struct t_twc_profile *profile, const char *short_id)
284+
{
285+
struct t_weelist_item *ignore_item;
286+
for (ignore_item = weechat_list_get(profile->ignores, 0); ignore_item;
287+
ignore_item = weechat_list_next(ignore_item))
288+
{
289+
if (!weechat_strncasecmp(short_id, weechat_list_string(ignore_item),
290+
strlen(weechat_list_string(ignore_item))))
291+
return true;
292+
}
293+
return false;
294+
}
295+
279296
/**
280297
* reverse the bytes of a 32-bit integer.
281298
*/

0 commit comments

Comments
 (0)