##// END OF EJS Templates
Added a form field for additional threads list in multi-thread posts
neko259 -
r1077:216451f2 default
parent child Browse files
Show More
@@ -4,13 +4,14 b' import pytz'
4
4
5 from django import forms
5 from django import forms
6 from django.core.files.uploadedfile import SimpleUploadedFile
6 from django.core.files.uploadedfile import SimpleUploadedFile
7 from django.core.exceptions import ObjectDoesNotExist
7 from django.forms.util import ErrorList
8 from django.forms.util import ErrorList
8 from django.utils.translation import ugettext_lazy as _
9 from django.utils.translation import ugettext_lazy as _
9 import requests
10 import requests
10
11
11 from boards.mdx_neboard import formatters
12 from boards.mdx_neboard import formatters
12 from boards.models.post import TITLE_MAX_LENGTH
13 from boards.models.post import TITLE_MAX_LENGTH
13 from boards.models import Tag
14 from boards.models import Tag, Post
14 from neboard import settings
15 from neboard import settings
15 import boards.settings as board_settings
16 import boards.settings as board_settings
16
17
@@ -148,6 +149,9 b' class PostForm(NeboardForm):'
148 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
149 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
149 widget=forms.TextInput(attrs={
150 widget=forms.TextInput(attrs={
150 'class': 'form-email'}))
151 'class': 'form-email'}))
152 threads = forms.CharField(required=False, label=_('Additional threads'),
153 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER:
154 '123 456 789'}))
151
155
152 session = None
156 session = None
153 need_to_ban = False
157 need_to_ban = False
@@ -193,6 +197,25 b' class PostForm(NeboardForm):'
193
197
194 return image
198 return image
195
199
200 def clean_threads(self):
201 threads_str = self.cleaned_data['threads']
202
203 if len(threads_str) > 0:
204 threads_id_list = threads_str.split(' ')
205
206 threads = list()
207
208 for thread_id in threads_id_list:
209 try:
210 thread = Post.objects.get(id=int(thread_id))
211 if not thread.is_opening():
212 raise ObjectDoesNotExist()
213 threads.append(thread)
214 except (ObjectDoesNotExist, ValueError):
215 raise forms.ValidationError(_('Invalid additional thread list'))
216
217 return threads
218
196 def clean(self):
219 def clean(self):
197 cleaned_data = super(PostForm, self).clean()
220 cleaned_data = super(PostForm, self).clean()
198
221
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: 2015-04-01 18:05+0300\n"
10 "POT-Creation-Date: 2015-04-07 15:26+0300\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"
@@ -38,97 +38,106 b' msgstr "\xd1\x80\xd0\xb0\xd0\xb7\xd1\x80\xd0\xb0\xd0\xb1\xd0\xbe\xd1\x82\xd1\x87\xd0\xb8\xd0\xba javascript"'
38 msgid "designer"
38 msgid "designer"
39 msgstr "дизайнер"
39 msgstr "дизайнер"
40
40
41 #: forms.py:34
41 #: forms.py:35
42 msgid "Type message here. Use formatting panel for more advanced usage."
42 msgid "Type message here. Use formatting panel for more advanced usage."
43 msgstr ""
43 msgstr ""
44 "Вводите сообщение сюда. Используйте панель для более сложного форматирования."
44 "Вводите сообщение сюда. Используйте панель для более сложного форматирования."
45
45
46 #: forms.py:35
46 #: forms.py:36
47 msgid "tag1 several_words_tag"
47 msgid "tag1 several_words_tag"
48 msgstr "метка1 метка_из_нескольких_слов"
48 msgstr "метка1 метка_из_нескольких_слов"
49
49
50 #: forms.py:37
50 #: forms.py:38
51 msgid "Title"
51 msgid "Title"
52 msgstr "Заголовок"
52 msgstr "Заголовок"
53
53
54 #: forms.py:38
54 #: forms.py:39
55 msgid "Text"
55 msgid "Text"
56 msgstr "Текст"
56 msgstr "Текст"
57
57
58 #: forms.py:39
58 #: forms.py:40
59 msgid "Tag"
59 msgid "Tag"
60 msgstr "Метка"
60 msgstr "Метка"
61
61
62 #: forms.py:40 templates/boards/base.html:36 templates/search/search.html:13
62 #: forms.py:41 templates/boards/base.html:36 templates/search/search.html:7
63 #: templates/search/search.html.py:17
64 msgid "Search"
63 msgid "Search"
65 msgstr "Поиск"
64 msgstr "Поиск"
66
65
67 #: forms.py:139
66 #: forms.py:140
68 msgid "Image"
67 msgid "Image"
69 msgstr "Изображение"
68 msgstr "Изображение"
70
69
71 #: forms.py:142
70 #: forms.py:143
72 msgid "Image URL"
71 msgid "Image URL"
73 msgstr "URL изображения"
72 msgstr "URL изображения"
74
73
75 #: forms.py:148
74 #: forms.py:149
76 msgid "e-mail"
75 msgid "e-mail"
77 msgstr ""
76 msgstr ""
78
77
79 #: forms.py:159
78 #: forms.py:152
79 #| msgid "All threads"
80 msgid "Additional threads"
81 msgstr "Дополнительные темы"
82
83 #: forms.py:163
80 #, python-format
84 #, python-format
81 msgid "Title must have less than %s characters"
85 msgid "Title must have less than %s characters"
82 msgstr "Заголовок должен иметь меньше %s символов"
86 msgstr "Заголовок должен иметь меньше %s символов"
83
87
84 #: forms.py:168
88 #: forms.py:172
85 #, python-format
89 #, python-format
86 msgid "Text must have less than %s characters"
90 msgid "Text must have less than %s characters"
87 msgstr "Текст должен быть короче %s символов"
91 msgstr "Текст должен быть короче %s символов"
88
92
89 #: forms.py:190
93 #: forms.py:194
90 msgid "Invalid URL"
94 msgid "Invalid URL"
91 msgstr "Неверный URL"
95 msgstr "Неверный URL"
92
96
93 #: forms.py:227
97 #: forms.py:214
98 msgid "Invalid additional thread list"
99 msgstr "Неверный список дополнительных тем"
100
101 #: forms.py:249
94 msgid "Either text or image must be entered."
102 msgid "Either text or image must be entered."
95 msgstr "Текст или картинка должны быть введены."
103 msgstr "Текст или картинка должны быть введены."
96
104
97 #: forms.py:243
105 #: forms.py:265
98 #, python-format
106 #, python-format
99 msgid "Wait %s seconds after last posting"
107 msgid "Wait %s seconds after last posting"
100 msgstr "Подождите %s секунд после последнего постинга"
108 msgstr "Подождите %s секунд после последнего постинга"
101
109
102 #: forms.py:255
110 #: forms.py:277
103 #, python-format
111 #, python-format
104 msgid "Image must be less than %s bytes"
112 msgid "Image must be less than %s bytes"
105 msgstr "Изображение должно быть менее %s байт"
113 msgstr "Изображение должно быть менее %s байт"
106
114
107 #: forms.py:302 templates/boards/rss/post.html:10 templates/boards/tags.html:7
115 #: forms.py:324 templates/boards/posting_general.html:148
116 #: templates/boards/rss/post.html:10 templates/boards/tags.html:7
108 msgid "Tags"
117 msgid "Tags"
109 msgstr "Метки"
118 msgstr "Метки"
110
119
111 #: forms.py:309
120 #: forms.py:331
112 msgid "Inappropriate characters in tags."
121 msgid "Inappropriate characters in tags."
113 msgstr "Недопустимые символы в метках."
122 msgstr "Недопустимые символы в метках."
114
123
115 #: forms.py:320
124 #: forms.py:342
116 msgid "Need at least 1 required tag."
125 msgid "Need at least 1 required tag."
117 msgstr "Нужна хотя бы 1 обязательная метка."
126 msgstr "Нужна хотя бы 1 обязательная метка."
118
127
119 #: forms.py:332
128 #: forms.py:354
120 msgid "Theme"
129 msgid "Theme"
121 msgstr "Тема"
130 msgstr "Тема"
122
131
123 #: forms.py:333
132 #: forms.py:355
124 msgid "User name"
133 msgid "User name"
125 msgstr "Имя пользователя"
134 msgstr "Имя пользователя"
126
135
127 #: forms.py:334
136 #: forms.py:356
128 msgid "Time zone"
137 msgid "Time zone"
129 msgstr "Часовой пояс"
138 msgstr "Часовой пояс"
130
139
131 #: forms.py:340
140 #: forms.py:362
132 msgid "Inappropriate characters."
141 msgid "Inappropriate characters."
133 msgstr "Недопустимые символы."
142 msgstr "Недопустимые символы."
134
143
@@ -265,11 +274,11 b' msgstr ""'
265 msgid "Text syntax"
274 msgid "Text syntax"
266 msgstr "Синтаксис текста"
275 msgstr "Синтаксис текста"
267
276
268 #: templates/boards/posting_general.html:157
277 #: templates/boards/posting_general.html:161
269 msgid "Pages:"
278 msgid "Pages:"
270 msgstr "Страницы: "
279 msgstr "Страницы: "
271
280
272 #: templates/boards/preview.html:6 templates/boards/staticpages/help.html:21
281 #: templates/boards/preview.html:6 templates/boards/staticpages/help.html:20
273 msgid "Preview"
282 msgid "Preview"
274 msgstr "Предпросмотр"
283 msgstr "Предпросмотр"
275
284
@@ -323,23 +332,19 b' msgid "Link to a post"'
323 msgstr "Ссылка на сообщение"
332 msgstr "Ссылка на сообщение"
324
333
325 #: templates/boards/staticpages/help.html:15
334 #: templates/boards/staticpages/help.html:15
326 msgid "Add post to this thread"
327 msgstr "Добавить сообщение в эту тему"
328
329 #: templates/boards/staticpages/help.html:16
330 msgid "Strikethrough text"
335 msgid "Strikethrough text"
331 msgstr "Зачеркнутый текст"
336 msgstr "Зачеркнутый текст"
332
337
333 #: templates/boards/staticpages/help.html:17
338 #: templates/boards/staticpages/help.html:16
334 msgid "Comment"
339 msgid "Comment"
335 msgstr "Комментарий"
340 msgstr "Комментарий"
336
341
342 #: templates/boards/staticpages/help.html:17
337 #: templates/boards/staticpages/help.html:18
343 #: templates/boards/staticpages/help.html:18
338 #: templates/boards/staticpages/help.html:19
339 msgid "Quote"
344 msgid "Quote"
340 msgstr "Цитата"
345 msgstr "Цитата"
341
346
342 #: templates/boards/staticpages/help.html:21
347 #: templates/boards/staticpages/help.html:20
343 msgid "You can try pasting the text and previewing the result here:"
348 msgid "You can try pasting the text and previewing the result here:"
344 msgstr "Вы можете попробовать вставить текст и проверить результат здесь:"
349 msgstr "Вы можете попробовать вставить текст и проверить результат здесь:"
345
350
@@ -384,3 +389,8 b' msgstr "\xd0\x97\xd0\xb0\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x84\xd0\xbe\xd1\x80\xd0\xbc\xd1\x83"'
384 #: templates/boards/thread_normal.html:68
389 #: templates/boards/thread_normal.html:68
385 msgid "Update"
390 msgid "Update"
386 msgstr "Обновить"
391 msgstr "Обновить"
392
393 #: templates/search/search.html:17
394 msgid "Ok"
395 msgstr ""
396
@@ -137,23 +137,6 b' def render_reflink(tag_name, value, opti'
137 return result
137 return result
138
138
139
139
140 def render_multithread(tag_name, value, options, parent, context):
141 result = '>>>%s' % value
142
143 if REFLINK_PATTERN.match(value):
144 post_id = int(value)
145
146 try:
147 post = boards.models.Post.objects.get(id=post_id)
148
149 if post.is_opening():
150 result = '<a href="%s">&gt;&gt;&gt;%s</a>' % (post.get_url(), post_id)
151 except ObjectDoesNotExist:
152 pass
153
154 return result
155
156
157 def render_quote(tag_name, value, options, parent, context):
140 def render_quote(tag_name, value, options, parent, context):
158 source = ''
141 source = ''
159 if 'source' in options:
142 if 'source' in options:
@@ -189,7 +172,6 b' formatters = ['
189
172
190
173
191 PREPARSE_PATTERNS = {
174 PREPARSE_PATTERNS = {
192 r'>>>(\d+)': r'[thread]\1[/thread]', # Multi-thread post ">>>123"
193 r'(?<!>)>>(\d+)': r'[post]\1[/post]', # Reflink ">>123"
175 r'(?<!>)>>(\d+)': r'[post]\1[/post]', # Reflink ">>123"
194 r'^>([^>].+)': r'[quote]\1[/quote]', # Quote ">text"
176 r'^>([^>].+)': r'[quote]\1[/quote]', # Quote ">text"
195 r'^//(.+)': r'[comment]\1[/comment]', # Comment "//text"
177 r'^//(.+)': r'[comment]\1[/comment]', # Comment "//text"
@@ -204,7 +186,6 b' class Parser:'
204 self.parser = bbcode.Parser(newline=LINE_BREAK_HTML)
186 self.parser = bbcode.Parser(newline=LINE_BREAK_HTML)
205
187
206 self.parser.add_formatter('post', render_reflink, strip=True)
188 self.parser.add_formatter('post', render_reflink, strip=True)
207 self.parser.add_formatter('thread', render_multithread, strip=True)
208 self.parser.add_formatter('quote', render_quote, strip=True)
189 self.parser.add_formatter('quote', render_quote, strip=True)
209 self.parser.add_formatter('user', render_notification, strip=True)
190 self.parser.add_formatter('user', render_notification, strip=True)
210 self.parser.add_simple_formatter(
191 self.parser.add_simple_formatter(
@@ -42,7 +42,6 b" NO_IP = '0.0.0.0'"
42 UNKNOWN_UA = ''
42 UNKNOWN_UA = ''
43
43
44 REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
44 REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
45 REGEX_MULTI_THREAD = re.compile(r'\[thread\](\d+)\[/thread\]')
46 REGEX_NOTIFICATION = re.compile(r'\[user\](\w+)\[/user\]')
45 REGEX_NOTIFICATION = re.compile(r'\[user\](\w+)\[/user\]')
47
46
48 PARAMETER_TRUNCATED = 'truncated'
47 PARAMETER_TRUNCATED = 'truncated'
@@ -65,13 +64,15 b" DIFF_TYPE_JSON = 'json'"
65 class PostManager(models.Manager):
64 class PostManager(models.Manager):
66 @transaction.atomic
65 @transaction.atomic
67 def create_post(self, title: str, text: str, image=None, thread=None,
66 def create_post(self, title: str, text: str, image=None, thread=None,
68 ip=NO_IP, tags: list=None):
67 ip=NO_IP, tags: list=None, threads: list=None):
69 """
68 """
70 Creates new post
69 Creates new post
71 """
70 """
72
71
73 if not tags:
72 if not tags:
74 tags = []
73 tags = []
74 if not threads:
75 threads = []
75
76
76 posting_time = timezone.now()
77 posting_time = timezone.now()
77 if not thread:
78 if not thread:
@@ -111,7 +112,7 b' class PostManager(models.Manager):'
111 thread.save()
112 thread.save()
112
113
113 post.connect_replies()
114 post.connect_replies()
114 post.connect_threads()
115 post.connect_threads(threads)
115 post.connect_notifications()
116 post.connect_notifications()
116
117
117 return post
118 return post
@@ -424,27 +425,20 b' class Post(models.Model, Viewable):'
424 except ObjectDoesNotExist:
425 except ObjectDoesNotExist:
425 pass
426 pass
426
427
427 def connect_threads(self):
428 def connect_threads(self, threads):
428 """
429 """
429 If the referenced post is an OP in another thread,
430 If the referenced post is an OP in another thread,
430 make this post multi-thread.
431 make this post multi-thread.
431 """
432 """
432
433
433 for reply_number in re.finditer(REGEX_MULTI_THREAD, self.get_raw_text()):
434 for referenced_post in threads:
434 post_id = reply_number.group(1)
435 if referenced_post.is_opening():
435
436 referenced_threads = referenced_post.get_threads().all()
436 try:
437 for thread in referenced_threads:
437 referenced_post = Post.objects.get(id=post_id)
438 if thread.can_bump():
439 thread.update_bump_status()
438
440
439 if referenced_post.is_opening():
441 thread.last_edit_time = self.pub_time
440 referenced_threads = referenced_post.get_threads().all()
442 thread.save(update_fields=['last_edit_time', 'bumpable'])
441 for thread in referenced_threads:
442 if thread.can_bump():
443 thread.update_bump_status()
444
443
445 thread.last_edit_time = self.pub_time
444 self.threads.add(thread)
446 thread.save(update_fields=['last_edit_time', 'bumpable'])
447
448 self.threads.add(thread)
449 except ObjectDoesNotExist:
450 pass
@@ -12,7 +12,6 b''
12 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
12 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
13 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
13 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
14 <p>[post]123[/post] — {% trans 'Link to a post' %}</p>
14 <p>[post]123[/post] — {% trans 'Link to a post' %}</p>
15 <p>[thread]123[/thread] — {% trans 'Add post to this thread' %}</p>
16 <p>[s]<span class="strikethrough">{% trans 'Strikethrough text' %}</span>[/s]</p>
15 <p>[s]<span class="strikethrough">{% trans 'Strikethrough text' %}</span>[/s]</p>
17 <p>[comment]<span class="comment">{% trans 'Comment' %}</span>[/comment]</p>
16 <p>[comment]<span class="comment">{% trans 'Comment' %}</span>[/comment]</p>
18 <p>[quote]<span class="quote">&gt;{% trans 'Quote' %}</span>[/quote]</p>
17 <p>[quote]<span class="quote">&gt;{% trans 'Quote' %}</span>[/quote]</p>
@@ -20,6 +20,7 b" FORM_TAGS = 'tags'"
20 FORM_TEXT = 'text'
20 FORM_TEXT = 'text'
21 FORM_TITLE = 'title'
21 FORM_TITLE = 'title'
22 FORM_IMAGE = 'image'
22 FORM_IMAGE = 'image'
23 FORM_THREADS = 'threads'
23
24
24 TAG_DELIMITER = ' '
25 TAG_DELIMITER = ' '
25
26
@@ -119,6 +120,7 b' class AllThreadsView(PostMixin, BaseBoar'
119 title = data[FORM_TITLE]
120 title = data[FORM_TITLE]
120 text = data[FORM_TEXT]
121 text = data[FORM_TEXT]
121 image = form.get_image()
122 image = form.get_image()
123 threads = data[FORM_THREADS]
122
124
123 text = self._remove_invalid_links(text)
125 text = self._remove_invalid_links(text)
124
126
@@ -127,7 +129,7 b' class AllThreadsView(PostMixin, BaseBoar'
127 tags = self.parse_tags_string(tag_strings)
129 tags = self.parse_tags_string(tag_strings)
128
130
129 post = Post.objects.create_post(title=title, text=text, image=image,
131 post = Post.objects.create_post(title=title, text=text, image=image,
130 ip=ip, tags=tags)
132 ip=ip, tags=tags, threads=threads)
131
133
132 # This is required to update the threads to which posts we have replied
134 # This is required to update the threads to which posts we have replied
133 # when creating this one
135 # when creating this one
@@ -21,6 +21,7 b" CONTEXT_WS_PORT = 'ws_port'"
21 FORM_TITLE = 'title'
21 FORM_TITLE = 'title'
22 FORM_TEXT = 'text'
22 FORM_TEXT = 'text'
23 FORM_IMAGE = 'image'
23 FORM_IMAGE = 'image'
24 FORM_THREADS = 'threads'
24
25
25
26
26 class ThreadView(BaseBoardView, PostMixin, FormMixin):
27 class ThreadView(BaseBoardView, PostMixin, FormMixin):
@@ -91,13 +92,14 b' class ThreadView(BaseBoardView, PostMixi'
91 title = data[FORM_TITLE]
92 title = data[FORM_TITLE]
92 text = data[FORM_TEXT]
93 text = data[FORM_TEXT]
93 image = form.get_image()
94 image = form.get_image()
95 threads = data[FORM_THREADS]
94
96
95 text = self._remove_invalid_links(text)
97 text = self._remove_invalid_links(text)
96
98
97 post_thread = opening_post.get_thread()
99 post_thread = opening_post.get_thread()
98
100
99 post = Post.objects.create_post(title=title, text=text, image=image,
101 post = Post.objects.create_post(title=title, text=text, image=image,
100 thread=post_thread, ip=ip)
102 thread=post_thread, ip=ip, threads=threads)
101 post.send_to_websocket(request)
103 post.send_to_websocket(request)
102
104
103 if html_response:
105 if html_response:
General Comments 0
You need to be logged in to leave comments. Login now