Logo Search packages:      
Sourcecode: autoprofile version File versions  Download package

comp_logstats.c

/*--------------------------------------------------------------------------*
 * AUTOPROFILE                                                              *
 *                                                                          *
 * A Gaim away message and profile manager that supports dynamic text       *
 *                                                                          *
 * AutoProfile is the legal property of its developers.  Please refer to    *
 * the COPYRIGHT file distributed with this source distribution.            *
 *                                                                          *
 * This program 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 2 of the License, or        *
 * (at your option) any later version.                                      *
 *                                                                          *
 * This program 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 this program; if not, write to the Free Software              *
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA *
 *--------------------------------------------------------------------------*/

#include "component.h"
#include "log.h"
#include "account.h"
#include "conversation.h"
#include "utility.h"
#include "util.h"

#include "comp_logstats.h"

extern GaimPlugin *plugin_handle;

struct conversation_time {
  time_t *start_time;
  char *name;
};

/* Represents data about a particular 24 hour period in the logs */
struct log_date {
  int year;                   // The year
  int month;                  // The month
  int day;                    // The day
  int received_msgs;          // # msgs received
  int received_words;         // # words received
  int sent_msgs;              // # msgs sent
  int sent_words;             // # words sent
  GSList *conversation_times; // List of conversation_time pointers
};

/* List of struct log_dates 
   This is SORTED by most recent first */
static GSList *dates = NULL;

/* Hashtable of log_dates */
static GHashTable *dates_table = NULL;

/* Is the current line part of a message sent or received? */
static gboolean receiving = FALSE;
/* Shortcut vars */
static char *cur_receiver = NULL;
static char *cur_sender = NULL;

/* Implements GCompareFunc */
static gint conversation_time_compare (gconstpointer x, gconstpointer y) {
  const struct conversation_time *a = x;
  const struct conversation_time *b = y;

  if (difftime (*(a->start_time), *(b->start_time)) == 0.0) {
    if (!strcmp (a->name, b->name))
      return 0;
  }

  return -1;
}

/* Implements GCompareFunc */
static gint log_date_compare (gconstpointer x, gconstpointer y)
{
  const struct log_date *a = y;
  const struct log_date *b = x;

  if (a->year == b->year) {
    if (a->month == b->month) {
      if (a->day == b->day)
        return 0;
      else
        return a->day - b->day;
    } else {
      return a->month - b->month;
    }
  } else {
    return a->year - b->year;
  }
}

/* Implements GHashFunc */
static guint log_date_hash (gconstpointer key)
{
  const struct log_date *d = key;
  return ((d->year * 365) + (d->month * 12) + (d->day));
}

/* Implements GEqualFunc */
static gboolean log_date_equal (gconstpointer x, gconstpointer y)
{
  const struct log_date *a = y;
  const struct log_date *b = x;

  if (a->year == b->year &&
      a->month == b->month &&
      a->day == b->day) {
    return TRUE;
  }
  return FALSE;
}

/* Returns the struct log_date associated with a particular date.
   Will MODIFY list of dates and insert sorted if not yet created */
static struct log_date *get_date (int year, int month, int day)
{
  struct log_date *cur_date;
  gpointer *node;

  cur_date = (struct log_date *)malloc(sizeof(struct log_date));
  cur_date->year = year;
  cur_date->month = month;
  cur_date->day = day;

  if ((node = g_hash_table_lookup (dates_table, cur_date))) {
    free (cur_date);
    return (struct log_date *)node;
  } else {
    g_hash_table_insert (dates_table, cur_date, cur_date);
    cur_date->received_msgs = 0;
    cur_date->received_words = 0;
    cur_date->sent_msgs = 0;
    cur_date->sent_words = 0;
    cur_date->conversation_times = NULL;
    return cur_date;
  }
}

/* Like get_date, except specific to the current date */
static struct log_date *get_today ()
{
  time_t the_time;
  struct tm *cur_time;

  time (&the_time);
  cur_time = localtime (&the_time);

  return get_date (cur_time->tm_year, cur_time->tm_mon, cur_time->tm_mday);
}

