diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-command.c | 209 | ||||
-rw-r--r-- | src/core/wee-config.c | 11 | ||||
-rw-r--r-- | src/gui/gui-completion.c | 21 | ||||
-rw-r--r-- | src/gui/gui-filter.c | 43 | ||||
-rw-r--r-- | src/gui/gui-filter.h | 6 | ||||
-rw-r--r-- | src/plugins/irc/irc-channel.c | 376 | ||||
-rw-r--r-- | src/plugins/irc/irc-channel.h | 26 | ||||
-rw-r--r-- | src/plugins/irc/irc-config.c | 33 | ||||
-rw-r--r-- | src/plugins/irc/irc-config.h | 2 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 66 | ||||
-rw-r--r-- | src/plugins/irc/irc-upgrade.c | 33 |
11 files changed, 608 insertions, 218 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 5ab53a761..118155fab 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -774,9 +774,6 @@ command_filter (void *data, struct t_gui_buffer *buffer, int argc, char **argv, char **argv_eol) { struct t_gui_filter *ptr_filter; - int i; - long number; - char *error; /* make C compiler happy */ (void) data; @@ -797,17 +794,15 @@ command_filter (void *data, struct t_gui_buffer *buffer, { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, _("Message filters:")); - i = 0; for (ptr_filter = gui_filters; ptr_filter; ptr_filter = ptr_filter->next_filter) { - i++; gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _(" %s[%s%d%s]%s buffer: %s%s%s " + _(" %s[%s%s%s]%s buffer: %s%s%s " "/ tags: %s / regex: %s %s"), GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), GUI_COLOR(GUI_COLOR_CHAT), - i, + ptr_filter->name, GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), GUI_COLOR(GUI_COLOR_CHAT), GUI_COLOR(GUI_COLOR_CHAT_BUFFER), @@ -834,34 +829,23 @@ command_filter (void *data, struct t_gui_buffer *buffer, if (argc > 2) { /* enable a filter */ - error = NULL; - number = strtol (argv[2], &error, 10); - if (error && !error[0]) + ptr_filter = gui_filter_search_by_name (argv[2]); + if (ptr_filter) { - ptr_filter = gui_filter_search_by_number (number); - if (ptr_filter) - { - if (!ptr_filter->enabled) - { - gui_filter_enable (ptr_filter); - gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("Filter %d enabled"), - number); - } - } - else + if (!ptr_filter->enabled) { + gui_filter_enable (ptr_filter); gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: filter not found"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - return WEECHAT_RC_ERROR; + _("Filter \"%s\" enabled"), + ptr_filter->name); } } else { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: wrong filter number"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); + _("%sError: filter \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); return WEECHAT_RC_ERROR; } } @@ -884,34 +868,23 @@ command_filter (void *data, struct t_gui_buffer *buffer, if (argc > 2) { /* enable a filter */ - error = NULL; - number = strtol (argv[2], &error, 10); - if (error && !error[0]) + ptr_filter = gui_filter_search_by_name (argv[2]); + if (ptr_filter) { - ptr_filter = gui_filter_search_by_number (number); - if (ptr_filter) - { - if (ptr_filter->enabled) - { - gui_filter_disable (ptr_filter); - gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("Filter %d disabled"), - number); - } - } - else + if (ptr_filter->enabled) { + gui_filter_disable (ptr_filter); gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: filter not found"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - return WEECHAT_RC_ERROR; + _("Filter \"%s\" disabled"), + ptr_filter->name); } } else { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: wrong filter number"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); + _("%sError: filter \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); return WEECHAT_RC_ERROR; } } @@ -927,38 +900,27 @@ command_filter (void *data, struct t_gui_buffer *buffer, } return WEECHAT_RC_OK; } - + /* toggle global filtering or a filter on/off */ if (string_strcasecmp (argv[1], "toggle") == 0) { if (argc > 2) { /* toggle a filter */ - error = NULL; - number = strtol (argv[2], &error, 10); - if (error && !error[0]) + ptr_filter = gui_filter_search_by_name (argv[2]); + if (ptr_filter) { - ptr_filter = gui_filter_search_by_number (number); - if (ptr_filter) - { - if (ptr_filter->enabled) - gui_filter_disable (ptr_filter); - else - gui_filter_enable (ptr_filter); - } + if (ptr_filter->enabled) + gui_filter_disable (ptr_filter); else - { - gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: filter not found"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - return WEECHAT_RC_ERROR; - } + gui_filter_enable (ptr_filter); } else { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: wrong filter number"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); + _("%sError: filter \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); return WEECHAT_RC_ERROR; } } @@ -975,7 +937,7 @@ command_filter (void *data, struct t_gui_buffer *buffer, /* add filter */ if (string_strcasecmp (argv[1], "add") == 0) { - if (argc < 5) + if (argc < 6) { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, _("%sError: missing arguments for \"%s\" " @@ -984,26 +946,27 @@ command_filter (void *data, struct t_gui_buffer *buffer, "filter add"); return WEECHAT_RC_ERROR; } - if (gui_filter_search (argv[2], argv[3], argv_eol[4])) + if (gui_filter_search (argv[3], argv[4], argv_eol[5])) { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, _("%sError: filter already exists"), gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); return WEECHAT_RC_ERROR; } - if ((strcmp (argv[3], "*") == 0) && (strcmp (argv_eol[4], "*") == 0)) + if ((strcmp (argv[4], "*") == 0) && (strcmp (argv_eol[5], "*") == 0)) { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: you must specify at least tag(s) or " - "regex for filter"), + _("%sError: you must specify at least " + "tag(s) or regex for filter"), gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); return WEECHAT_RC_ERROR; } - if (gui_filter_new (1, argv[2], argv[3], argv_eol[4])) + if (gui_filter_new (1, argv[2], argv[3], argv[4], argv_eol[5])) { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("Filter added")); + _("Filter \"%s\" added"), + argv[2]); } else { @@ -1014,6 +977,51 @@ command_filter (void *data, struct t_gui_buffer *buffer, return WEECHAT_RC_OK; } + + /* rename a filter */ + if (string_strcasecmp (argv[1], "rename") == 0) + { + if (argc < 4) + { + gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, + _("%sError: missing arguments for \"%s\" " + "command"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + "filter rename"); + return WEECHAT_RC_ERROR; + } + + /* rename filter */ + ptr_filter = gui_filter_search_by_name (argv[2]); + if (ptr_filter) + { + if (gui_filter_rename (ptr_filter, argv[3])) + { + gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, + _("Filter \"%s\" renamed to \"%s\""), + argv[2], argv[3]); + } + else + { + gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, + _("%sError: unable to rename filter " + "\"%s\" to \"%s\""), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2], argv[3]); + return WEECHAT_RC_ERROR; + } + } + else + { + gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, + _("%sError: filter \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); + return WEECHAT_RC_ERROR; + } + + return WEECHAT_RC_OK; + } /* delete filter */ if (string_strcasecmp (argv[1], "del") == 0) @@ -1043,31 +1051,21 @@ command_filter (void *data, struct t_gui_buffer *buffer, } else { - error = NULL; - number = strtol (argv[2], &error, 10); - if (error && !error[0]) + ptr_filter = gui_filter_search_by_name (argv[2]); + if (ptr_filter) { - ptr_filter = gui_filter_search_by_number (number); - if (ptr_filter) - { - gui_filter_free (ptr_filter); - gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("Filter deleted")); - } - else - { - gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: filter not found"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - return WEECHAT_RC_ERROR; - } + gui_filter_free (ptr_filter); + gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, + _("Filter \"%s\" deleted"), + argv[2]); } else { gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER, - _("%sError: wrong filter number"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - return WEECHAT_RC_ERROR; + _("%sError: filter \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); + return WEECHAT_RC_ERROR; } } return WEECHAT_RC_OK; @@ -3112,18 +3110,17 @@ command_init () hook_command (NULL, "filter", N_("filter messages in buffers, to hide/show them according " "to tags or regex"), - N_("[list] | [enable|disable|toggle] | " - "[add buffer tags regex] | " - "[del number|-all]"), + N_("[list] | [enable|disable|toggle [name]] | " + "[add name buffer tags regex] | " + "[del name|-all]"), N_(" list: list all filters\n" " enable: enable filters (filters are enabled by " "default)\n" "disable: disable filters\n" " toggle: toggle filters\n" + " name: filter name\n" " add: add a filter\n" " del: delete a filter\n" - " number: number of filter to delete (look at list to " - "find it)\n" " -all: delete all filters\n" " buffer: buffer where filter is active: it may be " "a name or \"*\" for all buffers\n" @@ -3132,16 +3129,18 @@ command_init () " regex: regular expression to search in " "line (use \\t to separate prefix from message)\n\n" "Examples:\n" - " filter IRC join/part/quit messages:\n" - " /filter add * irc_join,irc_part,irc_quit *\n" + " use IRC smart filter for join/part/quit messages:\n" + " /filter add irc_smart * irc_smart_filter *\n" + " filter all IRC join/part/quit messages:\n" + " /filter add joinquit * irc_join,irc_part,irc_quit *\n" " filter nick \"toto\" on channel #weechat:\n" - " /filter add freenode.#weechat * toto\\t\n" + " /filter add toto freenode.#weechat * toto\\t\n" " filter lines containing word \"spam\":\n" - " /filter add * * spam\n" + " /filter add filterspam * * spam\n" " filter lines containing \"weechat sucks\" on channel " "#weechat:\n" - " /filter add freenode.#weechat * weechat sucks"), - "list|enable|disable|toggle|add|del", + " /filter add sucks freenode.#weechat * weechat sucks"), + "list|enable|disable|toggle|add|rename|del %F", &command_filter, NULL); hook_command (NULL, "help", N_("display help about commands and options"), diff --git a/src/core/wee-config.c b/src/core/wee-config.c index c884b15ab..427934900 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -704,13 +704,10 @@ config_weechat_filter_read (void *data, { argv = string_explode (value, ";", 0, 0, &argc); argv_eol = string_explode (value, ";", 1, 0, NULL); - if (argv && argv_eol && (argc >= 3)) + if (argv && argv_eol && (argc >= 4)) { - if (argc == 3) - gui_filter_new (1, argv[0], argv[1], argv_eol[2]); - else - gui_filter_new ((string_strcasecmp (argv[0], "on") == 0) ? 1 : 0, - argv[1], argv[2], argv_eol[3]); + gui_filter_new ((string_strcasecmp (argv[0], "on") == 0) ? 1 : 0, + option_name, argv[1], argv[2], argv_eol[3]); } if (argv) string_free_exploded (argv); @@ -740,7 +737,7 @@ config_weechat_filter_write (void *data, struct t_config_file *config_file, ptr_filter = ptr_filter->next_filter) { config_file_write_line (config_file, - "filter", + ptr_filter->name, "%s;%s;%s;%s", (ptr_filter->enabled) ? "on" : "off", ptr_filter->buffer, diff --git a/src/gui/gui-completion.c b/src/gui/gui-completion.c index 5dfb20a3c..f5dcf2bf5 100644 --- a/src/gui/gui-completion.c +++ b/src/gui/gui-completion.c @@ -43,6 +43,7 @@ #include "gui-bar.h" #include "gui-buffer.h" #include "gui-color.h" +#include "gui-filter.h" #include "gui-keyboard.h" #include "gui-nicklist.h" @@ -464,6 +465,23 @@ gui_completion_list_add_filename (struct t_gui_completion *completion) } /* + * gui_completion_list_add_filters: add filters to completion list + */ + +void +gui_completion_list_add_filters (struct t_gui_completion *completion) +{ + struct t_gui_filter *ptr_filter; + + for (ptr_filter = gui_filters; ptr_filter; + ptr_filter = ptr_filter->next_filter) + { + gui_completion_list_add (completion, ptr_filter->name, + 0, WEECHAT_LIST_POS_SORT); + } +} + +/* * gui_completion_list_add_command_hooks: add command hooks to completion list */ @@ -931,6 +949,9 @@ gui_completion_build_list_template (struct t_gui_completion *completion, case 'f': /* filename */ gui_completion_list_add_filename (completion); break; + case 'F': /* filters */ + gui_completion_list_add_filters (completion); + break; case 'h': /* command hooks */ gui_completion_list_add_command_hooks (completion); break; diff --git a/src/gui/gui-filter.c b/src/gui/gui-filter.c index 158971cbb..a2e841ea6 100644 --- a/src/gui/gui-filter.c +++ b/src/gui/gui-filter.c @@ -253,22 +253,19 @@ gui_filter_search (const char *buffer, const char *tags, const char *regex) } /* - * gui_filter_search_by_number: search a filter by number (first is #1) + * gui_filter_search_by_name: search a filter by name */ struct t_gui_filter * -gui_filter_search_by_number (int number) +gui_filter_search_by_name (const char *name) { struct t_gui_filter *ptr_filter; - int i; - - i = 1; + for (ptr_filter = gui_filters; ptr_filter; ptr_filter = ptr_filter->next_filter) { - if (i == number) + if (strcmp (ptr_filter->name, name) == 0) return ptr_filter; - i++; } /* filter not found */ @@ -280,15 +277,18 @@ gui_filter_search_by_number (int number) */ struct t_gui_filter * -gui_filter_new (int enabled, const char *buffer, const char *tags, - const char *regex) +gui_filter_new (int enabled, const char *name, const char *buffer, + const char *tags, const char *regex) { struct t_gui_filter *new_filter; regex_t *regex1, *regex2; char *pos_tab, *regex_prefix; const char *pos_regex_message; - if (!buffer || !tags || !regex) + if (!name || !buffer || !tags || !regex) + return NULL; + + if (gui_filter_search_by_name (name)) return NULL; regex1 = NULL; @@ -347,6 +347,7 @@ gui_filter_new (int enabled, const char *buffer, const char *tags, { /* init filter */ new_filter->enabled = enabled; + new_filter->name = strdup (name); new_filter->buffer = (buffer) ? strdup (buffer) : strdup ("*"); if (tags) { @@ -383,6 +384,25 @@ gui_filter_new (int enabled, const char *buffer, const char *tags, } /* + * gui_filter_rename: rename a filter + */ + +int +gui_filter_rename (struct t_gui_filter *filter, const char *new_name) +{ + if (!filter || !new_name) + return 0; + + if (gui_filter_search_by_name (new_name)) + return 0; + + free (filter->name); + filter->name = strdup (new_name); + + return 1; +} + +/* * gui_filter_free: remove a filter */ @@ -393,6 +413,8 @@ gui_filter_free (struct t_gui_filter *filter) WEECHAT_HOOK_SIGNAL_POINTER, filter); /* free data */ + if (filter->name) + free (filter->name); if (filter->buffer) free (filter->buffer); if (filter->tags) @@ -501,6 +523,7 @@ gui_filter_print_log () log_printf (""); log_printf ("[filter (addr:0x%x)]", ptr_filter); log_printf (" enabled. . . . . . . . : %d", ptr_filter->enabled); + log_printf (" name . . . . . . . . . : '%s'", ptr_filter->name); log_printf (" buffer . . . . . . . . : '%s'", ptr_filter->buffer); log_printf (" tags . . . . . . . . . : '%s'", ptr_filter->tags); log_printf (" regex. . . . . . . . . : '%s'", ptr_filter->regex); diff --git a/src/gui/gui-filter.h b/src/gui/gui-filter.h index 0d79a5eef..f49513e37 100644 --- a/src/gui/gui-filter.h +++ b/src/gui/gui-filter.h @@ -31,6 +31,7 @@ struct t_gui_line; struct t_gui_filter { int enabled; /* 1 if filter enabled, otherwise 0 */ + char *name; char *buffer; /* name of buffer */ char *tags; /* tags */ int tags_count; /* number of tags */ @@ -59,11 +60,14 @@ extern void gui_filter_disable (struct t_gui_filter *filter); extern struct t_gui_filter *gui_filter_search (const char *buffer, const char *tags, const char *regex); -extern struct t_gui_filter *gui_filter_search_by_number (int number); +extern struct t_gui_filter *gui_filter_search_by_name (const char *name); extern struct t_gui_filter *gui_filter_new (int enabled, + const char *name, const char *buffer, const char *tags, const char *regex); +extern int gui_filter_rename (struct t_gui_filter *filter, + const char *new_name); extern void gui_filter_free (struct t_gui_filter *filter); extern void gui_filter_free_all (); extern int gui_filter_add_to_infolist (struct t_infolist *infolist, diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c index 0d2debba5..9ca7f2501 100644 --- a/src/plugins/irc/irc-channel.c +++ b/src/plugins/irc/irc-channel.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <unistd.h> +#include <stdio.h> #include <string.h> #include "../weechat-plugin.h" @@ -148,6 +149,8 @@ irc_channel_new (struct t_irc_server *server, int channel_type, new_channel->last_nick = NULL; new_channel->buffer = new_buffer; new_channel->nicks_speaking = NULL; + new_channel->nicks_speaking_time = NULL; + new_channel->last_nick_speaking_time = NULL; new_channel->buffer_as_string = NULL; /* add new channel to channels list */ @@ -181,66 +184,6 @@ irc_channel_set_topic (struct t_irc_channel *channel, char *topic) } /* - * irc_channel_free: free a channel and remove it from channels list - */ - -void -irc_channel_free (struct t_irc_server *server, struct t_irc_channel *channel) -{ - struct t_irc_channel *new_channels; - - if (!server || !channel) - return; - - /* remove channel from channels list */ - if (server->last_channel == channel) - server->last_channel = channel->prev_channel; - if (channel->prev_channel) - { - (channel->prev_channel)->next_channel = channel->next_channel; - new_channels = server->channels; - } - else - new_channels = channel->next_channel; - - if (channel->next_channel) - (channel->next_channel)->prev_channel = channel->prev_channel; - - /* free data */ - if (channel->name) - free (channel->name); - if (channel->topic) - free (channel->topic); - if (channel->modes) - free (channel->modes); - if (channel->key) - free (channel->key); - irc_nick_free_all (channel); - if (channel->away_message) - free (channel->away_message); - if (channel->nicks_speaking) - weechat_list_free (channel->nicks_speaking); - if (channel->buffer_as_string) - free (channel->buffer_as_string); - - free (channel); - - server->channels = new_channels; -} - -/* - * irc_channel_free_all: free all allocated channels - */ - -void -irc_channel_free_all (struct t_irc_server *server) -{ - /* remove all channels for the server */ - while (server->channels) - irc_channel_free (server, server->channels); -} - -/* * irc_channel_search: returns pointer on a channel with name */ @@ -386,11 +329,11 @@ irc_channel_set_away (struct t_irc_channel *channel, const char *nick, int is_aw } /* - * irc_channel_add_nick_speaking: add a nick speaking on a channel + * irc_channel_nick_speaking_add: add a nick speaking on a channel */ void -irc_channel_add_nick_speaking (struct t_irc_channel *channel, const char *nick) +irc_channel_nick_speaking_add (struct t_irc_channel *channel, const char *nick) { int size, to_remove, i; @@ -412,6 +355,233 @@ irc_channel_add_nick_speaking (struct t_irc_channel *channel, const char *nick) } /* + * irc_channel_nick_speaking_rename: rename a nick speaking on a channel + */ + +void +irc_channel_nick_speaking_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick) +{ + struct t_weelist_item *ptr_item; + + if (channel->nicks_speaking) + { + ptr_item = weechat_list_search (channel->nicks_speaking, old_nick); + if (ptr_item) + weechat_list_set (ptr_item, new_nick); + } +} + +/* + * irc_channel_nick_speaking_time_search: search a nick speaking time on a + * channel + */ + +struct t_irc_channel_speaking * +irc_channel_nick_speaking_time_search (struct t_irc_channel *channel, + const char *nick, + int check_time) +{ + struct t_irc_channel_speaking *ptr_nick; + time_t time_limit; + + time_limit = time (NULL) - + (weechat_config_integer (irc_config_look_smart_filter_delay) * 60); + + for (ptr_nick = channel->nicks_speaking_time; ptr_nick; + ptr_nick = ptr_nick->next_nick) + { + if (strcmp (ptr_nick->nick, nick) == 0) + { + if (check_time && (ptr_nick->time_last_message < time_limit)) + return NULL; + return ptr_nick; + } + } + + /* nick speaking time not found */ + return NULL; +} + +/* + * irc_channel_nick_speaking_time_free: free a nick speaking on a channel + */ + +void +irc_channel_nick_speaking_time_free (struct t_irc_channel *channel, + struct t_irc_channel_speaking *nick) +{ + /* free data */ + if (nick->nick) + free (nick->nick); + + /* remove nick from list */ + if (nick->prev_nick) + (nick->prev_nick)->next_nick = nick->next_nick; + if (nick->next_nick) + (nick->next_nick)->prev_nick = nick->prev_nick; + if (channel->nicks_speaking_time == nick) + channel->nicks_speaking_time = nick->next_nick; + if (channel->last_nick_speaking_time == nick) + channel->last_nick_speaking_time = nick->prev_nick; + + free (nick); +} + +/* + * irc_channel_nick_speaking_time_free_all: free all nick speaking on a channel + */ + +void +irc_channel_nick_speaking_time_free_all (struct t_irc_channel *channel) +{ + while (channel->nicks_speaking_time) + { + irc_channel_nick_speaking_time_free (channel, + channel->nicks_speaking_time); + } +} + +/* + * irc_channel_nick_speaking_time_remove_old: remove old nicks speaking + */ + +void +irc_channel_nick_speaking_time_remove_old (struct t_irc_channel *channel) +{ + time_t time_limit; + + time_limit = time (NULL) - + (weechat_config_integer (irc_config_look_smart_filter_delay) * 60); + + while (channel->last_nick_speaking_time) + { + if (channel->last_nick_speaking_time->time_last_message >= time_limit) + break; + + irc_channel_nick_speaking_time_free (channel, + channel->last_nick_speaking_time); + } +} + +/* + * irc_channel_nick_speaking_time_add: add a nick speaking time on a channel + */ + +void +irc_channel_nick_speaking_time_add (struct t_irc_channel *channel, + const char *nick, + time_t time_last_message) +{ + struct t_irc_channel_speaking *ptr_nick, *new_nick; + + ptr_nick = irc_channel_nick_speaking_time_search (channel, nick, 0); + if (ptr_nick) + irc_channel_nick_speaking_time_free (channel, ptr_nick); + + new_nick = malloc (sizeof (*new_nick)); + if (new_nick) + { + new_nick->nick = strdup (nick); + new_nick->time_last_message = time_last_message; + + /* insert nick at beginning of list */ + new_nick->prev_nick = NULL; + new_nick->next_nick = channel->nicks_speaking_time; + if (channel->nicks_speaking_time) + channel->nicks_speaking_time->prev_nick = new_nick; + else + channel->last_nick_speaking_time = new_nick; + channel->nicks_speaking_time = new_nick; + } +} + +/* + * irc_channel_nick_speaking_time_rename: rename a nick speaking time on a + * channel + */ + +void +irc_channel_nick_speaking_time_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick) +{ + struct t_irc_channel_speaking *ptr_nick; + + if (channel->nicks_speaking_time) + { + ptr_nick = irc_channel_nick_speaking_time_search (channel, old_nick, 0); + if (ptr_nick) + { + free (ptr_nick->nick); + ptr_nick->nick = strdup (new_nick); + } + } +} + +/* + * irc_channel_free: free a channel and remove it from channels list + */ + +void +irc_channel_free (struct t_irc_server *server, struct t_irc_channel *channel) +{ + struct t_irc_channel *new_channels; + + if (!server || !channel) + return; + + /* remove channel from channels list */ + if (server->last_channel == channel) + server->last_channel = channel->prev_channel; + if (channel->prev_channel) + { + (channel->prev_channel)->next_channel = channel->next_channel; + new_channels = server->channels; + } + else + new_channels = channel->next_channel; + + if (channel->next_channel) + (channel->next_channel)->prev_channel = channel->prev_channel; + + /* free data */ + if (channel->name) + free (channel->name); + if (channel->topic) + free (channel->topic); + if (channel->modes) + free (channel->modes); + if (channel->key) + free (channel->key); + irc_nick_free_all (channel); + if (channel->away_message) + free (channel->away_message); + if (channel->nicks_speaking) + weechat_list_free (channel->nicks_speaking); + irc_channel_nick_speaking_time_free_all (channel); + if (channel->buffer_as_string) + free (channel->buffer_as_string); + + free (channel); + + server->channels = new_channels; +} + +/* + * irc_channel_free_all: free all allocated channels + */ + +void +irc_channel_free_all (struct t_irc_server *server) +{ + /* remove all channels for the server */ + while (server->channels) + irc_channel_free (server, server->channels); +} + +/* * irc_channel_add_to_infolist: add a channel in an infolist * return 1 if ok, 0 if error */ @@ -421,6 +591,10 @@ irc_channel_add_to_infolist (struct t_infolist *infolist, struct t_irc_channel *channel) { struct t_infolist_item *ptr_item; + struct t_weelist_item *ptr_list_item; + struct t_irc_channel_speaking *ptr_nick; + char option_name[64]; + int i; if (!infolist || !channel) return 0; @@ -463,6 +637,39 @@ irc_channel_add_to_infolist (struct t_infolist *infolist, return 0; if (!weechat_infolist_new_var_integer (ptr_item, "nick_completion_reset", channel->nick_completion_reset)) return 0; + if (channel->nicks_speaking) + { + i = 0; + for (ptr_list_item = weechat_list_get (channel->nicks_speaking, 0); + ptr_list_item; + ptr_list_item = weechat_list_next (ptr_list_item)) + { + snprintf (option_name, sizeof (option_name), "nick_speaking_%05d", i); + if (!weechat_infolist_new_var_string (ptr_item, option_name, + weechat_list_string (ptr_list_item))) + return 0; + i++; + } + } + if (channel->nicks_speaking_time) + { + i = 0; + for (ptr_nick = channel->last_nick_speaking_time; ptr_nick; + ptr_nick = ptr_nick->prev_nick) + { + snprintf (option_name, sizeof (option_name), + "nick_speaking_time_nick_%05d", i); + if (!weechat_infolist_new_var_string (ptr_item, option_name, + ptr_nick->nick)) + return 0; + snprintf (option_name, sizeof (option_name), + "nick_speaking_time_time_%05d", i); + if (!weechat_infolist_new_var_time (ptr_item, option_name, + ptr_nick->time_last_message)) + return 0; + i++; + } + } return 1; } @@ -475,26 +682,29 @@ void irc_channel_print_log (struct t_irc_channel *channel) { struct t_weelist_item *ptr_item; + struct t_irc_channel_speaking *ptr_nick_speaking; int i; struct t_irc_nick *ptr_nick; weechat_log_printf (""); weechat_log_printf (" => channel %s (addr:0x%x)]", channel->name, channel); - weechat_log_printf (" type . . . . . . . . : %d", channel->type); - weechat_log_printf (" topic. . . . . . . . : '%s'", channel->topic); - weechat_log_printf (" modes. . . . . . . . : '%s'", channel->modes); - weechat_log_printf (" limit. . . . . . . . : %d", channel->limit); - weechat_log_printf (" key. . . . . . . . . : '%s'", channel->key); - weechat_log_printf (" checking_away. . . . : %d", channel->checking_away); - weechat_log_printf (" away_message . . . . : '%s'", channel->away_message); - weechat_log_printf (" cycle. . . . . . . . : %d", channel->cycle); - weechat_log_printf (" display_creation_date: %d", channel->display_creation_date); - weechat_log_printf (" nicks. . . . . . . . : 0x%x", channel->nicks); - weechat_log_printf (" last_nick. . . . . . : 0x%x", channel->last_nick); - weechat_log_printf (" buffer . . . . . . . : 0x%x", channel->buffer); - weechat_log_printf (" nicks_speaking . . . : 0x%x", channel->nicks_speaking); - weechat_log_printf (" prev_channel . . . . : 0x%x", channel->prev_channel); - weechat_log_printf (" next_channel . . . . : 0x%x", channel->next_channel); + weechat_log_printf (" type . . . . . . . . . . : %d", channel->type); + weechat_log_printf (" topic. . . . . . . . . . : '%s'", channel->topic); + weechat_log_printf (" modes. . . . . . . . . . : '%s'", channel->modes); + weechat_log_printf (" limit. . . . . . . . . . : %d", channel->limit); + weechat_log_printf (" key. . . . . . . . . . . : '%s'", channel->key); + weechat_log_printf (" checking_away. . . . . . : %d", channel->checking_away); + weechat_log_printf (" away_message . . . . . . : '%s'", channel->away_message); + weechat_log_printf (" cycle. . . . . . . . . . : %d", channel->cycle); + weechat_log_printf (" display_creation_date. . : %d", channel->display_creation_date); + weechat_log_printf (" nicks. . . . . . . . . . : 0x%x", channel->nicks); + weechat_log_printf (" last_nick. . . . . . . . : 0x%x", channel->last_nick); + weechat_log_printf (" buffer . . . . . . . . . : 0x%x", channel->buffer); + weechat_log_printf (" nicks_speaking . . . . . : 0x%x", channel->nicks_speaking); + weechat_log_printf (" nicks_speaking_time. . . : 0x%x", channel->nicks_speaking_time); + weechat_log_printf (" last_nick_speaking_time. : 0x%x", channel->last_nick_speaking_time); + weechat_log_printf (" prev_channel . . . . . . : 0x%x", channel->prev_channel); + weechat_log_printf (" next_channel . . . . . . : 0x%x", channel->next_channel); if (channel->nicks_speaking) { weechat_log_printf (""); @@ -507,6 +717,18 @@ irc_channel_print_log (struct t_irc_channel *channel) i++; } } + if (channel->nicks_speaking_time) + { + weechat_log_printf (""); + for (ptr_nick_speaking = channel->nicks_speaking_time; + ptr_nick_speaking; + ptr_nick_speaking = ptr_nick_speaking->next_nick) + { + weechat_log_printf (" nick speaking time: '%s', time: %ld", + ptr_nick_speaking->nick, + ptr_nick_speaking->time_last_message); + } + } for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) { irc_nick_print_log (ptr_nick); diff --git a/src/plugins/irc/irc-channel.h b/src/plugins/irc/irc-channel.h index 4d40ec72c..7a54244f7 100644 --- a/src/plugins/irc/irc-channel.h +++ b/src/plugins/irc/irc-channel.h @@ -31,6 +31,14 @@ struct t_irc_server; +struct t_irc_channel_speaking +{ + char *nick; /* nick speaking */ + time_t time_last_message; /* time */ + struct t_irc_channel_speaking *prev_nick; /* pointer to previous nick */ + struct t_irc_channel_speaking *next_nick; /* pointer to next nick */ +}; + struct t_irc_channel { int type; /* channel type */ @@ -49,6 +57,9 @@ struct t_irc_channel struct t_irc_nick *nicks; /* nicks on the channel */ struct t_irc_nick *last_nick; /* last nick on the channel */ struct t_weelist *nicks_speaking; /* for smart completion */ + struct t_irc_channel_speaking *nicks_speaking_time; /* for smart filter */ + /* of join/part/quit messages */ + struct t_irc_channel_speaking *last_nick_speaking_time; struct t_gui_buffer *buffer; /* buffer allocated for channel */ char *buffer_as_string; /* used to return buffer info */ struct t_irc_channel *prev_channel; /* link to previous channel */ @@ -77,8 +88,21 @@ extern void irc_channel_check_away (struct t_irc_server *server, struct t_irc_channel *channel, int force); extern void irc_channel_set_away (struct t_irc_channel *channel, const char *nick, int is_away); -extern void irc_channel_add_nick_speaking (struct t_irc_channel *channel, +extern void irc_channel_nick_speaking_add (struct t_irc_channel *channel, const char *nick); +extern void irc_channel_nick_speaking_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick); +extern struct t_irc_channel_speaking *irc_channel_nick_speaking_time_search (struct t_irc_channel *channel, + const char *nick, + int check_time); +extern void irc_channel_nick_speaking_time_remove_old (struct t_irc_channel *channel); +extern void irc_channel_nick_speaking_time_add (struct t_irc_channel *channel, + const char *nick, + time_t time_last_message); +extern void irc_channel_nick_speaking_time_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick); extern int irc_channel_add_to_infolist (struct t_infolist *infolist, struct t_irc_channel *channel); extern void irc_channel_print_log (struct t_irc_channel *channel); diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index 598dfd3d8..db2e33a3f 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -59,6 +59,8 @@ struct t_config_option *irc_config_look_display_away; struct t_config_option *irc_config_look_display_channel_modes; struct t_config_option *irc_config_look_highlight_tags; struct t_config_option *irc_config_look_show_away_once; +struct t_config_option *irc_config_look_smart_filter; +struct t_config_option *irc_config_look_smart_filter_delay; struct t_config_option *irc_config_look_notice_as_pv; /* IRC config, network section */ @@ -140,7 +142,7 @@ irc_config_get_server_from_option_name (const char *name) /* * irc_config_change_one_server_buffer: called when the "one server buffer" - * setting is changed + * option is changed */ void @@ -154,7 +156,7 @@ irc_config_change_one_server_buffer () /* * irc_config_change_display_channel_modes: called when the "display channel modes" - * setting is changed + * option is changed */ void @@ -164,6 +166,22 @@ irc_config_change_display_channel_modes () } /* + * irc_config_change_smart_filter: called when the "smart_filter" option is + * changed + */ + +void +irc_config_change_smart_filter () +{ + if (weechat_config_boolean (irc_config_look_smart_filter)) + { + weechat_printf (NULL, + _("You should now create filter on tag " + "\"irc_smart_filter\" with command /filter.")); + } +} + +/* * irc_config_change_away_check: called when away check is changed */ @@ -1023,6 +1041,17 @@ irc_config_init () "show_away_once", "boolean", N_("show remote away message only once in private"), NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL, NULL); + irc_config_look_smart_filter = weechat_config_new_option ( + irc_config_file, ptr_section, + "smart_filter", "boolean", + N_("filter join/part/quit messages for a nick if not speaking for " + "some minutes on channel"), + NULL, 0, 0, "off", NULL, NULL, NULL, &irc_config_change_smart_filter, NULL, NULL, NULL); + irc_config_look_smart_filter_delay = weechat_config_new_option ( + irc_config_file, ptr_section, + "smart_filter_delay", "integer", + N_("delay for filtering join/part/quit messages (in minutes)"), + NULL, 1, 60*24*7, "5", NULL, NULL, NULL, NULL, NULL, NULL, NULL); irc_config_look_notice_as_pv = weechat_config_new_option ( irc_config_file, ptr_section, "notice_as_pv", "boolean", diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h index d1c110254..4a16077a3 100644 --- a/src/plugins/irc/irc-config.h +++ b/src/plugins/irc/irc-config.h @@ -71,6 +71,8 @@ extern struct t_config_option *irc_config_look_display_away; extern struct t_config_option *irc_config_look_display_channel_modes; extern struct t_config_option *irc_config_look_highlight_tags; extern struct t_config_option *irc_config_look_show_away_once; +extern struct t_config_option *irc_config_look_smart_filter; +extern struct t_config_option *irc_config_look_smart_filter_delay; extern struct t_config_option *irc_config_look_notice_as_pv; extern struct t_config_option *irc_config_network_default_msg_part; diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 09fa4bc60..6a91259e2 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -267,7 +267,9 @@ irc_protocol_cmd_join (struct t_irc_server *server, const char *command, { struct t_irc_channel *ptr_channel; struct t_irc_nick *ptr_nick; + struct t_irc_channel_speaking *ptr_nick_speaking; char *pos_channel; + int local_join; /* JOIN message looks like: :nick!user@host JOIN :#channel @@ -299,8 +301,14 @@ irc_protocol_cmd_join (struct t_irc_server *server, const char *command, if (!irc_ignore_check (server, ptr_channel, nick, host)) { + local_join = (strcmp (nick, server->nick) == 0); + ptr_nick_speaking = (weechat_config_boolean (irc_config_look_smart_filter)) ? + irc_channel_nick_speaking_time_search (ptr_channel, nick, 1) : NULL; weechat_printf_tags (ptr_channel->buffer, - "irc_join", + (local_join + || !weechat_config_boolean (irc_config_look_smart_filter) + || ptr_nick_speaking) ? + "irc_join" : "irc_join,irc_smart_filter", _("%s%s%s %s(%s%s%s)%s has joined %s%s"), weechat_prefix ("join"), IRC_COLOR_CHAT_NICK, @@ -575,7 +583,7 @@ irc_protocol_cmd_nick (struct t_irc_server *server, const char *command, struct t_irc_channel *ptr_channel; struct t_irc_nick *ptr_nick; char *new_nick; - int nick_is_me; + int local_nick; /* NICK message looks like: :oldnick!user@host NICK :newnick @@ -590,7 +598,7 @@ irc_protocol_cmd_nick (struct t_irc_server *server, const char *command, new_nick = (argv[2][0] == ':') ? argv[2] + 1 : argv[2]; - nick_is_me = (strcmp (nick, server->nick) == 0) ? 1 : 0; + local_nick = (strcmp (nick, server->nick) == 0) ? 1 : 0; for (ptr_channel = server->channels; ptr_channel; ptr_channel = ptr_channel->next_channel) @@ -616,7 +624,7 @@ irc_protocol_cmd_nick (struct t_irc_server *server, const char *command, /* change nick and display message on all channels */ irc_nick_change (server, ptr_channel, ptr_nick, new_nick); - if (nick_is_me) + if (local_nick) { weechat_printf_tags (ptr_channel->buffer, "irc_nick", @@ -641,6 +649,10 @@ irc_protocol_cmd_nick (struct t_irc_server *server, const char *command, IRC_COLOR_CHAT_NICK, new_nick); } + irc_channel_nick_speaking_rename (ptr_channel, + nick, new_nick); + irc_channel_nick_speaking_time_rename (ptr_channel, + nick, new_nick); } /* enable hotlist */ @@ -650,7 +662,7 @@ irc_protocol_cmd_nick (struct t_irc_server *server, const char *command, } } - if (nick_is_me) + if (local_nick) irc_server_set_nick (server, new_nick); return WEECHAT_RC_OK; @@ -879,9 +891,10 @@ irc_protocol_cmd_part (struct t_irc_server *server, const char *command, int argc, char **argv, char **argv_eol) { char *pos_comment, *join_string; - int join_length; + int join_length, local_part; struct t_irc_channel *ptr_channel; struct t_irc_nick *ptr_nick; + struct t_irc_channel_speaking *ptr_nick_speaking; /* PART message looks like: :nick!user@host PART #channel :part message @@ -900,13 +913,20 @@ irc_protocol_cmd_part (struct t_irc_server *server, const char *command, ptr_nick = irc_nick_search (ptr_channel, nick); if (ptr_nick) { + local_part = (strcmp (nick, server->nick) == 0); + /* display part message */ if (!irc_ignore_check (server, ptr_channel, nick, host)) { + ptr_nick_speaking = (weechat_config_boolean (irc_config_look_smart_filter)) ? + irc_channel_nick_speaking_time_search (ptr_channel, nick, 1) : NULL; if (pos_comment) { weechat_printf_tags (ptr_channel->buffer, - "irc_part", + (local_part + || !weechat_config_boolean (irc_config_look_smart_filter) + || ptr_nick_speaking) ? + "irc_part" : "irc_part,irc_smart_filter", _("%s%s%s %s(%s%s%s)%s has left %s%s " "%s(%s%s%s)"), weechat_prefix ("quit"), @@ -927,7 +947,10 @@ irc_protocol_cmd_part (struct t_irc_server *server, const char *command, else { weechat_printf_tags (ptr_channel->buffer, - "irc_part", + (local_part + || !weechat_config_boolean (irc_config_look_smart_filter) + || ptr_nick_speaking) ? + "irc_part" : "irc_part,irc_smart_filter", _("%s%s%s %s(%s%s%s)%s has left " "%s%s"), weechat_prefix ("quit"), @@ -944,7 +967,7 @@ irc_protocol_cmd_part (struct t_irc_server *server, const char *command, } /* part request was issued by local client ? */ - if (strcmp (ptr_nick->name, server->nick) == 0) + if (local_part) { irc_nick_free_all (ptr_channel); @@ -1158,7 +1181,10 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, const char *command, IRC_COLOR_CHAT, pos_args); - irc_channel_add_nick_speaking (ptr_channel, nick); + irc_channel_nick_speaking_add (ptr_channel, nick); + irc_channel_nick_speaking_time_remove_old (ptr_channel); + irc_channel_nick_speaking_time_add (ptr_channel, nick, + time (NULL)); if (pos_end_01) pos_end_01[0] = '\01'; @@ -1315,7 +1341,10 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, const char *command, NULL), pos_args); - irc_channel_add_nick_speaking (ptr_channel, nick); + irc_channel_nick_speaking_add (ptr_channel, nick); + irc_channel_nick_speaking_time_remove_old (ptr_channel); + irc_channel_nick_speaking_time_add (ptr_channel, nick, + time (NULL)); } } else @@ -2011,6 +2040,8 @@ irc_protocol_cmd_quit (struct t_irc_server *server, const char *command, char *pos_comment; struct t_irc_channel *ptr_channel; struct t_irc_nick *ptr_nick; + struct t_irc_channel_speaking *ptr_nick_speaking; + int local_quit; /* QUIT message looks like: :nick!user@host QUIT :quit message @@ -2039,10 +2070,16 @@ irc_protocol_cmd_quit (struct t_irc_server *server, const char *command, /* display quit message */ if (!irc_ignore_check (server, ptr_channel, nick, host)) { + local_quit = (strcmp (nick, server->nick) == 0); + ptr_nick_speaking = (weechat_config_boolean (irc_config_look_smart_filter)) ? + irc_channel_nick_speaking_time_search (ptr_channel, nick, 1) : NULL; if (pos_comment && pos_comment[0]) { weechat_printf_tags (ptr_channel->buffer, - "irc_quit", + (local_quit + || !weechat_config_boolean (irc_config_look_smart_filter) + || ptr_nick_speaking) ? + "irc_quit" : "irc_quit,irc_smart_filter", _("%s%s%s %s(%s%s%s)%s has quit " "%s(%s%s%s)"), weechat_prefix ("quit"), @@ -2061,7 +2098,10 @@ irc_protocol_cmd_quit (struct t_irc_server *server, const char *command, else { weechat_printf_tags (ptr_channel->buffer, - "irc_quit", + (local_quit + || !weechat_config_boolean (irc_config_look_smart_filter) + || ptr_nick_speaking) ? + "irc_quit" : "irc_quit,irc_smart_filter", _("%s%s%s %s(%s%s%s)%s has quit"), weechat_prefix ("quit"), IRC_COLOR_CHAT_NICK, diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c index a46c37c02..c2a04000a 100644 --- a/src/plugins/irc/irc-upgrade.c +++ b/src/plugins/irc/irc-upgrade.c @@ -19,6 +19,7 @@ /* irc-upgrade.c: save/restore IRC plugin data */ +#include <stdio.h> #include <string.h> #include "../weechat-plugin.h" @@ -168,8 +169,8 @@ int irc_upgrade_read_cb (int object_id, struct t_infolist *infolist) { - int flags, sock, size; - char *str, *buf, *buffer_name; + int flags, sock, size, index; + char *str, *buf, *buffer_name, option_name[64], *nick; struct t_irc_nick *ptr_nick; struct t_gui_buffer *ptr_buffer; @@ -269,6 +270,34 @@ irc_upgrade_read_cb (int object_id, irc_upgrade_current_channel->cycle = weechat_infolist_integer (infolist, "cycle"); irc_upgrade_current_channel->display_creation_date = weechat_infolist_integer (infolist, "display_creation_date"); irc_upgrade_current_channel->nick_completion_reset = weechat_infolist_integer (infolist, "nick_completion_reset"); + index = 0; + while (1) + { + snprintf (option_name, sizeof (option_name), + "nick_speaking_%05d", index); + nick = weechat_infolist_string (infolist, option_name); + if (!nick) + break; + irc_channel_nick_speaking_add (irc_upgrade_current_channel, + nick); + index++; + } + index = 0; + while (1) + { + snprintf (option_name, sizeof (option_name), + "nick_speaking_time_nick_%05d", index); + nick = weechat_infolist_string (infolist, option_name); + if (!nick) + break; + snprintf (option_name, sizeof (option_name), + "nick_speaking_time_time_%05d", index); + irc_channel_nick_speaking_time_add (irc_upgrade_current_channel, + nick, + weechat_infolist_time (infolist, + option_name)); + index++; + } } } break; |