From 579201636ed255bddee6564f41511819479eff9e Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 04:10:03 +0100 Subject: [PATCH 1/8] 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 From 993554b1b09a9397ddc5510507179f77f3341160 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 04:13:00 +0100 Subject: [PATCH 2/8] Fixed history when no log --- src/chat_log.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index 5d8df0da..b67b5988 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -101,16 +101,18 @@ chat_log_get_previous(const gchar * const login, gchar *recipient, 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); + if (logp != NULL) { + 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); From 90164fc2c0dd675d64ea63a0ee812fac1538431d Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 16:29:31 +0100 Subject: [PATCH 3/8] Chat log get filename now takes datetime --- src/chat_log.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index b67b5988..ea19a594 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -44,7 +44,8 @@ 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); +static char * _get_log_filename(char *other, const char * const login, + GDateTime *dt); void chat_log_init(void) @@ -96,7 +97,8 @@ GSList * chat_log_get_previous(const gchar * const login, gchar *recipient, GSList *history) { - char *filename = _get_log_filename(recipient, login); + GDateTime *now = g_date_time_new_now_local(); + char *filename = _get_log_filename(recipient, login, now); FILE *logp = fopen(filename, "r"); char *line = NULL; @@ -116,6 +118,7 @@ chat_log_get_previous(const gchar * const login, gchar *recipient, } free(filename); + g_date_time_unref(now); return history; } @@ -128,7 +131,7 @@ chat_log_close(void) } static char * -_get_log_filename(char *other, const char * const login) +_get_log_filename(char *other, const char * const login, GDateTime *dt) { GString *log_file = g_string_new(getenv("HOME")); g_string_append(log_file, "/.profanity/log"); @@ -144,11 +147,13 @@ _get_log_filename(char *other, const char * const login) 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); + char *result = strdup(log_file->str); + g_string_free(log_file, TRUE); + + return result; } From 460b244048d9002b9fa9f3acd82998492cbfc93d Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 16:34:47 +0100 Subject: [PATCH 4/8] Refactored chat_log.c --- src/chat_log.c | 78 ++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index ea19a594..45daaeec 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -130,59 +130,17 @@ chat_log_close(void) g_date_time_unref(started); } -static char * -_get_log_filename(char *other, const char * const login, GDateTime *dt) -{ - 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); - - 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 struct dated_chat_log * _create_log(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); + GDateTime *now = g_date_time_new_now_local(); + char *filename = _get_log_filename(other, login, now); struct dated_chat_log *new_log = malloc(sizeof(struct dated_chat_log)); - new_log->filename = strdup(log_file->str); - new_log->date = dt; + new_log->filename = strdup(filename); + new_log->date = now; - g_string_free(log_file, TRUE); + free(filename); return new_log; } @@ -225,3 +183,29 @@ gboolean _key_equals(void *key1, void *key2) return (g_strcmp0(str1, str2) == 0); } + +static char * +_get_log_filename(char *other, const char * const login, GDateTime *dt) +{ + 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); + + 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; +} From 31295005283ecc1aee7dbc72c90c915b8c71c090 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 16:45:39 +0100 Subject: [PATCH 5/8] Show log if session started today --- src/chat_log.c | 59 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index 45daaeec..2a68c547 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -33,7 +33,7 @@ #include "ui.h" static GHashTable *logs; -static GDateTime *started; +static GDateTime *session_started; struct dated_chat_log { gchar *filename; @@ -50,7 +50,7 @@ static char * _get_log_filename(char *other, const char * const login, void chat_log_init(void) { - started = g_date_time_new_now_local(); + session_started = g_date_time_new_now_local(); log_info("Initialising chat logs"); logs = g_hash_table_new_full(g_str_hash, (GEqualFunc) _key_equals, g_free, (GDestroyNotify)_free_chat_log); @@ -98,36 +98,47 @@ chat_log_get_previous(const gchar * const login, gchar *recipient, GSList *history) { GDateTime *now = g_date_time_new_now_local(); - char *filename = _get_log_filename(recipient, login, now); - - FILE *logp = fopen(filename, "r"); - char *line = NULL; - size_t read = 0; - if (logp != NULL) { - 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); + gint session_started_day = g_date_time_get_day_of_year(session_started); + gint day_now = g_date_time_get_day_of_year(now); + + // session started today + if (day_now == session_started_day) { + char *filename = _get_log_filename(recipient, login, now); + + FILE *logp = fopen(filename, "r"); + char *line = NULL; + size_t read = 0; + if (logp != NULL) { + 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); + g_date_time_unref(now); + + return history; + + // session started before today + } else { + + return NULL; } - - free(filename); - g_date_time_unref(now); - - return history; } void chat_log_close(void) { g_hash_table_remove_all(logs); - g_date_time_unref(started); + g_date_time_unref(session_started); } static struct dated_chat_log * From c4fd08c430f937d66d86f783be387c15e414ebd2 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 17:23:38 +0100 Subject: [PATCH 6/8] Show history from day that session started --- src/chat_log.c | 54 +++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/chat_log.c b/src/chat_log.c index 2a68c547..ce044aaf 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -97,41 +97,49 @@ GSList * chat_log_get_previous(const gchar * const login, gchar *recipient, GSList *history) { + GTimeZone *tz = g_time_zone_new_local(); + GDateTime *now = g_date_time_new_now_local(); - gint session_started_day = g_date_time_get_day_of_year(session_started); - gint day_now = g_date_time_get_day_of_year(now); - - // session started today - if (day_now == session_started_day) { - char *filename = _get_log_filename(recipient, login, now); - + GDateTime *log_date = g_date_time_new(tz, + g_date_time_get_year(session_started), + g_date_time_get_month(session_started), + g_date_time_get_day_of_month(session_started), + g_date_time_get_hour(session_started), + g_date_time_get_minute(session_started), + g_date_time_get_second(session_started)); + + // get data from all logs from the day the session was started to today + while (g_date_time_get_day_of_year(log_date) <= g_date_time_get_day_of_year(now)) { + char *filename = _get_log_filename(recipient, login, log_date); + FILE *logp = fopen(filename, "r"); char *line = NULL; size_t read = 0; if (logp != NULL) { 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); + 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); } + + fclose(logp); } free(filename); - g_date_time_unref(now); - - return history; - - // session started before today - } else { - - return NULL; + GDateTime *next = g_date_time_add_days(log_date, 1); + g_date_time_unref(log_date); + log_date = g_date_time_ref(next); } + + g_time_zone_unref(tz); + + return history; } void From 655430418b354499e95c5f06dc9b05fe67c76028 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 17:26:35 +0100 Subject: [PATCH 7/8] Chaged padsize to 1000 --- src/windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows.c b/src/windows.c index 047f918d..141cf93c 100644 --- a/src/windows.c +++ b/src/windows.c @@ -45,7 +45,7 @@ #include "ui.h" #define CONS_WIN_TITLE "_cons" -#define PAD_SIZE 200 +#define PAD_SIZE 1000 #define NUM_WINS 10 // holds console at index 0 and chat wins 1 through to 9 From b2103b1c0fba54f6e65ce290505309836cbf543f Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Oct 2012 17:38:10 +0100 Subject: [PATCH 8/8] Shows log date when viewing history --- src/chat_log.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/chat_log.c b/src/chat_log.c index ce044aaf..ea3df7ef 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -116,6 +116,15 @@ chat_log_get_previous(const gchar * const login, gchar *recipient, char *line = NULL; size_t read = 0; if (logp != NULL) { + GString *gs_header = g_string_new("Log "); + g_string_append_printf(gs_header, "%d/%d/%d:", + g_date_time_get_day_of_month(log_date), + g_date_time_get_month(log_date), + g_date_time_get_year(log_date)); + char *header = strdup(gs_header->str); + history = g_slist_append(history, header); + g_string_free(gs_header, TRUE); + size_t length = getline(&line, &read, logp); while (length != -1) { char *copy = malloc(length);