summaryrefslogtreecommitdiffstats
path: root/hyperkitty
diff options
context:
space:
mode:
Diffstat (limited to 'hyperkitty')
-rw-r--r--hyperkitty/lib/__init__.py36
-rw-r--r--hyperkitty/templates/paginator.html9
-rw-r--r--hyperkitty/templates/search_results.html30
-rw-r--r--hyperkitty/tests/test_lib.py52
-rw-r--r--hyperkitty/views/accounts.py13
-rw-r--r--hyperkitty/views/list.py16
-rw-r--r--hyperkitty/views/search.py13
7 files changed, 101 insertions, 68 deletions
diff --git a/hyperkitty/lib/__init__.py b/hyperkitty/lib/__init__.py
index 40b065f..e5d35a4 100644
--- a/hyperkitty/lib/__init__.py
+++ b/hyperkitty/lib/__init__.py
@@ -25,6 +25,7 @@ import datetime
from django.core.exceptions import SuspiciousOperation
from django.core.mail import EmailMessage
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from mailmanclient import MailmanConnectionError
from hyperkitty.lib import mailman
@@ -126,3 +127,38 @@ def post_to_list(request, mlist, subject, message, headers={}):
headers=headers,
)
msg.send()
+
+
+def paginate(objects, page_num, max_page_range=10, paginator=None):
+ if paginator is None:
+ paginator = Paginator(objects, 10) # else use the provided instance
+ try:
+ objects = paginator.page(page_num)
+ except PageNotAnInteger:
+ # If page is not an integer, deliver first page.
+ objects = paginator.page(1)
+ except EmptyPage:
+ # If page is out of range (e.g. 9999), deliver last page of results.
+ objects = paginator.page(paginator.num_pages)
+ # Calculate the displayed page range
+ if paginator.num_pages > max_page_range:
+ objects.page_range = [ 1 ]
+ subrange_lower = page_num - (max_page_range / 2 - 2)
+ if subrange_lower > 3:
+ objects.page_range.append("...")
+ else:
+ subrange_lower = 2
+ objects.page_range.extend(range(subrange_lower, page_num))
+ if page_num != 1 and page_num != 100:
+ objects.page_range.append(page_num)
+ subrange_upper = page_num + (max_page_range / 2 - 2)
+ if subrange_upper >= paginator.num_pages - 2:
+ subrange_upper = paginator.num_pages - 1
+ objects.page_range.extend(range(page_num+1, subrange_upper+1))
+ if subrange_upper < paginator.num_pages - 2:
+ objects.page_range.append("...")
+ objects.page_range.append(paginator.num_pages)
+ else:
+ objects.page_range = [ p+1 for p in range(paginator.num_pages) ]
+ return objects
+
diff --git a/hyperkitty/templates/paginator.html b/hyperkitty/templates/paginator.html
index 0b4e0d7..efbce86 100644
--- a/hyperkitty/templates/paginator.html
+++ b/hyperkitty/templates/paginator.html
@@ -10,12 +10,17 @@
<li class="disabled">
<a href="#">
{% endif %}
- &larr; Newer</a>
+ &larr; {% if notbydate %}Previous{% else %}Newer{% endif %}
+ </a>
</li>
{% for pagenum in pager.page_range %}
<li{% if pagenum == pager.number %} class="active"{% endif %}>
+ {% if pagenum == "..." %}
+ <a href="#" class="disabled">...</a>
+ {% else %}
<a href="?{% add_to_query_string page_key|default:'page' pagenum %}">{{ pagenum }}</a>
+ {% endif %}
</li>
{% endfor %}
@@ -26,7 +31,7 @@
<li class="disabled">
<a href="#">
{% endif %}
- Older &rarr;</a>
+ {% if notbydate %}Next{% else %}Older{% endif %} &rarr;</a>
</li>
</ul>
</div>
diff --git a/hyperkitty/templates/search_results.html b/hyperkitty/templates/search_results.html
index c9cc754..f91d664 100644
--- a/hyperkitty/templates/search_results.html
+++ b/hyperkitty/templates/search_results.html
@@ -44,35 +44,7 @@ Search results for "{{ query }}"{% if mlist %} - {{ mlist.display_name|default:m
<p>Sorry no email could be found for this query.</p>
{% endfor %}
- <div class="pagination pagination-centered">
- <ul>
- {% if messages.has_previous %}
- <li>
- <a href="?{% add_to_query_string page=messages.previous_page_number %}">
- {% else %}
- <li class="disabled">
- <a href="#">
- {% endif %}
- &larr; Previous</a>
- </li>
-
- {% for pagenum in messages.page_range %}
- <li{% if pagenum == messages.number %} class="active"{% endif %}>
- <a href="?{% add_to_query_string page=pagenum %}">{{ pagenum }}</a>
- </li>
- {% endfor %}
-
- {% if messages.has_next %}
- <li>
- <a href="?{% add_to_query_string page=messages.next_page_number %}">
- {% else %}
- <li class="disabled">
- <a href="#">
- {% endif %}
- Next &rarr;</a>
- </li>
- </ul>
- </div>
+ {% include "paginator.html" with pager=messages notbydate=True %}
</div>
diff --git a/hyperkitty/tests/test_lib.py b/hyperkitty/tests/test_lib.py
index fb560ae..b24f5c4 100644
--- a/hyperkitty/tests/test_lib.py
+++ b/hyperkitty/tests/test_lib.py
@@ -23,7 +23,7 @@ import datetime
from django.test import TestCase
-from hyperkitty.lib import get_display_dates
+from hyperkitty.lib import get_display_dates, paginate
class GetDisplayDatesTestCase(TestCase):
@@ -45,3 +45,53 @@ class GetDisplayDatesTestCase(TestCase):
begin_date, end_date = get_display_dates('2012', '4', '2')
self.assertEqual(begin_date, datetime.datetime(2012, 4, 2))
self.assertEqual(end_date, datetime.datetime(2012, 4, 3))
+
+
+class PaginateTestCase(TestCase):
+
+ def test_page_range(self):
+ objects = range(1000)
+ self.assertEqual(paginate(objects, 1).page_range,
+ [1, 2, 3, 4, '...', 100])
+ self.assertEqual(paginate(objects, 2).page_range,
+ [1, 2, 3, 4, 5, '...', 100])
+ self.assertEqual(paginate(objects, 3).page_range,
+ [1, 2, 3, 4, 5, 6, '...', 100])
+ self.assertEqual(paginate(objects, 4).page_range,
+ [1, 2, 3, 4, 5, 6, 7, '...', 100])
+ self.assertEqual(paginate(objects, 5).page_range,
+ [1, 2, 3, 4, 5, 6, 7, 8, '...', 100])
+ self.assertEqual(paginate(objects, 6).page_range,
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, '...', 100])
+ self.assertEqual(paginate(objects, 7).page_range,
+ [1, '...', 4, 5, 6, 7, 8, 9, 10, '...', 100])
+ self.assertEqual(paginate(objects, 8).page_range,
+ [1, '...', 5, 6, 7, 8, 9, 10, 11, '...', 100])
+ self.assertEqual(paginate(objects, 9).page_range,
+ [1, '...', 6, 7, 8, 9, 10, 11, 12, '...', 100])
+ self.assertEqual(paginate(objects, 10).page_range,
+ [1, '...', 7, 8, 9, 10, 11, 12, 13, '...', 100])
+ self.assertEqual(paginate(objects, 40).page_range,
+ [1, '...', 37, 38, 39, 40, 41, 42, 43, '...', 100])
+ self.assertEqual(paginate(objects, 90).page_range,
+ [1, '...', 87, 88, 89, 90, 91, 92, 93, '...', 100])
+ self.assertEqual(paginate(objects, 91).page_range,
+ [1, '...', 88, 89, 90, 91, 92, 93, 94, '...', 100])
+ self.assertEqual(paginate(objects, 92).page_range,
+ [1, '...', 89, 90, 91, 92, 93, 94, 95, '...', 100])
+ self.assertEqual(paginate(objects, 93).page_range,
+ [1, '...', 90, 91, 92, 93, 94, 95, 96, '...', 100])
+ self.assertEqual(paginate(objects, 94).page_range,
+ [1, '...', 91, 92, 93, 94, 95, 96, 97, '...', 100])
+ self.assertEqual(paginate(objects, 95).page_range,
+ [1, '...', 92, 93, 94, 95, 96, 97, 98, 99, 100])
+ self.assertEqual(paginate(objects, 96).page_range,
+ [1, '...', 93, 94, 95, 96, 97, 98, 99, 100])
+ self.assertEqual(paginate(objects, 97).page_range,
+ [1, '...', 94, 95, 96, 97, 98, 99, 100])
+ self.assertEqual(paginate(objects, 98).page_range,
+ [1, '...', 95, 96, 97, 98, 99, 100])
+ self.assertEqual(paginate(objects, 99).page_range,
+ [1, '...', 96, 97, 98, 99, 100])
+ self.assertEqual(paginate(objects, 100).page_range,
+ [1, '...', 97, 98, 99, 100])
diff --git a/hyperkitty/views/accounts.py b/hyperkitty/views/accounts.py
index 946f965..d7e35c2 100644
--- a/hyperkitty/views/accounts.py
+++ b/hyperkitty/views/accounts.py
@@ -24,7 +24,6 @@ import logging
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.exceptions import SuspiciousOperation, ObjectDoesNotExist
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate, login, get_backends
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
@@ -37,7 +36,7 @@ from social_auth.backends import SocialAuthBackend
from hyperkitty.models import UserProfile, Rating, Favorite, LastView
from hyperkitty.views.forms import RegistrationForm, UserProfileForm
-from hyperkitty.lib import get_store, FLASH_MESSAGES
+from hyperkitty.lib import get_store, FLASH_MESSAGES, paginate
logger = logging.getLogger(__name__)
@@ -182,15 +181,7 @@ def last_views(request):
).order_by("view_date")
except Favorite.DoesNotExist:
last_views = []
- last_views_paginator = Paginator(last_views, 10)
- last_views_page = request.GET.get('lvpage')
- try:
- last_views = last_views_paginator.page(last_views_page)
- except PageNotAnInteger:
- last_views = last_views_paginator.page(1)
- except EmptyPage:
- last_views = last_views_paginator.page(last_views_paginator.num_pages)
- last_views.page_range = [ p+1 for p in range(last_views_paginator.num_pages) ]
+ last_views = paginate(last_views, request.GET.get('lvpage'))
for last_view in last_views:
thread = store.get_thread(last_view.list_address, last_view.threadid)
if thread.date_active.replace(tzinfo=utc) > last_view.view_date:
diff --git a/hyperkitty/views/list.py b/hyperkitty/views/list.py
index 610b148..c1fda99 100644
--- a/hyperkitty/views/list.py
+++ b/hyperkitty/views/list.py
@@ -26,7 +26,6 @@ from collections import namedtuple, defaultdict
from django.shortcuts import redirect, render
from django.conf import settings
from django.core.urlresolvers import reverse
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.utils import formats
from django.utils.dateformat import format as date_format
from django.utils.timezone import utc
@@ -34,7 +33,7 @@ from django.http import Http404
from hyperkitty.models import Tag, Favorite, LastView
from hyperkitty.lib import get_months, get_store, get_display_dates, daterange
-from hyperkitty.lib import FLASH_MESSAGES
+from hyperkitty.lib import FLASH_MESSAGES, paginate
from hyperkitty.lib.voting import get_votes, set_message_votes
@@ -142,17 +141,7 @@ def _thread_list(request, mlist, threads, template_name='thread_list.html', extr
> last_view_obj.view_date:
thread.unread = True
- paginator = Paginator(threads, 10)
- page_num = request.GET.get('page')
- try:
- threads = paginator.page(page_num)
- except PageNotAnInteger:
- # If page is not an integer, deliver first page.
- threads = paginator.page(1)
- except EmptyPage:
- # If page is out of range (e.g. 9999), deliver last page of results.
- threads = paginator.page(paginator.num_pages)
- threads.page_range = [ p+1 for p in range(paginator.num_pages) ]
+ threads = paginate(threads, request.GET.get('page'))
flash_messages = []
flash_msg = request.GET.get("msg")
@@ -163,7 +152,6 @@ def _thread_list(request, mlist, threads, template_name='thread_list.html', extr
context = {
'mlist' : mlist,
- 'current_page': page_num,
'threads': threads,
'participants': len(participants),
'months_list': get_months(store, mlist.name),
diff --git a/hyperkitty/views/search.py b/hyperkitty/views/search.py
index 199a836..9ea224a 100644
--- a/hyperkitty/views/search.py
+++ b/hyperkitty/views/search.py
@@ -24,7 +24,7 @@ from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger, Page
from hyperkitty.models import Tag
-from hyperkitty.lib import get_store
+from hyperkitty.lib import get_store, paginate
from hyperkitty.lib.voting import get_votes, set_message_votes
from .list import _thread_list
@@ -91,20 +91,11 @@ def search(request, page=1):
raise Http404("No archived mailing-list by that name.")
paginator = SearchPaginator(messages, 10, total)
- try:
- messages = paginator.page(page_num)
- except PageNotAnInteger:
- # If page is not an integer, deliver first page.
- messages = paginator.page(1)
- except EmptyPage:
- # If page is out of range (e.g. 9999), deliver last page of results.
- messages = paginator.page(paginator.num_pages)
- messages.page_range = [ p+1 for p in range(paginator.num_pages) ]
+ messages = paginate(messages, page_num, paginator=paginator)
context = {
'mlist' : mlist,
"query": query,
- 'current_page': page_num,
'messages': messages,
'total': total,
}