]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/utils/pagination.py
Adds the option to exclude users with unvalidate emails from notifications.
[osqa.git] / forum / utils / pagination.py
index 684992ca3cb595cdab385912bd59a4a0a33cb7a3..e3cfc291e2c40dc949746f747b5172e2ddef3c64 100644 (file)
@@ -17,6 +17,14 @@ class SimpleSort(object):
     def apply(self, objects):
         return objects.order_by(self.order_by)
 
+class DummySort(object):
+    def __init__(self, label, description=''):
+        self.label = label
+        self.description = description
+
+    def apply(self, objects):
+        return objects
+
 
 class PaginatorContext(object):
     visible_page_range = 5
@@ -24,7 +32,8 @@ class PaginatorContext(object):
 
     base_path = None
 
-    def __init__(self, id, sort_methods=None, default_sort=None, pagesizes=None, default_pagesize=None):
+    def __init__(self, id, sort_methods=None, default_sort=None, force_sort = None, sticky_sort=False,
+                 pagesizes=None, default_pagesize=None, prefix=''):
         self.id = id
         if sort_methods:
             self.has_sort = True
@@ -49,65 +58,105 @@ class PaginatorContext(object):
         else:
             self.has_pagesize = False
 
+        self.force_sort = force_sort
+        self.sticky_sort = sticky_sort
+        self.prefix = prefix
 
+    def session_preferences(self, request):
+        return request.session.get('paginator_%s%s' % (self.prefix, self.id), {})
 
-class labels(object):
-    PAGESIZE = _('pagesize')
-    PAGE = _('page')
-    SORT = _('sort')
+    def pagesize(self, request, session_prefs=None):
+        if not session_prefs:
+            session_prefs = self.session_preferences(request)
 
-page_numbers_template = template.loader.get_template('paginator/page_numbers.html')
-page_sizes_template = template.loader.get_template('paginator/page_sizes.html')
-sort_tabs_template = template.loader.get_template('paginator/sort_tabs.html')
 
