Inital commit
[patchwork] / apps / patchwork / paginator.py
1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
3 #
4 # This file is part of the Patchwork package.
5 #
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
21 from django.core import paginator
22 from django.conf import settings
23
24 DEFAULT_PATCHES_PER_PAGE = 100
25 LONG_PAGE_THRESHOLD = 30
26 LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 10
27 LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 8
28 NUM_PAGES_OUTSIDE_RANGE = 2
29 ADJACENT_PAGES = 4
30
31 # parts from:
32 #  http://blog.localkinegrinds.com/2007/09/06/digg-style-pagination-in-django/
33
34 class Paginator(paginator.Paginator):
35     def __init__(self, request, objects):
36
37         patches_per_page = settings.DEFAULT_PATCHES_PER_PAGE
38
39         if request.user.is_authenticated():
40             patches_per_page = request.user.get_profile().patches_per_page
41
42         n = request.META.get('ppp')
43         if n:
44             try:
45                 patches_per_page = int(n)
46             except ValueError:
47                 pass
48
49         super(Paginator, self).__init__(objects, patches_per_page)
50
51         try:
52             page_no = int(request.GET.get('page'))
53             self.current_page = self.page(int(page_no))
54         except Exception:
55             page_no = 1
56             self.current_page = self.page(page_no)
57
58         self.leading_set = self.trailing_set = []
59
60         pages = self.num_pages
61
62         if pages <= LEADING_PAGE_RANGE_DISPLAYED:
63             self.adjacent_set = [n for n in range(1, pages + 1) \
64                            if n > 0 and n <= pages]
65         elif page_no <= LEADING_PAGE_RANGE:
66             self.adjacent_set = [n for n in \
67                            range(1, LEADING_PAGE_RANGE_DISPLAYED + 1) \
68                            if n > 0 and n <= pages]
69             self.leading_set = [n + pages for n in \
70                                       range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
71         elif page_no > pages - TRAILING_PAGE_RANGE:
72             self.adjacent_set = [n for n in \
73                            range(pages - TRAILING_PAGE_RANGE_DISPLAYED + 1, \
74                                    pages + 1) if n > 0 and n <= pages]
75             self.trailing_set = [n + 1 for n in range(0, \
76                     NUM_PAGES_OUTSIDE_RANGE)]
77         else:
78             self.adjacent_set = [n for n in range(page_no - ADJACENT_PAGES, \
79                     page_no + ADJACENT_PAGES + 1) if n > 0 and n <= pages]
80             self.leading_set = [n + pages for n in \
81                     range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
82             self.trailing_set = [n + 1 for n in \
83                                            range(0, NUM_PAGES_OUTSIDE_RANGE)]
84
85
86         self.leading_set.reverse()
87         self.long_page = \
88                 len(self.current_page.object_list) >= LONG_PAGE_THRESHOLD