From 579201636ed255bddee6564f41511819479eff9e Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 04:10:03 +0100 Subject: [PATCH] Showing history from current log in chat windows --- src/chat_log.c | 97 ++++++++++++++++++++++++++++++++++++++++++------- src/chat_log.h | 2 + src/command.c | 2 +- src/profanity.c | 2 +- src/ui.h | 1 + src/windows.c | 41 +++++++++++++++++++-- 6 files changed, 127 insertions(+), 18 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index 3a139d31..5d8df0da 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include @@ -29,23 +30,28 @@ #include "chat_log.h" #include "common.h" #include "log.h" +#include "ui.h" static GHashTable *logs; +static GDateTime *started; struct dated_chat_log { - FILE *logp; + gchar *filename; GDateTime *date; }; 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 void _free_chat_log(struct dated_chat_log *dated_log); +static gboolean _key_equals(void *key1, void *key2); +static char * _get_log_filename(char *other, const char * const login); void chat_log_init(void) -{ +{ + started = g_date_time_new_now_local(); log_info("Initialising chat logs"); - logs = g_hash_table_new_full(NULL, (GEqualFunc) g_strcmp0, g_free, + logs = g_hash_table_new_full(g_str_hash, (GEqualFunc) _key_equals, g_free, (GDestroyNotify)_free_chat_log); } @@ -70,23 +76,80 @@ chat_log_chat(const gchar * const login, gchar *other, 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 (direction == IN) { - fprintf(dated_log->logp, "%s - %s: %s\n", date_fmt, other_copy, msg); + fprintf(logp, "%s - %s: %s\n", date_fmt, other_copy, msg); } else { - fprintf(dated_log->logp, "%s - me: %s\n", date_fmt, msg); + fprintf(logp, "%s - me: %s\n", date_fmt, msg); + } + fflush(logp); + int result = fclose(logp); + if (result == EOF) { + log_error("Error closing file %s, errno = %d", dated_log->filename, errno); } - fflush(dated_log->logp); - g_free(date_fmt); g_date_time_unref(dt); } +GSList * +chat_log_get_previous(const gchar * const login, gchar *recipient, + GSList *history) +{ + char *filename = _get_log_filename(recipient, login); + + FILE *logp = fopen(filename, "r"); + char *line = NULL; + size_t read = 0; + size_t length = getline(&line, &read, logp); + while (length != -1) { + char *copy = malloc(length); + copy = strncpy(copy, line, length); + copy[length -1] = '\0'; + history = g_slist_append(history, copy); + free(line); + line = NULL; + read = 0; + length = getline(&line, &read, logp); + } + + free(filename); + + return history; +} + void chat_log_close(void) { g_hash_table_remove_all(logs); + g_date_time_unref(started); } +static char * +_get_log_filename(char *other, const char * const login) +{ + GString *log_file = g_string_new(getenv("HOME")); + g_string_append(log_file, "/.profanity/log"); + create_dir(log_file->str); + + gchar *login_dir = str_replace(login, "@", "_at_"); + g_string_append_printf(log_file, "/%s", login_dir); + create_dir(log_file->str); + free(login_dir); + + gchar *other_file = str_replace(other, "@", "_at_"); + g_string_append_printf(log_file, "/%s", other_file); + create_dir(log_file->str); + free(other_file); + + GDateTime *dt = g_date_time_new_now_local(); + gchar *date = g_date_time_format(dt, "/%Y_%m_%d.log"); + g_string_append(log_file, date); + + return strdup(log_file->str); +} + + static struct dated_chat_log * _create_log(char *other, const char * const login) { @@ -106,10 +169,10 @@ _create_log(char *other, const char * const login) GDateTime *dt = g_date_time_new_now_local(); gchar *date = g_date_time_format(dt, "/%Y_%m_%d.log"); - g_string_append_printf(log_file, date); + g_string_append(log_file, date); struct dated_chat_log *new_log = malloc(sizeof(struct dated_chat_log)); - new_log->logp = fopen(log_file->str, "a"); + new_log->filename = strdup(log_file->str); new_log->date = dt; g_string_free(log_file, TRUE); @@ -117,7 +180,6 @@ _create_log(char *other, const char * const login) return new_log; } - static gboolean _log_roll_needed(struct dated_chat_log *dated_log) { @@ -136,9 +198,9 @@ static void _free_chat_log(struct dated_chat_log *dated_log) { if (dated_log != NULL) { - if (dated_log->logp != NULL) { - fclose(dated_log->logp); - dated_log->logp = NULL; + if (dated_log->filename != NULL) { + g_free(dated_log->filename); + dated_log->filename = NULL; } if (dated_log->date != NULL) { g_date_time_unref(dated_log->date); @@ -147,3 +209,12 @@ _free_chat_log(struct dated_chat_log *dated_log) } dated_log = NULL; } + +static +gboolean _key_equals(void *key1, void *key2) +{ + gchar *str1 = (gchar *) key1; + gchar *str2 = (gchar *) key2; + + return (g_strcmp0(str1, str2) == 0); +} diff --git a/src/chat_log.h b/src/chat_log.h index 61763d25..d8455a26 100644 --- a/src/chat_log.h +++ b/src/chat_log.h @@ -34,5 +34,7 @@ void chat_log_init(void); void chat_log_chat(const gchar * const login, gchar *other, const gchar * const msg, chat_log_direction_t direction); void chat_log_close(void); +GSList * chat_log_get_previous(const gchar * const login, gchar *recipient, + GSList *history); #endif diff --git a/src/command.c b/src/command.c index cdb0c384..806311cd 100644 --- a/src/command.c +++ b/src/command.c @@ -653,13 +653,13 @@ _cmd_msg(const char * const inp, struct cmd_help_t help) if (msg != NULL) { jabber_send(msg, usr); + win_show_outgoing_msg("me", usr, msg); if (prefs_get_chlog()) { const char *jid = jabber_get_jid(); chat_log_chat(jid, usr, msg, OUT); } - win_show_outgoing_msg("me", usr, msg); } else { cons_show("Usage: %s", help.usage); } diff --git a/src/profanity.c b/src/profanity.c index 521b277e..249268a5 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -103,7 +103,7 @@ prof_handle_incoming_message(char *from, char *message) { win_show_incomming_msg(from, message); win_page_off(); - + if (prefs_get_chlog()) { char from_cpy[strlen(from) + 1]; strcpy(from_cpy, from); diff --git a/src/ui.h b/src/ui.h index df1eab66..66a41e07 100644 --- a/src/ui.h +++ b/src/ui.h @@ -57,6 +57,7 @@ struct prof_win { int y_pos; int paged; int unread; + int history_shown; }; // gui startup and shutdown, resize diff --git a/src/windows.c b/src/windows.c index b36bea28..047f918d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -36,6 +36,7 @@ #include #endif +#include "chat_log.h" #include "command.h" #include "contact.h" #include "contact_list.h" @@ -172,6 +173,7 @@ win_close_win(void) // reset the chat win to unused strcpy(_wins[_curr_prof_win].from, ""); wclear(_wins[_curr_prof_win].win); + _wins[_curr_prof_win].history_shown = 0; // set it as inactive in the status bar status_bar_inactive(_curr_prof_win); @@ -262,12 +264,12 @@ win_show_incomming_msg(const char * const from, const char * const message) win_index = _new_prof_win(short_from); WINDOW *win = _wins[win_index].win; - _win_show_time(win); - _win_show_user(win, short_from, 1); - _win_show_message(win, message); // currently viewing chat window with sender if (win_index == _curr_prof_win) { + _win_show_time(win); + _win_show_user(win, short_from, 1); + _win_show_message(win, message); title_bar_set_typing(FALSE); title_bar_draw(); status_bar_active(win_index); @@ -281,6 +283,21 @@ win_show_incomming_msg(const char * const from, const char * const message) flash(); _wins[win_index].unread++; + if (prefs_get_chlog()) { + if (!_wins[win_index].history_shown) { + GSList *history = NULL; + history = chat_log_get_previous(jabber_get_jid(), short_from, history); + while (history != NULL) { + wprintw(win, "%s\n", history->data); + history = g_slist_next(history); + } + _wins[win_index].history_shown = 1; + } + } + + _win_show_time(win); + _win_show_user(win, short_from, 1); + _win_show_message(win, message); } if (prefs_get_beep()) @@ -371,6 +388,18 @@ win_show_outgoing_msg(const char * const from, const char * const to, if (win_index == NUM_WINS) { win_index = _new_prof_win(to); win = _wins[win_index].win; + + if (prefs_get_chlog()) { + if (!_wins[win_index].history_shown) { + GSList *history = NULL; + history = chat_log_get_previous(jabber_get_jid(), to, history); + while (history != NULL) { + wprintw(win, "%s\n", history->data); + history = g_slist_next(history); + } + _wins[win_index].history_shown = 1; + } + } if (strcmp(p_contact_show(contact), "offline") == 0) { const char const *show = p_contact_show(contact); @@ -703,6 +732,7 @@ _create_windows(void) cons.y_pos = 0; cons.paged = 0; cons.unread = 0; + cons.history_shown = 0; scrollok(cons.win, TRUE); _wins[0] = cons; @@ -746,6 +776,7 @@ _create_windows(void) chat.y_pos = 0; chat.paged = 0; chat.unread = 0; + chat.history_shown = 0; scrollok(chat.win, TRUE); _wins[i] = chat; } @@ -864,9 +895,13 @@ _win_show_user(WINDOW *win, const char * const user, const int colour) { if (colour) wattron(win, COLOUR_ONLINE); + else + wattron(win, COLOUR_INC); wprintw(win, "%s: ", user); if (colour) wattroff(win, COLOUR_ONLINE); + else + wattroff(win, COLOUR_INC); } static void