Show More
@@ -0,0 +1,31 b'' | |||||
|
1 | from django.core.urlresolvers import reverse | |||
|
2 | from django.shortcuts import get_object_or_404, render | |||
|
3 | ||||
|
4 | from boards import settings | |||
|
5 | from boards.abstracts.paginator import get_paginator | |||
|
6 | from boards.models import Tag | |||
|
7 | from boards.views.base import BaseBoardView | |||
|
8 | from boards.views.mixins import PaginatedMixin | |||
|
9 | ||||
|
10 | IMAGES_PER_PAGE = settings.get_int('View', 'ImagesPerPageGallery') | |||
|
11 | ||||
|
12 | TEMPLATE = 'boards/tag_gallery.html' | |||
|
13 | ||||
|
14 | ||||
|
15 | class TagGalleryView(BaseBoardView, PaginatedMixin): | |||
|
16 | ||||
|
17 | def get(self, request, tag_name): | |||
|
18 | page = int(request.GET.get('page', 1)) | |||
|
19 | ||||
|
20 | params = dict() | |||
|
21 | tag = get_object_or_404(Tag, name=tag_name) | |||
|
22 | params['tag'] = tag | |||
|
23 | paginator = get_paginator(tag.get_images(), IMAGES_PER_PAGE, | |||
|
24 | current_page=page) | |||
|
25 | params['paginator'] = paginator | |||
|
26 | params['images'] = paginator.page(page).object_list | |||
|
27 | paginator.set_url(reverse('tag_gallery', kwargs={'tag_name': tag_name}), | |||
|
28 | request.GET.dict()) | |||
|
29 | self.set_page_urls(paginator, params) | |||
|
30 | ||||
|
31 | return render(request, TEMPLATE, params) No newline at end of file |
@@ -12,7 +12,14 b' def get_paginator(*args, **kwargs):' | |||||
12 | class DividedPaginator(Paginator): |
|
12 | class DividedPaginator(Paginator): | |
13 |
|
13 | |||
14 | lookaround_size = PAGINATOR_LOOKAROUND_SIZE |
|
14 | lookaround_size = PAGINATOR_LOOKAROUND_SIZE | |
15 | current_page = 0 |
|
15 | ||
|
16 | def __init__(self, object_list, per_page, orphans=0, | |||
|
17 | allow_empty_first_page=True, current_page=1): | |||
|
18 | super().__init__(object_list, per_page, orphans, allow_empty_first_page) | |||
|
19 | ||||
|
20 | self.link = None | |||
|
21 | self.params = None | |||
|
22 | self.current_page = current_page | |||
16 |
|
23 | |||
17 | def _left_range(self): |
|
24 | def _left_range(self): | |
18 | return self.page_range[:self.lookaround_size] |
|
25 | return self.page_range[:self.lookaround_size] | |
@@ -67,8 +74,18 b' class DividedPaginator(Paginator):' | |||||
67 | def get_page_url(self, page): |
|
74 | def get_page_url(self, page): | |
68 | self.params['page'] = page |
|
75 | self.params['page'] = page | |
69 | url_params = '?' + '&'.join(['{}={}'.format(key, self.params[key]) |
|
76 | url_params = '?' + '&'.join(['{}={}'.format(key, self.params[key]) | |
70 | for key in self.params.keys()]) |
|
77 | for key in self.params.keys()]) | |
71 | return self.link + url_params |
|
78 | return self.link + url_params | |
72 |
|
79 | |||
73 | def supports_urls(self): |
|
80 | def supports_urls(self): | |
74 | return self.link is not None and self.params is not None |
|
81 | return self.link is not None and self.params is not None | |
|
82 | ||||
|
83 | def get_next_page_url(self): | |||
|
84 | current = self.page(self.current_page) | |||
|
85 | if current.has_next(): | |||
|
86 | return self.get_page_url(current.next_page_number()) | |||
|
87 | ||||
|
88 | def get_prev_page_url(self): | |||
|
89 | current = self.page(self.current_page) | |||
|
90 | if current.has_previous(): | |||
|
91 | return self.get_page_url(current.previous_page_number()) No newline at end of file |
@@ -24,6 +24,7 b' DefaultTheme = md' | |||||
24 | DefaultImageViewer = simple |
|
24 | DefaultImageViewer = simple | |
25 | LastRepliesCount = 3 |
|
25 | LastRepliesCount = 3 | |
26 | ThreadsPerPage = 3 |
|
26 | ThreadsPerPage = 3 | |
|
27 | ImagesPerPageGallery = 20 | |||
27 |
|
28 | |||
28 | [Storage] |
|
29 | [Storage] | |
29 | # Enable archiving threads instead of deletion when the thread limit is reached |
|
30 | # Enable archiving threads instead of deletion when the thread limit is reached |
@@ -4,6 +4,7 b' from django.db import models' | |||||
4 | from django.db.models import Count |
|
4 | from django.db.models import Count | |
5 | from django.core.urlresolvers import reverse |
|
5 | from django.core.urlresolvers import reverse | |
6 |
|
6 | |||
|
7 | from boards.models import PostImage | |||
7 | from boards.models.base import Viewable |
|
8 | from boards.models.base import Viewable | |
8 | from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE |
|
9 | from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE | |
9 | from boards.utils import cached_result |
|
10 | from boards.utils import cached_result | |
@@ -140,3 +141,7 b' class Tag(models.Model, Viewable):' | |||||
140 |
|
141 | |||
141 | def get_children(self): |
|
142 | def get_children(self): | |
142 | return self.children |
|
143 | return self.children | |
|
144 | ||||
|
145 | def get_images(self): | |||
|
146 | return PostImage.objects.filter(post_images__thread__tags__in=[self])\ | |||
|
147 | .order_by('-post_images__pub_time') No newline at end of file |
@@ -71,6 +71,7 b'' | |||||
71 | <button name="method" value="hide" class="not_fav">H</button> |
|
71 | <button name="method" value="hide" class="not_fav">H</button> | |
72 | {% endif %} |
|
72 | {% endif %} | |
73 | </form> |
|
73 | </form> | |
|
74 | <a href="{% url 'tag_gallery' tag.name %}">{% trans 'Gallery' %}</a> | |||
74 | </p> |
|
75 | </p> | |
75 | {% if tag.get_description %} |
|
76 | {% if tag.get_description %} | |
76 | <p>{{ tag.get_description|safe }}</p> |
|
77 | <p>{{ tag.get_description|safe }}</p> |
@@ -8,11 +8,7 b'' | |||||
8 | {% block head %} |
|
8 | {% block head %} | |
9 | <meta name="robots" content="noindex"> |
|
9 | <meta name="robots" content="noindex"> | |
10 |
|
10 | |||
11 | {% if tag %} |
|
11 | <title>{{ tag.name }} - {% trans 'Gallery' %} - {{ site_name }}</title> | |
12 | <title>{{ tag.name }} - {{ site_name }}</title> |
|
|||
13 | {% else %} |
|
|||
14 | <title>{{ site_name }}</title> |
|
|||
15 | {% endif %} |
|
|||
16 |
|
12 | |||
17 | {% if prev_page_link %} |
|
13 | {% if prev_page_link %} | |
18 | <link rel="prev" href="{{ prev_page_link }}" /> |
|
14 | <link rel="prev" href="{{ prev_page_link }}" /> | |
@@ -36,7 +32,6 b'' | |||||
36 | </div> |
|
32 | </div> | |
37 | {% endfor %} |
|
33 | {% endfor %} | |
38 |
|
34 | |||
39 | {% if tag %} |
|
|||
40 | <div class="tag_info" style="border-bottom: solid .5ex #{{ tag.get_color }}"> |
|
35 | <div class="tag_info" style="border-bottom: solid .5ex #{{ tag.get_color }}"> | |
41 | {% if random_image_post %} |
|
36 | {% if random_image_post %} | |
42 | <div class="tag-image"> |
|
37 | <div class="tag-image"> | |
@@ -56,22 +51,6 b'' | |||||
56 | <span class="moderator_info">| <a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></span> |
|
51 | <span class="moderator_info">| <a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></span> | |
57 | {% endif %} |
|
52 | {% endif %} | |
58 | </h2> |
|
53 | </h2> | |
59 | <p> |
|
|||
60 | <form action="{% url 'tag' tag.name %}" method="post" class="post-button-form"> |
|
|||
61 | {% if is_favorite %} |
|
|||
62 | <button name="method" value="unsubscribe" class="fav">★</button> |
|
|||
63 | {% else %} |
|
|||
64 | <button name="method" value="subscribe" class="not_fav">★</button> |
|
|||
65 | {% endif %} |
|
|||
66 | </form> |
|
|||
67 | <form action="{% url 'tag' tag.name %}" method="post" class="post-button-form"> |
|
|||
68 | {% if is_hidden %} |
|
|||
69 | <button name="method" value="unhide" class="fav">H</button> |
|
|||
70 | {% else %} |
|
|||
71 | <button name="method" value="hide" class="not_fav">H</button> |
|
|||
72 | {% endif %} |
|
|||
73 | </form> |
|
|||
74 | </p> |
|
|||
75 | {% if tag.get_description %} |
|
54 | {% if tag.get_description %} | |
76 | <p>{{ tag.get_description|safe }}</p> |
|
55 | <p>{{ tag.get_description|safe }}</p> | |
77 | {% endif %} |
|
56 | {% endif %} | |
@@ -99,79 +78,29 b'' | |||||
99 | {% endif %} |
|
78 | {% endif %} | |
100 | </div> |
|
79 | </div> | |
101 | </div> |
|
80 | </div> | |
102 | {% endif %} |
|
|||
103 |
|
81 | |||
104 |
{% if |
|
82 | {% if prev_page_link %} | |
105 | {% if prev_page_link %} |
|
83 | <div class="page_link"> | |
106 | <div class="page_link"> |
|
84 | <a href="{{ prev_page_link }}">{% trans "Previous page" %}</a> | |
107 | <a href="{{ prev_page_link }}">{% trans "Previous page" %}</a> |
|
85 | </div> | |
108 | </div> |
|
|||
109 | {% endif %} |
|
|||
110 |
|
||||
111 | {% for thread in threads %} |
|
|||
112 | <div class="thread"> |
|
|||
113 | {% post_view thread.get_opening_post thread=thread truncated=True need_open_link=True %} |
|
|||
114 | {% if not thread.archived %} |
|
|||
115 | {% with last_replies=thread.get_last_replies %} |
|
|||
116 | {% if last_replies %} |
|
|||
117 | {% with skipped_replies_count=thread.get_skipped_replies_count %} |
|
|||
118 | {% if skipped_replies_count %} |
|
|||
119 | <div class="skipped_replies"> |
|
|||
120 | <a href="{% url 'thread' thread.get_opening_post_id %}"> |
|
|||
121 | {% blocktrans count count=skipped_replies_count %}Skipped {{ count }} reply. Open thread to see all replies.{% plural %}Skipped {{ count }} replies. Open thread to see all replies.{% endblocktrans %} |
|
|||
122 | </a> |
|
|||
123 | </div> |
|
|||
124 | {% endif %} |
|
|||
125 | {% endwith %} |
|
|||
126 | <div class="last-replies"> |
|
|||
127 | {% for post in last_replies %} |
|
|||
128 | {% post_view post truncated=True %} |
|
|||
129 | {% endfor %} |
|
|||
130 | </div> |
|
|||
131 | {% endif %} |
|
|||
132 | {% endwith %} |
|
|||
133 | {% endif %} |
|
|||
134 | </div> |
|
|||
135 | {% endfor %} |
|
|||
136 |
|
||||
137 | {% if next_page_link %} |
|
|||
138 | <div class="page_link"> |
|
|||
139 | <a href="{{ next_page_link }}">{% trans "Next page" %}</a> |
|
|||
140 | </div> |
|
|||
141 | {% endif %} |
|
|||
142 | {% else %} |
|
|||
143 | <div class="post"> |
|
|||
144 | {% trans 'No threads exist. Create the first one!' %}</div> |
|
|||
145 | {% endif %} |
|
86 | {% endif %} | |
146 |
|
87 | |||
147 | <div class="post-form-w"> |
|
88 | {% for image in images %} | |
148 | <script src="{% static 'js/panel.js' %}"></script> |
|
89 | <div class="gallery_image"> | |
149 | <div class="post-form"> |
|
90 | {% autoescape off %} | |
150 | <div class="form-title">{% trans "Create new thread" %}</div> |
|
91 | {{ image.get_view }} | |
151 | <div class="swappable-form-full"> |
|
92 | {% endautoescape %} | |
152 | <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %} |
|
93 | <div class="gallery_image_metadata"> | |
153 | {{ form.as_div }} |
|
94 | {{ image.width }}x{{ image.height }} | |
154 | <div class="form-submit"> |
|
|||
155 | <input type="submit" value="{% trans "Post" %}"/> |
|
|||
156 | <button id="preview-button" onclick="return false;">{% trans 'Preview' %}</button> |
|
|||
157 | </div> |
|
|||
158 | </form> |
|
|||
159 | </div> |
|
95 | </div> | |
160 | <div> |
|
|||
161 | {% trans 'Tags must be delimited by spaces. Text or image is required.' %} |
|
|||
162 | {% with size=max_file_size|filesizeformat %} |
|
|||
163 | {% blocktrans %}Max file size is {{ size }}.{% endblocktrans %} |
|
|||
164 | {% endwith %} |
|
|||
165 | </div> |
|
|||
166 | <div id="preview-text"></div> |
|
|||
167 | <div><a href="{% url "staticpage" name="help" %}">{% trans 'Text syntax' %}</a></div> |
|
|||
168 | <div><a href="{% url "tags" "required" %}">{% trans 'Tags' %}</a></div> |
|
|||
169 | </div> |
|
96 | </div> | |
170 | </div> |
|
97 | {% endfor %} | |
171 |
|
98 | |||
172 | <script src="{% static 'js/form.js' %}"></script> |
|
99 | {% if next_page_link %} | |
173 | <script src="{% static 'js/thread_create.js' %}"></script> |
|
100 | <div class="page_link"> | |
174 |
|
101 | <a href="{{ next_page_link }}">{% trans "Next page" %}</a> | ||
|
102 | </div> | |||
|
103 | {% endif %} | |||
175 | {% endblock %} |
|
104 | {% endblock %} | |
176 |
|
105 | |||
177 | {% block metapanel %} |
|
106 | {% block metapanel %} | |
@@ -186,7 +115,7 b'' | |||||
186 | …, |
|
115 | …, | |
187 | {% endif %} |
|
116 | {% endif %} | |
188 | <a |
|
117 | <a | |
189 |
{% ifequal page current_page |
|
118 | {% ifequal page paginator.current_page %} | |
190 | class="current_page" |
|
119 | class="current_page" | |
191 | {% endifequal %} |
|
120 | {% endifequal %} | |
192 | href="{% page_url paginator page %}">{{ page }}</a> |
|
121 | href="{% page_url paginator page %}">{{ page }}</a> |
@@ -11,6 +11,7 b' from boards.views.search import BoardSea' | |||||
11 | from boards.views.static import StaticPageView |
|
11 | from boards.views.static import StaticPageView | |
12 | from boards.views.preview import PostPreviewView |
|
12 | from boards.views.preview import PostPreviewView | |
13 | from boards.views.random import RandomImageView |
|
13 | from boards.views.random import RandomImageView | |
|
14 | from boards.views.tag_gallery import TagGalleryView | |||
14 | from boards.views.translation import cached_javascript_catalog |
|
15 | from boards.views.translation import cached_javascript_catalog | |
15 |
|
16 | |||
16 |
|
17 | |||
@@ -45,6 +46,7 b" urlpatterns = patterns(''," | |||||
45 | name='staticpage'), |
|
46 | name='staticpage'), | |
46 |
|
47 | |||
47 | url(r'^random/$', RandomImageView.as_view(), name='random'), |
|
48 | url(r'^random/$', RandomImageView.as_view(), name='random'), | |
|
49 | url(r'^tag/(?P<tag_name>\w+)/gallery/$', TagGalleryView.as_view(), name='tag_gallery'), | |||
48 |
|
50 | |||
49 | # RSS feeds |
|
51 | # RSS feeds | |
50 | url(r'^rss/$', AllThreadsFeed()), |
|
52 | url(r'^rss/$', AllThreadsFeed()), |
@@ -15,8 +15,7 b' from boards.models import Post, Thread, ' | |||||
15 | from boards.views.banned import BannedView |
|
15 | from boards.views.banned import BannedView | |
16 | from boards.views.base import BaseBoardView, CONTEXT_FORM |
|
16 | from boards.views.base import BaseBoardView, CONTEXT_FORM | |
17 | from boards.views.posting_mixin import PostMixin |
|
17 | from boards.views.posting_mixin import PostMixin | |
18 | from boards.views.mixins import FileUploadMixin |
|
18 | from boards.views.mixins import FileUploadMixin, PaginatedMixin | |
19 |
|
||||
20 |
|
19 | |||
21 | FORM_TAGS = 'tags' |
|
20 | FORM_TAGS = 'tags' | |
22 | FORM_TEXT = 'text' |
|
21 | FORM_TEXT = 'text' | |
@@ -34,14 +33,11 b" PARAMETER_ADDITIONAL = 'additional_param" | |||||
34 | PARAMETER_MAX_FILE_SIZE = 'max_file_size' |
|
33 | PARAMETER_MAX_FILE_SIZE = 'max_file_size' | |
35 | PARAMETER_RSS_URL = 'rss_url' |
|
34 | PARAMETER_RSS_URL = 'rss_url' | |
36 |
|
35 | |||
37 | PARAMETER_PREV_LINK = 'prev_page_link' |
|
|||
38 | PARAMETER_NEXT_LINK = 'next_page_link' |
|
|||
39 |
|
||||
40 | TEMPLATE = 'boards/all_threads.html' |
|
36 | TEMPLATE = 'boards/all_threads.html' | |
41 | DEFAULT_PAGE = 1 |
|
37 | DEFAULT_PAGE = 1 | |
42 |
|
38 | |||
43 |
|
39 | |||
44 | class AllThreadsView(PostMixin, FileUploadMixin, BaseBoardView): |
|
40 | class AllThreadsView(PostMixin, FileUploadMixin, BaseBoardView, PaginatedMixin): | |
45 |
|
41 | |||
46 | def __init__(self): |
|
42 | def __init__(self): | |
47 | self.settings_manager = None |
|
43 | self.settings_manager = None | |
@@ -106,12 +102,7 b' class AllThreadsView(PostMixin, FileUplo' | |||||
106 | params[PARAMETER_PAGINATOR] = paginator |
|
102 | params[PARAMETER_PAGINATOR] = paginator | |
107 | current_page = paginator.page(int(page)) |
|
103 | current_page = paginator.page(int(page)) | |
108 | params[PARAMETER_CURRENT_PAGE] = current_page |
|
104 | params[PARAMETER_CURRENT_PAGE] = current_page | |
109 | if current_page.has_previous(): |
|
105 | self.set_page_urls(paginator, params) | |
110 | params[PARAMETER_PREV_LINK] = paginator.get_page_url( |
|
|||
111 | current_page.previous_page_number()) |
|
|||
112 | if current_page.has_next(): |
|
|||
113 | params[PARAMETER_NEXT_LINK] = paginator.get_page_url( |
|
|||
114 | current_page.next_page_number()) |
|
|||
115 |
|
106 | |||
116 | def get_reverse_url(self): |
|
107 | def get_reverse_url(self): | |
117 | return reverse('index') |
|
108 | return reverse('index') |
@@ -32,3 +32,9 b' class DispatcherMixin:' | |||||
32 | class FileUploadMixin: |
|
32 | class FileUploadMixin: | |
33 | def get_max_upload_size(self): |
|
33 | def get_max_upload_size(self): | |
34 | return boards.settings.get_int('Forms', 'MaxFileSize') |
|
34 | return boards.settings.get_int('Forms', 'MaxFileSize') | |
|
35 | ||||
|
36 | ||||
|
37 | class PaginatedMixin: | |||
|
38 | def set_page_urls(self, paginator, params): | |||
|
39 | params['prev_page_link'] = paginator.get_prev_page_url() | |||
|
40 | params['next_page_link'] = paginator.get_next_page_url() |
General Comments 0
You need to be logged in to leave comments.
Login now