From bf1cf0444702566d5b77a4e4e195ef7c8341a185 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 28 Jan 2013 20:16:18 +0000 Subject: Joined log and chat_log modules --- Makefile.am | 4 +- src/chat_log.c | 251 ------------------------------------------------------- src/chat_log.h | 40 --------- src/command.c | 1 - src/log.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++ src/log.h | 11 +++ src/profanity.c | 1 - src/ui_windows.c | 1 - 8 files changed, 232 insertions(+), 296 deletions(-) delete mode 100644 src/chat_log.c delete mode 100644 src/chat_log.h diff --git a/Makefile.am b/Makefile.am index d702610d..846f9bd0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,8 +5,8 @@ profanity_SOURCES = src/command.c src/contact.c src/command_history.c src/xmpp.h src/autocomplete.h src/ui_titlebar.c src/ui_windows.c src/common.c \ src/contact_list.c src/ui_inputwin.c src/log.h src/profanity.c \ src/history.c src/ui.h src/common.h src/ contact_list.h src/xmpp_conn.c \ - src/main.c src/profanity.h src/history.h src/chat_log.c \ - src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \ + src/main.c src/profanity.h src/history.h \ + src/tinyurl.c src/tinyurl.h src/chat_session.c \ src/chat_session.h src/muc.c \ src/muc.h src/xmpp_stanza.c src/command_parser.c \ src/theme.c src/theme.h src/window.c src/window.h \ diff --git a/src/chat_log.c b/src/chat_log.c deleted file mode 100644 index 9f6d9905..00000000 --- a/src/chat_log.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * chat_log.c - * - * Copyright (C) 2012, 2013 James Booth - * - * This file is part of Profanity. - * - * Profanity is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Profanity is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Profanity. If not, see . - * - */ - -#include -#include -#include -#include - -#include "glib.h" - -#include "chat_log.h" -#include "common.h" -#include "files.h" -#include "log.h" - -static GHashTable *logs; -static GDateTime *session_started; - -struct dated_chat_log { - 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(const char * const other, const char * const login, - GDateTime *dt, gboolean create); - -void -chat_log_init(void) -{ - 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); -} - -void -chat_log_chat(const gchar * const login, gchar *other, - const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp) -{ - gchar *other_copy = strdup(other); - struct dated_chat_log *dated_log = g_hash_table_lookup(logs, other_copy); - - // no log for user - if (dated_log == NULL) { - dated_log = _create_log(other_copy, login); - g_hash_table_insert(logs, other_copy, dated_log); - - // log exists but needs rolling - } else if (_log_roll_needed(dated_log)) { - dated_log = _create_log(other_copy, login); - g_hash_table_replace(logs, other_copy, dated_log); - } - - gchar *date_fmt = NULL; - GDateTime *dt = NULL; - if (tv_stamp == NULL) { - dt = g_date_time_new_now_local(); - } else { - dt = g_date_time_new_from_timeval_utc(tv_stamp); - } - - date_fmt = g_date_time_format(dt, "%H:%M:%S"); - - FILE *logp = fopen(dated_log->filename, "a"); - - if (direction == PROF_IN_LOG) { - if (strncmp(msg, "/me ", 4) == 0) { - fprintf(logp, "%s - *%s %s\n", date_fmt, other_copy, msg + 4); - } else { - fprintf(logp, "%s - %s: %s\n", date_fmt, other_copy, msg); - } - } else { - if (strncmp(msg, "/me ", 4) == 0) { - fprintf(logp, "%s - *me %s\n", date_fmt, msg + 4); - } else { - 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); - } - - g_free(date_fmt); - g_date_time_unref(dt); -} - -GSList * -chat_log_get_previous(const gchar * const login, const gchar * const 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_compare(log_date, now) != 1) { - char *filename = _get_log_filename(recipient, login, log_date, FALSE); - - FILE *logp = fopen(filename, "r"); - char *line; - if (logp != NULL) { - GString *gs_header = g_string_new(""); - 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); - - while ((line = prof_getline(logp)) != NULL) { - history = g_slist_append(history, line); - } - - 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) -{ - GDateTime *now = g_date_time_new_now_local(); - char *filename = _get_log_filename(other, 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) -{ - gboolean result = FALSE; - GDateTime *now = g_date_time_new_now_local(); - if (g_date_time_get_day_of_year(dated_log->date) != - g_date_time_get_day_of_year(now)) { - result = TRUE; - } - g_date_time_unref(now); - - return result; -} - -static void -_free_chat_log(struct dated_chat_log *dated_log) -{ - if (dated_log != 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); - dated_log->date = NULL; - } - } - 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(const char * const other, const char * const login, - GDateTime *dt, gboolean create) -{ - gchar *chatlogs_dir = files_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); - - gchar *other_file = str_replace(other, "@", "_at_"); - g_string_append_printf(log_file, "/%s", other_file); - if (create) { - 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 deleted file mode 100644 index db3f3565..00000000 --- a/src/chat_log.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * chat_log.h - * - * Copyright (C) 2012, 2013 James Booth - * - * This file is part of Profanity. - * - * Profanity is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Profanity is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Profanity. If not, see . - * - */ - -#ifndef CHAT_LOG_H -#define CHAT_LOG_H - -#include - -typedef enum { - PROF_IN_LOG, - PROF_OUT_LOG -} chat_log_direction_t; - -void chat_log_init(void); -void chat_log_chat(const gchar * const login, gchar *other, - const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp); -void chat_log_close(void); -GSList * chat_log_get_previous(const gchar * const login, - const gchar * const recipient, GSList *history); - -#endif diff --git a/src/command.c b/src/command.c index f8f5e432..04e99484 100644 --- a/src/command.c +++ b/src/command.c @@ -33,7 +33,6 @@ #include "common.h" #include "contact.h" #include "contact_list.h" -#include "chat_log.h" #include "jid.h" #include "log.h" #include "preferences.h" diff --git a/src/log.c b/src/log.c index 1e71ff9b..05e2ec3d 100644 --- a/src/log.c +++ b/src/log.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include @@ -46,6 +47,21 @@ static GTimeZone *tz; static GDateTime *dt; static log_level_t level_filter; +static GHashTable *logs; +static GDateTime *session_started; + +struct dated_chat_log { + 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(const char * const other, const char * const login, + GDateTime *dt, gboolean create); + static void _rotate_log_file(void); void @@ -164,3 +180,206 @@ _rotate_log_file(void) g_free(log_file); log_info("Log has been rotated"); } + +void +chat_log_init(void) +{ + 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); +} + +void +chat_log_chat(const gchar * const login, gchar *other, + const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp) +{ + gchar *other_copy = strdup(other); + struct dated_chat_log *dated_log = g_hash_table_lookup(logs, other_copy); + + // no log for user + if (dated_log == NULL) { + dated_log = _create_log(other_copy, login); + g_hash_table_insert(logs, other_copy, dated_log); + + // log exists but needs rolling + } else if (_log_roll_needed(dated_log)) { + dated_log = _create_log(other_copy, login); + g_hash_table_replace(logs, other_copy, dated_log); + } + + gchar *date_fmt = NULL; + GDateTime *dt = NULL; + if (tv_stamp == NULL) { + dt = g_date_time_new_now_local(); + } else { + dt = g_date_time_new_from_timeval_utc(tv_stamp); + } + + date_fmt = g_date_time_format(dt, "%H:%M:%S"); + + FILE *logp = fopen(dated_log->filename, "a"); + + if (direction == PROF_IN_LOG) { + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *%s %s\n", date_fmt, other_copy, msg + 4); + } else { + fprintf(logp, "%s - %s: %s\n", date_fmt, other_copy, msg); + } + } else { + if (strncmp(msg, "/me ", 4) == 0) { + fprintf(logp, "%s - *me %s\n", date_fmt, msg + 4); + } else { + 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); + } + + g_free(date_fmt); + g_date_time_unref(dt); +} + +GSList * +chat_log_get_previous(const gchar * const login, const gchar * const 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_compare(log_date, now) != 1) { + char *filename = _get_log_filename(recipient, login, log_date, FALSE); + + FILE *logp = fopen(filename, "r"); + char *line; + if (logp != NULL) { + GString *gs_header = g_string_new(""); + 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); + + while ((line = prof_getline(logp)) != NULL) { + history = g_slist_append(history, line); + } + + 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) +{ + GDateTime *now = g_date_time_new_now_local(); + char *filename = _get_log_filename(other, 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) +{ + gboolean result = FALSE; + GDateTime *now = g_date_time_new_now_local(); + if (g_date_time_get_day_of_year(dated_log->date) != + g_date_time_get_day_of_year(now)) { + result = TRUE; + } + g_date_time_unref(now); + + return result; +} + +static void +_free_chat_log(struct dated_chat_log *dated_log) +{ + if (dated_log != 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); + dated_log->date = NULL; + } + } + 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(const char * const other, const char * const login, + GDateTime *dt, gboolean create) +{ + gchar *chatlogs_dir = files_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); + + gchar *other_file = str_replace(other, "@", "_at_"); + g_string_append_printf(log_file, "/%s", other_file); + if (create) { + 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/log.h b/src/log.h index 579ec94c..146f55a4 100644 --- a/src/log.h +++ b/src/log.h @@ -31,6 +31,11 @@ typedef enum { PROF_LEVEL_ERROR } log_level_t; +typedef enum { + PROF_IN_LOG, + PROF_OUT_LOG +} chat_log_direction_t; + void log_init(log_level_t filter); log_level_t log_get_filter(void); void log_close(void); @@ -41,4 +46,10 @@ void log_error(const char * const msg, ...); void log_msg(log_level_t level, const char * const area, const char * const msg); +void chat_log_init(void); +void chat_log_chat(const gchar * const login, gchar *other, + const gchar * const msg, chat_log_direction_t direction, GTimeVal *tv_stamp); +void chat_log_close(void); +GSList * chat_log_get_previous(const gchar * const login, + const gchar * const recipient, GSList *history); #endif diff --git a/src/profanity.c b/src/profanity.c index ff167afb..e8ea1770 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -30,7 +30,6 @@ #include #include "accounts.h" -#include "chat_log.h" #include "chat_session.h" #include "command.h" #include "common.h" diff --git a/src/ui_windows.c b/src/ui_windows.c index a78a99c9..6c762e9b 100644 --- a/src/ui_windows.c +++ b/src/ui_windows.c @@ -44,7 +44,6 @@ #include #endif -#include "chat_log.h" #include "chat_session.h" #include "command.h" #include "common.h" -- cgit 1.4.1-2-gfad0