-def paginated(request, list_name, context, tpl_context):
-    session_prefs = request.session.get('paginator_%s' % context.id, {})
-    objects = tpl_context[list_name]
-
-    if context.has_pagesize:
-        if request.GET.get(labels.PAGESIZE, None):
-            try:
-                pagesize = int(request.GET[labels.PAGESIZE])
-            except ValueError:
-                logging.error('Found invalid page size "%s", loading %s, refered by %s' % (
-                    request.GET.get(labels.PAGESIZE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
-                ))
-                raise Http404()
-
-            session_prefs[labels.PAGESIZE] = pagesize
+        if self.has_pagesize:
+            if request.GET.get(self.PAGESIZE, None):
+                try:
+                    pagesize = int(request.GET[self.PAGESIZE])
+                except ValueError:
+                    logging.error('Found invalid page size "%s", loading %s, refered by %s' % (
+                        request.GET.get(self.PAGESIZE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+                    ))
+                    raise Http404()
+
+                session_prefs[self.PAGESIZE] = pagesize
+            else:
+                pagesize = session_prefs.get(self.PAGESIZE, self.default_pagesize)
+
+            if not pagesize in self.pagesizes:
+                pagesize = self.default_pagesize
         else:
-            pagesize = session_prefs.get(labels.PAGESIZE, context.default_pagesize)
+            pagesize = 30
+
+        return pagesize
+
+    def page(self, request):
+        try:
+            return int(request.GET.get(self.PAGE, 1))
+        except ValueError:
+            logging.error('Found invalid page number "%s", loading %s, refered by %s' % (
+                request.GET.get(self.PAGE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+            ))
+            raise Http404()
+
+    def sort(self, request, session_prefs=None):
+        if not session_prefs:
+            session_prefs = self.session_preferences(request)
+
+        sort = None
+        if self.has_sort:
+            if request.GET.get(self.SORT, None):
+                sort = request.GET[self.SORT]
+                if self.sticky_sort or session_prefs.get('sticky_sort', False):
+                    session_prefs[self.SORT] = sort
+            else:
+                sort = self.force_sort or session_prefs.get(self.SORT, self.default_sort)
 
-        if not pagesize in context.pagesizes:
-            pagesize = context.default_pagesize
-    else:
-        pagesize = 30
+            if not sort in self.sort_methods:
+                sort = self.default_sort
 
+        return sort
 
+    def sorted(self, objects, request, session_prefs=None):
+        sort = self.sort(request, session_prefs)
 
+        if sort:
+            objects = self.sort_methods[sort].apply(objects)
 
+        return sort, objects
 
-    try:
-        page = int(request.GET.get(labels.PAGE, 1))
-    except ValueError:
-        logging.error('Found invalid page number "%s", loading %s, refered by %s' % (
-            request.GET.get(labels.PAGE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
-        ))
-        raise Http404()
+    @property
+    def PAGESIZE(self):
+        return self.prefix and "%s_%s" % (self.prefix, _('pagesize')) or _('pagesize')
 
-    sort = None
-    if context.has_sort:
-        if request.GET.get(labels.SORT, None):
-            sort = request.GET[labels.SORT]
-            if session_prefs.get('sticky_sort', False):
-                session_prefs[labels.SORT] = sort
-        else:
-            sort = session_prefs.get(labels.SORT, context.default_sort)
+    @property
+    def PAGE(self):
+        return self.prefix and "%s_%s" % (self.prefix, _('page')) or _('page')
+
+    @property
+    def SORT(self):
+        return self.prefix and "%s_%s" % (self.prefix, _('sort')) or _('sort')
+
+page_numbers_template = template.loader.get_template('paginator/page_numbers.html')
+page_sizes_template = template.loader.get_template('paginator/page_sizes.html')
+sort_tabs_template = template.loader.get_template('paginator/sort_tabs.html')
+
+def paginated(request, paginators, tpl_context):
+    if len(paginators) == 2 and isinstance(paginators[0], basestring):
+        paginators = (paginators,)
+
+    for list_name, context in paginators:
+        tpl_context[list_name] = _paginated(request, tpl_context[list_name], context)
+
+    return tpl_context
 
-        if not sort in context.sort_methods:
-            sort = context.default_sort
+def _paginated(request, objects, context):
+    session_prefs = context.session_preferences(request)
 
-        objects = context.sort_methods[sort].apply(objects)
+    pagesize = context.pagesize(request, session_prefs)
+    page = context.page(request)
+    sort, objects = context.sorted(objects, request, session_prefs)
 
     paginator = Paginator(objects, pagesize)
 
@@ -115,7 +164,7 @@ def paginated(request, list_name, context, tpl_context):
         page_obj = paginator.page(page)
     except EmptyPage:
         logging.error('Found invalid page number "%s", loading %s, refered by %s' % (
-            request.GET.get(labels.PAGE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+            request.GET.get(context.PAGE, ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
         ))
         raise Http404()
 
@@ -123,7 +172,7 @@ def paginated(request, list_name, context, tpl_context):
         base_path = context.base_path
     else:
         base_path = request.path
-        get_params = ["%s=%s" % (k, v) for k, v in request.GET.items() if not k in (labels.PAGE, labels.PAGESIZE, labels.SORT)]
+        get_params = ["%s=%s" % (k, v) for k, v in request.GET.items() if not k in (context.PAGE, context.PAGESIZE, context.SORT)]
 
         if get_params:
             base_path += "?" + "&".join(get_params)
@@ -136,8 +185,8 @@ def paginated(request, list_name, context, tpl_context):
 
         if hasattr(object_list, 'lazy'):
             return object_list.lazy()
-        return page_obj.object_list
-    objects.page = get_page
+        return object_list
+    paginator.page = get_page()
 
     total_pages = paginator.num_pages
 
@@ -164,9 +213,9 @@ def paginated(request, list_name, context, tpl_context):
             page_numbers = []
 
             if sort:
-                url_builder = lambda n: mark_safe("%s%s%s=%s&%s=%s" % (base_path, url_joiner, labels.SORT, sort, labels.PAGE, n))
+                url_builder = lambda n: mark_safe("%s%s%s=%s&%s=%s" % (base_path, url_joiner, context.SORT, sort, context.PAGE, n))
             else:
-                url_builder = lambda n: mark_safe("%s%s%s=%s" % (base_path, url_joiner, labels.PAGE, n))
+                url_builder = lambda n: mark_safe("%s%s%s=%s" % (base_path, url_joiner, context.PAGE, n))
 
             if range_start > (context.outside_page_range + 1):
                 page_numbers.append([(n, url_builder(n)) for n in range(1, context.outside_page_range + 1)])
@@ -190,16 +239,16 @@ def paginated(request, list_name, context, tpl_context):
                 'current': page,
                 'page_numbers': page_numbers
             }))
-        objects.page_numbers = page_nums
+        paginator.page_numbers = page_nums
     else:
-        objects.page_numbers = ''
+        paginator.page_numbers = ''
 
     if pagesize:
         def page_sizes():
             if sort:
-                url_builder = lambda s: mark_safe("%s%s%s=%s&%s=%s" % (base_path, url_joiner, labels.SORT, sort, labels.PAGESIZE, s))
+                url_builder = lambda s: mark_safe("%s%s%s=%s&%s=%s" % (base_path, url_joiner, context.SORT, sort, context.PAGESIZE, s))
             else:
-                url_builder = lambda s: mark_safe("%s%s%s=%s" % (base_path, url_joiner, labels.PAGESIZE, s))
+                url_builder = lambda s: mark_safe("%s%s%s=%s" % (base_path, url_joiner, context.PAGESIZE, s))
 
             sizes = [(s, url_builder(s)) for s in context.pagesizes]
 
@@ -208,13 +257,13 @@ def paginated(request, list_name, context, tpl_context):
                 'sizes': sizes
             }))
 
-        objects.page_sizes = page_sizes
+        paginator.page_sizes = page_sizes
     else:
-        objects.page_sizes = ''
+        paginator.page_sizes = ''
 
     if sort:
         def sort_tabs():
-            url_builder = lambda s: mark_safe("%s%s%s=%s" % (base_path, url_joiner, labels.SORT, s))
+            url_builder = lambda s: mark_safe("%s%s%s=%s" % (base_path, url_joiner, context.SORT, s))
             sorts = [(n, s.label, url_builder(n), s.description) for n, s in context.sort_methods.items()]
 
             return sort_tabs_template.render(template.Context({
@@ -222,10 +271,10 @@ def paginated(request, list_name, context, tpl_context):
                 'sorts': sorts,
                 'sticky': session_prefs.get('sticky_sort', False)
             }))
-        objects.sort_tabs = sort_tabs()
+        paginator.sort_tabs = sort_tabs()
     else:
-        objects.sort_tabs = ''
+        paginator.sort_tabs = ''
 
     request.session['paginator_%s' % context.id] = session_prefs
-    tpl_context[list_name] = objects
-    return tpl_context
\ No newline at end of file
+    objects.paginator = paginator
+    return objects
\ No newline at end of file