From 8c5866ff52d38cecdf9e52f0d9f30c53bc1c3c03 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 5 May 2013 00:16:10 +0100 Subject: Added groupchat logs closes #168 --- src/command/command.c | 22 ++++++++++ src/config/preferences.c | 3 ++ src/config/preferences.h | 1 + src/log.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++- src/log.h | 4 ++ src/profanity.c | 7 +++ src/ui/console.c | 5 +++ 7 files changed, 149 insertions(+), 1 deletion(-) diff --git a/src/command/command.c b/src/command/command.c index 338fd27f..1a8d070f 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -115,6 +115,7 @@ static gboolean _cmd_set_intype(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_flash(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_splash(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_chlog(gchar **args, struct cmd_help_t help); +static gboolean _cmd_set_grlog(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_history(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_states(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_outtype(gchar **args, struct cmd_help_t help); @@ -597,6 +598,16 @@ static struct cmd_t setting_commands[] = "Switch chat logging on or off.", "This setting will be enabled if /history is set to on.", "When disabling this option, /history will also be disabled.", + "See the /grlog setting for enabling logging of chat room (groupchat) messages.", + NULL } } }, + + { "/grlog", + _cmd_set_grlog, parse_args, 1, 1, + { "/grlog on|off", "Chat logging of chat rooms to file", + { "/grlog on|off", + "-------------", + "Switch chat room logging on or off.", + "See the /chlog setting for enabling logging of one to one chat.", NULL } } }, { "/states", @@ -1107,6 +1118,8 @@ _cmd_complete_parameters(char *input, int *size) prefs_autocomplete_boolean_choice); _parameter_autocomplete(input, size, "/chlog", prefs_autocomplete_boolean_choice); + _parameter_autocomplete(input, size, "/grlog", + prefs_autocomplete_boolean_choice); _parameter_autocomplete(input, size, "/mouse", prefs_autocomplete_boolean_choice); _parameter_autocomplete(input, size, "/history", @@ -2783,6 +2796,15 @@ _cmd_set_chlog(gchar **args, struct cmd_help_t help) return result; } +static gboolean +_cmd_set_grlog(gchar **args, struct cmd_help_t help) +{ + gboolean result = _cmd_set_boolean_preference(args[0], help, + "Groupchat logging", PREF_GRLOG); + + return result; +} + static gboolean _cmd_set_mouse(gchar **args, struct cmd_help_t help) { diff --git a/src/config/preferences.c b/src/config/preferences.c index 1286961c..fe34e00e 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -303,6 +303,7 @@ _get_group(preference_t pref) case PREF_NOTIFY_SUB: return "notifications"; case PREF_CHLOG: + case PREF_GRLOG: return "logging"; case PREF_AUTOAWAY_CHECK: case PREF_AUTOAWAY_MODE: @@ -352,6 +353,8 @@ _get_key(preference_t pref) return "sub"; case PREF_CHLOG: return "chlog"; + case PREF_GRLOG: + return "grlog"; case PREF_AUTOAWAY_CHECK: return "autoaway.check"; case PREF_AUTOAWAY_MODE: diff --git a/src/config/preferences.h b/src/config/preferences.h index 3f4f0b79..cb1f9204 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -53,6 +53,7 @@ typedef enum { PREF_NOTIFY_INVITE, PREF_NOTIFY_SUB, PREF_CHLOG, + PREF_GRLOG, PREF_AUTOAWAY_CHECK, PREF_AUTOAWAY_MODE, PREF_AUTOAWAY_MESSAGE diff --git a/src/log.c b/src/log.c index 7df53b9c..1f877d21 100644 --- a/src/log.c +++ b/src/log.c @@ -49,6 +49,7 @@ static GDateTime *dt; static log_level_t level_filter; static GHashTable *logs; +static GHashTable *groupchat_logs; static GDateTime *session_started; struct dated_chat_log { @@ -57,11 +58,14 @@ struct dated_chat_log { }; static gboolean _log_roll_needed(struct dated_chat_log *dated_log); -static struct dated_chat_log *_create_log(char *other, const char * const login); +static struct dated_chat_log * _create_log(char *other, const char * const login); +static struct dated_chat_log * _create_groupchat_log(char *room, const char * const login); static void _free_chat_log(struct dated_chat_log *dated_log); static gboolean _key_equals(void *key1, void *key2); static char * _get_log_filename(const char * const other, const char * const login, GDateTime *dt, gboolean create); +static char * _get_groupchat_log_filename(const char * const room, + const char * const login, GDateTime *dt, gboolean create); static gchar * _get_chatlog_dir(void); static gchar * _get_log_file(void); static void _rotate_log_file(void); @@ -209,6 +213,15 @@ chat_log_init(void) (GDestroyNotify)_free_chat_log); } +void +groupchat_log_init(void) +{ + session_started = g_date_time_new_now_local(); + log_info("Initialising groupchat logs"); + groupchat_logs = g_hash_table_new_full(g_str_hash, (GEqualFunc) _key_equals, g_free, + (GDestroyNotify)_free_chat_log); +} + void chat_log_chat(const gchar * const login, gchar *other, const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp) @@ -262,6 +275,47 @@ chat_log_chat(const gchar * const login, gchar *other, g_date_time_unref(dt); } +void +groupchat_log_chat(const gchar * const login, const gchar * const room, + const gchar * const nick, const gchar * const msg) +{ + gchar *room_copy = strdup(room); + struct dated_chat_log *dated_log = g_hash_table_lookup(groupchat_logs, room_copy); + + // no log for room + if (dated_log == NULL) { + dated_log = _create_groupchat_log(room_copy, login); + g_hash_table_insert(groupchat_logs, room_copy, dated_log); + + // log exists but needs rolling + } else if (_log_roll_needed(dated_log)) { + dated_log = _create_groupchat_log(room_copy, login); + g_hash_table_replace(logs, room_copy, dated_log); + } + + GDateTime *dt = g_date_time_new_now_local(); + + gchar *date_fmt = g_date_time_format(dt, "%H:%M:%S"); + + FILE *logp = fopen(dated_log->filename, "a"); + + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *%s %s\n", date_fmt, nick, msg + 4); + } else { + fprintf(logp, "%s - %s: %s\n", date_fmt, nick, msg); + } + + fflush(logp); + int result = fclose(logp); + if (result == EOF) { + log_error("Error closing file %s, errno = %d", dated_log->filename, errno); + } + + g_free(date_fmt); + g_date_time_unref(dt); +} + + GSList * chat_log_get_previous(const gchar * const login, const gchar * const recipient, GSList *history) @@ -315,6 +369,7 @@ void chat_log_close(void) { g_hash_table_remove_all(logs); + g_hash_table_remove_all(groupchat_logs); g_date_time_unref(session_started); } @@ -333,6 +388,21 @@ _create_log(char *other, const char * const login) return new_log; } +static struct dated_chat_log * +_create_groupchat_log(char *room, const char * const login) +{ + GDateTime *now = g_date_time_new_now_local(); + char *filename = _get_groupchat_log_filename(room, login, now, TRUE); + + struct dated_chat_log *new_log = malloc(sizeof(struct dated_chat_log)); + new_log->filename = strdup(filename); + new_log->date = now; + + free(filename); + + return new_log; +} + static gboolean _log_roll_needed(struct dated_chat_log *dated_log) { @@ -403,6 +473,42 @@ _get_log_filename(const char * const other, const char * const login, return result; } +static char * +_get_groupchat_log_filename(const char * const room, const char * const login, + GDateTime *dt, gboolean create) +{ + gchar *chatlogs_dir = _get_chatlog_dir(); + GString *log_file = g_string_new(chatlogs_dir); + g_free(chatlogs_dir); + + gchar *login_dir = str_replace(login, "@", "_at_"); + g_string_append_printf(log_file, "/%s", login_dir); + if (create) { + create_dir(log_file->str); + } + free(login_dir); + + g_string_append(log_file, "/rooms"); + if (create) { + create_dir(log_file->str); + } + + gchar *room_file = str_replace(room, "@", "_at_"); + g_string_append_printf(log_file, "/%s", room_file); + if (create) { + create_dir(log_file->str); + } + free(room_file); + + gchar *date = g_date_time_format(dt, "/%Y_%m_%d.log"); + g_string_append(log_file, date); + + char *result = strdup(log_file->str); + g_string_free(log_file, TRUE); + + return result; +} + static gchar * _get_chatlog_dir(void) { diff --git a/src/log.h b/src/log.h index 82d2774d..25cbd1bb 100644 --- a/src/log.h +++ b/src/log.h @@ -53,4 +53,8 @@ void chat_log_chat(const gchar * const login, gchar *other, void chat_log_close(void); GSList * chat_log_get_previous(const gchar * const login, const gchar * const recipient, GSList *history); + +void groupchat_log_init(void); +void groupchat_log_chat(const gchar * const login, const gchar * const room, + const gchar * const nick, const gchar * const msg); #endif diff --git a/src/profanity.c b/src/profanity.c index ad646b85..f8441bdb 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -259,6 +259,12 @@ prof_handle_room_message(const char * const room_jid, const char * const nick, { ui_room_message(room_jid, nick, message); ui_current_page_off(); + + if (prefs_get_boolean(PREF_GRLOG)) { + Jid *jid = jid_create(jabber_get_jid()); + groupchat_log_chat(jid->barejid, room_jid, nick, message); + jid_destroy(jid); + } } void @@ -560,6 +566,7 @@ _init(const int disable_tls, char *log_level) log_info("Starting Profanity (%s)...", PACKAGE_VERSION); } chat_log_init(); + groupchat_log_init(); prefs_load(); accounts_load(); gchar *theme = prefs_get_string(PREF_THEME); diff --git a/src/ui/console.c b/src/ui/console.c index c6b50e38..4e4f074e 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1000,6 +1000,11 @@ cons_show_log_prefs(void) else cons_show("Chat logging (/chlog) : OFF"); + if (prefs_get_boolean(PREF_GRLOG)) + cons_show("Groupchat logging (/grlog) : ON"); + else + cons_show("Groupchat logging (/grlog) : OFF"); + ui_console_dirty(); _cons_alert(); } -- cgit 1.4.1-2-gfad0