##// END OF EJS Templates
Removed unused mixin. Refactored paginator a bit
neko259 -
r2035:3dd433d2 default
parent child Browse files
Show More
@@ -1,91 +1,93 b''
1 from boards.abstracts.constants import PARAM_PAGE
2
1 __author__ = 'neko259'
3 __author__ = 'neko259'
2
4
3 from django.core.paginator import Paginator
5 from django.core.paginator import Paginator
4
6
5 PAGINATOR_LOOKAROUND_SIZE = 2
7 PAGINATOR_LOOKAROUND_SIZE = 2
6
8
7
9
8 def get_paginator(*args, **kwargs):
10 def get_paginator(*args, **kwargs):
9 return DividedPaginator(*args, **kwargs)
11 return DividedPaginator(*args, **kwargs)
10
12
11
13
12 class DividedPaginator(Paginator):
14 class DividedPaginator(Paginator):
13
15
14 lookaround_size = PAGINATOR_LOOKAROUND_SIZE
16 lookaround_size = PAGINATOR_LOOKAROUND_SIZE
15
17
16 def __init__(self, object_list, per_page, orphans=0,
18 def __init__(self, object_list, per_page, orphans=0,
17 allow_empty_first_page=True, current_page=1):
19 allow_empty_first_page=True, current_page=1):
18 super().__init__(object_list, per_page, orphans, allow_empty_first_page)
20 super().__init__(object_list, per_page, orphans, allow_empty_first_page)
19
21
20 self.link = None
22 self.link = None
21 self.params = None
23 self.params = None
22 self.current_page = current_page
24 self.current_page = current_page
23
25
24 def _left_range(self):
26 def _left_range(self):
25 return self.page_range[:self.lookaround_size]
27 return self.page_range[:self.lookaround_size]
26
28
27 def _right_range(self):
29 def _right_range(self):
28 pages = self.num_pages-self.lookaround_size
30 pages = self.num_pages-self.lookaround_size
29 if pages <= 0:
31 if pages <= 0:
30 return []
32 return []
31 else:
33 else:
32 return self.page_range[pages:]
34 return self.page_range[pages:]
33
35
34 def _center_range(self):
36 def _center_range(self):
35 index = self.page_range.index(self.current_page)
37 index = self.page_range.index(self.current_page)
36
38
37 start = max(self.lookaround_size, index - self.lookaround_size)
39 start = max(self.lookaround_size, index - self.lookaround_size)
38 end = min(self.num_pages - self.lookaround_size, index + self.lookaround_size + 1)
40 end = min(self.num_pages - self.lookaround_size, index + self.lookaround_size + 1)
39 return self.page_range[start:end]
41 return self.page_range[start:end]
40
42
41 def get_divided_range(self):
43 def get_divided_range(self):
42 dr = list()
44 dr = list()
43
45
44 dr += self._left_range()
46 dr += self._left_range()
45 dr += self._center_range()
47 dr += self._center_range()
46 dr += self._right_range()
48 dr += self._right_range()
47
49
48 # Remove duplicates
50 # Remove duplicates
49 dr = list(set(dr))
51 dr = list(set(dr))
50 dr.sort()
52 dr.sort()
51
53
52 return dr
54 return dr
53
55
54 def get_dividers(self):
56 def get_dividers(self):
55 dividers = []
57 dividers = []
56
58
57 prev_page = 1
59 prev_page = 1
58 for page in self.get_divided_range():
60 for page in self.get_divided_range():
59 if page - prev_page > 1:
61 if page - prev_page > 1:
60 dividers.append(page)
62 dividers.append(page)
61
63
62 # There can be no more than 2 dividers, so don't bother going
64 # There can be no more than 2 dividers, so don't bother going
63 # further
65 # further
64 if len(dividers) > 2:
66 if len(dividers) > 2:
65 break
67 break
66 prev_page = page
68 prev_page = page
67
69
68 return dividers
70 return dividers
69
71
70 def set_url(self, link, params):
72 def set_url(self, link, params):
71 self.link = link
73 self.link = link
72 self.params = params
74 self.params = params
73
75
74 def get_page_url(self, page):
76 def get_page_url(self, page):
75 self.params['page'] = page
77 self.params[PARAM_PAGE] = page
76 url_params = '?' + '&'.join(['{}={}'.format(key, self.params[key])
78 url_params = '&'.join(['{}={}'.format(key, self.params[key])
77 for key in self.params.keys()])
79 for key in self.params.keys()])
78 return self.link + url_params
80 return '{}?{}'.format(self.link, url_params)
79
81
80 def supports_urls(self):
82 def supports_urls(self):
81 return self.link is not None and self.params is not None
83 return self.link is not None and self.params is not None
82
84
83 def get_next_page_url(self):
85 def get_next_page_url(self):
84 current = self.page(self.current_page)
86 current = self.page(self.current_page)
85 if current.has_next():
87 if current.has_next():
86 return self.get_page_url(current.next_page_number())
88 return self.get_page_url(current.next_page_number())
87
89
88 def get_prev_page_url(self):
90 def get_prev_page_url(self):
89 current = self.page(self.current_page)
91 current = self.page(self.current_page)
90 if current.has_previous():
92 if current.has_previous():
91 return self.get_page_url(current.previous_page_number()) No newline at end of file
93 return self.get_page_url(current.previous_page_number())
@@ -1,132 +1,132 b''
1 from django.core.paginator import EmptyPage
1 from django.core.paginator import EmptyPage
2 from django.http import Http404
2 from django.http import Http404
3 from django.shortcuts import render, redirect
3 from django.shortcuts import render
4 from django.urls import reverse
4 from django.urls import reverse
5 from django.utils.decorators import method_decorator
5 from django.utils.decorators import method_decorator
6 from django.views.decorators.csrf import csrf_protect
6 from django.views.decorators.csrf import csrf_protect
7
7
8 from boards import settings
8 from boards import settings
9 from boards.abstracts.constants import PARAM_PAGE
9 from boards.abstracts.constants import PARAM_PAGE
10 from boards.abstracts.paginator import get_paginator
10 from boards.abstracts.paginator import get_paginator
11 from boards.abstracts.settingsmanager import get_settings_manager, \
11 from boards.abstracts.settingsmanager import get_settings_manager, \
12 SETTING_ONLY_FAVORITES
12 SETTING_ONLY_FAVORITES
13 from boards.forms import ThreadForm, PlainErrorList
13 from boards.forms import ThreadForm, PlainErrorList
14 from boards.models import Post, Thread
14 from boards.models import Post, Thread
15 from boards.settings import SECTION_VIEW
15 from boards.views.base import BaseBoardView, CONTEXT_FORM
16 from boards.views.base import BaseBoardView, CONTEXT_FORM
16 from boards.views.mixins import FileUploadMixin, PaginatedMixin, \
17 from boards.views.mixins import PaginatedMixin, \
17 DispatcherMixin, PARAMETER_METHOD
18 DispatcherMixin, PARAMETER_METHOD
18 from boards.settings import SECTION_VIEW, SECTION_FORMS
19
19
20 ORDER_BUMP = 'bump'
20 ORDER_BUMP = 'bump'
21
21
22 PARAM_ORDER = 'order'
22 PARAM_ORDER = 'order'
23
23
24 FORM_TAGS = 'tags'
24 FORM_TAGS = 'tags'
25 FORM_TEXT = 'text'
25 FORM_TEXT = 'text'
26 FORM_TITLE = 'title'
26 FORM_TITLE = 'title'
27 FORM_IMAGE = 'image'
27 FORM_IMAGE = 'image'
28 FORM_THREADS = 'threads'
28 FORM_THREADS = 'threads'
29
29
30 TAG_DELIMITER = ' '
30 TAG_DELIMITER = ' '
31
31
32 PARAMETER_CURRENT_PAGE = 'current_page'
32 PARAMETER_CURRENT_PAGE = 'current_page'
33 PARAMETER_PAGINATOR = 'paginator'
33 PARAMETER_PAGINATOR = 'paginator'
34 PARAMETER_THREADS = 'threads'
34 PARAMETER_THREADS = 'threads'
35 PARAMETER_ADDITIONAL = 'additional_params'
35 PARAMETER_ADDITIONAL = 'additional_params'
36 PARAMETER_RSS_URL = 'rss_url'
36 PARAMETER_RSS_URL = 'rss_url'
37
37
38 TEMPLATE = 'boards/all_threads.html'
38 TEMPLATE = 'boards/all_threads.html'
39 DEFAULT_PAGE = 1
39 DEFAULT_PAGE = 1
40
40
41
41
42 class AllThreadsView(BaseBoardView, PaginatedMixin, DispatcherMixin):
42 class AllThreadsView(BaseBoardView, PaginatedMixin, DispatcherMixin):
43
43
44 tag_name = ''
44 tag_name = ''
45
45
46 def __init__(self):
46 def __init__(self):
47 self.settings_manager = None
47 self.settings_manager = None
48 super(AllThreadsView, self).__init__()
48 super(AllThreadsView, self).__init__()
49
49
50 @method_decorator(csrf_protect)
50 @method_decorator(csrf_protect)
51 def get(self, request, form: ThreadForm=None):
51 def get(self, request, form: ThreadForm=None):
52 page = request.GET.get(PARAM_PAGE, DEFAULT_PAGE)
52 page = request.GET.get(PARAM_PAGE, DEFAULT_PAGE)
53
53
54 params = self.get_context_data(request=request)
54 params = self.get_context_data(request=request)
55
55
56 if not form:
56 if not form:
57 form = ThreadForm(error_class=PlainErrorList,
57 form = ThreadForm(error_class=PlainErrorList,
58 initial={FORM_TAGS: self.tag_name})
58 initial={FORM_TAGS: self.tag_name})
59
59
60 self.settings_manager = get_settings_manager(request)
60 self.settings_manager = get_settings_manager(request)
61
61
62 threads = self.get_threads()
62 threads = self.get_threads()
63
63
64 order = request.GET.get(PARAM_ORDER, ORDER_BUMP)
64 order = request.GET.get(PARAM_ORDER, ORDER_BUMP)
65 if order == ORDER_BUMP:
65 if order == ORDER_BUMP:
66 threads = threads.order_by('-bump_time')
66 threads = threads.order_by('-bump_time')
67 else:
67 else:
68 threads = threads.filter(replies__opening=True)\
68 threads = threads.filter(replies__opening=True)\
69 .order_by('-replies__pub_time')
69 .order_by('-replies__pub_time')
70 threads = threads.distinct()
70 threads = threads.distinct()
71
71
72 paginator = get_paginator(threads, settings.get_int(
72 paginator = get_paginator(threads, settings.get_int(
73 SECTION_VIEW, 'ThreadsPerPage'))
73 SECTION_VIEW, 'ThreadsPerPage'))
74 paginator.current_page = int(page)
74 paginator.current_page = int(page)
75
75
76 try:
76 try:
77 threads = paginator.page(page).object_list
77 threads = paginator.page(page).object_list
78 except EmptyPage:
78 except EmptyPage:
79 raise Http404()
79 raise Http404()
80
80
81 params[PARAMETER_THREADS] = threads
81 params[PARAMETER_THREADS] = threads
82 params[CONTEXT_FORM] = form
82 params[CONTEXT_FORM] = form
83 params[PARAMETER_RSS_URL] = self.get_rss_url()
83 params[PARAMETER_RSS_URL] = self.get_rss_url()
84
84
85 paginator.set_url(self.get_reverse_url(), request.GET.dict())
85 paginator.set_url(self.get_reverse_url(), request.GET.dict())
86 params.update(self.get_page_context(paginator, page))
86 params.update(self.get_page_context(paginator, page))
87
87
88 return render(request, TEMPLATE, params)
88 return render(request, TEMPLATE, params)
89
89
90 @method_decorator(csrf_protect)
90 @method_decorator(csrf_protect)
91 def post(self, request):
91 def post(self, request):
92 if PARAMETER_METHOD in request.POST:
92 if PARAMETER_METHOD in request.POST:
93 self.dispatch_method(request)
93 self.dispatch_method(request)
94
94
95 return self.get_reverse_url()
95 return self.get_reverse_url()
96
96
97 form = ThreadForm(request.POST, request.FILES,
97 form = ThreadForm(request.POST, request.FILES,
98 error_class=PlainErrorList)
98 error_class=PlainErrorList)
99 form.session = request.session
99 form.session = request.session
100
100
101 if form.is_valid():
101 if form.is_valid():
102 return Post.objects.create_from_form(request, form, None)
102 return Post.objects.create_from_form(request, form, None)
103 if form.need_to_ban:
103 if form.need_to_ban:
104 # Ban user because he is suspected to be a bot
104 # Ban user because he is suspected to be a bot
105 self._ban_current_user(request)
105 self._ban_current_user(request)
106
106
107 return self.get(request, form)
107 return self.get(request, form)
108
108
109 def get_reverse_url(self):
109 def get_reverse_url(self):
110 return reverse('index')
110 return reverse('index')
111
111
112 def get_threads(self):
112 def get_threads(self):
113 """
113 """
114 Gets list of threads that will be shown on a page.
114 Gets list of threads that will be shown on a page.
115 """
115 """
116
116
117 threads = Thread.objects\
117 threads = Thread.objects\
118 .exclude(tags__in=self.settings_manager.get_hidden_tags())
118 .exclude(tags__in=self.settings_manager.get_hidden_tags())
119 if self.settings_manager.get_setting(SETTING_ONLY_FAVORITES):
119 if self.settings_manager.get_setting(SETTING_ONLY_FAVORITES):
120 fav_tags = self.settings_manager.get_fav_tags()
120 fav_tags = self.settings_manager.get_fav_tags()
121 if len(fav_tags) > 0:
121 if len(fav_tags) > 0:
122 threads = threads.filter(tags__in=fav_tags)
122 threads = threads.filter(tags__in=fav_tags)
123
123
124 return threads
124 return threads
125
125
126 def get_rss_url(self):
126 def get_rss_url(self):
127 return self.get_reverse_url() + 'rss/'
127 return self.get_reverse_url() + 'rss/'
128
128
129 def toggle_fav(self, request):
129 def toggle_fav(self, request):
130 settings_manager = get_settings_manager(request)
130 settings_manager = get_settings_manager(request)
131 settings_manager.set_setting(SETTING_ONLY_FAVORITES,
131 settings_manager.set_setting(SETTING_ONLY_FAVORITES,
132 not settings_manager.get_setting(SETTING_ONLY_FAVORITES, False))
132 not settings_manager.get_setting(SETTING_ONLY_FAVORITES, False))
@@ -1,62 +1,53 b''
1 import boards
2 from boards.settings import SECTION_FORMS
3
4 PARAM_NEXT = 'next'
1 PARAM_NEXT = 'next'
5 PARAMETER_METHOD = 'method'
2 PARAMETER_METHOD = 'method'
6
3
7 PARAMETER_CURRENT_PAGE = 'current_page'
4 PARAMETER_CURRENT_PAGE = 'current_page'
8 PARAMETER_PAGINATOR = 'paginator'
5 PARAMETER_PAGINATOR = 'paginator'
9
6
10 PARAMETER_PREV_LINK = 'prev_page_link'
7 PARAMETER_PREV_LINK = 'prev_page_link'
11 PARAMETER_NEXT_LINK = 'next_page_link'
8 PARAMETER_NEXT_LINK = 'next_page_link'
12
9
13
10
14 class DispatcherMixin:
11 class DispatcherMixin:
15 """
12 """
16 This class contains a dispather method that can run a method specified by
13 This class contains a dispather method that can run a method specified by
17 'method' request parameter.
14 'method' request parameter.
18 """
15 """
19
16
20 def __init__(self):
17 def __init__(self):
21 self.user = None
18 self.user = None
22
19
23 def dispatch_method(self, *args, **kwargs):
20 def dispatch_method(self, *args, **kwargs):
24 request = args[0]
21 request = args[0]
25
22
26 self.user = request.user
23 self.user = request.user
27
24
28 method_name = None
25 method_name = None
29 if PARAMETER_METHOD in request.GET:
26 if PARAMETER_METHOD in request.GET:
30 method_name = request.GET[PARAMETER_METHOD]
27 method_name = request.GET[PARAMETER_METHOD]
31 elif PARAMETER_METHOD in request.POST:
28 elif PARAMETER_METHOD in request.POST:
32 method_name = request.POST[PARAMETER_METHOD]
29 method_name = request.POST[PARAMETER_METHOD]
33
30
34 if method_name:
31 if method_name:
35 return getattr(self, method_name)(*args, **kwargs)
32 return getattr(self, method_name)(*args, **kwargs)
36
33
37
34
38 # TODO Check if it is still used anywhere and safely remove
39 class FileUploadMixin:
40 def get_max_upload_size(self):
41 return boards.settings.get_int(SECTION_FORMS, 'MaxFileSize')
42
43
44 class PaginatedMixin:
35 class PaginatedMixin:
45 def get_page_context(self, paginator, page):
36 def get_page_context(self, paginator, page):
46 """
37 """
47 Get pagination context variables
38 Get pagination context variables
48 """
39 """
49
40
50 params = {}
41 params = {}
51
42
52 params[PARAMETER_PAGINATOR] = paginator
43 params[PARAMETER_PAGINATOR] = paginator
53 current_page = paginator.page(int(page))
44 current_page = paginator.page(int(page))
54 params[PARAMETER_CURRENT_PAGE] = current_page
45 params[PARAMETER_CURRENT_PAGE] = current_page
55 if current_page.has_previous():
46 if current_page.has_previous():
56 params[PARAMETER_PREV_LINK] = paginator.get_page_url(
47 params[PARAMETER_PREV_LINK] = paginator.get_page_url(
57 current_page.previous_page_number())
48 current_page.previous_page_number())
58 if current_page.has_next():
49 if current_page.has_next():
59 params[PARAMETER_NEXT_LINK] = paginator.get_page_url(
50 params[PARAMETER_NEXT_LINK] = paginator.get_page_url(
60 current_page.next_page_number())
51 current_page.next_page_number())
61
52
62 return params
53 return params
@@ -1,33 +1,30 b''
1 from boards import settings
2 from boards.settings import SECTION_FORMS
3 from boards.views.thread import ThreadView
1 from boards.views.thread import ThreadView
4 from boards.views.mixins import FileUploadMixin
5
2
6 TEMPLATE_NORMAL = 'boards/thread_normal.html'
3 TEMPLATE_NORMAL = 'boards/thread_normal.html'
7
4
8 CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress'
5 CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress'
9 CONTEXT_POSTS_LEFT = 'posts_left'
6 CONTEXT_POSTS_LEFT = 'posts_left'
10 CONTEXT_BUMPABLE = 'bumpable'
7 CONTEXT_BUMPABLE = 'bumpable'
11
8
12
9
13 class NormalThreadView(ThreadView):
10 class NormalThreadView(ThreadView):
14
11
15 def get_template(self):
12 def get_template(self):
16 return TEMPLATE_NORMAL
13 return TEMPLATE_NORMAL
17
14
18 def get_mode(self):
15 def get_mode(self):
19 return 'normal'
16 return 'normal'
20
17
21 def get_data(self, thread):
18 def get_data(self, thread):
22 params = dict()
19 params = dict()
23
20
24 bumpable = thread.can_bump()
21 bumpable = thread.can_bump()
25 params[CONTEXT_BUMPABLE] = bumpable
22 params[CONTEXT_BUMPABLE] = bumpable
26 max_posts = thread.max_posts
23 max_posts = thread.max_posts
27 if bumpable and thread.has_post_limit():
24 if bumpable and thread.has_post_limit():
28 left_posts = max_posts - thread.get_reply_count()
25 left_posts = max_posts - thread.get_reply_count()
29 params[CONTEXT_POSTS_LEFT] = left_posts
26 params[CONTEXT_POSTS_LEFT] = left_posts
30 params[CONTEXT_BUMPLIMIT_PRG] = str(
27 params[CONTEXT_BUMPLIMIT_PRG] = str(
31 float(left_posts) / max_posts * 100)
28 float(left_posts) / max_posts * 100)
32
29
33 return params
30 return params
General Comments 0
You need to be logged in to leave comments. Login now