static int string_word_count (const char *line)
{
  int count, state;

  count = 0;
  state = 0;

  /* If state is 1, currently processing a word */
  while (*line) {
    if (state == 0) {
      if (!isspace (*line))
        state = 1;
    } else {
      if (isspace (*line)) {
        state = 0;
        count++;
      }
    }
    line++;
  }

  if (state == 1)
    count++;

  return count;
}

/* Figure out if a person is yourself or someone else */
static gboolean is_self (GaimAccount *a, const char *name) {
  GList *accounts, *aliases, *aliases_start;
  GaimAccount *account;

  char *normalized;
  const char *normalized_alias;

  if (cur_sender && !strcmp (cur_sender, name)) {
    return TRUE;
  }

  if (cur_receiver && !strcmp (cur_receiver, name)) {
    return FALSE;
  }

  normalized = strdup (gaim_normalize (a, name));
  accounts = gaim_accounts_get_all ();

  aliases_start = aliases = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/components/logstat/aliases");

  while (aliases) {
    normalized_alias = gaim_normalize (a, (char *)aliases->data);

    if (!strcmp (normalized, normalized_alias)) {
      free_string_list (aliases_start);
      free (normalized);

      if (cur_sender)
        free (cur_sender);
      cur_sender = strdup (name);

      return TRUE;
    }

    aliases = aliases->next;
  }

  free_string_list (aliases_start);

  while (accounts) {
    account = (GaimAccount *)accounts->data;
    if (!strcmp (normalized, gaim_account_get_username (account))) {
      free (normalized);
      if (cur_sender)
        free (cur_sender);
      cur_sender = strdup (name);
      return TRUE;
    }
    accounts = accounts->next;
  }

  free (normalized);

  if (cur_receiver)
    free (cur_receiver);
  cur_receiver = strdup (name);
  return FALSE;
}

/* Parses a line of a conversation */
static void parse_line (GaimLog *cur_log, char *l, struct log_date *d)
{
  char *cur_line, *cur_line_start;
  char *name;
  char *message;

  char *line = l;

  if (strlen (line) > 14 && *line == ' ')
    line++;

  if (strlen (line) > 13 &&
      *line == '(' &&
      isdigit (*(line + 1)) &&
      isdigit (*(line + 2)) &&
      *(line + 3) == ':' &&
      isdigit (*(line + 4)) &&
      isdigit (*(line + 5)) &&
      *(line + 6) == ':' &&
      isdigit (*(line + 7)) &&
      isdigit (*(line + 8)) &&
      *(line + 9) == ')' &&
      isspace (*(line + 10))) {
    cur_line_start = cur_line = line + 11;
    while (*cur_line) {
      if (*cur_line == ':') {
        *cur_line = '\0';
        name = cur_line_start;
        message = ++cur_line;

        receiving = !is_self (cur_log->account, name);

        if (receiving) {
          d->received_msgs++;
          d->received_words += string_word_count (message);
        } else {
          d->sent_msgs++;
          d->sent_words += string_word_count (message);
        }

        return;
      }
      cur_line++;
    }

  }

  if (receiving) {
    d->received_words += string_word_count (line);
  } else {
    d->sent_words += string_word_count (line);
  }
}

/* Parses a conversation if hasn't been handled yet */
static void parse_log (GaimLog *cur_log)
{
  struct log_date *the_date;
  struct tm *the_time;
  struct conversation_time *conv_time;

  GaimLogReadFlags flags;
  char *content, *cur_content, *cur_content_start, *temp;

  the_time = localtime (&(cur_log->time));
  the_date = get_date (the_time->tm_year, the_time->tm_mon, the_time->tm_mday);

  /* Check for old log and if no conflicts, add to list */
  conv_time = (struct conversation_time *)malloc (
    sizeof (struct conversation_time));
  conv_time->start_time = (time_t *)malloc (sizeof(time_t));
  *(conv_time->start_time) = cur_log->time;
  conv_time->name = strdup (cur_log->name);

  if (g_slist_find_custom (the_date->conversation_times, conv_time, 
    conversation_time_compare)) {
    /* We already processed this!  Halt! */
    free (conv_time->start_time);
    free (conv_time->name);
    free (conv_time);
    return;
  }

  the_date->conversation_times = g_slist_prepend (the_date->conversation_times,
    conv_time);

  /* Start rolling the counters! */
  temp = gaim_log_read (cur_log, &flags);
  if (!strcmp ("html", cur_log->logger->id)) {
    content = gaim_markup_strip_html (temp);
    free (temp);
  } else {
    content = temp;
  }

  cur_content_start = cur_content = content;

  /* Splits the conversation into lines (each line may not necessarily
     be a seperate message */
  while (*cur_content) {
    if (*cur_content == '\n') {
      *cur_content = '\0';
      parse_line (cur_log, cur_content_start, the_date);
      cur_content_start = cur_content + 1;
    }
    cur_content++;
  }

  parse_line (cur_log, cur_content_start, the_date);

  free (content);
}

