Show More
@@ -20,11 +20,6 b' from boards.models.user import Notificat' | |||||
20 | import boards.models.thread |
|
20 | import boards.models.thread | |
21 |
|
21 | |||
22 |
|
22 | |||
23 | WS_NOTIFICATION_TYPE_NEW_POST = 'new_post' |
|
|||
24 | WS_NOTIFICATION_TYPE = 'notification_type' |
|
|||
25 |
|
||||
26 | WS_CHANNEL_THREAD = "thread:" |
|
|||
27 |
|
||||
28 | APP_LABEL_BOARDS = 'boards' |
|
23 | APP_LABEL_BOARDS = 'boards' | |
29 |
|
24 | |||
30 | POSTS_PER_DAY_RANGE = 7 |
|
25 | POSTS_PER_DAY_RANGE = 7 | |
@@ -195,15 +190,11 b' class Post(models.Model, Viewable):' | |||||
195 | the server from recalculating the map on every post show. |
|
190 | the server from recalculating the map on every post show. | |
196 | """ |
|
191 | """ | |
197 |
|
192 | |||
198 | post_urls = [REFMAP_STR.format( |
|
193 | post_urls = [REFMAP_STR.format(refpost.get_url(), refpost.id) | |
199 |
|
|
194 | for refpost in self.referenced_posts.all()] | |
200 |
|
195 | |||
201 | self.refmap = ', '.join(post_urls) |
|
196 | self.refmap = ', '.join(post_urls) | |
202 |
|
197 | |||
203 | # TODO Is this still needed? |
|
|||
204 | def get_sorted_referenced_posts(self): |
|
|||
205 | return self.refmap |
|
|||
206 |
|
||||
207 | def is_referenced(self) -> bool: |
|
198 | def is_referenced(self) -> bool: | |
208 | return self.refmap and len(self.refmap) > 0 |
|
199 | return self.refmap and len(self.refmap) > 0 | |
209 |
|
200 | |||
@@ -240,9 +231,6 b' class Post(models.Model, Viewable):' | |||||
240 |
|
231 | |||
241 | return self.threads |
|
232 | return self.threads | |
242 |
|
233 | |||
243 | def get_referenced_posts(self) -> list: |
|
|||
244 | return self.referenced_posts.only('id', 'threads') |
|
|||
245 |
|
||||
246 | def get_view(self, moderator=False, need_open_link=False, |
|
234 | def get_view(self, moderator=False, need_open_link=False, | |
247 | truncated=False, *args, **kwargs) -> str: |
|
235 | truncated=False, *args, **kwargs) -> str: | |
248 | """ |
|
236 | """ | |
@@ -327,7 +315,7 b' class Post(models.Model, Viewable):' | |||||
327 | self.get_thread().bump_time) |
|
315 | self.get_thread().bump_time) | |
328 | return post_json |
|
316 | return post_json | |
329 |
|
317 | |||
330 |
def |
|
318 | def notify_clients(self, request, recursive=True): | |
331 | """ |
|
319 | """ | |
332 | Sends post HTML data to the thread web socket. |
|
320 | Sends post HTML data to the thread web socket. | |
333 | """ |
|
321 | """ | |
@@ -335,22 +323,11 b' class Post(models.Model, Viewable):' | |||||
335 | if not settings.WEBSOCKETS_ENABLED: |
|
323 | if not settings.WEBSOCKETS_ENABLED: | |
336 | return |
|
324 | return | |
337 |
|
325 | |||
338 | client = Client() |
|
|||
339 |
|
||||
340 | logger = logging.getLogger('boards.post.websocket') |
|
|||
341 |
|
||||
342 | thread_ids = list() |
|
326 | thread_ids = list() | |
343 | for thread in self.get_threads().all(): |
|
327 | for thread in self.get_threads().all(): | |
344 | thread_ids.append(thread.id) |
|
328 | thread_ids.append(thread.id) | |
345 |
|
329 | |||
346 | channel_name = WS_CHANNEL_THREAD + str(thread.get_opening_post_id()) |
|
330 | thread.notify_clients(request) | |
347 | client.publish(channel_name, { |
|
|||
348 | WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST, |
|
|||
349 | }) |
|
|||
350 | client.send() |
|
|||
351 |
|
||||
352 | logger.info('Sent notification from post #{} to channel {}'.format( |
|
|||
353 | self.id, channel_name)) |
|
|||
354 |
|
331 | |||
355 | if recursive: |
|
332 | if recursive: | |
356 | for reply_number in re.finditer(REGEX_REPLY, self.get_raw_text()): |
|
333 | for reply_number in re.finditer(REGEX_REPLY, self.get_raw_text()): | |
@@ -362,7 +339,7 b' class Post(models.Model, Viewable):' | |||||
362 | if ref_post.get_threads().exclude(id__in=thread_ids).exists(): |
|
339 | if ref_post.get_threads().exclude(id__in=thread_ids).exists(): | |
363 | # If post is in this thread, its thread was already notified. |
|
340 | # If post is in this thread, its thread was already notified. | |
364 | # Otherwise, notify its thread separately. |
|
341 | # Otherwise, notify its thread separately. | |
365 |
ref_post. |
|
342 | ref_post.notify_clients(request, recursive=False) | |
366 | except ObjectDoesNotExist: |
|
343 | except ObjectDoesNotExist: | |
367 | pass |
|
344 | pass | |
368 |
|
345 | |||
@@ -370,6 +347,13 b' class Post(models.Model, Viewable):' | |||||
370 | update_fields=None): |
|
347 | update_fields=None): | |
371 | self._text_rendered = Parser().parse(self.get_raw_text()) |
|
348 | self._text_rendered = Parser().parse(self.get_raw_text()) | |
372 |
|
349 | |||
|
350 | if self.id: | |||
|
351 | for thread in self.get_threads().all(): | |||
|
352 | thread.update_bump_status() | |||
|
353 | thread.last_edit_time = self.last_edit_time | |||
|
354 | ||||
|
355 | thread.save(update_fields=['last_edit_time', 'bumpable']) | |||
|
356 | ||||
373 | super().save(force_insert, force_update, using, update_fields) |
|
357 | super().save(force_insert, force_update, using, update_fields) | |
374 |
|
358 | |||
375 | def get_text(self) -> str: |
|
359 | def get_text(self) -> str: | |
@@ -409,31 +393,22 b' class Post(models.Model, Viewable):' | |||||
409 | referenced_post.last_edit_time = self.pub_time |
|
393 | referenced_post.last_edit_time = self.pub_time | |
410 | referenced_post.build_refmap() |
|
394 | referenced_post.build_refmap() | |
411 | referenced_post.save(update_fields=['refmap', 'last_edit_time']) |
|
395 | referenced_post.save(update_fields=['refmap', 'last_edit_time']) | |
412 |
|
||||
413 | referenced_threads = referenced_post.get_threads().all() |
|
|||
414 | for thread in referenced_threads: |
|
|||
415 | if thread.can_bump(): |
|
|||
416 | thread.update_bump_status() |
|
|||
417 |
|
||||
418 | thread.last_edit_time = self.pub_time |
|
|||
419 | thread.save(update_fields=['last_edit_time', 'bumpable']) |
|
|||
420 | except ObjectDoesNotExist: |
|
396 | except ObjectDoesNotExist: | |
421 | pass |
|
397 | pass | |
422 |
|
398 | |||
423 |
def connect_threads(self, |
|
399 | def connect_threads(self, opening_posts): | |
424 | """ |
|
400 | """ | |
425 | If the referenced post is an OP in another thread, |
|
401 | If the referenced post is an OP in another thread, | |
426 | make this post multi-thread. |
|
402 | make this post multi-thread. | |
427 | """ |
|
403 | """ | |
428 |
|
404 | |||
429 |
for |
|
405 | for opening_post in opening_posts: | |
430 | if referenced_post.is_opening(): |
|
406 | threads = opening_post.get_threads().all() | |
431 | referenced_threads = referenced_post.get_threads().all() |
|
407 | for thread in threads: | |
432 |
f |
|
408 | if thread.can_bump(): | |
433 |
|
|
409 | thread.update_bump_status() | |
434 | thread.update_bump_status() |
|
|||
435 |
|
410 | |||
436 |
thread.last_edit_time = self. |
|
411 | thread.last_edit_time = self.last_edit_time | |
437 | thread.save(update_fields=['last_edit_time', 'bumpable']) |
|
412 | thread.save(update_fields=['last_edit_time', 'bumpable']) | |
438 |
|
413 | |||
439 | self.threads.add(thread) |
|
414 | self.threads.add(thread) |
@@ -1,4 +1,5 b'' | |||||
1 | import logging |
|
1 | import logging | |
|
2 | from adjacent import Client | |||
2 |
|
3 | |||
3 | from django.db.models import Count, Sum |
|
4 | from django.db.models import Count, Sum | |
4 | from django.utils import timezone |
|
5 | from django.utils import timezone | |
@@ -17,6 +18,12 b' from boards.models.tag import Tag' | |||||
17 | logger = logging.getLogger(__name__) |
|
18 | logger = logging.getLogger(__name__) | |
18 |
|
19 | |||
19 |
|
20 | |||
|
21 | WS_NOTIFICATION_TYPE_NEW_POST = 'new_post' | |||
|
22 | WS_NOTIFICATION_TYPE = 'notification_type' | |||
|
23 | ||||
|
24 | WS_CHANNEL_THREAD = "thread:" | |||
|
25 | ||||
|
26 | ||||
20 | class ThreadManager(models.Manager): |
|
27 | class ThreadManager(models.Manager): | |
21 | def process_oldest_threads(self): |
|
28 | def process_oldest_threads(self): | |
22 | """ |
|
29 | """ | |
@@ -199,3 +206,15 b' class Thread(models.Model):' | |||||
199 | self.post_set.update(last_edit_time=self.last_edit_time) |
|
206 | self.post_set.update(last_edit_time=self.last_edit_time) | |
200 | for post in self.post_set.all(): |
|
207 | for post in self.post_set.all(): | |
201 | post.threads.update(last_edit_time=self.last_edit_time) |
|
208 | post.threads.update(last_edit_time=self.last_edit_time) | |
|
209 | ||||
|
210 | def notify_clients(self, request): | |||
|
211 | if not settings.WEBSOCKETS_ENABLED: | |||
|
212 | return | |||
|
213 | ||||
|
214 | client = Client() | |||
|
215 | ||||
|
216 | channel_name = WS_CHANNEL_THREAD + str(self.get_opening_post_id()) | |||
|
217 | client.publish(channel_name, { | |||
|
218 | WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST, | |||
|
219 | }) | |||
|
220 | client.send() No newline at end of file |
@@ -14,11 +14,14 b' class ApiTest(TestCase):' | |||||
14 | opening_post = Post.objects.create_post(title='title', text='text', |
|
14 | opening_post = Post.objects.create_post(title='title', text='text', | |
15 | tags=[tag]) |
|
15 | tags=[tag]) | |
16 |
|
16 | |||
17 |
last_edit_time = |
|
17 | last_edit_time = str(opening_post.last_edit_time) | |
18 |
|
18 | |||
|
19 | req = MockRequest() | |||
|
20 | req.GET['thread'] = opening_post.id | |||
|
21 | req.GET['last_update'] = last_edit_time | |||
|
22 | req.GET['last_post'] = opening_post.id | |||
19 | # Check the exact timestamp post was added |
|
23 | # Check the exact timestamp post was added | |
20 | empty_response = api.api_get_threaddiff( |
|
24 | empty_response = api.api_get_threaddiff(req) | |
21 | MockRequest(), str(opening_post.get_thread().id), str(last_edit_time)) |
|
|||
22 | diff = simplejson.loads(empty_response.content) |
|
25 | diff = simplejson.loads(empty_response.content) | |
23 | self.assertEqual(0, len(diff['added']), |
|
26 | self.assertEqual(0, len(diff['added']), | |
24 | 'There must be no added posts in the diff.') |
|
27 | 'There must be no added posts in the diff.') | |
@@ -29,18 +32,23 b' class ApiTest(TestCase):' | |||||
29 | text='[post]%d[/post]\ntext' % opening_post.id, |
|
32 | text='[post]%d[/post]\ntext' % opening_post.id, | |
30 | thread=opening_post.get_thread()) |
|
33 | thread=opening_post.get_thread()) | |
31 |
|
34 | |||
|
35 | req = MockRequest() | |||
|
36 | req.GET['thread'] = opening_post.id | |||
|
37 | req.GET['last_update'] = last_edit_time | |||
|
38 | req.GET['last_post'] = opening_post.id | |||
32 | # Check the timestamp before post was added |
|
39 | # Check the timestamp before post was added | |
33 | response = api.api_get_threaddiff( |
|
40 | response = api.api_get_threaddiff(req) | |
34 | MockRequest(), str(opening_post.get_thread().id), str(last_edit_time)) |
|
|||
35 | diff = simplejson.loads(response.content) |
|
41 | diff = simplejson.loads(response.content) | |
36 | self.assertEqual(1, len(diff['added']), |
|
42 | self.assertEqual(1, len(diff['added']), | |
37 | 'There must be 1 added posts in the diff.') |
|
43 | 'There must be 1 added posts in the diff.') | |
38 | self.assertEqual(1, len(diff['updated']), |
|
44 | self.assertEqual(1, len(diff['updated']), | |
39 | 'There must be 1 updated posts in the diff.') |
|
45 | 'There must be 1 updated posts in the diff.') | |
40 |
|
46 | |||
41 | empty_response = api.api_get_threaddiff(MockRequest(), |
|
47 | req = MockRequest() | |
42 | str(opening_post.get_thread().id), |
|
48 | req.GET['thread'] = opening_post.id | |
43 | str(datetime_to_epoch(reply.last_edit_time))) |
|
49 | req.GET['last_update'] = str(reply.last_edit_time) | |
|
50 | req.GET['last_post'] = reply.id | |||
|
51 | empty_response = api.api_get_threaddiff(req) | |||
44 | diff = simplejson.loads(empty_response.content) |
|
52 | diff = simplejson.loads(empty_response.content) | |
45 | self.assertEqual(0, len(diff['added']), |
|
53 | self.assertEqual(0, len(diff['added']), | |
46 | 'There must be no added posts in the diff.') |
|
54 | 'There must be no added posts in the diff.') |
@@ -7,7 +7,7 b" NEW_THREAD_PAGE = '/'" | |||||
7 | THREAD_PAGE_ONE = '/thread/1/' |
|
7 | THREAD_PAGE_ONE = '/thread/1/' | |
8 | THREAD_PAGE = '/thread/' |
|
8 | THREAD_PAGE = '/thread/' | |
9 | TAG_PAGE = '/tag/' |
|
9 | TAG_PAGE = '/tag/' | |
10 |
HTTP_CODE_REDIRECT = 30 |
|
10 | HTTP_CODE_REDIRECT = 302 | |
11 | HTTP_CODE_OK = 200 |
|
11 | HTTP_CODE_OK = 200 | |
12 | HTTP_CODE_NOT_FOUND = 404 |
|
12 | HTTP_CODE_NOT_FOUND = 404 | |
13 |
|
13 | |||
@@ -45,7 +45,7 b' class PagesTest(TestCase):' | |||||
45 |
|
45 | |||
46 | reply_id = Post.objects.create_post('', TEST_TEXT, |
|
46 | reply_id = Post.objects.create_post('', TEST_TEXT, | |
47 | thread=Post.objects.all()[0] |
|
47 | thread=Post.objects.all()[0] | |
48 | .get_thread()) |
|
48 | .get_thread()).id | |
49 | response_not_existing = client.get(THREAD_PAGE + str( |
|
49 | response_not_existing = client.get(THREAD_PAGE + str( | |
50 | reply_id) + '/') |
|
50 | reply_id) + '/') | |
51 | self.assertEqual(HTTP_CODE_REDIRECT, response_not_existing.status_code, |
|
51 | self.assertEqual(HTTP_CODE_REDIRECT, response_not_existing.status_code, |
@@ -10,6 +10,7 b' HTTP_CODE_OK = 200' | |||||
10 |
|
10 | |||
11 | EXCLUDED_VIEWS = { |
|
11 | EXCLUDED_VIEWS = { | |
12 | 'banned', |
|
12 | 'banned', | |
|
13 | 'get_thread_diff', | |||
13 | } |
|
14 | } | |
14 |
|
15 | |||
15 |
|
16 |
@@ -133,7 +133,7 b' class AllThreadsView(PostMixin, BaseBoar' | |||||
133 |
|
133 | |||
134 | # 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 | |
135 | # when creating this one |
|
135 | # when creating this one | |
136 |
post. |
|
136 | post.notify_clients(request) | |
137 |
|
137 | |||
138 | if html_response: |
|
138 | if html_response: | |
139 | return redirect(post.get_url()) |
|
139 | return redirect(post.get_url()) |
@@ -106,7 +106,7 b' class ThreadView(BaseBoardView, PostMixi' | |||||
106 |
|
106 | |||
107 | post = Post.objects.create_post(title=title, text=text, image=image, |
|
107 | post = Post.objects.create_post(title=title, text=text, image=image, | |
108 | thread=post_thread, ip=ip, threads=threads) |
|
108 | thread=post_thread, ip=ip, threads=threads) | |
109 |
post. |
|
109 | post.notify_clients(request) | |
110 |
|
110 | |||
111 | if html_response: |
|
111 | if html_response: | |
112 | if opening_post: |
|
112 | if opening_post: |
General Comments 0
You need to be logged in to leave comments.
Login now