diff options
author | Aurélien Bompard <aurelien@bompard.org> | 2013-06-18 16:30:38 +0200 |
---|---|---|
committer | Aurélien Bompard <aurelien@bompard.org> | 2013-06-18 16:30:38 +0200 |
commit | 5924b67e6716be1530436dd986ddb941125fa5e3 (patch) | |
tree | 299f4e209b6f9a0f524375af527c49423077b698 | |
parent | c8f2ecc0476b0caf2c8a87033c5ffcdf6ac6263b (diff) | |
download | hyperkitty-5924b67e6716be1530436dd986ddb941125fa5e3.tar.gz hyperkitty-5924b67e6716be1530436dd986ddb941125fa5e3.tar.xz hyperkitty-5924b67e6716be1530436dd986ddb941125fa5e3.zip |
Add Top Posters and Popular Threads widgets to the overview
-rw-r--r-- | hyperkitty/lib/voting.py | 10 | ||||
-rw-r--r-- | hyperkitty/static/css/hyperkitty-overview.css | 12 | ||||
-rw-r--r-- | hyperkitty/templates/recent_activities.html | 52 | ||||
-rw-r--r-- | hyperkitty/views/list.py | 25 |
4 files changed, 77 insertions, 22 deletions
diff --git a/hyperkitty/lib/voting.py b/hyperkitty/lib/voting.py index 7d7cc64..8624d75 100644 --- a/hyperkitty/lib/voting.py +++ b/hyperkitty/lib/voting.py @@ -23,14 +23,16 @@ from hyperkitty.models import Rating -def get_votes(message_id_hash, user=None): +def get_votes(msgid, user=None): """Extract all the votes for this message""" - likes = dislikes = 0 + likes = dislikes = myvote = 0 try: - votes = Rating.objects.filter(messageid=message_id_hash) + if isinstance(msgid, basestring): + votes = Rating.objects.filter(messageid=msgid) + elif isinstance(msgid, list): + votes = Rating.objects.filter(messageid__in=msgid) except Rating.DoesNotExist: votes = {} - myvote = 0 for vote in votes: if vote.vote == 1: likes += 1 diff --git a/hyperkitty/static/css/hyperkitty-overview.css b/hyperkitty/static/css/hyperkitty-overview.css index 7898764..e96f7a2 100644 --- a/hyperkitty/static/css/hyperkitty-overview.css +++ b/hyperkitty/static/css/hyperkitty-overview.css @@ -7,6 +7,13 @@ text-align: center; } +#recent_activities h3 { + font-size: 20px; + line-height: 28px; + margin-bottom: 0.5em; + text-align: center; +} + #graph h2 { text-align: center; } @@ -37,10 +44,7 @@ } -#top-discussion, -#discussion-by-topic, -#most-active, -#discussion-maker { +#recent_activities .widget { padding: 1em; padding-bottom: 0; border: 1px solid #ddd; diff --git a/hyperkitty/templates/recent_activities.html b/hyperkitty/templates/recent_activities.html index 5b175d6..fb22d92 100644 --- a/hyperkitty/templates/recent_activities.html +++ b/hyperkitty/templates/recent_activities.html @@ -33,8 +33,8 @@ <div class="row-fluid"> <div class="span6"> - <section id="most-active"> - <h2>Recently active discussions</h2> + <section id="most-active" class="widget"> + <h3>Recently active discussions</h3> {% for thread in most_active_threads %} {% include "threads/summary_thread.html" with counter=forloop.counter %} {% endfor %} @@ -42,8 +42,8 @@ </div> <div class="span6"> - <section id="top-discussion"> - <h2>Top discussions the last 30 days</h2> + <section id="top-discussion" class="widget"> + <h3>Most active discussions</h3> {% for thread in top_threads %} {% include "threads/summary_thread.html" with counter=forloop.counter %} {% endfor %} @@ -51,12 +51,44 @@ </div> </div> + <div class="row-fluid"> + <div class="span6"> + <section id="discussion-maker" class="widget"> + <h3>Most active posters</h3> + {% for poster in top_posters %} + <div class="maker"> + <div class="inline-block maker-id"> + #{{forloop.counter}} + </div> + <div class="inline-block gravatar"> + {% gravatar poster.email 40 %} + <br /> + </div> + <div class="inline-block"> + <span class="maker-name">{{ poster.name }}</span> + <br /> + <span class="score">{{ poster.count }}</span> posts + </div> + </div> + {% endfor %} + </section> + </div> + <div class="span6"> + <section id="popular-threads" class="widget"> + <h3>Most popular discussions</h3> + {% for thread in pop_threads %} + {% include "threads/summary_thread.html" with counter=forloop.counter %} + {% endfor %} + </section> + </div> + </div> + <div class="row-fluid"> <div class="span6"> {% if top_author %} - <section id="discussion-maker"> - <h2>Prominent discussion maker</h2> + <section id="discussion-maker" class="widget"> + <h3>Prominent discussion maker</h3> {% for author in top_author %} <!-- Start discussion maker --> <div class="maker"> @@ -78,7 +110,7 @@ <!-- End discussion maker --> {% endfor %} - <h2>Tag cloud</h2> + <h3>Tag cloud</h3> </section> {% endif %} </div> @@ -86,11 +118,11 @@ <div class="span6"> {% if threads_per_category %} - <section id="discussion-by-topic"> - <h2>Discussion by topic the last 30 days</h2> + <section id="discussion-by-topic" class="widget"> + <h3>Discussion by topic the last 30 days</h3> {% for category, thread in threads_per_category.items %} <div> - <h2 class="category type_{{category}}"> {{category}} </h2> + <h3 class="category type_{{category}}"> {{category}} </h3> <ul class="category_entry"> {% for email in thread %} <li> diff --git a/hyperkitty/views/list.py b/hyperkitty/views/list.py index c1fda99..896edb2 100644 --- a/hyperkitty/views/list.py +++ b/hyperkitty/views/list.py @@ -175,17 +175,21 @@ def overview(request, mlist_fqdn=None): mlist = store.get_list(mlist_fqdn) if mlist is None: raise Http404("No archived mailing-list by that name.") - threads_result = store.get_threads(list_name=mlist.name, start=begin_date, - end=end_date) + threads_result = store.get_threads( + list_name=mlist.name, start=begin_date, end=end_date) threads = [] Thread = namedtuple('Thread', ["thread_id", "subject", "participants", - "length", "date_active"]) + "length", "date_active", "likes", "dislikes"]) participants = set() for thread_obj in threads_result: + # Votes + # XXX: 1 SQL request per thread, possible optimization here + likes, dislikes, myvote = get_votes(thread_obj.email_id_hashes) thread = Thread(thread_obj.thread_id, thread_obj.subject, thread_obj.participants, len(thread_obj), - thread_obj.date_active.replace(tzinfo=utc)) + thread_obj.date_active.replace(tzinfo=utc), + likes, dislikes) # Statistics on how many participants and threads this month participants.update(thread.participants) threads.append(thread) @@ -205,6 +209,17 @@ def overview(request, mlist_fqdn=None): else: authors = [] + # Top posters + top_posters = [] + for poster in store.get_top_participants(list_name=mlist.name, + start=begin_date, end=end_date, limit=5): + top_posters.append({"name": poster[0], "email": poster[1], + "count": poster[2]}) + + # Popular threads + pop_threads = sorted(threads, key=lambda t: t.likes - t.dislikes, + reverse=True)[:5] + # List activity # Use get_messages and not get_threads to count the emails, because # recently active threads include messages from before the start date @@ -238,6 +253,8 @@ def overview(request, mlist_fqdn=None): 'top_threads': top_threads[:5], 'most_active_threads': active_threads[:5], 'top_author': authors, + 'top_posters': top_posters, + 'pop_threads': pop_threads, 'threads_per_category': threads_per_category, 'months_list': get_months(store, mlist.name), 'evolution': evolution, |