/* Get names of users in logs */
static GList *logstats_get_names (GaimLogType type, GaimAccount *account)
{
  GDir *dir;
  const char *prpl;
  GList *ret;
  const char *filename;
  char *path, *me, *tmp;

  ret = NULL;

  if (type == GAIM_LOG_CHAT)
    me = g_strdup_printf ("%s.chat", gaim_normalize(account, 
      gaim_account_get_username(account)));
  else
    me = g_strdup (gaim_normalize(account, 
      gaim_account_get_username(account)));

  /* Get the old logger names */
  path = g_build_filename(gaim_user_dir(), "logs", NULL);
  if (!(dir = g_dir_open(path, 0, NULL))) {
    g_free(path);
    return ret;
  }

  while ((filename = g_dir_read_name (dir))) {
    if (gaim_str_has_suffix (filename, ".log")) {
      tmp = strdup (filename);
      *(tmp + strlen (filename) - 4) = '\0';
      if (!string_list_find (ret, tmp))
        ret = g_list_prepend (ret, strdup (tmp));
      free (tmp);
    }
  }

  g_dir_close (dir);
  g_free (path);

  /* Get the account-specific names */
  prpl = GAIM_PLUGIN_PROTOCOL_INFO
    (gaim_find_prpl (gaim_account_get_protocol_id(account)))->list_icon(
      account, NULL);

  path = g_build_filename(gaim_user_dir(), "logs", prpl, me, NULL);
  g_free (me);

  if (!(dir = g_dir_open(path, 0, NULL))) {
    g_free(path);
    return ret;
  }

  while ((filename = g_dir_read_name (dir))) {
    if (!string_list_find (ret, filename))
      ret = g_list_prepend (ret, strdup (filename));
  }

  g_dir_close (dir);
  g_free (path);

  return ret;
}

/* On load, reads in all logs and initializes stats database */
static void logstats_read_logs ()
{
  GList *accounts, *logs, *logs_start, *names, *names_start;
  GaimLog *cur_log;

  accounts = gaim_accounts_get_all();

  auto_debug ("logstats", "parsing log files");

  while (accounts) {
    names_start = names = logstats_get_names (GAIM_LOG_IM, 
      (GaimAccount *)accounts->data);

    while (names) {
      logs_start = gaim_log_get_logs (GAIM_LOG_IM, (char *)names->data,
        (GaimAccount *)accounts->data);
      logs = logs_start;

      while (logs) {
        cur_log = (GaimLog *)logs->data;
        parse_log (cur_log);
        gaim_log_free (cur_log);
        logs = logs->next;
      }

      g_list_free (logs_start);
      names = names->next;
    }

    free_string_list (names_start);
    accounts = accounts->next;
  }
 
  /* Cleanup */

  auto_debug ("logstats", "finished parsing log files");
}

/* Implements GHFunc */
static void add_element (gpointer key, gpointer value, gpointer data)
{
  dates = g_slist_insert_sorted (dates, value, log_date_compare);
}

/* Updates GList against hashtable */
static void logstats_update_dates ()
{
  g_slist_free (dates);
  dates = NULL;
  g_hash_table_foreach (dates_table, add_element, NULL);
}

