pidgin.next.minor: 9e31989c: A patch from Chris Connett to change the...

rlaager at pidgin.im rlaager at pidgin.im
Sun Jan 25 23:35:29 EST 2009


-----------------------------------------------------------------
Revision: 9e31989cbbfb97087f98e6a64e1da18efa3c3f54
Ancestor: 8f41da4c41ab16a6fdf59d851a2d183853b2013e
Author: rlaager at pidgin.im
Date: 2009-01-26T04:19:00
Branch: im.pidgin.pidgin.next.minor
URL: http://d.pidgin.im/viewmtn/revision/info/9e31989cbbfb97087f98e6a64e1da18efa3c3f54

Modified files:
        COPYRIGHT ChangeLog.API libpurple/log.c libpurple/log.h
        pidgin/gtkblist.c

ChangeLog: 

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

-------------- next part --------------
============================================================
--- COPYRIGHT	dec9f511cf7d5f746e7acd54a10bd0756d5096c3
+++ COPYRIGHT	d4ff82f9ce9a8e854bf906bdcc3008d539f426e2
@@ -85,6 +85,7 @@ Jeff Connelly
 Lorenzo Colitti
 Collabora Ltd.
 Jeff Connelly
+Chris Connett
 Nathan Conrad
 Felipe Contreras
 Alex Converse
============================================================
--- ChangeLog.API	b1b796350ca11221dfaa100d437464e3d6cac58b
+++ ChangeLog.API	aedd20b39a1125b36eed3e2d1f81c4030c143f26
@@ -24,6 +24,7 @@ version 2.6.0 (??/??/????):
 		* purple_network_force_online
 		* purple_global_proxy_set_info
 		* purple_strequal
+		* purple_log_get_activity_score
 
 		Deprecated:
 		* purple_buddy_get_local_alias
============================================================
--- libpurple/log.c	514ba9820fad672aa6e38d96bfe5a804cb93eb8f
+++ libpurple/log.c	21bc901a8a53f088f9d3ed1a792a77e2d466161f
@@ -34,6 +34,7 @@
 #include "util.h"
 #include "stringref.h"
 #include "imgstore.h"
+#include "time.h"
 
 static GSList *loggers = NULL;
 
@@ -46,6 +47,7 @@ static GHashTable *logsize_users = NULL;
 	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 @@ void purple_log_write(PurpleLog *log, Pu
 	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 @@ int purple_log_get_total_size(PurpleLogT
 	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 @@ void purple_log_init(void)
 	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_uninit(void)
 	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);
 }
 
 /****************************************************************************
============================================================
--- libpurple/log.h	706f21c8c4d726634fee1d6e3bd3f8c1629be44e
+++ libpurple/log.h	755036e9eddc4a71475eb54f928e7520ea09e3c5
@@ -294,6 +294,19 @@ int purple_log_get_total_size(PurpleLogT
 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
============================================================
--- pidgin/gtkblist.c	9acd6803537b860b2d3d90c453a98c559749ddfb
+++ pidgin/gtkblist.c	5901e3547884b2da37609d0f434622e1ea955ea1
@@ -149,7 +149,7 @@ static void sort_method_status(PurpleBli
 #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 @@ void pidgin_blist_setup_sort_methods()
 #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_status(PurpleBli
 	}
 }
 
-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 @@ static void sort_method_log(PurpleBlistN
 
 	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 @@ static void sort_method_log(PurpleBlistN
 		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 @@ static void sort_method_log(PurpleBlistN
 
 		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);


More information about the Commits mailing list