##// END OF EJS Templates
Added post admin page with tags edit capability
neko259 -
r566:f1e34d4b 1.7-dev
parent child Browse files
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 27 LABEL_TITLE = _('Title')
28 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 36 class FormatPanel(forms.Textarea):
@@ -311,3 +316,24 b' class LoginForm(NeboardForm):'
311 316 cleaned_data = super(LoginForm, self).clean()
312 317
313 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
@@ -7,7 +7,7 b' msgid ""'
7 7 msgstr ""
8 8 "Project-Id-Version: PACKAGE VERSION\n"
9 9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2014-01-15 10:46+0200\n"
10 "POT-Creation-Date: 2014-01-22 13:07+0200\n"
11 11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 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 58 msgid "Text"
59 59 msgstr "Текст"
60 60
61 #: forms.py:89
61 #: forms.py:29
62 msgid "Tag"
63 msgstr "Тег"
64
65 #: forms.py:106
62 66 msgid "Image"
63 67 msgstr "Изображение"
64 68
65 #: forms.py:92
69 #: forms.py:109
66 70 msgid "e-mail"
67 71 msgstr ""
68 72
69 #: forms.py:103
73 #: forms.py:120
70 74 #, python-format
71 75 msgid "Title must have less than %s characters"
72 76 msgstr "Заголовок должен иметь меньше %s символов"
73 77
74 #: forms.py:112
78 #: forms.py:129
75 79 #, python-format
76 80 msgid "Text must have less than %s characters"
77 81 msgstr "Текст должен быть короче %s символов"
78 82
79 #: forms.py:123
83 #: forms.py:140
80 84 #, python-format
81 85 msgid "Image must be less than %s bytes"
82 86 msgstr "Изображение должно быть менее %s байт"
83 87
84 #: forms.py:158
88 #: forms.py:175
85 89 msgid "Either text or image must be entered."
86 90 msgstr "Текст или картинка должны быть введены."
87 91
88 #: forms.py:171
92 #: forms.py:188
89 93 #, python-format
90 94 msgid "Wait %s seconds after last posting"
91 95 msgstr "Подождите %s секунд после последнего постинга"
92 96
93 #: forms.py:187 templates/boards/tags.html:6 templates/boards/rss/post.html:10
97 #: forms.py:204 templates/boards/tags.html:6 templates/boards/rss/post.html:10
94 98 msgid "Tags"
95 99 msgstr "Теги"
96 100
97 #: forms.py:195
101 #: forms.py:212 forms.py:331
98 102 msgid "Inappropriate characters in tags."
99 103 msgstr "Недопустимые символы в тегах."
100 104
101 #: forms.py:223 forms.py:244
105 #: forms.py:240 forms.py:261
102 106 msgid "Captcha validation failed"
103 107 msgstr "Проверка капчи провалена"
104 108
105 #: forms.py:250
109 #: forms.py:267
106 110 msgid "Theme"
107 111 msgstr "Тема"
108 112
109 #: forms.py:255
113 #: forms.py:272
110 114 msgid "Enable moderation panel"
111 115 msgstr "Включить панель модерации"
112 116
113 #: forms.py:270
117 #: forms.py:287
114 118 msgid "No such user found"
115 119 msgstr "Данный пользователь не найден"
116 120
117 #: forms.py:284
121 #: forms.py:301
118 122 #, python-format
119 123 msgid "Wait %s minutes after last login"
120 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 131 msgid "This page does not exist"
128 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 134 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
181 135 msgid "Authors"
182 136 msgstr "Авторы"
183 137
184 #: templates/boards/authors.html:25
138 #: templates/boards/authors.html:26
185 139 msgid "Distributed under the"
186 140 msgstr "Распространяется под"
187 141
188 #: templates/boards/authors.html:27
142 #: templates/boards/authors.html:28
189 143 msgid "license"
190 144 msgstr "лицензией"
191 145
192 #: templates/boards/authors.html:29
146 #: templates/boards/authors.html:30
193 147 msgid "Repository"
194 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 159 msgid "Tag management"
206 160 msgstr "Управление тегами"
207 161
208 #: templates/boards/base.html:38
162 #: templates/boards/base.html:38 templates/boards/settings.html:7
209 163 msgid "Settings"
210 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 168 msgid "Login"
215 169 msgstr "Вход"
216 170
171 #: templates/boards/base.html:51
172 msgid "Archive"
173 msgstr "Архив"
174
217 175 #: templates/boards/base.html:53
218 176 #, python-format
219 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 189 msgid "Insert your user id above"
232 190 msgstr "Вставьте свой ID пользователя выше"
233 191
234 #: templates/boards/posting_general.html:97
192 #: templates/boards/post.html:47
193 msgid "Open"
194 msgstr "Открыть"
195
196 #: templates/boards/post.html:49
235 197 msgid "Reply"
236 198 msgstr "Ответ"
237 199
238 #: templates/boards/posting_general.html:142
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 234 #, python-format
240 235 msgid "Skipped %(count)s replies. Open thread to see all replies."
241 236 msgstr "Пропущено %(count)s ответов. Откройте тред, чтобы увидеть все ответы."
242 237
243 #: templates/boards/posting_general.html:214
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 247 msgid "Create new thread"
245 248 msgstr "Создать новую тему"
246 249
247 #: templates/boards/posting_general.html:218 templates/boards/thread.html:115
250 #: templates/boards/posting_general.html:115 templates/boards/thread.html:50
248 251 msgid "Post"
249 252 msgstr "Отправить"
250 253
251 #: templates/boards/posting_general.html:222
254 #: templates/boards/posting_general.html:119
252 255 msgid "Tags must be delimited by spaces. Text or image is required."
253 256 msgstr ""
254 257 "Теги должны быть разделены пробелами. Текст или изображение обязательны."
255 258
256 #: templates/boards/posting_general.html:225 templates/boards/thread.html:119
259 #: templates/boards/posting_general.html:122 templates/boards/thread.html:54
257 260 msgid "Text syntax"
258 261 msgstr "Синтаксис текста"
259 262
263 #: templates/boards/posting_general.html:132
264 msgid "Pages:"
265 msgstr "Страницы: "
266
260 267 #: templates/boards/settings.html:14
261 268 msgid "User:"
262 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 292 msgid "No tags found."
286 293 msgstr "Теги не найдены."
287 294
288 #: templates/boards/thread.html:19 templates/boards/thread_gallery.html:20
295 #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:21
289 296 msgid "Normal mode"
290 297 msgstr "Нормальный режим"
291 298
292 #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:21
299 #: templates/boards/thread.html:21 templates/boards/thread_gallery.html:22
293 300 msgid "Gallery mode"
294 301 msgstr "Режим галереи"
295 302
296 #: templates/boards/thread.html:28
303 #: templates/boards/thread.html:29
297 304 msgid "posts to bumplimit"
298 305 msgstr "сообщений до бамплимита"
299 306
300 #: templates/boards/thread.html:109
307 #: templates/boards/thread.html:44
301 308 msgid "Reply to thread"
302 309 msgstr "Ответить в тему"
303 310
304 #: templates/boards/thread.html:139 templates/boards/thread_gallery.html:59
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 316 msgid "Last update: "
306 317 msgstr "Последнее обновление: "
307 318
@@ -10,7 +10,7 b' import hashlib'
10 10 from django.core.cache import cache
11 11 from django.core.paginator import Paginator
12 12
13 from django.db import models
13 from django.db import models, transaction
14 14 from django.http import Http404
15 15 from django.utils import timezone
16 16 from markupfield.fields import MarkupField
@@ -283,6 +283,30 b' class Post(models.Model):'
283 283 self.image_hash = md5.hexdigest()
284 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 311 class Thread(models.Model):
288 312
@@ -52,6 +52,8 b''
52 52
53 53 {% if moderator %}
54 54 <span class="moderator_info">
55 [<a href="{% url 'post_admin' post_id=post.id %}"
56 >{% trans 'Edit' %}</a>]
55 57 [<a href="{% url 'delete' post_id=post.id %}"
56 58 >{% trans 'Delete' %}</a>]
57 59 ({{ post.poster_ip }})
@@ -7,6 +7,7 b' from boards.views.authors import Authors'
7 7 from boards.views.delete_post import DeletePostView
8 8 from boards.views.ban import BanUserView
9 9 from boards.views.static import StaticPageView
10 from boards.views.post_admin import PostAdminView
10 11
11 12 js_info_dict = {
12 13 'packages': ('boards',),
@@ -40,6 +41,10 b" urlpatterns = patterns('',"
40 41 url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread.ThreadView
41 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 48 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
44 49 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
45 50 url(r'^captcha/', include('captcha.urls')),
@@ -60,7 +65,8 b" urlpatterns = patterns('',"
60 65 url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()),
61 66
62 67 # i18n
63 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, name='js_info_dict'),
68 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict,
69 name='js_info_dict'),
64 70
65 71 # API
66 72 url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"),
@@ -71,6 +77,7 b" urlpatterns = patterns('',"
71 77 url(r'^api/tags/$', api.api_get_tags, name='get_tags'),
72 78 url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts,
73 79 name='get_thread'),
74 url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, name='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 26 'method' request parameter.
27 27 """
28 28
29 def dispatch_method(self, request):
29 def dispatch_method(self, *args, **kwargs):
30 request = args[0]
31
32 method_name = None
30 33 if PARAMETER_METHOD in request.GET:
31 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