/*--------------------- Total calculations -------------------*/
static int get_total (const char *field)
{
  GSList *cur_day;
  int count;
  struct log_date *d;

  cur_day = dates;
  count = 0;
  while (cur_day) {
    d = (struct log_date *)cur_day->data;
    if (!strcmp (field, "received_msgs")) {
      count += d->received_msgs;
    } else if (!strcmp (field, "received_words")) {
      count += d->received_words;
    } else if (!strcmp (field, "sent_msgs")) {
      count += d->sent_msgs;
    } else if (!strcmp (field, "sent_words")) {
      count += d->sent_words;
    } else if (!strcmp (field, "num_convos")) {
      count += g_slist_length (d->conversation_times);
    } 

    cur_day = cur_day->next;
  }

  return count;
}

static int get_recent_total (const char *field, int hours)
{
  GSList *cur_day;
  int count;
  struct log_date *d;
  time_t cur_day_time;

  cur_day = dates;
  count = 0;

  while (cur_day) {
    d = (struct log_date *)cur_day->data;
    cur_day_time = gaim_time_build (d->year + 1900, d->month + 1, d->day, 
      0, 0, 0);
    if (difftime (time (NULL), cur_day_time) > (double) hours * 60.0 * 60.0)
      break;

    if (!strcmp (field, "received_msgs")) {
      count += d->received_msgs;
    } else if (!strcmp (field, "sent_msgs")) {
      count += d->sent_msgs;
    } else if (!strcmp (field, "num_convos")) {
      count += g_slist_length (d->conversation_times);
    } 

    cur_day = cur_day->next;
  }

  return count;
}

static int num_days_since_start ()
{
  GSList *first_day;
  double difference;
  struct log_date *d;

  first_day = g_slist_last (dates);

  if (!first_day)
    return 0;

  d = (struct log_date *)first_day->data;

  difference = difftime (
    time (NULL), gaim_time_build (d->year + 1900, d->month + 1, d->day, 
      0, 0, 0));

  return (int) difference / (60.0 * 60.0 * 24.0); 
}

static struct log_date *get_max_date (const char *field)
{
  struct log_date *max_date, *cur_date;
  int max_so_far, cur_max;
  GSList *cur_day;

  max_so_far = 0;
  max_date = NULL;
  cur_day = dates;

  while (cur_day) {
    cur_date = (struct log_date *)cur_day->data;
    if (!strcmp (field, "conversations")) {
      cur_max = g_slist_length (cur_date->conversation_times);
    } else if (!strcmp (field, "received")) {
      cur_max = cur_date->received_msgs;
    } else if (!strcmp (field, "sent")) {
      cur_max = cur_date->sent_msgs;
    } else if (!strcmp (field, "total")) {
      cur_max = cur_date->sent_msgs + cur_date->received_msgs;
    } else {
      cur_max = 0;
    }

    if (cur_max >= max_so_far) {
      max_date = cur_date;
      max_so_far = cur_max;
    }

    cur_day = cur_day->next;
  }

  return max_date;
}

static char *date_string (const char *field)
{
  struct log_date *d;
  char *output;
  struct tm *t_struct;
  time_t t;
  GSList *last_day;

  last_day = g_slist_last (dates);

  if (!last_day)
    return NULL;

  if (!strcmp (field, "first")) {
    d = (struct log_date *) last_day->data;
  } else {
    d = get_max_date (field);
  }

  if (!d)
    return NULL;

  output = (char *)malloc (1024);
  t_struct = (struct tm *)malloc(sizeof(struct tm));
  t_struct->tm_year = d->year;
  t_struct->tm_mon = d->month;
  t_struct->tm_mday = d->day;
  t_struct->tm_sec = 0;
  t_struct->tm_min = 0;
  t_struct->tm_hour = 0;
  t = mktime (t_struct);
  free (t_struct);
  t_struct = localtime (&t);

  strftime (output, 1000, "%a %b %d, %Y", t_struct);
  return output; 
}

