mirror of
https://github.com/irssi/irssi.git
synced 2024-09-01 04:14:16 -04:00
Merge pull request #1108 from ailin-nemui/server-time
implement server-time
This commit is contained in:
commit
b47257048c
@ -6,7 +6,7 @@
|
||||
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
|
||||
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
|
||||
|
||||
#define IRSSI_ABI_VERSION 33
|
||||
#define IRSSI_ABI_VERSION 34
|
||||
|
||||
#define DEFAULT_SERVER_ADD_PORT 6667
|
||||
#define DEFAULT_SERVER_ADD_TLS_PORT 6697
|
||||
|
@ -48,6 +48,7 @@ typedef struct {
|
||||
} EXPANDO_REC;
|
||||
|
||||
const char *current_expando = NULL;
|
||||
time_t reference_time = (time_t) -1;
|
||||
time_t current_time = (time_t)-1;
|
||||
|
||||
static int timer_tag;
|
||||
@ -59,6 +60,7 @@ static char *last_privmsg_from, *last_public_from;
|
||||
static char *sysname, *sysrelease, *sysarch;
|
||||
|
||||
static char *timestamp_format;
|
||||
static char *timestamp_format_alt;
|
||||
static int timestamp_seconds;
|
||||
static time_t last_timestamp;
|
||||
|
||||
@ -441,12 +443,24 @@ static char *expando_time(SERVER_REC *server, void *item, int *free_ret)
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
char str[256];
|
||||
char *format;
|
||||
|
||||
now = current_time != (time_t)-1 ? current_time : time(NULL);
|
||||
now = current_time != (time_t) -1 ? current_time : time(NULL);
|
||||
tm = localtime(&now);
|
||||
format = timestamp_format;
|
||||
|
||||
if (strftime(str, sizeof(str), timestamp_format, tm) == 0)
|
||||
return "";
|
||||
if (reference_time != (time_t) -1) {
|
||||
time_t ref = reference_time;
|
||||
struct tm tm_ref;
|
||||
if (localtime_r(&ref, &tm_ref)) {
|
||||
if (tm_ref.tm_yday != tm->tm_yday || tm_ref.tm_year != tm->tm_year) {
|
||||
format = timestamp_format_alt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strftime(str, sizeof(str), format, tm) == 0)
|
||||
return "";
|
||||
|
||||
*free_ret = TRUE;
|
||||
return g_strdup(str);
|
||||
@ -576,7 +590,9 @@ static int sig_timer(void)
|
||||
static void read_settings(void)
|
||||
{
|
||||
g_free_not_null(timestamp_format);
|
||||
g_free_not_null(timestamp_format_alt);
|
||||
timestamp_format = g_strdup(settings_get_str("timestamp_format"));
|
||||
timestamp_format_alt = g_strdup(settings_get_str("timestamp_format_alt"));
|
||||
|
||||
timestamp_seconds =
|
||||
strstr(timestamp_format, "%r") != NULL ||
|
||||
@ -594,6 +610,7 @@ void expandos_init(void)
|
||||
#endif
|
||||
settings_add_str("misc", "STATUS_OPER", "*");
|
||||
settings_add_str("lookandfeel", "timestamp_format", "%H:%M");
|
||||
settings_add_str("lookandfeel", "timestamp_format_alt", "%a %e %b %H:%M");
|
||||
settings_add_bool("lookandfeel", "chanmode_expando_strip", FALSE);
|
||||
|
||||
last_sent_msg = NULL; last_sent_msg_body = NULL;
|
||||
@ -730,6 +747,7 @@ void expandos_deinit(void)
|
||||
g_free_not_null(sysrelease);
|
||||
g_free_not_null(sysarch);
|
||||
g_free_not_null(timestamp_format);
|
||||
g_free_not_null(timestamp_format_alt);
|
||||
|
||||
g_source_remove(timer_tag);
|
||||
signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
|
||||
|
@ -18,6 +18,7 @@ typedef char* (*EXPANDO_FUNC)
|
||||
|
||||
extern const char *current_expando;
|
||||
extern time_t current_time;
|
||||
extern time_t reference_time;
|
||||
|
||||
/* Create expando - overrides any existing ones.
|
||||
... = signal, type, ..., NULL - list of signals that might change the
|
||||
|
@ -1,9 +1,44 @@
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irssi/src/core/refstrings.h>
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 58, 0)
|
||||
/* nothing */
|
||||
|
||||
void i_refstr_init(void)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
char *i_refstr_intern(const char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_ref_string_new_intern(str);
|
||||
}
|
||||
|
||||
void i_refstr_release(char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_ref_string_release(str);
|
||||
}
|
||||
|
||||
void i_refstr_deinit(void)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
char *i_refstr_table_size_info(void)
|
||||
{
|
||||
/* not available */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
GHashTable *i_refstr_table;
|
||||
|
@ -1,18 +1,6 @@
|
||||
#ifndef IRSSI_CORE_REFSTRINGS_H
|
||||
#define IRSSI_CORE_REFSTRINGS_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 58, 0)
|
||||
|
||||
#define i_refstr_init() /* nothing */
|
||||
#define i_refstr_release(str) ((str) == NULL ? NULL : g_ref_string_release(str))
|
||||
#define i_refstr_intern(str) ((str) == NULL ? NULL : g_ref_string_new_intern(str))
|
||||
#define i_refstr_deinit() /* nothing */
|
||||
#define i_refstr_table_size_info() NULL
|
||||
|
||||
#else
|
||||
|
||||
void i_refstr_init(void);
|
||||
char *i_refstr_intern(const char *str);
|
||||
void i_refstr_release(char *str);
|
||||
@ -20,5 +8,3 @@ void i_refstr_deinit(void);
|
||||
char *i_refstr_table_size_info(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -44,6 +44,9 @@ int lag; /* server lag in milliseconds */
|
||||
GSList *channels;
|
||||
GSList *queries;
|
||||
|
||||
/* transient meta data stash */
|
||||
GHashTable *current_incoming_meta;
|
||||
|
||||
/* -- support for multiple server types -- */
|
||||
|
||||
/* -- must not be NULL: -- */
|
||||
|
@ -19,14 +19,15 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include <irssi/src/core/signals.h>
|
||||
#include <irssi/src/core/commands.h>
|
||||
#include <irssi/src/core/misc.h>
|
||||
#include <irssi/src/core/net-disconnect.h>
|
||||
#include <irssi/src/core/net-nonblock.h>
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/misc.h>
|
||||
#include <irssi/src/core/rawlog.h>
|
||||
#include <irssi/src/core/refstrings.h>
|
||||
#include <irssi/src/core/settings.h>
|
||||
#include <irssi/src/core/signals.h>
|
||||
|
||||
#include <irssi/src/core/chat-protocols.h>
|
||||
#include <irssi/src/core/servers.h>
|
||||
@ -354,6 +355,9 @@ void server_connect_init(SERVER_REC *server)
|
||||
MODULE_DATA_INIT(server);
|
||||
server->type = module_get_uniq_id("SERVER", 0);
|
||||
server_ref(server);
|
||||
server->current_incoming_meta =
|
||||
g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0,
|
||||
(GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free);
|
||||
|
||||
server->nick = g_strdup(server->connrec->nick);
|
||||
if (server->connrec->username == NULL || *server->connrec->username == '\0') {
|
||||
@ -535,6 +539,7 @@ int server_unref(SERVER_REC *server)
|
||||
g_free(server->away_reason);
|
||||
g_free(server->nick);
|
||||
g_free(server->tag);
|
||||
g_hash_table_destroy(server->current_incoming_meta);
|
||||
|
||||
server->type = 0;
|
||||
g_free(server);
|
||||
@ -655,6 +660,22 @@ void server_change_nick(SERVER_REC *server, const char *nick)
|
||||
signal_emit("server nick changed", 1, server);
|
||||
}
|
||||
|
||||
void server_meta_stash(SERVER_REC *server, const char *meta_key, const char *meta_value)
|
||||
{
|
||||
g_hash_table_replace(server->current_incoming_meta, i_refstr_intern(meta_key),
|
||||
g_strdup(meta_value));
|
||||
}
|
||||
|
||||
const char *server_meta_stash_find(SERVER_REC *server, const char *meta_key)
|
||||
{
|
||||
return g_hash_table_lookup(server->current_incoming_meta, meta_key);
|
||||
}
|
||||
|
||||
void server_meta_clear_all(SERVER_REC *server)
|
||||
{
|
||||
g_hash_table_remove_all(server->current_incoming_meta);
|
||||
}
|
||||
|
||||
/* Update own IPv4 and IPv6 records */
|
||||
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn,
|
||||
IPADDR *ip4, IPADDR *ip6)
|
||||
|
@ -66,6 +66,13 @@ void server_connect_failed(SERVER_REC *server, const char *msg);
|
||||
/* Change your nick */
|
||||
void server_change_nick(SERVER_REC *server, const char *nick);
|
||||
|
||||
/* Push meta data onto the server stash */
|
||||
void server_meta_stash(SERVER_REC *server, const char *meta_key, const char *meta_value);
|
||||
/* Get a value from the stash */
|
||||
const char *server_meta_stash_find(SERVER_REC *server, const char *meta_key);
|
||||
/* clear meta stash */
|
||||
void server_meta_clear_all(SERVER_REC *server);
|
||||
|
||||
/* Update own IPv4 and IPv6 records */
|
||||
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn,
|
||||
IPADDR *ip4, IPADDR *ip6);
|
||||
|
@ -406,16 +406,10 @@ void format_read_arglist(va_list va, FORMAT_REC *format,
|
||||
}
|
||||
}
|
||||
}
|
||||
void format_create_dest(TEXT_DEST_REC *dest,
|
||||
void *server, const char *target,
|
||||
int level, WINDOW_REC *window)
|
||||
{
|
||||
format_create_dest_tag(dest, server, NULL, target, level, window);
|
||||
}
|
||||
|
||||
void format_create_dest_tag(TEXT_DEST_REC *dest, void *server,
|
||||
const char *server_tag, const char *target,
|
||||
int level, WINDOW_REC *window)
|
||||
void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char *server_tag,
|
||||
const char *target, int level, WINDOW_REC *window,
|
||||
GHashTable *meta)
|
||||
{
|
||||
memset(dest, 0, sizeof(TEXT_DEST_REC));
|
||||
|
||||
@ -425,6 +419,20 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server,
|
||||
dest->level = level;
|
||||
dest->window = window != NULL ? window :
|
||||
window_find_closest(server, target, level);
|
||||
dest->meta = meta;
|
||||
}
|
||||
|
||||
void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag,
|
||||
const char *target, int level, WINDOW_REC *window)
|
||||
{
|
||||
format_create_dest_tag_meta(dest, server, server_tag, target, level, window,
|
||||
server != NULL ? SERVER(server)->current_incoming_meta : NULL);
|
||||
}
|
||||
|
||||
void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level,
|
||||
WINDOW_REC *window)
|
||||
{
|
||||
format_create_dest_tag(dest, server, NULL, target, level, window);
|
||||
}
|
||||
|
||||
/* Return length of text part in string (ie. without % codes) */
|
||||
|
@ -64,6 +64,7 @@ typedef struct _TEXT_DEST_REC {
|
||||
int hilight_priority;
|
||||
char *hilight_color;
|
||||
int flags;
|
||||
GHashTable *meta;
|
||||
} TEXT_DEST_REC;
|
||||
|
||||
#define window_get_theme(window) \
|
||||
|
@ -348,14 +348,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
|
||||
return;
|
||||
}
|
||||
|
||||
lineinfo.level = dest == NULL ? 0 : dest->level;
|
||||
gui = WINDOW_GUI(window);
|
||||
lineinfo.time = (gui->use_insert_after && gui->insert_after_time) ?
|
||||
gui->insert_after_time : time(NULL);
|
||||
view = gui->view;
|
||||
|
||||
lineinfo.level = dest == NULL ? 0 : dest->level;
|
||||
lineinfo.time =
|
||||
(gui->use_insert_after && gui->insert_after_time) ? gui->insert_after_time : time(NULL);
|
||||
lineinfo.format =
|
||||
dest != NULL && dest->flags & PRINT_FLAG_FORMAT ? LINE_INFO_FORMAT_SET : NULL;
|
||||
|
||||
view = gui->view;
|
||||
insert_after = gui->use_insert_after ?
|
||||
gui->insert_after : view->buffer->cur_line;
|
||||
|
||||
|
@ -14,7 +14,23 @@
|
||||
#include <irssi/src/fe-text/textbuffer-view.h>
|
||||
|
||||
TEXT_BUFFER_REC *color_buf;
|
||||
int scrollback_format;
|
||||
gboolean scrollback_format;
|
||||
gboolean show_server_time;
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 56, 0)
|
||||
/* nothing */
|
||||
#else
|
||||
/* compatibility code for old GLib */
|
||||
static GDateTime *g_date_time_new_from_iso8601(const gchar *iso_date, GTimeZone *default_tz)
|
||||
{
|
||||
GTimeVal time;
|
||||
if (g_time_val_from_iso8601(iso_date, &time)) {
|
||||
return g_date_time_new_from_timeval_utc(&time);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void collector_free(GSList **collector)
|
||||
{
|
||||
@ -86,6 +102,55 @@ static void format_rec_set_dest(TEXT_BUFFER_FORMAT_REC *rec, const TEXT_DEST_REC
|
||||
rec->flags = dest->flags & ~PRINT_FLAG_FORMAT;
|
||||
}
|
||||
|
||||
void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec)
|
||||
{
|
||||
if (rec == NULL)
|
||||
return;
|
||||
|
||||
if (rec->hash != NULL)
|
||||
g_hash_table_destroy(rec->hash);
|
||||
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta)
|
||||
{
|
||||
if (meta->hash == NULL) {
|
||||
meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0,
|
||||
(GDestroyNotify) i_refstr_release,
|
||||
(GDestroyNotify) g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash)
|
||||
{
|
||||
struct _TEXT_BUFFER_META_REC *meta;
|
||||
GHashTableIter iter;
|
||||
const char *key;
|
||||
const char *val;
|
||||
|
||||
if (meta_hash == NULL || g_hash_table_size(meta_hash) == 0)
|
||||
return NULL;
|
||||
|
||||
meta = g_new0(struct _TEXT_BUFFER_META_REC, 1);
|
||||
|
||||
g_hash_table_iter_init(&iter, meta_hash);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) {
|
||||
if (g_strcmp0("time", key) == 0) {
|
||||
GDateTime *time;
|
||||
if ((time = g_date_time_new_from_iso8601(val, NULL)) != NULL) {
|
||||
meta->server_time = g_date_time_to_unix(time);
|
||||
g_date_time_unref(time);
|
||||
}
|
||||
} else {
|
||||
meta_hash_create(meta);
|
||||
g_hash_table_replace(meta->hash, i_refstr_intern(key), g_strdup(val));
|
||||
}
|
||||
}
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
static LINE_INFO_REC *store_lineinfo_tmp(TEXT_DEST_REC *dest)
|
||||
{
|
||||
GUI_WINDOW_REC *gui;
|
||||
@ -120,7 +185,7 @@ static void free_lineinfo_tmp(WINDOW_REC *window)
|
||||
|
||||
info = buffer->cur_info->data;
|
||||
buffer->cur_info = g_slist_delete_link(buffer->cur_info, buffer->cur_info);
|
||||
textbuffer_format_rec_free(info->format);
|
||||
textbuffer_line_info_free1(info);
|
||||
g_free(info);
|
||||
}
|
||||
|
||||
@ -211,14 +276,17 @@ static void sig_gui_print_text_finished(WINDOW_REC *window, TEXT_DEST_REC *dest)
|
||||
info->format->expando_cache = reverse_collector(info->format->expando_cache);
|
||||
format_rec_set_dest(info->format, dest);
|
||||
|
||||
info->meta = line_meta_create(dest->meta);
|
||||
|
||||
info->level |= MSGLEVEL_FORMAT;
|
||||
|
||||
/* the line will be inserted into the view with textbuffer_view_insert_line by
|
||||
gui-printtext.c:view_add_eol */
|
||||
insert_after = textbuffer_insert(buffer, insert_after, (const unsigned char[]){}, 0, info);
|
||||
|
||||
/* the TEXT_BUFFER_FORMAT_REC pointer is now owned by the textbuffer */
|
||||
/* the TEXT_BUFFER_FORMAT_REC and meta pointer is now owned by the textbuffer */
|
||||
info->format = LINE_INFO_FORMAT_SET;
|
||||
info->meta = NULL;
|
||||
|
||||
if (gui->use_insert_after)
|
||||
gui->insert_after = insert_after;
|
||||
@ -294,12 +362,14 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
THEME_REC *theme;
|
||||
int formatnum;
|
||||
TEXT_BUFFER_FORMAT_REC *format_rec;
|
||||
TEXT_BUFFER_META_REC *meta;
|
||||
char *str;
|
||||
|
||||
curr = line;
|
||||
line = NULL;
|
||||
|
||||
format_rec = curr->info.format;
|
||||
meta = curr->info.meta;
|
||||
|
||||
format_create_dest_tag(
|
||||
&dest,
|
||||
format_rec->server_tag != NULL ? server_find_tag(format_rec->server_tag) : NULL,
|
||||
@ -326,7 +396,12 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
}
|
||||
|
||||
if (text != NULL && *text != '\0') {
|
||||
current_time = curr->info.time;
|
||||
reference_time = curr->info.time;
|
||||
if (show_server_time && meta != NULL && meta->server_time != 0) {
|
||||
current_time = meta->server_time;
|
||||
} else {
|
||||
current_time = curr->info.time;
|
||||
}
|
||||
|
||||
tmp = format_get_level_tag(theme, &dest);
|
||||
str = !theme->info_eol ? format_add_linestart(text, tmp) :
|
||||
@ -334,7 +409,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
g_free_not_null(tmp);
|
||||
g_free_not_null(text);
|
||||
text = str;
|
||||
tmp = format_get_line_start(theme, &dest, curr->info.time);
|
||||
tmp = format_get_line_start(theme, &dest, current_time);
|
||||
str = !theme->info_eol ? format_add_linestart(text, tmp) :
|
||||
format_add_lineend(text, tmp);
|
||||
g_free_not_null(tmp);
|
||||
@ -345,7 +420,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
|
||||
dest.flags |= PRINT_FLAG_FORMAT;
|
||||
|
||||
current_time = (time_t) -1;
|
||||
reference_time = current_time = (time_t) -1;
|
||||
} else if (format_rec->format != NULL) {
|
||||
g_free(text);
|
||||
text = NULL;
|
||||
@ -363,11 +438,13 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
static void read_settings(void)
|
||||
{
|
||||
scrollback_format = settings_get_bool("scrollback_format");
|
||||
show_server_time = settings_get_bool("show_server_time");
|
||||
}
|
||||
|
||||
void textbuffer_formats_init(void)
|
||||
{
|
||||
settings_add_bool("lookandfeel", "scrollback_format", TRUE);
|
||||
settings_add_bool("lookandfeel", "show_server_time", FALSE);
|
||||
|
||||
read_settings();
|
||||
signal_add("print format", (SIGNAL_FUNC) sig_print_format);
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
#include <irssi/src/fe-text/textbuffer.h>
|
||||
|
||||
typedef struct _TEXT_BUFFER_META_REC {
|
||||
gint64 server_time;
|
||||
GHashTable *hash;
|
||||
} TEXT_BUFFER_META_REC;
|
||||
|
||||
typedef struct _TEXT_BUFFER_FORMAT_REC {
|
||||
char *module;
|
||||
char *format;
|
||||
@ -17,6 +22,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC {
|
||||
} TEXT_BUFFER_FORMAT_REC;
|
||||
|
||||
void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec);
|
||||
void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec);
|
||||
char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line);
|
||||
void textbuffer_formats_init(void);
|
||||
void textbuffer_formats_deinit(void);
|
||||
|
@ -54,8 +54,7 @@ void textbuffer_destroy(TEXT_BUFFER_REC *buffer)
|
||||
g_string_free(buffer->cur_text, TRUE);
|
||||
for (tmp = buffer->cur_info; tmp != NULL; tmp = tmp->next) {
|
||||
LINE_INFO_REC *info = buffer->cur_info->data;
|
||||
textbuffer_format_rec_free(info->format);
|
||||
g_free(info->text);
|
||||
textbuffer_line_info_free1(info);
|
||||
g_free(info);
|
||||
}
|
||||
g_slist_free(buffer->cur_info);
|
||||
@ -64,6 +63,13 @@ void textbuffer_destroy(TEXT_BUFFER_REC *buffer)
|
||||
g_slice_free(TEXT_BUFFER_REC, buffer);
|
||||
}
|
||||
|
||||
void textbuffer_line_info_free1(LINE_INFO_REC *info)
|
||||
{
|
||||
textbuffer_format_rec_free(info->format);
|
||||
textbuffer_meta_rec_free(info->meta);
|
||||
g_free(info->text);
|
||||
}
|
||||
|
||||
static void text_chunk_append(TEXT_BUFFER_REC *buffer,
|
||||
const unsigned char *data, int len)
|
||||
{
|
||||
@ -198,8 +204,7 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
line->prev = line->next = NULL;
|
||||
|
||||
buffer->lines_count--;
|
||||
g_free(line->info.text);
|
||||
textbuffer_format_rec_free(line->info.format);
|
||||
textbuffer_line_info_free1(&line->info);
|
||||
g_slice_free(LINE_REC, line);
|
||||
}
|
||||
|
||||
@ -212,10 +217,9 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer)
|
||||
|
||||
while (buffer->first_line != NULL) {
|
||||
line = buffer->first_line->next;
|
||||
g_free(buffer->first_line->info.text);
|
||||
textbuffer_format_rec_free(buffer->first_line->info.format);
|
||||
textbuffer_line_info_free1(&buffer->first_line->info);
|
||||
g_slice_free(LINE_REC, buffer->first_line);
|
||||
buffer->first_line = line;
|
||||
buffer->first_line = line;
|
||||
}
|
||||
buffer->lines_count = 0;
|
||||
|
||||
|
@ -17,6 +17,7 @@ typedef struct {
|
||||
int level;
|
||||
time_t time;
|
||||
char *text;
|
||||
struct _TEXT_BUFFER_META_REC *meta;
|
||||
struct _TEXT_BUFFER_FORMAT_REC *format;
|
||||
} LINE_INFO_REC;
|
||||
|
||||
@ -84,6 +85,7 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after,
|
||||
void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line);
|
||||
/* Removes all lines from buffer, ignoring reference counters */
|
||||
void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer);
|
||||
void textbuffer_line_info_free1(LINE_INFO_REC *info);
|
||||
|
||||
void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, GString *str);
|
||||
GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline,
|
||||
|
@ -242,6 +242,7 @@ static void server_init(IRC_SERVER_REC *server)
|
||||
irc_cap_toggle(server, CAP_CHGHOST, TRUE);
|
||||
irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE);
|
||||
irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE);
|
||||
irc_cap_toggle(server, CAP_SERVER_TIME, TRUE);
|
||||
|
||||
irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define CAP_CHGHOST "chghost"
|
||||
#define CAP_ACCOUNT_NOTIFY "account-notify"
|
||||
#define CAP_SELF_MESSAGE "znc.in/self-message"
|
||||
#define CAP_SERVER_TIME "server-time"
|
||||
|
||||
/* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */
|
||||
#define IRC_SERVER(server) \
|
||||
|
@ -19,14 +19,15 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include <irssi/src/core/modules.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/rawlog.h>
|
||||
#include <irssi/src/core/misc.h>
|
||||
#include <irssi/src/core/modules.h>
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
#include <irssi/src/core/rawlog.h>
|
||||
#include <irssi/src/core/refstrings.h>
|
||||
|
||||
#include <irssi/src/irc/core/irc-servers.h>
|
||||
#include <irssi/src/irc/core/irc-channels.h>
|
||||
#include <irssi/src/irc/core/irc-servers.h>
|
||||
#include <irssi/src/irc/core/servers-redirect.h>
|
||||
|
||||
char *current_server_event;
|
||||
@ -383,11 +384,83 @@ static void irc_server_event(IRC_SERVER_REC *server, const char *line,
|
||||
g_free(event);
|
||||
}
|
||||
|
||||
static void irc_server_event_tags(IRC_SERVER_REC *server, const char *line,
|
||||
const char *nick, const char *address, const char *tags)
|
||||
static void unescape_tag(char *tag)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (tag == NULL)
|
||||
return;
|
||||
|
||||
tmp = tag;
|
||||
for (; *tmp != '\0'; tmp++, tag++) {
|
||||
if (*tmp == '\\') {
|
||||
tmp++;
|
||||
switch (*tmp) {
|
||||
case ':':
|
||||
*tag = ';';
|
||||
break;
|
||||
case 'n':
|
||||
*tag = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*tag = '\r';
|
||||
break;
|
||||
case 's':
|
||||
*tag = ' ';
|
||||
break;
|
||||
default:
|
||||
*tag = *tmp;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*tag = *tmp;
|
||||
}
|
||||
}
|
||||
*tag = '\0';
|
||||
}
|
||||
|
||||
static gboolean i_str0_equal(const char *s1, const char *s2)
|
||||
{
|
||||
return g_strcmp0(s1, s2) == 0;
|
||||
}
|
||||
|
||||
GHashTable *irc_parse_message_tags(const char *tags)
|
||||
{
|
||||
char **split, **tmp, **kv;
|
||||
GHashTable *hash;
|
||||
|
||||
hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) i_str0_equal,
|
||||
(GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free);
|
||||
split = g_strsplit(tags, ";", -1);
|
||||
for (tmp = split; *tmp != NULL; tmp++) {
|
||||
kv = g_strsplit(*tmp, "=", 2);
|
||||
unescape_tag(kv[1]);
|
||||
g_hash_table_replace(hash, i_refstr_intern(kv[0]),
|
||||
g_strdup(kv[1] == NULL ? "" : kv[1]));
|
||||
g_strfreev(kv);
|
||||
}
|
||||
g_strfreev(split);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void irc_server_event_tags(IRC_SERVER_REC *server, const char *line, const char *nick,
|
||||
const char *address, const char *tags)
|
||||
{
|
||||
char *timestr;
|
||||
GHashTable *tags_hash = NULL;
|
||||
|
||||
if (tags != NULL && *tags != '\0') {
|
||||
tags_hash = irc_parse_message_tags(tags);
|
||||
if ((timestr = g_hash_table_lookup(tags_hash, "time")) != NULL) {
|
||||
server_meta_stash(SERVER(server), "time", timestr);
|
||||
}
|
||||
}
|
||||
|
||||
if (*line != '\0')
|
||||
signal_emit_id(signal_server_event, 4, server, line, nick, address);
|
||||
|
||||
if (tags_hash != NULL)
|
||||
g_hash_table_destroy(tags_hash);
|
||||
}
|
||||
|
||||
static char *irc_parse_prefix(char *line, char **nick, char **address, char **tags)
|
||||
@ -449,6 +522,8 @@ static void irc_parse_incoming_line(IRC_SERVER_REC *server, char *line)
|
||||
line = irc_parse_prefix(line, &nick, &address, &tags);
|
||||
if (*line != '\0' || tags != NULL)
|
||||
signal_emit_id(signal_server_event_tags, 5, server, line, nick, address, tags);
|
||||
|
||||
server_meta_clear_all(SERVER(server));
|
||||
}
|
||||
|
||||
/* input function: handle incoming server messages */
|
||||
|
@ -48,6 +48,9 @@ void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd);
|
||||
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
|
||||
int send_now, int immediate, int raw);
|
||||
|
||||
/* Extract a tag value from tags */
|
||||
GHashTable *irc_parse_message_tags(const char *tags);
|
||||
|
||||
/* Get count parameters from data */
|
||||
#include <irssi/src/core/commands.h>
|
||||
char *event_get_param(char **data);
|
||||
|
@ -103,3 +103,17 @@ send_message(server, target, msg, target_type)
|
||||
CODE:
|
||||
server->send_message(server, target, msg, target_type);
|
||||
|
||||
void
|
||||
server_meta_stash(server, meta_key, meta_value)
|
||||
Irssi::Server server
|
||||
char *meta_key
|
||||
char *meta_value
|
||||
|
||||
char *
|
||||
server_meta_stash_find(server, meta_key)
|
||||
Irssi::Server server
|
||||
char *meta_key
|
||||
CODE:
|
||||
RETVAL = (char *) server_meta_stash_find(server, meta_key);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
@ -199,10 +199,29 @@ static PLAIN_OBJECT_INIT_REC irc_plains[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
MODULE = Irssi::Irc PACKAGE = Irssi::Irc
|
||||
MODULE = Irssi::Irc PACKAGE = Irssi::Irc PREFIX = irc_
|
||||
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
void
|
||||
irc_parse_message_tags(tags)
|
||||
char *tags
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
char *key;
|
||||
char *val;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hash = irc_parse_message_tags(tags);
|
||||
g_hash_table_iter_init(&iter, hash);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) {
|
||||
(void) hv_store(hv, key, strlen(key), new_pv(val), 0);
|
||||
}
|
||||
g_hash_table_destroy(hash);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV *) hv)));
|
||||
|
||||
void
|
||||
init()
|
||||
PREINIT:
|
||||
|
@ -68,3 +68,29 @@ PPCODE:
|
||||
(void) hv_store(hv, "text", 4, new_pv(l->info.text), 0);
|
||||
}
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV *) hv)));
|
||||
|
||||
void
|
||||
textbuffer_line_get_meta(line)
|
||||
Irssi::TextUI::Line line
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
LINE_REC *l;
|
||||
TEXT_BUFFER_META_REC *m;
|
||||
GHashTableIter iter;
|
||||
char *key;
|
||||
char *val;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
l = line->line;
|
||||
if (l->info.meta != NULL) {
|
||||
m = l->info.meta;
|
||||
if (m->hash != NULL) {
|
||||
g_hash_table_iter_init(&iter, m->hash);
|
||||
while (
|
||||
g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) {
|
||||
(void) hv_store(hv, key, strlen(key), new_pv(val), 0);
|
||||
}
|
||||
}
|
||||
(void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0);
|
||||
}
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV *) hv)));
|
||||
|
Loading…
Reference in New Issue
Block a user