git » blitiri » commit b1902b1

Support sorting, and configurable # of articles in the index

author Leandro Lucarella
2022-08-20 19:12:22 UTC
committer Alberto Bertogli
2022-08-20 19:30:34 UTC
parent b1ff211c18a518a8df4d51f6a2a871243f4336a5

Support sorting, and configurable # of articles in the index

blitiri.cgi +44 -17

diff --git a/blitiri.cgi b/blitiri.cgi
index 78ee66b..4da3660 100755
--- a/blitiri.cgi
+++ b/blitiri.cgi
@@ -51,6 +51,9 @@ encoding = "utf8"
 # below for details.
 captcha_method = "title"
 
+# How many articles to show in the index
+index_articles = 10
+
 
 #
 # End of configuration
@@ -866,19 +869,11 @@ class Article (object):
 			self.load()
 		return self._comments
 
-	def __cmp__(self, other):
-		if self.path == other.path:
-			return 0
-		if not self.created:
-			return 1
-		if not other.created:
-			return -1
-		if self.created < other.created:
-			return -1
-		return 1
 
-	def title_cmp(self, other):
-		return cmp(self.title, other.title)
+	def __eq__(self, other):
+		if self.path == other.path:
+			return True
+		return False
 
 
 	def add_comment(self, author, raw_content, link = ''):
@@ -1148,6 +1143,37 @@ def render_style():
 	print 'Content-type: text/css\r\n\r\n',
 	print default_css
 
+# Get a dictionary with sort() arguments (key and reverse) by parsing the sort
+# specification format:
+# [+-]?<key>?
+# Where "-" is used to specify reverse order, while "+" is regular, ascending,
+# order (reverse = False). The key value is an Article's attribute name (title,
+# author, created, updated and uuid are accepted), and will be used as key for
+# sorting. If a value is omitted, that value is taken from the default, which
+# should be provided using the same format specification, with the difference
+# that all values must be provided for the default.
+def get_sort_args(sort_str, default):
+	def parse(s):
+		d = dict()
+		if not s:
+			return d
+		key = None
+		if len(s) > 0:
+			# accept ' ' as an alias of '+' since '+' is translated
+			# to ' ' in URLs
+			if s[0] in ('+', ' ', '-'):
+				key = s[1:]
+				d['reverse'] = (s[0] == '-')
+			else:
+				key = s
+		if key in ('title', 'author', 'created', 'updated', 'uuid'):
+			d['key'] = lambda a: getattr(a, key)
+		return d
+	args = parse(default)
+	assert args['key'] is not None and args['reverse'] is not None
+	args.update(parse(sort_str))
+	return args
+
 def handle_cgi():
 	import cgitb; cgitb.enable()
 
@@ -1156,6 +1182,7 @@ def handle_cgi():
 	month = int(form.getfirst("month", 0))
 	day = int(form.getfirst("day", 0))
 	tags = set(form.getlist("tag"))
+	sort_str = form.getfirst("sort", None)
 	uuid = None
 	atom = False
 	style = False
@@ -1214,8 +1241,8 @@ def handle_cgi():
 	db = ArticleDB(os.path.join(data_path, 'db'))
 	if atom:
 		articles = db.get_articles(tags = tags)
-		articles.sort(reverse = True)
-		render_atom(articles[:10])
+		articles.sort(**get_sort_args(sort_str, '-created'))
+		render_atom(articles[:index_articles])
 	elif style:
 		render_style()
 	elif post:
@@ -1226,7 +1253,7 @@ def handle_cgi():
 		render_html( [article], db, year, enable_comments )
 	elif artlist:
 		articles = db.get_articles()
-		articles.sort(cmp = Article.title_cmp)
+		articles.sort(**get_sort_args(sort_str, '+title'))
 		render_artlist(articles, db)
 	elif comment and enable_comments:
 		form_data = CommentFormData(author.strip().replace('\n', ' '),
@@ -1276,9 +1303,9 @@ def handle_cgi():
 				form_data )
 	else:
 		articles = db.get_articles(year, month, day, tags)
-		articles.sort(reverse = True)
+		articles.sort(**get_sort_args(sort_str, '-created'))
 		if not year and not month and not day and not tags:
-			articles = articles[:10]
+			articles = articles[:index_articles]
 		render_html(articles, db, year)