Mercurial > pidgin
changeset 25919:52b2e7260340
A patch from Chris Connett to change the log size sorting method to weight
logs by date. In other words, to sort them by *recent* activity as opposed
to total log size.
Fixes #5447
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Mon, 26 Jan 2009 04:19:00 +0000 |
parents | bc8d1607f9b8 |
children | c0e3b62f8098 |
files | COPYRIGHT ChangeLog.API libpurple/log.c libpurple/log.h pidgin/gtkblist.c |
diffstat | 5 files changed, 97 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Mon Jan 26 02:39:55 2009 +0000 +++ b/COPYRIGHT Mon Jan 26 04:19:00 2009 +0000 @@ -85,6 +85,7 @@ Lorenzo Colitti Collabora Ltd. Jeff Connelly +Chris Connett Nathan Conrad Felipe Contreras Alex Converse
--- a/ChangeLog.API Mon Jan 26 02:39:55 2009 +0000 +++ b/ChangeLog.API Mon Jan 26 04:19:00 2009 +0000 @@ -24,6 +24,7 @@ * purple_network_force_online * purple_global_proxy_set_info * purple_strequal + * purple_log_get_activity_score Deprecated: * purple_buddy_get_local_alias
--- a/libpurple/log.c Mon Jan 26 02:39:55 2009 +0000 +++ b/libpurple/log.c Mon Jan 26 04:19:00 2009 +0000 @@ -34,6 +34,7 @@ #include "util.h" #include "stringref.h" #include "imgstore.h" +#include "time.h" static GSList *loggers = NULL; @@ -46,6 +47,7 @@ PurpleAccount *account; }; static GHashTable *logsize_users = NULL; +static GHashTable *logsize_users_decayed = NULL; static void log_get_log_sets_common(GHashTable *sets); @@ -161,14 +163,27 @@ lu->account = log->account; if(g_hash_table_lookup_extended(logsize_users, lu, NULL, &ptrsize)) { + char *tmp = lu->name; + total = GPOINTER_TO_INT(ptrsize); total += written; g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(total)); + + /* The hash table takes ownership of lu, so create a new one + * for the logsize_users_decayed check below. */ + lu = g_new(struct _purple_logsize_user, 1); + lu->name = g_strdup(tmp); + lu->account = log->account; + } + + if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrsize)) { + total = GPOINTER_TO_INT(ptrsize); + total += written; + g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(total)); } else { g_free(lu->name); g_free(lu); } - } char *purple_log_read(PurpleLog *log, PurpleLogReadFlags *flags) @@ -250,6 +265,49 @@ return size; } +gint purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account) +{ + gpointer ptrscore; + int score; + GSList *n; + struct _purple_logsize_user *lu; + time_t now; + time(&now); + + lu = g_new(struct _purple_logsize_user, 1); + lu->name = g_strdup(purple_normalize(account, name)); + lu->account = account; + + if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrscore)) { + score = GPOINTER_TO_INT(ptrscore); + g_free(lu->name); + g_free(lu); + } else { + double score_double = 0.0; + for (n = loggers; n; n = n->next) { + PurpleLogLogger *logger = n->data; + + if(logger->list) { + GList *logs = (logger->list)(type, name, account); + + while (logs) { + PurpleLog *log = (PurpleLog*)(logs->data); + /* Activity score counts bytes in the log, exponentially + decayed with a half-life of 14 days. */ + score_double += purple_log_get_size(log) * + pow(0.5, difftime(now, log->time)/1209600.0); + purple_log_free(log); + logs = g_list_delete_link(logs, logs); + } + } + } + + score = (gint)score_double; + g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(score)); + } + return score; +} + gboolean purple_log_is_deletable(PurpleLog *log) { g_return_val_if_fail(log != NULL, FALSE); @@ -661,6 +719,9 @@ logsize_users = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash, (GEqualFunc)_purple_logsize_user_equal, (GDestroyNotify)_purple_logsize_user_free_key, NULL); + logsize_users_decayed = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash, + (GEqualFunc)_purple_logsize_user_equal, + (GDestroyNotify)_purple_logsize_user_free_key, NULL); } void @@ -679,6 +740,9 @@ purple_log_logger_remove(old_logger); purple_log_logger_free(old_logger); old_logger = NULL; + + g_hash_table_destroy(logsize_users); + g_hash_table_destroy(logsize_users_decayed); } /****************************************************************************
--- a/libpurple/log.h Mon Jan 26 02:39:55 2009 +0000 +++ b/libpurple/log.h Mon Jan 26 04:19:00 2009 +0000 @@ -294,6 +294,19 @@ int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccount *account); /** + * Returns the activity score of a log, based on total size in bytes, + * which is then decayed based on age + * + * @param type The type of the log + * @param name The name of the log + * @param account The account + * @return The activity score + * + * @since 2.6.0 + */ +int purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account); + +/** * Tests whether a log is deletable * * A return value of @c FALSE indicates that purple_log_delete() will fail on this
--- a/pidgin/gtkblist.c Mon Jan 26 02:39:55 2009 +0000 +++ b/pidgin/gtkblist.c Mon Jan 26 04:19:00 2009 +0000 @@ -149,7 +149,7 @@ #if GTK_CHECK_VERSION(2,2,1) static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); -static void sort_method_log(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); +static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); #endif static PidginBuddyList *gtkblist = NULL; @@ -4490,7 +4490,7 @@ #if GTK_CHECK_VERSION(2,2,1) pidgin_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical); pidgin_blist_sort_method_reg("status", _("By status"), sort_method_status); - pidgin_blist_sort_method_reg("log_size", _("By log size"), sort_method_log); + pidgin_blist_sort_method_reg("log_size", _("By recent log activity"), sort_method_log_activity); #endif pidgin_blist_sort_method_set(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type")); } @@ -7683,11 +7683,11 @@ } } -static void sort_method_log(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter) +static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter) { GtkTreeIter more_z; - int log_size = 0, this_log_size = 0; + int activity_score = 0, this_log_activity_score = 0; const char *buddy_name, *this_buddy_name; if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) { @@ -7697,8 +7697,11 @@ if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *n; - for (n = node->child; n; n = n->next) - log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy*)(n))->name, ((PurpleBuddy*)(n))->account); + PurpleBuddy *buddy; + for (n = node->child; n; n = n->next) { + buddy = (PurpleBuddy*)n; + activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account); + } buddy_name = purple_contact_get_alias((PurpleContact*)node); } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) { /* we don't have a reliable way of getting the log filename @@ -7725,16 +7728,19 @@ GValue val; PurpleBlistNode *n; PurpleBlistNode *n2; + PurpleBuddy *buddy; int cmp; val.g_type = 0; gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); n = g_value_get_pointer(&val); - this_log_size = 0; + this_log_activity_score = 0; if(PURPLE_BLIST_NODE_IS_CONTACT(n)) { - for (n2 = n->child; n2; n2 = n2->next) - this_log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy*)(n2))->name, ((PurpleBuddy*)(n2))->account); + for (n2 = n->child; n2; n2 = n2->next) { + buddy = (PurpleBuddy*)n2; + this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account); + } this_buddy_name = purple_contact_get_alias((PurpleContact*)n); } else { this_buddy_name = NULL; @@ -7742,8 +7748,8 @@ cmp = purple_utf8_strcasecmp(buddy_name, this_buddy_name); - if (!PURPLE_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || - ((log_size == this_log_size) && + if (!PURPLE_BLIST_NODE_IS_CONTACT(n) || activity_score > this_log_activity_score || + ((activity_score == this_log_activity_score) && (cmp < 0 || (cmp == 0 && node < n)))) { if (cur != NULL) { gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z);