about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-10-14 17:52:35 +0100
committerJames Booth <boothj5@gmail.com>2012-10-14 17:52:35 +0100
commit5d49993151eecd4be09c7c33ecb99ff7dd81d170 (patch)
treeae9ba471c6ee83576f1f3b1b58efbd7f8363b05c
parent51cde2338bfe4a0baf6c99b377952b4dcbcedd7f (diff)
parentb2103b1c0fba54f6e65ce290505309836cbf543f (diff)
downloadprofani-tty-5d49993151eecd4be09c7c33ecb99ff7dd81d170.tar.gz
Merge branch 'master' into type_out
-rw-r--r--src/chat_log.c152
-rw-r--r--src/chat_log.h2
-rw-r--r--src/command.c2
-rw-r--r--src/profanity.c2
-rw-r--r--src/ui.h1
-rw-r--r--src/windows.c43
6 files changed, 165 insertions, 37 deletions
diff --git a/src/chat_log.c b/src/chat_log.c
index 3a139d31..ea3df7ef 100644
--- a/src/chat_log.c
+++ b/src/chat_log.c
@@ -20,6 +20,7 @@
  *
  */
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -29,23 +30,29 @@
 #include "chat_log.h"
 #include "common.h"
 #include "log.h"
+#include "ui.h"
 
 static GHashTable *logs;
+static GDateTime *session_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, 
+    GDateTime *dt);
 
 void
 chat_log_init(void)
-{
+{   
+    session_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,54 +77,102 @@ 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)
+{
+    GTimeZone *tz = g_time_zone_new_local();
+    
+    GDateTime *now = g_date_time_new_now_local();
+    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) {
+            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);
+                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);
+        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
 chat_log_close(void)
 {
     g_hash_table_remove_all(logs);
+    g_date_time_unref(session_started);
 }
 
 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_printf(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->logp = fopen(log_file->str, "a");
-    new_log->date = dt;
+    new_log->filename = strdup(filename);
+    new_log->date = now;
 
-    g_string_free(log_file, TRUE);
+    free(filename);
 
     return new_log;
 }
 
-
 static gboolean
 _log_roll_needed(struct dated_chat_log *dated_log)
 {
@@ -136,9 +191,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 +202,38 @@ _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);
+}
+
+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;
+}
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 1a56f0cb..cdb084bf 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -105,7 +105,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..141cf93c 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -36,6 +36,7 @@
 #include <ncurses/ncurses.h>
 #endif
 
+#include "chat_log.h"
 #include "command.h"
 #include "contact.h"
 #include "contact_list.h"
@@ -44,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
@@ -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