[PATCH] New option for sorting threads: sort by date of last posted article

Michael Bienia <[email protected]>
Newsgroups gmane.network.tin.devel
Message-ID <[email protected]>
Hello,

I've added a new option for sorting threads: sort by date of last posted
article.  Especially in groups with many new threads one can easily miss
the threads which are still active.  With this option one can sort these
threads to the top (or the end) of the thread list.

Michael
patch-20060621.diff (text/plain, 7.6 KB)
 include/tin.h  |    5 +++-
 src/art.c      |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/attrib.c   |    5 +++-
 src/config.c   |    2 -
 src/lang.c     |    8 +++++-
 src/tincfg.tbl |    2 -
 6 files changed, 81 insertions(+), 7 deletions(-)
diff -Nurp tin-1.9.1/include/tin.h tin-1.9.1.patched/include/tin.h
--- tin-1.9.1/include/tin.h	2006-04-22 20:54:54.834353921 +0200
+++ tin-1.9.1.patched/include/tin.h	2006-06-20 15:54:51.165176606 +0200
@@ -1085,6 +1085,8 @@ enum {
 #define SORT_THREADS_BY_NOTHING			0
 #define SORT_THREADS_BY_SCORE_DESCEND	1
 #define SORT_THREADS_BY_SCORE_ASCEND	2
+#define SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND	3
+#define SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND	4
 
 /*
  * Different values of strip_bogus - the ways to handle bogus groups
@@ -1420,7 +1422,8 @@ struct t_attribute {
 						   3=from descend, 4=from ascend,
 						   5=date descend, 6=date ascend,
 						   7=score descend, 8=score ascend */
-	unsigned sort_threads_type:2;	/* 0=none, 1=score descend, 2=score ascend */
+	unsigned sort_threads_type:3;		/* 0=none, 1=score descend, 2=score ascend,
+						   3=last posting date descend, 4=last posting date ascend */
 	unsigned int post_proc_type:2;		/* 0=none, 1=shar, 2=uudecode */
 	unsigned int x_comment_to:1;		/* insert X-Comment-To: in Followup */
 	unsigned int tex2iso_conv:1;		/* Convert TeX2ISO */
diff -Nurp tin-1.9.1/src/art.c tin-1.9.1.patched/src/art.c
--- tin-1.9.1/src/art.c	2006-02-15 19:44:38.000000000 +0100
+++ tin-1.9.1.patched/src/art.c	2006-06-20 15:27:46.911202146 +0200
@@ -70,6 +70,8 @@ static int from_comp_asc(t_comptype p1, 
 static int from_comp_desc(t_comptype p1, t_comptype p2);
 static int global_get_multiparts(int aindex, MultiPartInfo **malloc_and_setme_info);
 static int global_look_for_multipart_info(int aindex, MultiPartInfo *setme, char start, char stop, int *offset);
+static int last_date_comp_base_asc(t_comptype p1, t_comptype p2);
+static int last_date_comp_base_desc(t_comptype p1, t_comptype p2);
 static int lines_comp_asc(t_comptype p1, t_comptype p2);
 static int lines_comp_desc(t_comptype p1, t_comptype p2);
 static int read_art_headers(struct t_group *group, int total, long top);
@@ -84,6 +86,7 @@ static long find_first_unread(struct t_g
 static long setup_hard_base(struct t_group *group);
 static t_bool parse_headers(FILE *fp, struct t_article *h);
 static t_compfunc eval_sort_arts_func(unsigned int sort_art_type);
+static time_t get_last_posting_date(long n);
 static void sort_base(unsigned int sort_threads_type);
 static void thread_by_multipart(void);
 static void thread_by_percentage(struct t_group *group);
@@ -1168,11 +1171,17 @@ static void
 sort_base(
 	unsigned int sort_threads_type)
 {
-	switch (sort_threads_type) { /* this switch doesn't look very usefull */
+	switch (sort_threads_type) {
 		case SORT_THREADS_BY_SCORE_DESCEND:
 		case SORT_THREADS_BY_SCORE_ASCEND:
 			qsort(base, (size_t) grpmenu.max, sizeof(long), score_comp_base);
 			break;
+		case SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND:
+			qsort(base, (size_t) grpmenu.max, sizeof(long), last_date_comp_base_desc);
+			break;
+		case SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND:
+			qsort(base, (size_t) grpmenu.max, sizeof(long), last_date_comp_base_asc);
+			break;
 	}
 }
 
@@ -2166,6 +2175,61 @@ score_comp_base(
 }
 
 
+/*
+ * Compare the date of the last posted article of two threads.
+ * Used for sorting base[].
+ */
+static int
+last_date_comp_base_desc(
+	t_comptype p1,
+	t_comptype p2)
+{
+	time_t s1_last = get_last_posting_date(*(const long *) p1);
+	time_t s2_last = get_last_posting_date(*(const long *) p2);
+
+	if (s2_last < s1_last)
+		return -1;
+
+	if (s2_last > s1_last)
+		return 1;
+
+	return 0;	
+}
+
+
+static int
+last_date_comp_base_asc(
+	t_comptype p1,
+	t_comptype p2)
+{
+	time_t s1_last = get_last_posting_date(*(const long *) p1);
+	time_t s2_last = get_last_posting_date(*(const long *) p2);
+
+	if (s2_last > s1_last)
+		return -1;
+
+	if (s2_last < s1_last)
+		return 1;
+
+	return 0;	
+}
+
+
+static time_t get_last_posting_date(
+	long n)
+{
+	long i;
+	time_t last = (time_t) 0;
+
+	for (i = n; i >= 0; i = arts[i].thread) {
+		if (arts[i].date > last)
+			last = arts[i].date;
+	}
+
+	return last;
+}
+
+
 void
 set_article(
 	struct t_article *art)
diff -Nurp tin-1.9.1/src/attrib.c tin-1.9.1.patched/src/attrib.c
--- tin-1.9.1/src/attrib.c	2006-02-15 22:22:01.000000000 +0100
+++ tin-1.9.1.patched/src/attrib.c	2006-06-20 15:51:09.574524862 +0200
@@ -351,7 +351,7 @@ read_attributes_file(
 					MATCH_BOOLEAN("show_only_unread=", ATTRIB_SHOW_ONLY_UNREAD);
 					MATCH_STRING("sigfile=", ATTRIB_SIGFILE);
 					MATCH_INTEGER("sort_art_type=", ATTRIB_SORT_ART_TYPE, SORT_ARTICLES_BY_LINES_ASCEND);
-					MATCH_INTEGER("sort_threads_type=", ATTRIB_SORT_THREADS_TYPE, SORT_THREADS_BY_SCORE_DESCEND);
+					MATCH_INTEGER("sort_threads_type=", ATTRIB_SORT_THREADS_TYPE, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND);
 					break;
 
 				case 't':
@@ -712,6 +712,9 @@ write_attributes_file(
 		SORT_THREADS_BY_NOTHING, _(txt_sort_t_type[SORT_THREADS_BY_NOTHING]),
 		SORT_THREADS_BY_SCORE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_DESCEND]),
 		SORT_THREADS_BY_SCORE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_ASCEND]));
+	fprintf(fp, "#    %d=%s, %d=%s\n",
+		SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND]),
+		SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND]));
 	fprintf(fp, _("#  post_proc_type=NUM\n"));
 	fprintf(fp, "#    %d=%s, %d=%s, %d=%s\n",
 		POST_PROC_NO, _(txt_post_process_type[POST_PROC_NO]),
diff -Nurp tin-1.9.1/src/config.c tin-1.9.1.patched/src/config.c
--- tin-1.9.1/src/config.c	2006-04-22 20:54:54.836353572 +0200
+++ tin-1.9.1.patched/src/config.c	2006-06-20 14:35:41.094292386 +0200
@@ -658,7 +658,7 @@ read_config_file(
 			if (match_integer(buf, "sort_article_type=", &tinrc.sort_article_type, SORT_ARTICLES_BY_LINES_ASCEND))
 				break;
 
-			if (match_integer(buf, "sort_threads_type=", &tinrc.sort_threads_type, SORT_THREADS_BY_SCORE_ASCEND))
+			if (match_integer(buf, "sort_threads_type=", &tinrc.sort_threads_type, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND))
 				break;
 
 			if (match_integer(buf, "scroll_lines=", &tinrc.scroll_lines, 0))
diff -Nurp tin-1.9.1/src/lang.c tin-1.9.1.patched/src/lang.c
--- tin-1.9.1/src/lang.c	2006-04-22 20:54:54.844352178 +0200
+++ tin-1.9.1.patched/src/lang.c	2006-06-20 14:37:56.688814579 +0200
@@ -1240,7 +1240,9 @@ constext *txt_sort_a_type[] = {
 constext *txt_sort_t_type[] = {
 		N_("Nothing"),
 		N_("Score (descending)"),
-		N_("Score (ascending)")
+		N_("Score (ascending)"),
+		N_("Last posting date (descending)"),
+		N_("Last posting date (ascending)")
 };
 
 /* Ways of handling bogus groups */
@@ -1467,7 +1469,9 @@ struct opttxt txt_sort_threads_type = {
 # Possible values are (the default is marked with *):\n\
 #   0 = nothing\n\
 # * 1 = Score descending\n\
-#   2 = Score ascending\n")
+#   2 = Score ascending\n\
+#   3 = Last posting date descending\n\
+#   4 = Last posting date ascending\n")
 };
 
 struct opttxt txt_pos_first_unread = {
diff -Nurp tin-1.9.1/src/tincfg.tbl tin-1.9.1.patched/src/tincfg.tbl
--- tin-1.9.1/src/tincfg.tbl	2006-04-22 20:54:54.847351655 +0200
+++ tin-1.9.1.patched/src/tincfg.tbl	2006-06-20 14:28:06.484006867 +0200
@@ -45,7 +45,7 @@
 	thread_articles			txt_threading	THREAD_MAX+1
 	thread_perc			OPT_NUM
 	sort_article_type		txt_sort_a_type	SORT_ARTICLES_BY_LINES_ASCEND+1
-	sort_threads_type		txt_sort_t_type	SORT_THREADS_BY_SCORE_ASCEND+1
+	sort_threads_type		txt_sort_t_type	SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND+1
 	pos_first_unread		OPT_ON_OFF
 	show_only_unread_arts		OPT_ON_OFF
 	show_only_unread_groups		OPT_ON_OFF
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.