diff options
author | Aurélien Bompard <aurelien@bompard.org> | 2012-12-14 19:14:20 +0100 |
---|---|---|
committer | Aurélien Bompard <aurelien@bompard.org> | 2012-12-14 19:14:20 +0100 |
commit | a132cf2b84bd250514c33e6393e9d9ef31b0b7c9 (patch) | |
tree | 31e2b5d32df22d45a8e052c274cbea7992de17ce | |
parent | 90d3f91df7851b97f07b903f353497742f80d325 (diff) | |
download | hyperkitty-a132cf2b84bd250514c33e6393e9d9ef31b0b7c9.tar.gz hyperkitty-a132cf2b84bd250514c33e6393e9d9ef31b0b7c9.tar.xz hyperkitty-a132cf2b84bd250514c33e6393e9d9ef31b0b7c9.zip |
Sort replies by thread, with indentation
-rw-r--r-- | hyperkitty/lib/__init__.py | 21 | ||||
-rw-r--r-- | hyperkitty/static/css/style.css | 4 | ||||
-rw-r--r-- | hyperkitty/templates/thread.html | 13 | ||||
-rw-r--r-- | hyperkitty/templatetags/hk_generic.py | 9 | ||||
-rw-r--r-- | hyperkitty/views/thread.py | 47 | ||||
-rw-r--r-- | requirements.txt | 1 |
6 files changed, 75 insertions, 20 deletions
diff --git a/hyperkitty/lib/__init__.py b/hyperkitty/lib/__init__.py index 52b6bdc..14bde15 100644 --- a/hyperkitty/lib/__init__.py +++ b/hyperkitty/lib/__init__.py @@ -23,6 +23,7 @@ import urllib from hashlib import md5 import datetime +import networkx as nx from django.conf import settings @@ -86,3 +87,23 @@ def get_display_dates(year, month, day): end_date = begin_date + datetime.timedelta(days=1) return begin_date, end_date + + +def sort_thread(thread): + def walk_successors(msgid, level, result): + obj = graph.node[msgid]["obj"] + obj.level = level + result.append(obj) + level += 1 + for succ in sorted(graph.successors(msgid), + key=lambda m: graph.node[m]["num"]): + walk_successors(succ, level, result) + level -= 1 + graph = nx.DiGraph() + for index, email in enumerate(thread.emails): + graph.add_node(email.message_id, num=index, obj=email) + if email.in_reply_to is not None: + graph.add_edge(email.in_reply_to, email.message_id) + result = [] + walk_successors(thread.starting_email.message_id, 0, result) + return result diff --git a/hyperkitty/static/css/style.css b/hyperkitty/static/css/style.css index 9ac592a..68f13e2 100644 --- a/hyperkitty/static/css/style.css +++ b/hyperkitty/static/css/style.css @@ -651,6 +651,10 @@ ul.attachments-list li { float: right; } +.sort-mode { + text-align: right; +} + /* The email thread */ .even, .odd { border-top: 1px solid rgb(179, 179, 179); diff --git a/hyperkitty/templates/thread.html b/hyperkitty/templates/thread.html index 8ea45d2..add1fba 100644 --- a/hyperkitty/templates/thread.html +++ b/hyperkitty/templates/thread.html @@ -26,8 +26,19 @@ {% include 'messages/first_email.html' %} <!-- End first email --> + <p class="sort-mode"> + {% if sort_mode == "date" %} + <a href="{% url thread threadid=threadid, mlist_fqdn=list_address %}?sort=thread" + >Show replies by thread</a> + {% else %} + <a href="{% url thread threadid=threadid, mlist_fqdn=list_address %}?sort=date" + >Show replies by date</a> + {% endif %} + </p> + {% for email in replies %} - <div class="{% cycle 'even' 'odd' %}"> + <div class="{% cycle 'even' 'odd' %}" + {% if email.level %}style="margin-left:{{ email.level|multiply:"2" }}em;"{% endif %}> <!-- Start email --> {% include 'messages/message.html' %} <!-- End of email --> diff --git a/hyperkitty/templatetags/hk_generic.py b/hyperkitty/templatetags/hk_generic.py index 555246f..390c51c 100644 --- a/hyperkitty/templatetags/hk_generic.py +++ b/hyperkitty/templatetags/hk_generic.py @@ -171,3 +171,12 @@ def snip_quoted(content, quotemsg="[...]", autoescape=None): +' </div>') content = content.replace("\n".join(quote_orig), replaced) return mark_safe(content) + + +@register.filter() +def multiply(num1, num2): + if int(num2) == float(num2): + num2 = int(num2) + else: + num2 = float(num2) + return num1 * num2 diff --git a/hyperkitty/views/thread.py b/hyperkitty/views/thread.py index afe389b..f0c959f 100644 --- a/hyperkitty/views/thread.py +++ b/hyperkitty/views/thread.py @@ -37,7 +37,7 @@ from django.contrib.auth.decorators import (login_required, from hyperkitty.models import Rating, Tag #from hyperkitty.lib.mockup import * from forms import * -from hyperkitty.lib import get_months, get_store, stripped_subject +from hyperkitty.lib import get_months, get_store, stripped_subject, sort_thread def thread_index(request, mlist_fqdn, threadid): @@ -50,13 +50,18 @@ def thread_index(request, mlist_fqdn, threadid): raise Http404 prev_thread, next_thread = store.get_thread_neighbors(mlist_fqdn, threadid) - participants = {} - cnt = 0 + if "sort" in request.GET and request.GET["sort"] == "date": + sort_mode = "date" + emails = thread.emails + else: + sort_mode = "thread" + emails = sort_thread(thread) - for message in thread.emails: + participants = {} + for email in emails: # Extract all the votes for this message try: - votes = Rating.objects.filter(messageid=message.message_id) + votes = Rating.objects.filter(messageid=email.message_id) except Rating.DoesNotExist: votes = {} @@ -71,21 +76,25 @@ def thread_index(request, mlist_fqdn, threadid): else: pass - message.votes = votes - message.likes = likes - message.dislikes = dislikes - message.likestatus = "neutral" - if message.likes - message.dislikes >= 10: - message.likestatus = "likealot" - elif message.likes - message.dislikes > 0: - message.likestatus = "like" - #elif message.likes - message.dislikes < 0: - # message.likestatus = "dislike" + email.votes = votes + email.likes = likes + email.dislikes = dislikes + email.likestatus = "neutral" + if email.likes - email.dislikes >= 10: + email.likestatus = "likealot" + elif email.likes - email.dislikes > 0: + email.likestatus = "like" + #elif email.likes - email.dislikes < 0: + # email.likestatus = "dislike" # Statistics on how many participants and messages this month - participants[message.sender_name] = message.sender_email - cnt = cnt + 1 + participants[email.sender_name] = email.sender_email + + if sort_mode == "thread": + email.level -= 1 # replies start ragged left + if email.level > 5: + email.level = 5 archives_length = get_months(store, mlist_fqdn) from_url = reverse("thread", kwargs={"mlist_fqdn":mlist_fqdn, @@ -115,14 +124,14 @@ def thread_index(request, mlist_fqdn, threadid): 'addtag_form': tag_form, 'month': 'Thread', 'participants': participants, - 'answers': cnt, 'first_mail': thread.starting_email, - 'replies': list(thread.emails)[1:], + 'replies': list(emails)[1:], 'neighbors': (prev_thread, next_thread), 'archives_length': archives_length, 'days_inactive': days_inactive.days, 'days_old': days_old.days, 'use_mockups': settings.USE_MOCKUPS, + 'sort_mode': sort_mode, }) return HttpResponse(t.render(c)) diff --git a/requirements.txt b/requirements.txt index 77cc578..9fd8461 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ django-social-auth>=0.7.1 djangorestframework>=2.0.0 mailman>=3.0.0b2 kittystore +networkx |