|
|
from django.core.paginator import Paginator
|
|
|
from boards.abstracts.constants import PARAM_PAGE
|
|
|
|
|
|
__author__ = 'neko259'
|
|
|
|
|
|
PATTERN_PAGE_URL = '<a {} href="{}">{}</a>'
|
|
|
PAGINATOR_LOOKAROUND_SIZE = 2
|
|
|
|
|
|
|
|
|
def get_paginator(*args, **kwargs):
|
|
|
return DividedPaginator(*args, **kwargs)
|
|
|
|
|
|
|
|
|
class DividedPaginator(Paginator):
|
|
|
|
|
|
lookaround_size = PAGINATOR_LOOKAROUND_SIZE
|
|
|
|
|
|
def __init__(self, object_list, per_page, orphans=0,
|
|
|
allow_empty_first_page=True, current_page=1, link=None, params=None):
|
|
|
super().__init__(object_list, per_page, orphans, allow_empty_first_page)
|
|
|
|
|
|
self.link = link
|
|
|
self.params = params
|
|
|
self.current_page = current_page
|
|
|
|
|
|
def _left_range(self):
|
|
|
return self.page_range[:self.lookaround_size]
|
|
|
|
|
|
def _right_range(self):
|
|
|
pages = self.num_pages-self.lookaround_size
|
|
|
if pages <= 0:
|
|
|
return []
|
|
|
else:
|
|
|
return self.page_range[pages:]
|
|
|
|
|
|
def _center_range(self):
|
|
|
index = self.page_range.index(self.current_page)
|
|
|
|
|
|
start = max(self.lookaround_size, index - self.lookaround_size)
|
|
|
end = min(self.num_pages - self.lookaround_size, index + self.lookaround_size + 1)
|
|
|
return self.page_range[start:end]
|
|
|
|
|
|
def _get_divided_range(self):
|
|
|
dr = list()
|
|
|
|
|
|
dr += self._left_range()
|
|
|
dr += self._center_range()
|
|
|
dr += self._right_range()
|
|
|
|
|
|
# Remove duplicates
|
|
|
dr = list(set(dr))
|
|
|
dr.sort()
|
|
|
|
|
|
return dr
|
|
|
|
|
|
def get_dividers(self, divided_range):
|
|
|
dividers = []
|
|
|
|
|
|
prev_page = 1
|
|
|
for page in divided_range:
|
|
|
if page - prev_page > 1:
|
|
|
dividers.append(page)
|
|
|
|
|
|
# There can be no more than 2 dividers, so don't bother going
|
|
|
# further
|
|
|
if len(dividers) > 2:
|
|
|
break
|
|
|
prev_page = page
|
|
|
|
|
|
return dividers
|
|
|
|
|
|
def get_page_url(self, page):
|
|
|
self.params[PARAM_PAGE] = page
|
|
|
url_params = '&'.join(['{}={}'.format(key, self.params[key])
|
|
|
for key in self.params.keys()])
|
|
|
return '{}?{}'.format(self.link, url_params)
|
|
|
|
|
|
def supports_urls(self):
|
|
|
return self.link is not None and self.params is not None
|
|
|
|
|
|
def get_next_page_url(self):
|
|
|
current = self.page(self.current_page)
|
|
|
if current.has_next():
|
|
|
return self.get_page_url(current.next_page_number())
|
|
|
|
|
|
def get_prev_page_url(self):
|
|
|
current = self.page(self.current_page)
|
|
|
if current.has_previous():
|
|
|
return self.get_page_url(current.previous_page_number())
|
|
|
|
|
|
def get_page_url_list(self):
|
|
|
output = []
|
|
|
|
|
|
divided_range = self._get_divided_range()
|
|
|
dividers = self.get_dividers(divided_range)
|
|
|
for page in divided_range:
|
|
|
if page in dividers:
|
|
|
output.append('...')
|
|
|
|
|
|
if page == self.current_page:
|
|
|
cls = 'class="current_page"'
|
|
|
else:
|
|
|
cls = ''
|
|
|
output.append(PATTERN_PAGE_URL.format(cls, self.get_page_url(page),
|
|
|
page))
|
|
|
|
|
|
return ', '.join(output)
|
|
|
|