Show More
@@ -0,0 +1,38 b'' | |||||
|
1 | {% extends "boards/base.html" %} | |||
|
2 | ||||
|
3 | {% load i18n %} | |||
|
4 | {% load cache %} | |||
|
5 | {% load static from staticfiles %} | |||
|
6 | {% load board %} | |||
|
7 | ||||
|
8 | {% block head %} | |||
|
9 | <title>#{{ post.id }} - {{ site_name }}</title> | |||
|
10 | {% endblock %} | |||
|
11 | ||||
|
12 | {% block content %} | |||
|
13 | {% spaceless %} | |||
|
14 | ||||
|
15 | {% post_view post moderator=moderator %} | |||
|
16 | ||||
|
17 | {% if post.is_opening %} | |||
|
18 | <div class="post"> | |||
|
19 | {% trans 'Tags:' %} | |||
|
20 | {% for tag in post.thread_new.get_tags %} | |||
|
21 | <a class="tag" href={% url 'tag' tag.name %}>#{{ tag.name }}</a> | |||
|
22 | <a href="?method=delete_tag&tag={{ tag.name }}">[X]</a> | |||
|
23 | {% if not forloop.last %},{% endif %} | |||
|
24 | {% endfor %} | |||
|
25 | <div class="post-form-w"> | |||
|
26 | <form id="form" enctype="multipart/form-data" | |||
|
27 | method="post">{% csrf_token %} | |||
|
28 | {{ tag_form.as_div }} | |||
|
29 | <div class="form-submit"> | |||
|
30 | <input type="submit" value="{% trans "Add tag" %}"/> | |||
|
31 | </div> | |||
|
32 | </form> | |||
|
33 | </div> | |||
|
34 | </div> | |||
|
35 | {% endif %} | |||
|
36 | ||||
|
37 | {% endspaceless %} | |||
|
38 | {% endblock %} |
@@ -0,0 +1,57 b'' | |||||
|
1 | from django.shortcuts import render, get_object_or_404, redirect | |||
|
2 | ||||
|
3 | from boards.views.base import BaseBoardView | |||
|
4 | from boards.views.mixins import DispatcherMixin | |||
|
5 | from boards.models.post import Post | |||
|
6 | from boards.models.tag import Tag | |||
|
7 | from boards.forms import AddTagForm, PlainErrorList | |||
|
8 | ||||
|
9 | class PostAdminView(BaseBoardView, DispatcherMixin): | |||
|
10 | ||||
|
11 | def get(self, request, post_id, form=None): | |||
|
12 | user = self._get_user(request) | |||
|
13 | if not user.is_moderator: | |||
|
14 | redirect('index') | |||
|
15 | ||||
|
16 | post = get_object_or_404(Post, id=post_id) | |||
|
17 | ||||
|
18 | if not form: | |||
|
19 | dispatch_result = self.dispatch_method(request, post) | |||
|
20 | if dispatch_result: | |||
|
21 | return dispatch_result | |||
|
22 | form = AddTagForm() | |||
|
23 | ||||
|
24 | context = self.get_context_data(request=request) | |||
|
25 | ||||
|
26 | context['post'] = post | |||
|
27 | ||||
|
28 | context['tag_form'] = form | |||
|
29 | ||||
|
30 | return render(request, 'boards/post_admin.html', context) | |||
|
31 | ||||
|
32 | def post(self, request, post_id): | |||
|
33 | user = self._get_user(request) | |||
|
34 | if not user.is_moderator: | |||
|
35 | redirect('index') | |||
|
36 | ||||
|
37 | post = get_object_or_404(Post, id=post_id) | |||
|
38 | return self.dispatch_method(request, post) | |||
|
39 | ||||
|
40 | def delete_tag(self, request, post): | |||
|
41 | tag_name = request.GET['tag'] | |||
|
42 | tag = get_object_or_404(Tag, name=tag_name) | |||
|
43 | ||||
|
44 | post.remove_tag(tag) | |||
|
45 | ||||
|
46 | return redirect('post_admin', post.id) | |||
|
47 | ||||
|
48 | def add_tag(self, request, post): | |||
|
49 | form = AddTagForm(request.POST, error_class=PlainErrorList) | |||
|
50 | if form.is_valid(): | |||
|
51 | tag_name = form.cleaned_data['tag'] | |||
|
52 | tag, created = Tag.objects.get_or_create(name=tag_name) | |||
|
53 | ||||
|
54 | post.add_tag(tag) | |||
|
55 | return redirect('post_admin', post.id) | |||
|
56 | else: | |||
|
57 | return self.get(request, post.id, form) |
@@ -26,6 +26,11 b" ERROR_IMAGE_DUPLICATE = _('Such image wa" | |||||
26 |
|
26 | |||
27 | LABEL_TITLE = _('Title') |
|
27 | LABEL_TITLE = _('Title') | |
28 | LABEL_TEXT = _('Text') |
|
28 | LABEL_TEXT = _('Text') | |
|
29 | LABEL_TAG = _('Tag') | |||
|
30 | ||||
|
31 | TAG_MAX_LENGTH = 20 | |||
|
32 | ||||
|
33 | REGEX_TAG = ur'^[\w\d]+$' | |||
29 |
|
34 | |||
30 |
|
35 | |||
31 | class FormatPanel(forms.Textarea): |
|
36 | class FormatPanel(forms.Textarea): | |
@@ -311,3 +316,24 b' class LoginForm(NeboardForm):' | |||||
311 | cleaned_data = super(LoginForm, self).clean() |
|
316 | cleaned_data = super(LoginForm, self).clean() | |
312 |
|
317 | |||
313 | return cleaned_data |
|
318 | return cleaned_data | |
|
319 | ||||
|
320 | ||||
|
321 | class AddTagForm(NeboardForm): | |||
|
322 | ||||
|
323 | tag = forms.CharField(max_length=TAG_MAX_LENGTH, label=LABEL_TAG) | |||
|
324 | method = forms.CharField(widget=forms.HiddenInput(), initial='add_tag') | |||
|
325 | ||||
|
326 | def clean_tag(self): | |||
|
327 | tag = self.cleaned_data['tag'] | |||
|
328 | ||||
|
329 | regex_tag = re.compile(REGEX_TAG, re.UNICODE) | |||
|
330 | if not regex_tag.match(tag): | |||
|
331 | raise forms.ValidationError(_('Inappropriate characters in tags.')) | |||
|
332 | ||||
|
333 | return tag | |||
|
334 | ||||
|
335 | def clean(self): | |||
|
336 | cleaned_data = super(AddTagForm, self).clean() | |||
|
337 | ||||
|
338 | return cleaned_data | |||
|
339 |
1 | NO CONTENT: modified file, binary diff hidden |
|
NO CONTENT: modified file, binary diff hidden |
@@ -7,7 +7,7 b' msgid ""' | |||||
7 | msgstr "" |
|
7 | msgstr "" | |
8 | "Project-Id-Version: PACKAGE VERSION\n" |
|
8 | "Project-Id-Version: PACKAGE VERSION\n" | |
9 | "Report-Msgid-Bugs-To: \n" |
|
9 | "Report-Msgid-Bugs-To: \n" | |
10 |
"POT-Creation-Date: 2014-01- |
|
10 | "POT-Creation-Date: 2014-01-22 13:07+0200\n" | |
11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|
11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |
12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
|
12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
|
13 | "Language-Team: LANGUAGE <LL@li.org>\n" | |
@@ -58,63 +58,67 b' msgstr "\xd0\x97\xd0\xb0\xd0\xb3\xd0\xbe\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xbe\xd0\xba"' | |||||
58 | msgid "Text" |
|
58 | msgid "Text" | |
59 | msgstr "Текст" |
|
59 | msgstr "Текст" | |
60 |
|
60 | |||
61 |
#: forms.py: |
|
61 | #: forms.py:29 | |
|
62 | msgid "Tag" | |||
|
63 | msgstr "Тег" | |||
|
64 | ||||
|
65 | #: forms.py:106 | |||
62 | msgid "Image" |
|
66 | msgid "Image" | |
63 | msgstr "Изображение" |
|
67 | msgstr "Изображение" | |
64 |
|
68 | |||
65 |
#: forms.py:9 |
|
69 | #: forms.py:109 | |
66 | msgid "e-mail" |
|
70 | msgid "e-mail" | |
67 | msgstr "" |
|
71 | msgstr "" | |
68 |
|
72 | |||
69 |
#: forms.py:10 |
|
73 | #: forms.py:120 | |
70 | #, python-format |
|
74 | #, python-format | |
71 | msgid "Title must have less than %s characters" |
|
75 | msgid "Title must have less than %s characters" | |
72 | msgstr "Заголовок должен иметь меньше %s символов" |
|
76 | msgstr "Заголовок должен иметь меньше %s символов" | |
73 |
|
77 | |||
74 |
#: forms.py:1 |
|
78 | #: forms.py:129 | |
75 | #, python-format |
|
79 | #, python-format | |
76 | msgid "Text must have less than %s characters" |
|
80 | msgid "Text must have less than %s characters" | |
77 | msgstr "Текст должен быть короче %s символов" |
|
81 | msgstr "Текст должен быть короче %s символов" | |
78 |
|
82 | |||
79 |
#: forms.py:1 |
|
83 | #: forms.py:140 | |
80 | #, python-format |
|
84 | #, python-format | |
81 | msgid "Image must be less than %s bytes" |
|
85 | msgid "Image must be less than %s bytes" | |
82 | msgstr "Изображение должно быть менее %s байт" |
|
86 | msgstr "Изображение должно быть менее %s байт" | |
83 |
|
87 | |||
84 |
#: forms.py:15 |
|
88 | #: forms.py:175 | |
85 | msgid "Either text or image must be entered." |
|
89 | msgid "Either text or image must be entered." | |
86 | msgstr "Текст или картинка должны быть введены." |
|
90 | msgstr "Текст или картинка должны быть введены." | |
87 |
|
91 | |||
88 |
#: forms.py:1 |
|
92 | #: forms.py:188 | |
89 | #, python-format |
|
93 | #, python-format | |
90 | msgid "Wait %s seconds after last posting" |
|
94 | msgid "Wait %s seconds after last posting" | |
91 | msgstr "Подождите %s секунд после последнего постинга" |
|
95 | msgstr "Подождите %s секунд после последнего постинга" | |
92 |
|
96 | |||
93 |
#: forms.py: |
|
97 | #: forms.py:204 templates/boards/tags.html:6 templates/boards/rss/post.html:10 | |
94 | msgid "Tags" |
|
98 | msgid "Tags" | |
95 | msgstr "Теги" |
|
99 | msgstr "Теги" | |
96 |
|
100 | |||
97 |
#: forms.py: |
|
101 | #: forms.py:212 forms.py:331 | |
98 | msgid "Inappropriate characters in tags." |
|
102 | msgid "Inappropriate characters in tags." | |
99 | msgstr "Недопустимые символы в тегах." |
|
103 | msgstr "Недопустимые символы в тегах." | |
100 |
|
104 | |||
101 |
#: forms.py:2 |
|
105 | #: forms.py:240 forms.py:261 | |
102 | msgid "Captcha validation failed" |
|
106 | msgid "Captcha validation failed" | |
103 | msgstr "Проверка капчи провалена" |
|
107 | msgstr "Проверка капчи провалена" | |
104 |
|
108 | |||
105 |
#: forms.py:2 |
|
109 | #: forms.py:267 | |
106 | msgid "Theme" |
|
110 | msgid "Theme" | |
107 | msgstr "Тема" |
|
111 | msgstr "Тема" | |
108 |
|
112 | |||
109 |
#: forms.py:2 |
|
113 | #: forms.py:272 | |
110 | msgid "Enable moderation panel" |
|
114 | msgid "Enable moderation panel" | |
111 | msgstr "Включить панель модерации" |
|
115 | msgstr "Включить панель модерации" | |
112 |
|
116 | |||
113 |
#: forms.py:27 |
|
117 | #: forms.py:287 | |
114 | msgid "No such user found" |
|
118 | msgid "No such user found" | |
115 | msgstr "Данный пользователь не найден" |
|
119 | msgstr "Данный пользователь не найден" | |
116 |
|
120 | |||
117 |
#: forms.py: |
|
121 | #: forms.py:301 | |
118 | #, python-format |
|
122 | #, python-format | |
119 | msgid "Wait %s minutes after last login" |
|
123 | msgid "Wait %s minutes after last login" | |
120 | msgstr "Подождите %s минут после последнего входа" |
|
124 | msgstr "Подождите %s минут после последнего входа" | |
@@ -127,69 +131,19 b' msgstr "\xd0\x9d\xd0\xb5 \xd0\xbd\xd0\xb0\xd0\xb9\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xbe"' | |||||
127 | msgid "This page does not exist" |
|
131 | msgid "This page does not exist" | |
128 | msgstr "Этой страницы не существует" |
|
132 | msgstr "Этой страницы не существует" | |
129 |
|
133 | |||
130 | #: templates/boards/archive.html:9 templates/boards/base.html:51 |
|
|||
131 | msgid "Archive" |
|
|||
132 | msgstr "Архив" |
|
|||
133 |
|
||||
134 | #: templates/boards/archive.html:39 templates/boards/posting_general.html:64 |
|
|||
135 | msgid "Previous page" |
|
|||
136 | msgstr "Предыдущая страница" |
|
|||
137 |
|
||||
138 | #: templates/boards/archive.html:68 |
|
|||
139 | msgid "Open" |
|
|||
140 | msgstr "Открыть" |
|
|||
141 |
|
||||
142 | #: templates/boards/archive.html:74 templates/boards/post.html:37 |
|
|||
143 | #: templates/boards/posting_general.html:103 templates/boards/thread.html:69 |
|
|||
144 | msgid "Delete" |
|
|||
145 | msgstr "Удалить" |
|
|||
146 |
|
||||
147 | #: templates/boards/archive.html:78 templates/boards/post.html:40 |
|
|||
148 | #: templates/boards/posting_general.html:107 templates/boards/thread.html:72 |
|
|||
149 | msgid "Ban IP" |
|
|||
150 | msgstr "Заблокировать IP" |
|
|||
151 |
|
||||
152 | #: templates/boards/archive.html:87 templates/boards/post.html:53 |
|
|||
153 | #: templates/boards/posting_general.html:116 |
|
|||
154 | #: templates/boards/posting_general.html:180 templates/boards/thread.html:81 |
|
|||
155 | msgid "Replies" |
|
|||
156 | msgstr "Ответы" |
|
|||
157 |
|
||||
158 | #: templates/boards/archive.html:96 templates/boards/posting_general.html:125 |
|
|||
159 | #: templates/boards/thread.html:138 templates/boards/thread_gallery.html:58 |
|
|||
160 | msgid "images" |
|
|||
161 | msgstr "изображений" |
|
|||
162 |
|
||||
163 | #: templates/boards/archive.html:97 templates/boards/thread.html:137 |
|
|||
164 | #: templates/boards/thread_gallery.html:57 |
|
|||
165 | msgid "replies" |
|
|||
166 | msgstr "ответов" |
|
|||
167 |
|
||||
168 | #: templates/boards/archive.html:116 templates/boards/posting_general.html:203 |
|
|||
169 | msgid "Next page" |
|
|||
170 | msgstr "Следующая страница" |
|
|||
171 |
|
||||
172 | #: templates/boards/archive.html:121 templates/boards/posting_general.html:208 |
|
|||
173 | msgid "No threads exist. Create the first one!" |
|
|||
174 | msgstr "Нет тем. Создайте первую!" |
|
|||
175 |
|
||||
176 | #: templates/boards/archive.html:130 templates/boards/posting_general.html:235 |
|
|||
177 | msgid "Pages:" |
|
|||
178 | msgstr "Страницы: " |
|
|||
179 |
|
||||
180 | #: templates/boards/authors.html:6 templates/boards/authors.html.py:12 |
|
134 | #: templates/boards/authors.html:6 templates/boards/authors.html.py:12 | |
181 | msgid "Authors" |
|
135 | msgid "Authors" | |
182 | msgstr "Авторы" |
|
136 | msgstr "Авторы" | |
183 |
|
137 | |||
184 |
#: templates/boards/authors.html:2 |
|
138 | #: templates/boards/authors.html:26 | |
185 | msgid "Distributed under the" |
|
139 | msgid "Distributed under the" | |
186 | msgstr "Распространяется под" |
|
140 | msgstr "Распространяется под" | |
187 |
|
141 | |||
188 |
#: templates/boards/authors.html:2 |
|
142 | #: templates/boards/authors.html:28 | |
189 | msgid "license" |
|
143 | msgid "license" | |
190 | msgstr "лицензией" |
|
144 | msgstr "лицензией" | |
191 |
|
145 | |||
192 |
#: templates/boards/authors.html: |
|
146 | #: templates/boards/authors.html:30 | |
193 | msgid "Repository" |
|
147 | msgid "Repository" | |
194 | msgstr "Репозиторий" |
|
148 | msgstr "Репозиторий" | |
195 |
|
149 | |||
@@ -205,7 +159,7 b' msgstr "\xd0\x92\xd1\x81\xd0\xb5 \xd1\x82\xd0\xb5\xd0\xbc\xd1\x8b"' | |||||
205 | msgid "Tag management" |
|
159 | msgid "Tag management" | |
206 | msgstr "Управление тегами" |
|
160 | msgstr "Управление тегами" | |
207 |
|
161 | |||
208 | #: templates/boards/base.html:38 |
|
162 | #: templates/boards/base.html:38 templates/boards/settings.html:7 | |
209 | msgid "Settings" |
|
163 | msgid "Settings" | |
210 | msgstr "Настройки" |
|
164 | msgstr "Настройки" | |
211 |
|
165 | |||
@@ -214,6 +168,10 b' msgstr "\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8"' | |||||
214 | msgid "Login" |
|
168 | msgid "Login" | |
215 | msgstr "Вход" |
|
169 | msgstr "Вход" | |
216 |
|
170 | |||
|
171 | #: templates/boards/base.html:51 | |||
|
172 | msgid "Archive" | |||
|
173 | msgstr "Архив" | |||
|
174 | ||||
217 | #: templates/boards/base.html:53 |
|
175 | #: templates/boards/base.html:53 | |
218 | #, python-format |
|
176 | #, python-format | |
219 | msgid "Speed: %(ppd)s posts per day" |
|
177 | msgid "Speed: %(ppd)s posts per day" | |
@@ -231,32 +189,81 b' msgstr "ID \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x8c\xd0\xb7\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8f"' | |||||
231 | msgid "Insert your user id above" |
|
189 | msgid "Insert your user id above" | |
232 | msgstr "Вставьте свой ID пользователя выше" |
|
190 | msgstr "Вставьте свой ID пользователя выше" | |
233 |
|
191 | |||
234 |
#: templates/boards/post |
|
192 | #: templates/boards/post.html:47 | |
|
193 | msgid "Open" | |||
|
194 | msgstr "Открыть" | |||
|
195 | ||||
|
196 | #: templates/boards/post.html:49 | |||
235 | msgid "Reply" |
|
197 | msgid "Reply" | |
236 | msgstr "Ответ" |
|
198 | msgstr "Ответ" | |
237 |
|
199 | |||
238 |
#: templates/boards/post |
|
200 | #: templates/boards/post.html:56 | |
|
201 | msgid "Edit" | |||
|
202 | msgstr "Изменить" | |||
|
203 | ||||
|
204 | #: templates/boards/post.html:58 | |||
|
205 | msgid "Delete" | |||
|
206 | msgstr "Удалить" | |||
|
207 | ||||
|
208 | #: templates/boards/post.html:61 | |||
|
209 | msgid "Ban IP" | |||
|
210 | msgstr "Заблокировать IP" | |||
|
211 | ||||
|
212 | #: templates/boards/post.html:74 | |||
|
213 | msgid "Replies" | |||
|
214 | msgstr "Ответы" | |||
|
215 | ||||
|
216 | #: templates/boards/post.html:85 templates/boards/thread.html:74 | |||
|
217 | #: templates/boards/thread_gallery.html:59 | |||
|
218 | msgid "images" | |||
|
219 | msgstr "изображений" | |||
|
220 | ||||
|
221 | #: templates/boards/post_admin.html:19 | |||
|
222 | msgid "Tags:" | |||
|
223 | msgstr "Теги:" | |||
|
224 | ||||
|
225 | #: templates/boards/post_admin.html:30 | |||
|
226 | msgid "Add tag" | |||
|
227 | msgstr "Добавить тег" | |||
|
228 | ||||
|
229 | #: templates/boards/posting_general.html:64 | |||
|
230 | msgid "Previous page" | |||
|
231 | msgstr "Предыдущая страница" | |||
|
232 | ||||
|
233 | #: templates/boards/posting_general.html:77 | |||
239 | #, python-format |
|
234 | #, python-format | |
240 | msgid "Skipped %(count)s replies. Open thread to see all replies." |
|
235 | msgid "Skipped %(count)s replies. Open thread to see all replies." | |
241 | msgstr "Пропущено %(count)s ответов. Откройте тред, чтобы увидеть все ответы." |
|
236 | msgstr "Пропущено %(count)s ответов. Откройте тред, чтобы увидеть все ответы." | |
242 |
|
237 | |||
243 |
#: templates/boards/posting_general.html: |
|
238 | #: templates/boards/posting_general.html:100 | |
|
239 | msgid "Next page" | |||
|
240 | msgstr "Следующая страница" | |||
|
241 | ||||
|
242 | #: templates/boards/posting_general.html:105 | |||
|
243 | msgid "No threads exist. Create the first one!" | |||
|
244 | msgstr "Нет тем. Создайте первую!" | |||
|
245 | ||||
|
246 | #: templates/boards/posting_general.html:111 | |||
244 | msgid "Create new thread" |
|
247 | msgid "Create new thread" | |
245 | msgstr "Создать новую тему" |
|
248 | msgstr "Создать новую тему" | |
246 |
|
249 | |||
247 |
#: templates/boards/posting_general.html: |
|
250 | #: templates/boards/posting_general.html:115 templates/boards/thread.html:50 | |
248 | msgid "Post" |
|
251 | msgid "Post" | |
249 | msgstr "Отправить" |
|
252 | msgstr "Отправить" | |
250 |
|
253 | |||
251 |
#: templates/boards/posting_general.html: |
|
254 | #: templates/boards/posting_general.html:119 | |
252 | msgid "Tags must be delimited by spaces. Text or image is required." |
|
255 | msgid "Tags must be delimited by spaces. Text or image is required." | |
253 | msgstr "" |
|
256 | msgstr "" | |
254 | "Теги должны быть разделены пробелами. Текст или изображение обязательны." |
|
257 | "Теги должны быть разделены пробелами. Текст или изображение обязательны." | |
255 |
|
258 | |||
256 |
#: templates/boards/posting_general.html:22 |
|
259 | #: templates/boards/posting_general.html:122 templates/boards/thread.html:54 | |
257 | msgid "Text syntax" |
|
260 | msgid "Text syntax" | |
258 | msgstr "Синтаксис текста" |
|
261 | msgstr "Синтаксис текста" | |
259 |
|
262 | |||
|
263 | #: templates/boards/posting_general.html:132 | |||
|
264 | msgid "Pages:" | |||
|
265 | msgstr "Страницы: " | |||
|
266 | ||||
260 | #: templates/boards/settings.html:14 |
|
267 | #: templates/boards/settings.html:14 | |
261 | msgid "User:" |
|
268 | msgid "User:" | |
262 | msgstr "Пользователь:" |
|
269 | msgstr "Пользователь:" | |
@@ -285,23 +292,27 b' msgstr "\xd0\xa1\xd0\xbe\xd1\x85\xd1\x80\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8c"' | |||||
285 | msgid "No tags found." |
|
292 | msgid "No tags found." | |
286 | msgstr "Теги не найдены." |
|
293 | msgstr "Теги не найдены." | |
287 |
|
294 | |||
288 |
#: templates/boards/thread.html: |
|
295 | #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:21 | |
289 | msgid "Normal mode" |
|
296 | msgid "Normal mode" | |
290 | msgstr "Нормальный режим" |
|
297 | msgstr "Нормальный режим" | |
291 |
|
298 | |||
292 |
#: templates/boards/thread.html:2 |
|
299 | #: templates/boards/thread.html:21 templates/boards/thread_gallery.html:22 | |
293 | msgid "Gallery mode" |
|
300 | msgid "Gallery mode" | |
294 | msgstr "Режим галереи" |
|
301 | msgstr "Режим галереи" | |
295 |
|
302 | |||
296 |
#: templates/boards/thread.html:2 |
|
303 | #: templates/boards/thread.html:29 | |
297 | msgid "posts to bumplimit" |
|
304 | msgid "posts to bumplimit" | |
298 | msgstr "сообщений до бамплимита" |
|
305 | msgstr "сообщений до бамплимита" | |
299 |
|
306 | |||
300 |
#: templates/boards/thread.html: |
|
307 | #: templates/boards/thread.html:44 | |
301 | msgid "Reply to thread" |
|
308 | msgid "Reply to thread" | |
302 | msgstr "Ответить в тему" |
|
309 | msgstr "Ответить в тему" | |
303 |
|
310 | |||
304 |
#: templates/boards/thread.html: |
|
311 | #: templates/boards/thread.html:73 templates/boards/thread_gallery.html:58 | |
|
312 | msgid "replies" | |||
|
313 | msgstr "ответов" | |||
|
314 | ||||
|
315 | #: templates/boards/thread.html:75 templates/boards/thread_gallery.html:60 | |||
305 | msgid "Last update: " |
|
316 | msgid "Last update: " | |
306 | msgstr "Последнее обновление: " |
|
317 | msgstr "Последнее обновление: " | |
307 |
|
318 |
@@ -10,7 +10,7 b' import hashlib' | |||||
10 | from django.core.cache import cache |
|
10 | from django.core.cache import cache | |
11 | from django.core.paginator import Paginator |
|
11 | from django.core.paginator import Paginator | |
12 |
|
12 | |||
13 | from django.db import models |
|
13 | from django.db import models, transaction | |
14 | from django.http import Http404 |
|
14 | from django.http import Http404 | |
15 | from django.utils import timezone |
|
15 | from django.utils import timezone | |
16 | from markupfield.fields import MarkupField |
|
16 | from markupfield.fields import MarkupField | |
@@ -283,6 +283,30 b' class Post(models.Model):' | |||||
283 | self.image_hash = md5.hexdigest() |
|
283 | self.image_hash = md5.hexdigest() | |
284 | super(Post, self).save(*args, **kwargs) |
|
284 | super(Post, self).save(*args, **kwargs) | |
285 |
|
285 | |||
|
286 | @transaction.atomic | |||
|
287 | def add_tag(self, tag): | |||
|
288 | edit_time = timezone.now() | |||
|
289 | ||||
|
290 | thread = self.thread_new | |||
|
291 | thread.add_tag(tag) | |||
|
292 | self.last_edit_time = edit_time | |||
|
293 | self.save() | |||
|
294 | ||||
|
295 | thread.last_edit_time = edit_time | |||
|
296 | thread.save() | |||
|
297 | ||||
|
298 | @transaction.atomic | |||
|
299 | def remove_tag(self, tag): | |||
|
300 | edit_time = timezone.now() | |||
|
301 | ||||
|
302 | thread = self.thread_new | |||
|
303 | thread.tags.remove(tag) | |||
|
304 | self.last_edit_time = edit_time | |||
|
305 | self.save() | |||
|
306 | ||||
|
307 | thread.last_edit_time = edit_time | |||
|
308 | thread.save() | |||
|
309 | ||||
286 |
|
310 | |||
287 | class Thread(models.Model): |
|
311 | class Thread(models.Model): | |
288 |
|
312 |
@@ -52,6 +52,8 b'' | |||||
52 |
|
52 | |||
53 | {% if moderator %} |
|
53 | {% if moderator %} | |
54 | <span class="moderator_info"> |
|
54 | <span class="moderator_info"> | |
|
55 | [<a href="{% url 'post_admin' post_id=post.id %}" | |||
|
56 | >{% trans 'Edit' %}</a>] | |||
55 | [<a href="{% url 'delete' post_id=post.id %}" |
|
57 | [<a href="{% url 'delete' post_id=post.id %}" | |
56 | >{% trans 'Delete' %}</a>] |
|
58 | >{% trans 'Delete' %}</a>] | |
57 | ({{ post.poster_ip }}) |
|
59 | ({{ post.poster_ip }}) |
@@ -7,6 +7,7 b' from boards.views.authors import Authors' | |||||
7 | from boards.views.delete_post import DeletePostView |
|
7 | from boards.views.delete_post import DeletePostView | |
8 | from boards.views.ban import BanUserView |
|
8 | from boards.views.ban import BanUserView | |
9 | from boards.views.static import StaticPageView |
|
9 | from boards.views.static import StaticPageView | |
|
10 | from boards.views.post_admin import PostAdminView | |||
10 |
|
11 | |||
11 | js_info_dict = { |
|
12 | js_info_dict = { | |
12 | 'packages': ('boards',), |
|
13 | 'packages': ('boards',), | |
@@ -40,17 +41,21 b" urlpatterns = patterns(''," | |||||
40 | url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread.ThreadView |
|
41 | url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread.ThreadView | |
41 | .as_view(), name='thread_mode'), |
|
42 | .as_view(), name='thread_mode'), | |
42 |
|
43 | |||
|
44 | # /boards/post_admin/ | |||
|
45 | url(r'^post_admin/(?P<post_id>\w+)/$', PostAdminView.as_view(), | |||
|
46 | name='post_admin'), | |||
|
47 | ||||
43 | url(r'^settings/$', settings.SettingsView.as_view(), name='settings'), |
|
48 | url(r'^settings/$', settings.SettingsView.as_view(), name='settings'), | |
44 | url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'), |
|
49 | url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'), | |
45 | url(r'^captcha/', include('captcha.urls')), |
|
50 | url(r'^captcha/', include('captcha.urls')), | |
46 | url(r'^authors/$', AuthorsView.as_view(), name='authors'), |
|
51 | url(r'^authors/$', AuthorsView.as_view(), name='authors'), | |
47 | url(r'^delete/(?P<post_id>\w+)/$', DeletePostView.as_view(), |
|
52 | url(r'^delete/(?P<post_id>\w+)/$', DeletePostView.as_view(), | |
48 | name='delete'), |
|
53 | name='delete'), | |
49 | url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'), |
|
54 | url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'), | |
50 |
|
55 | |||
51 | url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'), |
|
56 | url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'), | |
52 | url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(), |
|
57 | url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(), | |
53 | name='staticpage'), |
|
58 | name='staticpage'), | |
54 |
|
59 | |||
55 | # RSS feeds |
|
60 | # RSS feeds | |
56 | url(r'^rss/$', AllThreadsFeed()), |
|
61 | url(r'^rss/$', AllThreadsFeed()), | |
@@ -60,7 +65,8 b" urlpatterns = patterns(''," | |||||
60 | url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()), |
|
65 | url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()), | |
61 |
|
66 | |||
62 | # i18n |
|
67 | # i18n | |
63 |
url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, |
|
68 | url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, | |
|
69 | name='js_info_dict'), | |||
64 |
|
70 | |||
65 | # API |
|
71 | # API | |
66 | url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"), |
|
72 | url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"), | |
@@ -71,6 +77,7 b" urlpatterns = patterns(''," | |||||
71 | url(r'^api/tags/$', api.api_get_tags, name='get_tags'), |
|
77 | url(r'^api/tags/$', api.api_get_tags, name='get_tags'), | |
72 | url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts, |
|
78 | url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts, | |
73 | name='get_thread'), |
|
79 | name='get_thread'), | |
74 |
url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, |
|
80 | url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, | |
|
81 | name='add_post'), | |||
75 |
|
82 | |||
76 | ) |
|
83 | ) |
@@ -26,8 +26,14 b' class DispatcherMixin:' | |||||
26 | 'method' request parameter. |
|
26 | 'method' request parameter. | |
27 | """ |
|
27 | """ | |
28 |
|
28 | |||
29 |
def dispatch_method(self, |
|
29 | def dispatch_method(self, *args, **kwargs): | |
|
30 | request = args[0] | |||
|
31 | ||||
|
32 | method_name = None | |||
30 | if PARAMETER_METHOD in request.GET: |
|
33 | if PARAMETER_METHOD in request.GET: | |
31 | method_name = request.GET[PARAMETER_METHOD] |
|
34 | method_name = request.GET[PARAMETER_METHOD] | |
32 | return getattr(self, method_name)(request) |
|
35 | elif PARAMETER_METHOD in request.POST: | |
|
36 | method_name = request.POST[PARAMETER_METHOD] | |||
33 |
|
37 | |||
|
38 | if method_name: | |||
|
39 | return getattr(self, method_name)(*args, **kwargs) |
General Comments 0
You need to be logged in to leave comments.
Login now