>From a63f2c5a81dacc4addb0a0e420722b5e83e9a713 Mon Sep 17 00:00:00 2001
From: Amir <Am-Ro@users.noreply.github.com>
Date: Tue, 29 Sep 2015 18:36:20 +0300
Subject: [PATCH] Add whole thread[as mbox] link to message view


diff --git a/django/archives/mailarchives/templates/message.html b/django/archives/mailarchives/templates/message.html
index 1d09e24..d0eeebf 100644
--- a/django/archives/mailarchives/templates/message.html
+++ b/django/archives/mailarchives/templates/message.html
@@ -45,7 +45,7 @@ $(function(){
  </tr>
  <tr>
   <th>Message-ID:</th>
-  <td><a href="/message-id/{{msg.messageid}}">{{msg.messageid}}</a> (view <a href="/message-id/raw/{{msg.messageid}}">raw</a> or <a href="/message-id/flat/{{msg.messageid}}">whole thread</a>)</td>
+  <td><a href="/message-id/{{msg.messageid}}">{{msg.messageid}}</a> (view <a href="/message-id/raw/{{msg.messageid}}">raw</a> or <a href="/message-id/flat/{{msg.messageid}}">whole thread</a> <a href="/message-id/thread_raw/{{msg.messageid}}">[as mbox]</a>)</td>
  </tr>
  <tr>
   <th>Thread:</th>
diff --git a/django/archives/mailarchives/views.py b/django/archives/mailarchives/views.py
index e011827..ff373b5 100644
--- a/django/archives/mailarchives/views.py
+++ b/django/archives/mailarchives/views.py
@@ -255,6 +255,19 @@ SELECT id,_from,subject,date,messageid,has_attachment,parentid,datepath FROM t O
 	for id,_from,subject,date,messageid,has_attachment,parentid,parentpath in curs.fetchall():
 		yield {'id':id, 'mailfrom':_from, 'subject': subject, 'date': date, 'printdate': date.strftime("%Y-%m-%d %H:%M:%S"), 'messageid': messageid, 'hasattachment': has_attachment, 'parentid': parentid, 'indent': "&nbsp;" * len(parentpath)}
 
+def _retrieve_thread_raw_messages(threadid):
+	# Yeah, this is *way* too complicated for the django ORM Too
+	curs = connection.cursor()
+	curs.execute("""WITH RECURSIVE t(id, date, rawtxt) AS(
+  SELECT id, date, rawtxt FROM messages m WHERE m.threadid=%(threadid)s AND parentid IS NULL AND hiddenstatus IS NULL
+ UNION ALL
+  SELECT m.id, m.date, m.rawtxt FROM messages m INNER JOIN t ON t.id=m.parentid WHERE m.threadid=%(threadid)s AND hiddenstatus IS NULL
+)
+SELECT id, date, rawtxt FROM t;
+""", {'threadid': threadid})
+
+	for id, date,rawtxt in curs.fetchall():
+		yield {'id':id, 'date': date, 'rawtext': rawtxt}
 
 def _get_nextprevious(listmap, dt):
 	curs = connection.cursor()
@@ -390,6 +403,44 @@ def message_raw(request, msgid):
 	response['WWW-Authenticate'] = 'Basic realm="Please authenticate with user archives and password antispam"'
 	return response
 
+@nocache
+def message_thread_raw(request, msgid):
+	if 'HTTP_AUTHORIZATION' in request.META:
+		auth = request.META['HTTP_AUTHORIZATION'].split()
+		if len(auth) != 2:
+			return HttpResponseForbidden("Invalid authentication")
+		if auth[0].lower() == "basic":
+			user, pwd = base64.b64decode(auth[1]).split(':')
+			if user == 'archives' and pwd == 'antispam':
+				try:
+					m = Message.objects.get(messageid=msgid)
+				except Message.DoesNotExist:
+					raise Http404('Message does not exist')
+
+				ms = list(_retrieve_thread_raw_messages(251))
+				newest = calendar.timegm(max(ms, key=lambda x: x['date'])['date'].utctimetuple())
+				if request.META.has_key('HTTP_IF_MODIFIED_SINCE') and not settings.DEBUG:
+					ims = parse_http_date_safe(request.META.get("HTTP_IF_MODIFIED_SINCE"))
+					if ims >= newest:
+						return HttpResponseNotModified()
+
+				# raise Http403('Message does not exist')
+
+
+				r = HttpResponse(u"".join(unicode(m['rawtext']) for m in ms), content_type='text/plain')
+				r['X-pgthread'] = ":%s:" % m.threadid
+				return r
+
+			# Invalid password falls through
+		# Other authentication types fall through
+
+	# Require authentication
+	response = HttpResponse()
+	response.status_code = 401
+	response['WWW-Authenticate'] = 'Basic realm="Please authenticate with user archives and password antispam"'
+	return response
+
+
 def testview(request, seqid):
 	m = Message.objects.get(pk=seqid)
 	try:
diff --git a/django/archives/urls.py b/django/archives/urls.py
index 16fc718..5ca545c 100644
--- a/django/archives/urls.py
+++ b/django/archives/urls.py
@@ -27,6 +27,7 @@ urlpatterns = patterns('',
     (r'^message-id/([^/]+)$', 'archives.mailarchives.views.message'),
     (r'^message-id/flat/([^/]+)$', 'archives.mailarchives.views.message_flat'),
     (r'^message-id/raw/([^/]+)$', 'archives.mailarchives.views.message_raw'),
+    (r'^message-id/thread_raw/([^/]+)$', 'archives.mailarchives.views.message_thread_raw'),
 
     # Search
     (r'^archives-search/', 'archives.mailarchives.views.search'),
-- 
2.4.3