static int get_max (const char *field)
{
  struct log_date *max_date = get_max_date (field);

  if (!max_date)
    return 0;
  
  if (!strcmp (field, "conversations")) {
    return g_slist_length (max_date->conversation_times);
  } else if (!strcmp (field, "received")) {
    return max_date->received_msgs;
  } else if (!strcmp (field, "sent")) {
    return max_date->sent_msgs;
  } else if (!strcmp (field, "total")) {
    return max_date->sent_msgs + max_date->received_msgs;
  } else {
    auto_debug ("logstats", "get-max: invalid paramater");
    return 0;
  }

}


/*--------------------- Signal handlers ----------------------*/
static void logstats_received_im (GaimAccount *account, char *sender,
                                  char *message, int flags)
{
  struct log_date *the_date; 

  the_date = get_today ();
  the_date->received_msgs++;
  the_date->received_words += string_word_count (message);

  receiving = TRUE;
}

static void logstats_sent_im (GaimAccount *account, const char *receiver,
                              const char *message)
{
  struct log_date *the_date;

  the_date = get_today ();  
  the_date->sent_msgs++;
  the_date->sent_words += string_word_count (message);

  receiving = FALSE;
}

static void logstats_conv_created (GaimConversation *conv)
{
  struct log_date *the_date;
  struct conversation_time *the_time;
  
  if (conv->type == GAIM_CONV_IM) {
    the_time = malloc (sizeof(struct conversation_time));
    the_time->name = strdup (conv->name);
    the_time->start_time = malloc (sizeof(time_t));
    time (the_time->start_time);

    the_date = get_today ();
    the_date->conversation_times = g_slist_prepend (
      the_date->conversation_times, the_time);

    logstats_update_dates ();
  }
}

/*--------------------------- Main functions -------------------------*/

/* Component load */
void logstats_load ()
{
  int count;
  char *msg;

  if (!gaim_prefs_get_bool (
    "/plugins/gtk/autoprofile/components/logstat/enabled")) {
    return;
  }

  /* Initialize database */
  dates_table = g_hash_table_new (log_date_hash, log_date_equal);
  logstats_read_logs ();
  logstats_update_dates ();

  /* Debug */
  msg = (char *)malloc (1000);
  count = get_total ("received_msgs");
  g_snprintf (msg, 1000, "received msg total is %d", count);
  auto_debug ("logstats", msg);
  count = get_total ("sent_msgs");
  g_snprintf (msg, 1000, "sent msg total is %d", count);
  auto_debug ("logstats", msg);
  count = get_total ("received_words");
  g_snprintf (msg, 1000, "received word total is %d", count);
  auto_debug ("logstats", msg);
  count = get_total ("sent_words");
  g_snprintf (msg, 1000, "sent word total is %d", count);
  auto_debug ("logstats", msg);
  count = get_total ("num_convos");
  g_snprintf (msg, 1000, "num conversations is %d", count);
  auto_debug ("logstats", msg);
  count = g_slist_length (dates);
  g_snprintf (msg, 1000, "num days with conversations is %d", count);
  auto_debug ("logstats", msg);

  free(msg);

  /* Connect signals */
  gaim_signal_connect (gaim_conversations_get_handle (),
                       "received-im-msg", plugin_handle,
                       GAIM_CALLBACK (logstats_received_im), NULL);
  gaim_signal_connect (gaim_conversations_get_handle (),
                       "sent-im-msg", plugin_handle,
                       GAIM_CALLBACK (logstats_sent_im), NULL);
  gaim_signal_connect (gaim_conversations_get_handle (),
                       "conversation-created", plugin_handle,
                       GAIM_CALLBACK (logstats_conv_created), NULL);
}

