pidgin/purple-plugin-pack

Tweak plugins.cfg for switchspell to note the change in enchant support
org.guifications.plugins
2008-07-22, rekkanoryo
6bf9c444fc79
Tweak plugins.cfg for switchspell to note the change in enchant support
status, which is unfortunately somewhat buggy. I'll trust the distro
packagers to handle this correctly for their individual distros.
/*--------------------------------------------------------------------------*
* AUTOPROFILE *
* *
* A Purple 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 "autoprofile.h"
#include "log.h"
#include "account.h"
#include "conversation.h"
#include "utility.h"
#include "util.h"
#include "comp_logstats.h"
#include <ctype.h>
#include <string.h>
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 (PurpleAccount *a, const char *name) {
GList *accounts, *aliases, *aliases_start;
PurpleAccount *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 (purple_normalize (a, name));
accounts = purple_accounts_get_all ();
aliases_start = aliases = purple_prefs_get_string_list (
"/plugins/gtk/autoprofile/components/logstat/aliases");
while (aliases) {
normalized_alias = purple_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 = (PurpleAccount *)accounts->data;
if (!strcmp (normalized, purple_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 (PurpleLog *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 (PurpleLog *cur_log)
{
struct log_date *the_date;
struct tm *the_time;
struct conversation_time *conv_time;
PurpleLogReadFlags 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 = purple_log_read (cur_log, &flags);
if (!strcmp ("html", cur_log->logger->id)) {
content = purple_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 (PurpleLogType type, PurpleAccount *account)
{
GDir *dir;
const char *prpl;
GList *ret;
const char *filename;
char *path, *me, *tmp;
ret = NULL;
if (type == PURPLE_LOG_CHAT)
me = g_strdup_printf ("%s.chat", purple_normalize(account,
purple_account_get_username(account)));
else
me = g_strdup (purple_normalize(account,
purple_account_get_username(account)));
/* Get the old logger names */
path = g_build_filename(purple_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 (purple_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 = PURPLE_PLUGIN_PROTOCOL_INFO
(purple_find_prpl (purple_account_get_protocol_id(account)))->list_icon(
account, NULL);
path = g_build_filename(purple_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;
PurpleLog *cur_log;
accounts = purple_accounts_get_all();
ap_debug ("logstats", "parsing log files");
while (accounts) {
names_start = names = logstats_get_names (PURPLE_LOG_IM,
(PurpleAccount *)accounts->data);
while (names) {
logs_start = purple_log_get_logs (PURPLE_LOG_IM, (char *)names->data,
(PurpleAccount *)accounts->data);
logs = logs_start;
while (logs) {
cur_log = (PurpleLog *)logs->data;
parse_log (cur_log);
purple_log_free (cur_log);
logs = logs->next;
}
g_list_free (logs_start);
names = names->next;
}
free_string_list (names_start);
accounts = accounts->next;
}
/* Cleanup */
ap_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 = purple_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), purple_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 (sizeof(char) * AP_SIZE_MAXIMUM);
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, AP_SIZE_MAXIMUM - 1, "%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 {
ap_debug ("logstats", "get-max: invalid paramater");
return 0;
}
}
/*--------------------- Signal handlers ----------------------*/
static void logstats_received_im (PurpleAccount *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 (PurpleAccount *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 (PurpleConversation *conv)
{
struct log_date *the_date;
struct conversation_time *the_time;
if (conv->type == PURPLE_CONV_TYPE_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 (struct widget *w)
{
int count;
char *msg;
if (!purple_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 (sizeof(char) * AP_SIZE_MAXIMUM);
count = get_total ("received_msgs");
g_snprintf (msg, AP_SIZE_MAXIMUM, "received msg total is %d", count);
ap_debug ("logstats", msg);
count = get_total ("sent_msgs");
g_snprintf (msg, AP_SIZE_MAXIMUM, "sent msg total is %d", count);
ap_debug ("logstats", msg);
count = get_total ("received_words");
g_snprintf (msg, AP_SIZE_MAXIMUM, "received word total is %d", count);
ap_debug ("logstats", msg);
count = get_total ("sent_words");
g_snprintf (msg, AP_SIZE_MAXIMUM, "sent word total is %d", count);
ap_debug ("logstats", msg);
count = get_total ("num_convos");
g_snprintf (msg, AP_SIZE_MAXIMUM, "num conversations is %d", count);
ap_debug ("logstats", msg);
count = g_slist_length (dates);
g_snprintf (msg, AP_SIZE_MAXIMUM, "num days with conversations is %d", count);
ap_debug ("logstats", msg);
free(msg);
/* Connect signals */
purple_signal_connect (purple_conversations_get_handle (),
"received-im-msg", ap_get_plugin_handle (),
PURPLE_CALLBACK (logstats_received_im), NULL);
purple_signal_connect (purple_conversations_get_handle (),
"sent-im-msg", ap_get_plugin_handle (),
PURPLE_CALLBACK (logstats_sent_im), NULL);
purple_signal_connect (purple_conversations_get_handle (),
"conversation-created", ap_get_plugin_handle (),
PURPLE_CALLBACK (logstats_conv_created), NULL);
}
/* Component unload */
void logstats_unload (struct widget *w)
{
struct log_date *cur_date;
struct conversation_time *cur_time;
GSList *temp;
if (!purple_prefs_get_bool (
"/plugins/gtk/autoprofile/components/logstat/enabled")) {
return;
}
/* Disconnect signals */
purple_signal_disconnect (purple_conversations_get_handle (),
"received-im-msg", ap_get_plugin_handle (),
PURPLE_CALLBACK (logstats_received_im));
purple_signal_disconnect (purple_conversations_get_handle (),
"sent-im-msg", ap_get_plugin_handle (),
PURPLE_CALLBACK (logstats_sent_im));
purple_signal_disconnect (purple_conversations_get_handle (),
"conversation-created", ap_get_plugin_handle (),
PURPLE_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 (struct widget *w)
{
char *buf, *output, *date;
int state;
const char *format;
if (!purple_prefs_get_bool (
"/plugins/gtk/autoprofile/components/logstat/enabled")) {
return NULL;
}
format = purple_prefs_get_string (
"/plugins/gtk/autoprofile/components/logstat/format");
output = (char *)malloc (sizeof(char)*AP_SIZE_MAXIMUM);
*output = '\0';
buf = (char *)malloc (sizeof(char)*AP_SIZE_MAXIMUM);
*buf = '\0';
state = 0;
while (*format) {
if (state == 1) {
switch (*format) {
case '%':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%c", output, *format);
break;
case 'R':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_total ("received_msgs"));
break;
case 'r':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_total ("received_words"));
break;
case 'S':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_total ("sent_msgs"));
break;
case 's':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_total ("sent_words"));
break;
case 'T':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
get_total ("sent_msgs") + get_total ("received_msgs"));
break;
case 't':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
get_total ("sent_words") + get_total ("received_words"));
break;
case 'D':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
num_days_since_start ());
break;
case 'd':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, g_slist_length (dates));
break;
case 'N':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_total ("num_convos"));
break;
case 'n':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("num_convos") / (double) g_slist_length (dates));
break;
case 'i':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_max ("conversations"));
break;
case 'I':
date = date_string ("conversations");
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%s", output, date);
free (date);
break;
case 'j':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_max ("sent"));
break;
case 'J':
date = date_string ("sent");
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%s", output, date);
free (date);
break;
case 'k':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_max ("received"));
break;
case 'K':
date = date_string ("received");
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%s", output, date);
free (date);
break;
case 'l':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_max ("total"));
break;
case 'L':
date = date_string ("total");
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%s", output, date);
free (date);
break;
case 'f':
date = date_string ("first");
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%s", output, date);
free (date);
break;
case 'u':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("received_words") / (double) get_total ("received_msgs"));
break;
case 'v':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("sent_words") / (double) get_total ("sent_msgs"));
break;
case 'w':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%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, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("received_msgs") / (double) get_total ("num_convos"));
break;
case 'V':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("sent_msgs") / (double) get_total ("num_convos"));
break;
case 'W':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) (get_total ("received_msgs") + get_total ("sent_msgs")) / (double) get_total("num_convos"));
break;
case 'x':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("received_words") / (double) g_slist_length (dates));
break;
case 'y':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("sent_words") / (double) g_slist_length (dates));
break;
case 'z':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
((double) get_total ("received_words") + (double) get_total ("sent_words")) / (double) g_slist_length (dates));
break;
case 'X':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("received_msgs") / (double) g_slist_length (dates));
break;
case 'Y':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) get_total ("sent_msgs") / (double) g_slist_length (dates));
break;
case 'Z':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.2f", output,
(double) (get_total ("received_msgs") + get_total ("sent_msgs")) / (double) g_slist_length (dates));
break;
case 'p':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%.1f", output,
100.0 * (double) g_slist_length (dates) / (double) num_days_since_start ());
break;
case 'a':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
((struct log_date *) dates->data)->received_msgs);
break;
case 'b':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
((struct log_date *) dates->data)->sent_msgs);
break;
case 'c':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
g_slist_length (((struct log_date *) dates->data)->conversation_times));
break;
case 'e':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
((struct log_date *) dates->data)->sent_msgs + ((struct log_date *) dates->data)->received_msgs);
break;
case 'A':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_recent_total ("received_msgs", 24 * 7));
break;
case 'B':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_recent_total ("sent_msgs", 24 * 7));
break;
case 'C':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output, get_recent_total ("num_convos", 24 * 7));
break;
case 'E':
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%d", output,
get_recent_total ("received_msgs", 24 * 7) + get_recent_total ("received_msgs", 24 * 7));
break;
default:
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%c", output, *format);
break;
}
strcpy (output, buf);
format++;
state = 0;
} else {
if (*format == '%') {
state = 1;
} else {
g_snprintf (buf, AP_SIZE_MAXIMUM, "%s%c", output, *format);
strcpy (output, buf);
}
format++;
}
}
free (buf);
return output;
}
/* Initialize preferences */
static void logstats_init (struct widget *w)
{
purple_prefs_add_none ("/plugins/gtk/autoprofile/components/logstat");
purple_prefs_add_bool (
"/plugins/gtk/autoprofile/components/logstat/enabled", FALSE);
purple_prefs_add_string (
"/plugins/gtk/autoprofile/components/logstat/format", "");
purple_prefs_add_string_list (
"/plugins/gtk/autoprofile/components/logstat/aliases", NULL);
}
/* The heart of the component */
static char *identifiers [7] = {
N_("logs"),
N_("log"),
N_("stat"),
N_("stats"),
N_("logstats"),
N_("log statistics"),
NULL
};
struct component logstats =
{
N_("Purple log statistics"),
N_("Display various statistics about your message and system logs"),
identifiers,
logstats_generate,
logstats_init,
logstats_load,
logstats_unload,
NULL,
logstats_prefs
};