Show More
@@ -1,45 +1,48 b'' | |||||
1 | [Version] |
|
1 | [Version] | |
2 | Version = 4.0.0 2017 |
|
2 | Version = 4.0.0 2017 | |
3 | SiteName = Neboard DEV |
|
3 | SiteName = Neboard DEV | |
4 |
|
4 | |||
5 | [Cache] |
|
5 | [Cache] | |
6 | # Timeout for caching, if cache is used |
|
6 | # Timeout for caching, if cache is used | |
7 | CacheTimeout = 600 |
|
7 | CacheTimeout = 600 | |
8 |
|
8 | |||
9 | [Forms] |
|
9 | [Forms] | |
10 | # Max post length in characters |
|
10 | # Max post length in characters | |
11 | MaxTextLength = 30000 |
|
11 | MaxTextLength = 30000 | |
12 | MaxFileSize = 8000000 |
|
12 | MaxFileSize = 8000000 | |
13 | LimitFirstPosting = true |
|
13 | LimitFirstPosting = true | |
14 | LimitPostingSpeed = false |
|
14 | LimitPostingSpeed = false | |
15 | PowDifficulty = 0 |
|
15 | PowDifficulty = 0 | |
16 | # Delay in seconds |
|
16 | # Delay in seconds | |
17 | PostingDelay = 30 |
|
17 | PostingDelay = 30 | |
18 | Autoban = false |
|
18 | Autoban = false | |
19 | DefaultTag = test |
|
19 | DefaultTag = test | |
20 | MaxFileCount = 1 |
|
20 | MaxFileCount = 1 | |
21 |
|
21 | |||
22 | [Messages] |
|
22 | [Messages] | |
23 | # Thread bumplimit |
|
23 | # Thread bumplimit | |
24 | MaxPostsPerThread = 10 |
|
24 | MaxPostsPerThread = 10 | |
25 | ThreadArchiveDays = 300 |
|
25 | ThreadArchiveDays = 300 | |
26 | AnonymousMode = false |
|
26 | AnonymousMode = false | |
27 |
|
27 | |||
28 | [View] |
|
28 | [View] | |
29 | DefaultTheme = md |
|
29 | DefaultTheme = md | |
30 | DefaultImageViewer = simple |
|
30 | DefaultImageViewer = simple | |
31 | LastRepliesCount = 3 |
|
31 | LastRepliesCount = 3 | |
32 | ThreadsPerPage = 3 |
|
32 | ThreadsPerPage = 3 | |
33 | PostsPerPage = 10 |
|
33 | PostsPerPage = 10 | |
34 | ImagesPerPageGallery = 20 |
|
34 | ImagesPerPageGallery = 20 | |
35 | MaxFavoriteThreads = 20 |
|
35 | MaxFavoriteThreads = 20 | |
36 | MaxLandingThreads = 20 |
|
36 | MaxLandingThreads = 20 | |
37 | Themes=md:Mystic Dark,md_centered:Mystic Dark (centered),sw:Snow White,pg:Photon Grey,ad:Amanita Dark,iw:Inocibe White |
|
37 | Themes=md:Mystic Dark,md_centered:Mystic Dark (centered),sw:Snow White,pg:Photon Grey,ad:Amanita Dark,iw:Inocibe White | |
38 | ImageViewers=simple:Simple,popup:Popup |
|
38 | ImageViewers=simple:Simple,popup:Popup | |
39 |
|
39 | |||
40 | [Storage] |
|
40 | [Storage] | |
41 | # Enable archiving threads instead of deletion when the thread limit is reached |
|
41 | # Enable archiving threads instead of deletion when the thread limit is reached | |
42 | ArchiveThreads = true |
|
42 | ArchiveThreads = true | |
43 |
|
43 | |||
44 | [RSS] |
|
44 | [RSS] | |
45 | MaxItems = 20 |
|
45 | MaxItems = 20 | |
|
46 | ||||
|
47 | [External] | |||
|
48 | ImageSearchHost=http://127.0.0.1/ |
@@ -1,39 +1,40 b'' | |||||
1 | {% extends "boards/thread.html" %} |
|
1 | {% extends "boards/thread.html" %} | |
2 |
|
2 | |||
3 | {% load i18n %} |
|
3 | {% load i18n %} | |
4 | {% load static from staticfiles %} |
|
4 | {% load static from staticfiles %} | |
5 | {% load board %} |
|
5 | {% load board %} | |
6 | {% load tz %} |
|
6 | {% load tz %} | |
7 |
|
7 | |||
8 | {% block head %} |
|
8 | {% block head %} | |
9 | <meta name="robots" content="noindex"> |
|
9 | <meta name="robots" content="noindex"> | |
10 | <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }} |
|
10 | <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }} | |
11 | - {{ site_name }}</title> |
|
11 | - {{ site_name }}</title> | |
12 | {% endblock %} |
|
12 | {% endblock %} | |
13 |
|
13 | |||
14 | {% block thread_content %} |
|
14 | {% block thread_content %} | |
15 | {% get_current_language as LANGUAGE_CODE %} |
|
15 | {% get_current_language as LANGUAGE_CODE %} | |
16 | {% get_current_timezone as TIME_ZONE %} |
|
16 | {% get_current_timezone as TIME_ZONE %} | |
17 |
|
17 | |||
18 | <div id="posts-table"> |
|
18 | <div id="posts-table"> | |
19 | {% if posts %} |
|
19 | {% if posts %} | |
20 | {% for post in posts %} |
|
20 | {% for post in posts %} | |
21 | {% for image in post.get_images %} |
|
21 | {% for image in post.get_images %} | |
22 | <div class="gallery_image"> |
|
22 | <div class="gallery_image"> | |
23 | {% autoescape off %} |
|
23 | {% autoescape off %} | |
24 | {{ image.get_view }} |
|
24 | {{ image.get_view }} | |
25 | <div class="gallery_image_metadata"> |
|
25 | <div class="gallery_image_metadata"> | |
26 | {{ image.get_size.0 }}x{{ image.get_size.1 }} |
|
26 | {{ image.get_size.0 }}x{{ image.get_size.1 }} | |
27 |
{% image_actions image.file.url |
|
27 | {% image_actions image.file.url %}, | |
|
28 | [<a href="{% url 'feed' %}?image_hash={{ image.hash }}">{{ site_name }}</a>] | |||
28 | <br /> |
|
29 | <br /> | |
29 | <a href="{{ post.get_absolute_url }}">>>{{ post.id }}</a> |
|
30 | <a href="{{ post.get_absolute_url }}">>>{{ post.id }}</a> | |
30 | </div> |
|
31 | </div> | |
31 | {% endautoescape %} |
|
32 | {% endautoescape %} | |
32 | </div> |
|
33 | </div> | |
33 | {% endfor %} |
|
34 | {% endfor %} | |
34 | {% endfor %} |
|
35 | {% endfor %} | |
35 | {% else %} |
|
36 | {% else %} | |
36 | {% trans 'No images.' %} |
|
37 | {% trans 'No images.' %} | |
37 | {% endif %} |
|
38 | {% endif %} | |
38 | </div> |
|
39 | </div> | |
39 | {% endblock %} |
|
40 | {% endblock %} |
@@ -1,119 +1,123 b'' | |||||
1 | import re |
|
1 | import re | |
2 |
|
2 | |||
3 | from django.shortcuts import get_object_or_404 |
|
3 | from django.shortcuts import get_object_or_404 | |
4 | from django import template |
|
4 | from django import template | |
5 | from django.utils.text import re_tag |
|
5 | from django.utils.text import re_tag | |
|
6 | from django.core.urlresolvers import reverse | |||
6 |
|
7 | |||
7 | from boards.mdx_neboard import LINE_BREAK_HTML |
|
8 | from boards.mdx_neboard import LINE_BREAK_HTML | |
|
9 | from boards import settings | |||
8 |
|
10 | |||
9 |
|
11 | |||
10 | IMG_ACTION_URL = '[<a href="{}">{}</a>]' |
|
12 | IMG_ACTION_URL = '[<a href="{}">{}</a>]' | |
11 | REGEX_NEWLINE = re.compile(LINE_BREAK_HTML) |
|
13 | REGEX_NEWLINE = re.compile(LINE_BREAK_HTML) | |
12 | TRUNCATOR = '...' |
|
14 | TRUNCATOR = '...' | |
13 | HTML4_SINGLETS =( |
|
15 | HTML4_SINGLETS =( | |
14 | 'br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input' |
|
16 | 'br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input' | |
15 | ) |
|
17 | ) | |
16 |
|
18 | |||
17 |
|
19 | |||
18 | register = template.Library() |
|
20 | register = template.Library() | |
19 |
|
21 | |||
20 | actions = [ |
|
22 | actions = [ | |
21 | { |
|
23 | { | |
22 | 'name': 'google', |
|
24 | 'name': 'google', | |
23 |
'link': 'http://google.com/searchbyimage?image_url= |
|
25 | 'link': 'https://www.google.com/searchbyimage?image_url={}', | |
24 | }, |
|
26 | }, | |
25 | { |
|
27 | { | |
26 | 'name': 'iqdb', |
|
28 | 'name': 'iqdb', | |
27 |
'link': 'http://iqdb.org/?url= |
|
29 | 'link': 'http://iqdb.org/?url={}', | |
28 | }, |
|
30 | }, | |
29 | ] |
|
31 | ] | |
30 |
|
32 | |||
31 |
|
33 | |||
32 | @register.simple_tag(name='post_url') |
|
34 | @register.simple_tag(name='post_url') | |
33 | def post_url(*args, **kwargs): |
|
35 | def post_url(*args, **kwargs): | |
34 | post_id = args[0] |
|
36 | post_id = args[0] | |
35 |
|
37 | |||
36 | post = get_object_or_404('Post', id=post_id) |
|
38 | post = get_object_or_404('Post', id=post_id) | |
37 |
|
39 | |||
38 | return post.get_absolute_url() |
|
40 | return post.get_absolute_url() | |
39 |
|
41 | |||
40 |
|
42 | |||
41 | @register.simple_tag(name='image_actions') |
|
43 | @register.simple_tag(name='image_actions') | |
42 | def image_actions(*args, **kwargs): |
|
44 | def image_actions(*args, **kwargs): | |
43 | image_link = args[0] |
|
45 | image_link = args[0] | |
44 | if len(args) > 1: |
|
46 | host = settings.get('External', 'ImageSearchHost') | |
45 | image_link = 'http://' + args[1] + image_link # TODO https? |
|
47 | if host.endswith('/'): | |
|
48 | host = host[:-1] | |||
|
49 | image_link = settings.get('External', 'ImageSearchHost') + image_link | |||
46 |
|
50 | |||
47 | return ', '.join([IMG_ACTION_URL.format( |
|
51 | return ', '.join([IMG_ACTION_URL.format( | |
48 |
action['link'] |
|
52 | action['link'].format(image_link), action['name']) for action in actions]) | |
49 |
|
53 | |||
50 |
|
54 | |||
51 | @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True) |
|
55 | @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True) | |
52 | def post_view(context, post, *args, **kwargs): |
|
56 | def post_view(context, post, *args, **kwargs): | |
53 | kwargs['perms'] = context['perms'] |
|
57 | kwargs['perms'] = context['perms'] | |
54 | return post.get_view_params(*args, **kwargs) |
|
58 | return post.get_view_params(*args, **kwargs) | |
55 |
|
59 | |||
56 |
|
60 | |||
57 | @register.simple_tag(name='page_url') |
|
61 | @register.simple_tag(name='page_url') | |
58 | def page_url(paginator, page_number, *args, **kwargs): |
|
62 | def page_url(paginator, page_number, *args, **kwargs): | |
59 | if paginator.supports_urls(): |
|
63 | if paginator.supports_urls(): | |
60 | return paginator.get_page_url(page_number) |
|
64 | return paginator.get_page_url(page_number) | |
61 |
|
65 | |||
62 |
|
66 | |||
63 | @register.filter(name='truncatenewlines_html') |
|
67 | @register.filter(name='truncatenewlines_html') | |
64 | def truncatenewlines_html(value, arg): |
|
68 | def truncatenewlines_html(value, arg): | |
65 | end_pos = 0 |
|
69 | end_pos = 0 | |
66 | start_pos = 0 |
|
70 | start_pos = 0 | |
67 | match_count = 0 |
|
71 | match_count = 0 | |
68 |
|
72 | |||
69 | # Collect places for truncation |
|
73 | # Collect places for truncation | |
70 | while match_count <= arg: |
|
74 | while match_count <= arg: | |
71 | m = REGEX_NEWLINE.search(value, end_pos) |
|
75 | m = REGEX_NEWLINE.search(value, end_pos) | |
72 | if m is None: |
|
76 | if m is None: | |
73 | break |
|
77 | break | |
74 | else: |
|
78 | else: | |
75 | match_count += 1 |
|
79 | match_count += 1 | |
76 | end_pos = m.end() |
|
80 | end_pos = m.end() | |
77 | start_pos = m.start() |
|
81 | start_pos = m.start() | |
78 |
|
82 | |||
79 | # Find and close open tags |
|
83 | # Find and close open tags | |
80 | if match_count > arg: |
|
84 | if match_count > arg: | |
81 | truncate_pos = start_pos |
|
85 | truncate_pos = start_pos | |
82 |
|
86 | |||
83 | open_tags = [] |
|
87 | open_tags = [] | |
84 | text = value[:truncate_pos] |
|
88 | text = value[:truncate_pos] | |
85 | current_pos = 0 |
|
89 | current_pos = 0 | |
86 | while True: |
|
90 | while True: | |
87 | tag = re_tag.search(text, current_pos) |
|
91 | tag = re_tag.search(text, current_pos) | |
88 | if tag is None: |
|
92 | if tag is None: | |
89 | break |
|
93 | break | |
90 | else: |
|
94 | else: | |
91 | closing_tag, tagname, self_closing = tag.groups() |
|
95 | closing_tag, tagname, self_closing = tag.groups() | |
92 | tagname = tagname.lower() |
|
96 | tagname = tagname.lower() | |
93 | if self_closing or tagname in HTML4_SINGLETS: |
|
97 | if self_closing or tagname in HTML4_SINGLETS: | |
94 | pass |
|
98 | pass | |
95 | elif closing_tag: |
|
99 | elif closing_tag: | |
96 | # Check for match in open tags list |
|
100 | # Check for match in open tags list | |
97 | try: |
|
101 | try: | |
98 | i = open_tags.index(tagname) |
|
102 | i = open_tags.index(tagname) | |
99 | except ValueError: |
|
103 | except ValueError: | |
100 | pass |
|
104 | pass | |
101 | else: |
|
105 | else: | |
102 | # SGML: An end tag closes, back to the matching start tag, |
|
106 | # SGML: An end tag closes, back to the matching start tag, | |
103 | # all unclosed intervening start tags with omitted end tags |
|
107 | # all unclosed intervening start tags with omitted end tags | |
104 | open_tags = open_tags[i + 1:] |
|
108 | open_tags = open_tags[i + 1:] | |
105 | else: |
|
109 | else: | |
106 | # Add it to the start of the open tags list |
|
110 | # Add it to the start of the open tags list | |
107 | open_tags.insert(0, tagname) |
|
111 | open_tags.insert(0, tagname) | |
108 |
|
112 | |||
109 | current_pos = tag.end() |
|
113 | current_pos = tag.end() | |
110 |
|
114 | |||
111 | if not text.endswith(TRUNCATOR): |
|
115 | if not text.endswith(TRUNCATOR): | |
112 | text += TRUNCATOR |
|
116 | text += TRUNCATOR | |
113 | for tag in open_tags: |
|
117 | for tag in open_tags: | |
114 | text += '</{}>'.format(tag) |
|
118 | text += '</{}>'.format(tag) | |
115 | else: |
|
119 | else: | |
116 | text = value |
|
120 | text = value | |
117 |
|
121 | |||
118 | return text |
|
122 | return text | |
119 |
|
123 |
@@ -1,74 +1,123 b'' | |||||
1 | from django.core.urlresolvers import reverse |
|
1 | from django.core.urlresolvers import reverse | |
2 | from django.shortcuts import render |
|
2 | from django.shortcuts import render | |
3 |
|
3 | |||
4 | from boards import settings |
|
4 | from boards import settings | |
5 | from boards.abstracts.paginator import get_paginator |
|
5 | from boards.abstracts.paginator import get_paginator | |
6 | from boards.abstracts.settingsmanager import get_settings_manager |
|
6 | from boards.abstracts.settingsmanager import get_settings_manager | |
7 | from boards.models import Post |
|
7 | from boards.models import Post | |
8 | from boards.views.base import BaseBoardView |
|
8 | from boards.views.base import BaseBoardView | |
9 | from boards.views.posting_mixin import PostMixin |
|
9 | from boards.views.posting_mixin import PostMixin | |
10 |
|
10 | |||
11 | POSTS_PER_PAGE = settings.get_int('View', 'PostsPerPage') |
|
11 | POSTS_PER_PAGE = settings.get_int('View', 'PostsPerPage') | |
12 |
|
12 | |||
13 | PARAMETER_CURRENT_PAGE = 'current_page' |
|
13 | PARAMETER_CURRENT_PAGE = 'current_page' | |
14 | PARAMETER_PAGINATOR = 'paginator' |
|
14 | PARAMETER_PAGINATOR = 'paginator' | |
15 | PARAMETER_POSTS = 'posts' |
|
15 | PARAMETER_POSTS = 'posts' | |
16 |
|
16 | |||
17 | PARAMETER_PREV_LINK = 'prev_page_link' |
|
17 | PARAMETER_PREV_LINK = 'prev_page_link' | |
18 | PARAMETER_NEXT_LINK = 'next_page_link' |
|
18 | PARAMETER_NEXT_LINK = 'next_page_link' | |
19 |
|
19 | |||
20 | TEMPLATE = 'boards/feed.html' |
|
20 | TEMPLATE = 'boards/feed.html' | |
21 | DEFAULT_PAGE = 1 |
|
21 | DEFAULT_PAGE = 1 | |
22 |
|
22 | |||
23 |
|
23 | |||
|
24 | class FeedFilter: | |||
|
25 | @staticmethod | |||
|
26 | def get_filtered_posts(request, posts): | |||
|
27 | return posts | |||
|
28 | ||||
|
29 | ||||
|
30 | class TripcodeFilter(FeedFilter): | |||
|
31 | @staticmethod | |||
|
32 | def get_filtered_posts(request, posts): | |||
|
33 | filtered_posts = posts | |||
|
34 | tripcode = request.GET.get('tripcode', None) | |||
|
35 | if tripcode: | |||
|
36 | filtered_posts = filtered_posts.filter(tripcode) | |||
|
37 | return filtered_posts | |||
|
38 | ||||
|
39 | ||||
|
40 | class FavoritesFilter(FeedFilter): | |||
|
41 | @staticmethod | |||
|
42 | def get_filtered_posts(request, posts): | |||
|
43 | filtered_posts = posts | |||
|
44 | ||||
|
45 | favorites = 'favorites' in request.GET | |||
|
46 | if favorites: | |||
|
47 | settings_manager = get_settings_manager(request) | |||
|
48 | fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys()) | |||
|
49 | fav_threads = [op.get_thread() for op in fav_thread_ops] | |||
|
50 | filtered_posts = filtered_posts.filter(thread__in=fav_threads) | |||
|
51 | return filtered_posts | |||
|
52 | ||||
|
53 | ||||
|
54 | class IpFilter(FeedFilter): | |||
|
55 | @staticmethod | |||
|
56 | def get_filtered_posts(request, posts): | |||
|
57 | filtered_posts = posts | |||
|
58 | ||||
|
59 | ip = request.GET.get('ip', None) | |||
|
60 | if ip and request.user.has_perm('post_delete'): | |||
|
61 | filtered_posts = filtered_posts.filter(poster_ip=ip) | |||
|
62 | return filtered_posts | |||
|
63 | ||||
|
64 | ||||
|
65 | class HashFilter(FeedFilter): | |||
|
66 | @staticmethod | |||
|
67 | def get_filtered_posts(request, posts): | |||
|
68 | filtered_posts = posts | |||
|
69 | ||||
|
70 | image_hash = request.GET.get('image_hash', None) | |||
|
71 | if image_hash: | |||
|
72 | filtered_posts = filtered_posts.filter(attachments__hash=image_hash) | |||
|
73 | return filtered_posts | |||
|
74 | ||||
|
75 | ||||
24 | class FeedView(PostMixin, BaseBoardView): |
|
76 | class FeedView(PostMixin, BaseBoardView): | |
|
77 | filters = ( | |||
|
78 | TripcodeFilter, | |||
|
79 | FavoritesFilter, | |||
|
80 | IpFilter, | |||
|
81 | HashFilter, | |||
|
82 | ) | |||
25 |
|
83 | |||
26 | def get(self, request): |
|
84 | def get(self, request): | |
27 | page = request.GET.get('page', DEFAULT_PAGE) |
|
85 | page = request.GET.get('page', DEFAULT_PAGE) | |
28 | tripcode = request.GET.get('tripcode', None) |
|
|||
29 | favorites = 'favorites' in request.GET |
|
|||
30 | ip = request.GET.get('ip', None) |
|
|||
31 |
|
86 | |||
32 | params = self.get_context_data(request=request) |
|
87 | params = self.get_context_data(request=request) | |
33 |
|
88 | |||
34 | settings_manager = get_settings_manager(request) |
|
89 | settings_manager = get_settings_manager(request) | |
35 |
|
90 | |||
36 | posts = Post.objects.exclude( |
|
91 | posts = Post.objects.exclude( | |
37 | thread__tags__in=settings_manager.get_hidden_tags()).order_by( |
|
92 | thread__tags__in=settings_manager.get_hidden_tags()).order_by( | |
38 | '-pub_time').prefetch_related('attachments', 'thread') |
|
93 | '-pub_time').prefetch_related('attachments', 'thread') | |
39 | if tripcode: |
|
94 | for filter in self.filters: | |
40 | posts = posts.filter(tripcode=tripcode) |
|
95 | posts = filter.get_filtered_posts(request, posts) | |
41 | if favorites: |
|
|||
42 | fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys()) |
|
|||
43 | fav_threads = [op.get_thread() for op in fav_thread_ops] |
|
|||
44 | posts = posts.filter(thread__in=fav_threads) |
|
|||
45 | if ip and request.user.has_perm('post_delete'): |
|
|||
46 | posts = posts.filter(poster_ip=ip) |
|
|||
47 |
|
96 | |||
48 | paginator = get_paginator(posts, POSTS_PER_PAGE) |
|
97 | paginator = get_paginator(posts, POSTS_PER_PAGE) | |
49 | paginator.current_page = int(page) |
|
98 | paginator.current_page = int(page) | |
50 |
|
99 | |||
51 | params[PARAMETER_POSTS] = paginator.page(page).object_list |
|
100 | params[PARAMETER_POSTS] = paginator.page(page).object_list | |
52 |
|
101 | |||
53 | paginator.set_url(reverse('feed'), request.GET.dict()) |
|
102 | paginator.set_url(reverse('feed'), request.GET.dict()) | |
54 |
|
103 | |||
55 | self.get_page_context(paginator, params, page) |
|
104 | self.get_page_context(paginator, params, page) | |
56 |
|
105 | |||
57 | return render(request, TEMPLATE, params) |
|
106 | return render(request, TEMPLATE, params) | |
58 |
|
107 | |||
59 | # TODO Dedup this into PagedMixin |
|
108 | # TODO Dedup this into PagedMixin | |
60 | def get_page_context(self, paginator, params, page): |
|
109 | def get_page_context(self, paginator, params, page): | |
61 | """ |
|
110 | """ | |
62 | Get pagination context variables |
|
111 | Get pagination context variables | |
63 | """ |
|
112 | """ | |
64 |
|
113 | |||
65 | params[PARAMETER_PAGINATOR] = paginator |
|
114 | params[PARAMETER_PAGINATOR] = paginator | |
66 | current_page = paginator.page(int(page)) |
|
115 | current_page = paginator.page(int(page)) | |
67 | params[PARAMETER_CURRENT_PAGE] = current_page |
|
116 | params[PARAMETER_CURRENT_PAGE] = current_page | |
68 | if current_page.has_previous(): |
|
117 | if current_page.has_previous(): | |
69 | params[PARAMETER_PREV_LINK] = paginator.get_page_url( |
|
118 | params[PARAMETER_PREV_LINK] = paginator.get_page_url( | |
70 | current_page.previous_page_number()) |
|
119 | current_page.previous_page_number()) | |
71 | if current_page.has_next(): |
|
120 | if current_page.has_next(): | |
72 | params[PARAMETER_NEXT_LINK] = paginator.get_page_url( |
|
121 | params[PARAMETER_NEXT_LINK] = paginator.get_page_url( | |
73 | current_page.next_page_number()) |
|
122 | current_page.next_page_number()) | |
74 |
|
123 |
General Comments 0
You need to be logged in to leave comments.
Login now