/* Component unload */
void logstats_unload ()
{
  struct log_date *cur_date;
  struct conversation_time *cur_time;
  GSList *temp;

  if (!gaim_prefs_get_bool (
    "/plugins/gtk/autoprofile/components/logstat/enabled")) {
    return;
  }

  /* Disconnect signals */
  gaim_signal_disconnect (gaim_conversations_get_handle (),
                          "received-im-msg", plugin_handle,
                          GAIM_CALLBACK (logstats_received_im));
  gaim_signal_disconnect (gaim_conversations_get_handle (),
                          "sent-im-msg", plugin_handle,
                          GAIM_CALLBACK (logstats_sent_im));
  gaim_signal_disconnect (gaim_conversations_get_handle (),
                          "conversation-created", plugin_handle,
                          GAIM_CALLBACK (logstats_conv_created));

  logstats_update_dates ();

  /* Free all the memory */
  while (dates) {
    cur_date = (struct log_date *)dates->data;
    while (cur_date->conversation_times) {
      temp = cur_date->conversation_times;
      cur_time = (struct conversation_time *)temp->data;
      cur_date->conversation_times = temp->next;
      free (cur_time->start_time);
      free (cur_time->name);
      free (cur_time);
      g_slist_free_1 (temp);
    }
    free (cur_date);
    temp = dates;
    dates = dates->next; 
    g_slist_free_1 (temp);
  }

  if (cur_receiver) {
    free (cur_receiver);
    cur_receiver = NULL;
  }
  if (cur_sender) {
    free (cur_sender);
    cur_sender = NULL;
  }
  g_hash_table_destroy (dates_table);
  dates_table = NULL;
}

