diff options
author | Aurélien Bompard <aurelien@bompard.org> | 2013-05-14 13:44:42 +0200 |
---|---|---|
committer | Aurélien Bompard <aurelien@bompard.org> | 2013-05-14 13:44:42 +0200 |
commit | fb6423fd8d2e0068c9c5b5bb8a643ea991e59739 (patch) | |
tree | 5b8e07532ca7763052017e3027eb8db8affa06e6 /hyperkitty/views/thread.py | |
parent | 4b1df7bbdb0f0fa35cf738235aff8170a37b7d04 (diff) | |
download | hyperkitty-fb6423fd8d2e0068c9c5b5bb8a643ea991e59739.tar.gz hyperkitty-fb6423fd8d2e0068c9c5b5bb8a643ea991e59739.tar.xz hyperkitty-fb6423fd8d2e0068c9c5b5bb8a643ea991e59739.zip |
Speed up page loading on long threads
Speed up page loading on threads with many replies by loading the
replies asynchronously.
Preserve search engine indexation by detecting bots and serving the
usual page in one go.
Diffstat (limited to 'hyperkitty/views/thread.py')
-rw-r--r-- | hyperkitty/views/thread.py | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/hyperkitty/views/thread.py b/hyperkitty/views/thread.py index 7929ac6..be92be7 100644 --- a/hyperkitty/views/thread.py +++ b/hyperkitty/views/thread.py @@ -31,6 +31,7 @@ from django.template import RequestContext, loader from django.shortcuts import render from django.core.urlresolvers import reverse from django.core.exceptions import SuspiciousOperation +import robot_detection from hyperkitty.models import Tag, Favorite from forms import SearchForm, AddTagForm, ReplyForm @@ -38,14 +39,10 @@ from hyperkitty.lib import get_months, get_store, stripped_subject from hyperkitty.lib.voting import set_message_votes -def thread_index(request, mlist_fqdn, threadid, month=None, year=None): - ''' Displays all the email for a given thread identifier ''' - search_form = SearchForm(auto_id=False) - store = get_store(request) - thread = store.get_thread(mlist_fqdn, threadid) +def _get_thread_replies(request, thread): + '''Get and sort the replies for a thread''' if not thread: raise Http404 - prev_thread, next_thread = store.get_thread_neighbors(mlist_fqdn, threadid) if "sort" in request.GET and request.GET["sort"] == "date": sort_mode = "date" @@ -54,7 +51,10 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): sort_mode = "thread" emails = thread.emails_by_reply - participants = {} + # Don't forget to add the sender to the participants + participants = {thread.starting_email.sender_name: + thread.starting_email.sender_email} + emails = list(emails)[1:] # only select replies for email in emails: # Extract all the votes for this message set_message_votes(email, request.user) @@ -67,6 +67,21 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): if email.level > 5: email.level = 5 + return {"replies": emails, "participants": participants} + + +def thread_index(request, mlist_fqdn, threadid, month=None, year=None): + ''' Displays all the email for a given thread identifier ''' + search_form = SearchForm(auto_id=False) + store = get_store(request) + thread = store.get_thread(mlist_fqdn, threadid) + if not thread: + raise Http404 + prev_thread, next_thread = store.get_thread_neighbors(mlist_fqdn, threadid) + + sort_mode = request.GET.get("sort", "thread") + set_message_votes(thread.starting_email, request.user) + from_url = reverse("thread", kwargs={"mlist_fqdn":mlist_fqdn, "threadid":threadid}) # Tags @@ -95,17 +110,22 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): mlist = store.get_list(mlist_fqdn) subject = stripped_subject(mlist, thread.starting_email.subject) + # TODO: eventually move to a middleware ? + # http://djangosnippets.org/snippets/1865/ + is_bot = True + user_agent = request.META.get('HTTP_USER_AGENT', None) + if user_agent: + is_bot = robot_detection.is_robot(user_agent) + context = { - 'mlist' : mlist, - 'threadid' : threadid, + 'mlist': mlist, + 'threadid': threadid, 'subject': subject, - 'tags' : tags, + 'tags': tags, 'search_form': search_form, 'addtag_form': tag_form, 'month': thread.date_active, - 'participants': participants, 'first_mail': thread.starting_email, - 'replies': list(emails)[1:], 'neighbors': (prev_thread, next_thread), 'months_list': get_months(store, mlist.name), 'days_inactive': days_inactive.days, @@ -113,10 +133,43 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): 'sort_mode': sort_mode, 'fav_action': fav_action, 'reply_form': ReplyForm(), + 'is_bot': is_bot, } + + if is_bot: + # Don't rely on AJAX to load the replies + thread_replies = _get_thread_replies(request, thread) + context["participants"] = thread_replies["participants"] + context["replies"] = thread_replies["replies"] + return render(request, "thread.html", context) +def replies(request, mlist_fqdn, threadid): + """Get JSON encoded lists with the replies and the participants""" + store = get_store(request) + thread = store.get_thread(mlist_fqdn, threadid) + thread_replies = _get_thread_replies(request, thread) + mlist = store.get_list(mlist_fqdn) + context = { + 'mlist': mlist, + 'threadid': threadid, + 'reply_form': ReplyForm(), + } + context["participants"] = thread_replies["participants"] + context["replies"] = thread_replies["replies"] + + replies_tpl = loader.get_template('threads/replies.html') + replies_html = replies_tpl.render(RequestContext(request, context)) + participants_tpl = loader.get_template('threads/participants.html') + participants_html = participants_tpl.render(RequestContext(request, context)) + response = {"replies_html": replies_html, + "participants_html": participants_html, + } + return HttpResponse(json.dumps(response), + mimetype='application/javascript') + + def add_tag(request, mlist_fqdn, threadid): """ Add a tag to a given thread. """ if not request.user.is_authenticated(): |