/* Generate the output */
static char *logstats_generate ()
{ 
  char *buf, *output, *date;
  int state;
  const char *format;

  if (!gaim_prefs_get_bool (
    "/plugins/gtk/autoprofile/components/logstat/enabled")) {
    return NULL;
  }

  format = gaim_prefs_get_string (
    "/plugins/gtk/autoprofile/components/logstat/format");

  output = (char *)malloc (1024);
  *output = '\0';
  buf = (char *)malloc (1024);
  *buf = '\0';

  state = 0;

  while (*format) {
    if (state == 1) {
      switch (*format) {
        case '%':
          g_snprintf (buf, 1000, "%s%c", output, *format);
          break;
        case 'R':
          g_snprintf (buf, 1000, "%s%d", output, get_total ("received_msgs"));
          break;
        case 'r':
          g_snprintf (buf, 1000, "%s%d", output, get_total ("received_words"));
          break;
        case 'S':
          g_snprintf (buf, 1000, "%s%d", output, get_total ("sent_msgs"));
          break;
        case 's':
          g_snprintf (buf, 1000, "%s%d", output, get_total ("sent_words"));
          break;
        case 'T':
          g_snprintf (buf, 1000, "%s%d", output, 
            get_total ("sent_msgs") + get_total ("received_msgs"));
          break;
        case 't':
          g_snprintf (buf, 1000, "%s%d", output, 
            get_total ("sent_words") + get_total ("received_words"));
          break;
        case 'D':
          g_snprintf (buf, 1000, "%s%d", output,
            num_days_since_start ());
          break;
        case 'd':
          g_snprintf (buf, 1000, "%s%d", output, g_slist_length (dates));
          break;
        case 'N':
          g_snprintf (buf, 1000, "%s%d", output, get_total ("num_convos"));
          break;
        case 'n':
          g_snprintf (buf, 1000, "%s%.2f", output,
            (double) get_total ("num_convos") / (double) g_slist_length (dates));
          break;
        case 'i':
          g_snprintf (buf, 1000, "%s%d", output, get_max ("conversations"));
          break;
        case 'I':
          date = date_string ("conversations");
          g_snprintf (buf, 1000, "%s%s", output, date);
          free (date);
          break;
        case 'j':
          g_snprintf (buf, 1000, "%s%d", output, get_max ("sent"));
          break;
        case 'J':
          date = date_string ("sent");
          g_snprintf (buf, 1000, "%s%s", output, date);
          free (date);
          break;
        case 'k':
          g_snprintf (buf, 1000, "%s%d", output, get_max ("received"));
          break;
        case 'K':
          date = date_string ("received");
          g_snprintf (buf, 1000, "%s%s", output, date);
          free (date);
          break;
        case 'l':
          g_snprintf (buf, 1000, "%s%d", output, get_max ("total"));
          break;
        case 'L':
          date = date_string ("total");
          g_snprintf (buf, 1000, "%s%s", output, date);
          free (date);
          break;
        case 'f':
          date = date_string ("first");
          g_snprintf (buf, 1000, "%s%s", output, date);
          free (date);
          break;
        case 'u':
          g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("received_words") / (double) get_total ("received_msgs"));
          break;
        case 'v':
          g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("sent_words") / (double) get_total ("sent_msgs"));
          break;
        case 'w':
          g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) (get_total ("received_words") + get_total ("sent_words")) / (double) (get_total("received_msgs") + get_total ("sent_msgs")));
          break;
        case 'U':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("received_msgs") / (double) get_total ("num_convos"));
          break;
        case 'V':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("sent_msgs") / (double) get_total ("num_convos"));
          break;
        case 'W':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) (get_total ("received_msgs") + get_total ("sent_msgs")) / (double) get_total("num_convos"));
          break;
        case 'x':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("received_words") / (double) g_slist_length (dates));
          break;
        case 'y':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("sent_words") / (double) g_slist_length (dates));
          break;
        case 'z':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            ((double) get_total ("received_words") + (double) get_total ("sent_words")) / (double) g_slist_length (dates));
          break;
        case 'X':
         g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("received_msgs") / (double) g_slist_length (dates));
          break;
        case 'Y':
          g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) get_total ("sent_msgs") / (double) g_slist_length (dates));
          break;
        case 'Z':
          g_snprintf (buf, 1000, "%s%.2f", output, 
            (double) (get_total ("received_msgs") + get_total ("sent_msgs")) / (double) g_slist_length (dates));
          break;
        case 'p':
          g_snprintf (buf, 1000, "%s%.1f", output,
            100.0 * (double) g_slist_length (dates) / (double) num_days_since_start ());
          break;
        case 'a':
          g_snprintf (buf, 1000, "%s%d", output,
            ((struct log_date *) dates->data)->received_msgs);
          break;
        case 'b':
          g_snprintf (buf, 1000, "%s%d", output,
            ((struct log_date *) dates->data)->sent_msgs);
          break;
        case 'c':
          g_snprintf (buf, 1000, "%s%d", output,
            g_slist_length (((struct log_date *) dates->data)->conversation_times));
          break;
        case 'e':
          g_snprintf (buf, 1000, "%s%d", output,
            ((struct log_date *) dates->data)->sent_msgs + ((struct log_date *) dates->data)->received_msgs);
          break;
        case 'A':
          g_snprintf (buf, 1000, "%s%d", output, get_recent_total ("received_msgs", 24 * 7));
          break;
        case 'B':
          g_snprintf (buf, 1000, "%s%d", output, get_recent_total ("sent_msgs", 24 * 7));
          break;
        case 'C':
          g_snprintf (buf, 1000, "%s%d", output, get_recent_total ("num_convos", 24 * 7));
          break;
        case 'E':
          g_snprintf (buf, 1000, "%s%d", output, 
            get_recent_total ("received_msgs", 24 * 7) + get_recent_total ("received_msgs", 24 * 7));
          break;
        default:
          g_snprintf (buf, 1000, "%s%c", output, *format);
          break;
      }

      strcpy (output, buf);
      format++;
      state = 0;
    } else {
      if (*format == '%') {
        state = 1;
      } else {
        g_snprintf (buf, 1000, "%s%c", output, *format);
        strcpy (output, buf);
      }
      format++;
    }

  }

  free (buf);
  return output;
}

/* Initialize preferences */
static void logstats_init ()
{
  gaim_prefs_add_none ("/plugins/gtk/autoprofile/components/logstat");
  gaim_prefs_add_bool (
    "/plugins/gtk/autoprofile/components/logstat/enabled", FALSE);
  gaim_prefs_add_string (
    "/plugins/gtk/autoprofile/components/logstat/format", "");
  gaim_prefs_add_string_list (
    "/plugins/gtk/autoprofile/components/logstat/aliases", NULL);
}

/* The heart of the component */
struct component logstats =
{
  N_("Log statistics"),
  N_("Display various statistics about your message and system logs"),
  'l',
  &logstats_generate,
  &logstats_init,
  &logstats_load,
  &logstats_unload,
  &logstats_prefs
};


Generated by  Doxygen 1.6.0   Back to index