Show More
@@ -0,0 +1,25 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | # Generated by Django 1.9.5 on 2016-11-27 13:41 | |||
|
3 | from __future__ import unicode_literals | |||
|
4 | ||||
|
5 | from django.db import migrations, models | |||
|
6 | import django.db.models.deletion | |||
|
7 | ||||
|
8 | ||||
|
9 | class Migration(migrations.Migration): | |||
|
10 | ||||
|
11 | dependencies = [ | |||
|
12 | ('boards', '0052_auto_20161120_1344'), | |||
|
13 | ] | |||
|
14 | ||||
|
15 | operations = [ | |||
|
16 | migrations.RemoveField( | |||
|
17 | model_name='post', | |||
|
18 | name='threads', | |||
|
19 | ), | |||
|
20 | migrations.AlterField( | |||
|
21 | model_name='post', | |||
|
22 | name='thread', | |||
|
23 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='replies', to='boards.Thread'), | |||
|
24 | ), | |||
|
25 | ] |
@@ -13,7 +13,7 b' class PostAdmin(admin.ModelAdmin):' | |||||
13 | list_filter = ('pub_time',) |
|
13 | list_filter = ('pub_time',) | |
14 | search_fields = ('id', 'title', 'text', 'poster_ip') |
|
14 | search_fields = ('id', 'title', 'text', 'poster_ip') | |
15 | exclude = ('referenced_posts', 'refmap', 'images', 'global_id') |
|
15 | exclude = ('referenced_posts', 'refmap', 'images', 'global_id') | |
16 |
readonly_fields = ('poster_ip', ' |
|
16 | readonly_fields = ('poster_ip', 'thread', 'linked_images', | |
17 | 'attachments', 'uid', 'url', 'pub_time', 'opening', 'linked_global_id', |
|
17 | 'attachments', 'uid', 'url', 'pub_time', 'opening', 'linked_global_id', | |
18 | 'version', 'foreign', 'tags') |
|
18 | 'version', 'foreign', 'tags') | |
19 |
|
19 |
@@ -179,9 +179,6 b' class PostForm(NeboardForm):' | |||||
179 | email = forms.CharField(max_length=100, required=False, label=_('e-mail'), |
|
179 | email = forms.CharField(max_length=100, required=False, label=_('e-mail'), | |
180 | widget=forms.TextInput(attrs={ |
|
180 | widget=forms.TextInput(attrs={ | |
181 | 'class': 'form-email'})) |
|
181 | 'class': 'form-email'})) | |
182 | threads = forms.CharField(required=False, label=_('Additional threads'), |
|
|||
183 | widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: |
|
|||
184 | '123 456 789'})) |
|
|||
185 | subscribe = forms.BooleanField(required=False, label=_('Subscribe to thread')) |
|
182 | subscribe = forms.BooleanField(required=False, label=_('Subscribe to thread')) | |
186 |
|
183 | |||
187 | guess = forms.CharField(widget=forms.HiddenInput(), required=False) |
|
184 | guess = forms.CharField(widget=forms.HiddenInput(), required=False) | |
@@ -263,25 +260,6 b' class PostForm(NeboardForm):' | |||||
263 |
|
260 | |||
264 | return file |
|
261 | return file | |
265 |
|
262 | |||
266 | def clean_threads(self): |
|
|||
267 | threads_str = self.cleaned_data['threads'] |
|
|||
268 |
|
||||
269 | if len(threads_str) > 0: |
|
|||
270 | threads_id_list = threads_str.split(' ') |
|
|||
271 |
|
||||
272 | threads = list() |
|
|||
273 |
|
||||
274 | for thread_id in threads_id_list: |
|
|||
275 | try: |
|
|||
276 | thread = Post.objects.get(id=int(thread_id)) |
|
|||
277 | if not thread.is_opening() or thread.get_thread().is_archived(): |
|
|||
278 | raise ObjectDoesNotExist() |
|
|||
279 | threads.append(thread) |
|
|||
280 | except (ObjectDoesNotExist, ValueError): |
|
|||
281 | raise forms.ValidationError(_('Invalid additional thread list')) |
|
|||
282 |
|
||||
283 | return threads |
|
|||
284 |
|
||||
285 | def clean(self): |
|
263 | def clean(self): | |
286 | cleaned_data = super(PostForm, self).clean() |
|
264 | cleaned_data = super(PostForm, self).clean() | |
287 |
|
265 |
@@ -87,9 +87,7 b' class Post(models.Model, Viewable):' | |||||
87 | blank=True, related_name='refposts', |
|
87 | blank=True, related_name='refposts', | |
88 | db_index=True) |
|
88 | db_index=True) | |
89 | refmap = models.TextField(null=True, blank=True) |
|
89 | refmap = models.TextField(null=True, blank=True) | |
90 |
thread |
|
90 | thread = models.ForeignKey('Thread', db_index=True, related_name='replies') | |
91 | related_name='multi_replies') |
|
|||
92 | thread = models.ForeignKey('Thread', db_index=True, related_name='pt+') |
|
|||
93 |
|
91 | |||
94 | url = models.TextField() |
|
92 | url = models.TextField() | |
95 | uid = models.TextField(db_index=True) |
|
93 | uid = models.TextField(db_index=True) | |
@@ -279,10 +277,7 b' class Post(models.Model, Viewable):' | |||||
279 | return |
|
277 | return | |
280 |
|
278 | |||
281 | thread_ids = list() |
|
279 | thread_ids = list() | |
282 | for thread in self.get_threads().all(): |
|
280 | self.get_thread().notify_clients() | |
283 | thread_ids.append(thread.id) |
|
|||
284 |
|
||||
285 | thread.notify_clients() |
|
|||
286 |
|
281 | |||
287 | if recursive: |
|
282 | if recursive: | |
288 | for reply_number in re.finditer(REGEX_REPLY, self.get_raw_text()): |
|
283 | for reply_number in re.finditer(REGEX_REPLY, self.get_raw_text()): | |
@@ -291,7 +286,7 b' class Post(models.Model, Viewable):' | |||||
291 | try: |
|
286 | try: | |
292 | ref_post = Post.objects.get(id=post_id) |
|
287 | ref_post = Post.objects.get(id=post_id) | |
293 |
|
288 | |||
294 |
if ref_post.get_thread |
|
289 | if ref_post.get_thread().id not in thread_ids: | |
295 | # If post is in this thread, its thread was already notified. |
|
290 | # If post is in this thread, its thread was already notified. | |
296 | # Otherwise, notify its thread separately. |
|
291 | # Otherwise, notify its thread separately. | |
297 | ref_post.notify_clients(recursive=False) |
|
292 | ref_post.notify_clients(recursive=False) | |
@@ -316,9 +311,9 b' class Post(models.Model, Viewable):' | |||||
316 | update_fields += ['uid'] |
|
311 | update_fields += ['uid'] | |
317 |
|
312 | |||
318 | if not new_post: |
|
313 | if not new_post: | |
319 |
|
|
314 | thread = self.get_thread() | |
|
315 | if thread: | |||
320 | thread.last_edit_time = self.last_edit_time |
|
316 | thread.last_edit_time = self.last_edit_time | |
321 |
|
||||
322 | thread.save(update_fields=['last_edit_time', 'status']) |
|
317 | thread.save(update_fields=['last_edit_time', 'status']) | |
323 |
|
318 | |||
324 | super().save(force_insert, force_update, using, update_fields) |
|
319 | super().save(force_insert, force_update, using, update_fields) | |
@@ -354,17 +349,6 b' class Post(models.Model, Viewable):' | |||||
354 |
|
349 | |||
355 | return text |
|
350 | return text | |
356 |
|
351 | |||
357 | def connect_threads(self, opening_posts): |
|
|||
358 | for opening_post in opening_posts: |
|
|||
359 | threads = opening_post.get_threads().all() |
|
|||
360 | for thread in threads: |
|
|||
361 | if thread.can_bump(): |
|
|||
362 | thread.update_bump_status() |
|
|||
363 |
|
||||
364 | thread.last_edit_time = self.last_edit_time |
|
|||
365 | thread.save(update_fields=['last_edit_time', 'status']) |
|
|||
366 | self.threads.add(opening_post.get_thread()) |
|
|||
367 |
|
||||
368 | def get_tripcode(self): |
|
352 | def get_tripcode(self): | |
369 | if self.tripcode: |
|
353 | if self.tripcode: | |
370 | return Tripcode(self.tripcode) |
|
354 | return Tripcode(self.tripcode) |
@@ -27,7 +27,7 b' post_import_deps = Signal()' | |||||
27 | class PostManager(models.Manager): |
|
27 | class PostManager(models.Manager): | |
28 | @transaction.atomic |
|
28 | @transaction.atomic | |
29 | def create_post(self, title: str, text: str, file=None, thread=None, |
|
29 | def create_post(self, title: str, text: str, file=None, thread=None, | |
30 |
ip=NO_IP, tags: list=None, |
|
30 | ip=NO_IP, tags: list=None, | |
31 | tripcode='', monochrome=False, images=[], |
|
31 | tripcode='', monochrome=False, images=[], | |
32 | file_url=None): |
|
32 | file_url=None): | |
33 | """ |
|
33 | """ | |
@@ -47,15 +47,13 b' class PostManager(models.Manager):' | |||||
47 |
|
47 | |||
48 | if not tags: |
|
48 | if not tags: | |
49 | tags = [] |
|
49 | tags = [] | |
50 | if not opening_posts: |
|
|||
51 | opening_posts = [] |
|
|||
52 |
|
50 | |||
53 | posting_time = timezone.now() |
|
51 | posting_time = timezone.now() | |
54 | new_thread = False |
|
52 | new_thread = False | |
55 | if not thread: |
|
53 | if not thread: | |
56 | thread = boards.models.thread.Thread.objects.create( |
|
54 | thread = boards.models.thread.Thread.objects.create( | |
57 | bump_time=posting_time, last_edit_time=posting_time, |
|
55 | bump_time=posting_time, last_edit_time=posting_time, | |
58 |
|
|
56 | monochrome=monochrome) | |
59 | list(map(thread.tags.add, tags)) |
|
57 | list(map(thread.tags.add, tags)) | |
60 | new_thread = True |
|
58 | new_thread = True | |
61 |
|
59 | |||
@@ -69,7 +67,6 b' class PostManager(models.Manager):' | |||||
69 | last_edit_time=posting_time, |
|
67 | last_edit_time=posting_time, | |
70 | tripcode=tripcode, |
|
68 | tripcode=tripcode, | |
71 | opening=new_thread) |
|
69 | opening=new_thread) | |
72 | post.threads.add(thread) |
|
|||
73 |
|
70 | |||
74 | logger = logging.getLogger('boards.post.create') |
|
71 | logger = logging.getLogger('boards.post.create') | |
75 |
|
72 | |||
@@ -83,7 +80,6 b' class PostManager(models.Manager):' | |||||
83 | if file_url: |
|
80 | if file_url: | |
84 | post.attachments.add(Attachment.objects.create_from_url(file_url)) |
|
81 | post.attachments.add(Attachment.objects.create_from_url(file_url)) | |
85 |
|
82 | |||
86 | post.connect_threads(opening_posts) |
|
|||
87 | post.set_global_id() |
|
83 | post.set_global_id() | |
88 |
|
84 | |||
89 | # Thread needs to be bumped only when the post is already created |
|
85 | # Thread needs to be bumped only when the post is already created | |
@@ -165,8 +161,6 b' class PostManager(models.Manager):' | |||||
165 | for file in files: |
|
161 | for file in files: | |
166 | self._add_file_to_post(file, post) |
|
162 | self._add_file_to_post(file, post) | |
167 |
|
163 | |||
168 | post.threads.add(thread) |
|
|||
169 |
|
||||
170 | url_to_post = '[post]{}[/post]'.format(str(global_id)) |
|
164 | url_to_post = '[post]{}[/post]'.format(str(global_id)) | |
171 | replies = self.filter(text__contains=url_to_post) |
|
165 | replies = self.filter(text__contains=url_to_post) | |
172 | for reply in replies: |
|
166 | for reply in replies: |
@@ -102,7 +102,7 b' class Tag(models.Model, Viewable):' | |||||
102 |
|
102 | |||
103 | @cached_result() |
|
103 | @cached_result() | |
104 | def get_post_count(self): |
|
104 | def get_post_count(self): | |
105 |
return self.get_threads().aggregate(num_posts=Count(' |
|
105 | return self.get_threads().aggregate(num_posts=Count('replies'))['num_posts'] | |
106 |
|
106 | |||
107 | def get_description(self): |
|
107 | def get_description(self): | |
108 | return self.description |
|
108 | return self.description | |
@@ -110,7 +110,7 b' class Tag(models.Model, Viewable):' | |||||
110 | def get_random_image_post(self, status=[STATUS_ACTIVE, STATUS_BUMPLIMIT]): |
|
110 | def get_random_image_post(self, status=[STATUS_ACTIVE, STATUS_BUMPLIMIT]): | |
111 | posts = boards.models.Post.objects.filter(attachments__mimetype__in=FILE_TYPES_IMAGE)\ |
|
111 | posts = boards.models.Post.objects.filter(attachments__mimetype__in=FILE_TYPES_IMAGE)\ | |
112 | .annotate(images_count=Count( |
|
112 | .annotate(images_count=Count( | |
113 |
'attachments')).filter(images_count__gt=0, thread |
|
113 | 'attachments')).filter(images_count__gt=0, thread__tags__in=[self]) | |
114 | if status is not None: |
|
114 | if status is not None: | |
115 | posts = posts.filter(thread__status__in=status) |
|
115 | posts = posts.filter(thread__status__in=status) | |
116 | return posts.order_by('?').first() |
|
116 | return posts.order_by('?').first() |
@@ -181,8 +181,8 b' class Thread(models.Model):' | |||||
181 | """ |
|
181 | """ | |
182 | Gets sorted thread posts |
|
182 | Gets sorted thread posts | |
183 | """ |
|
183 | """ | |
184 |
query = self. |
|
184 | query = self.replies.order_by('pub_time').prefetch_related( | |
185 |
|
|
185 | 'attachments') | |
186 | return query |
|
186 | return query | |
187 |
|
187 | |||
188 | def get_viewable_replies(self) -> QuerySet: |
|
188 | def get_viewable_replies(self) -> QuerySet: |
@@ -37,7 +37,7 b'' | |||||
37 |
|
37 | |||
38 | <div class="thread"> |
|
38 | <div class="thread"> | |
39 | {% for post in thread.get_viewable_replies %} |
|
39 | {% for post in thread.get_viewable_replies %} | |
40 | {% post_view post reply_link=True %} |
|
40 | {% post_view post reply_link=True thread=thread %} | |
41 | {% endfor %} |
|
41 | {% endfor %} | |
42 | </div> |
|
42 | </div> | |
43 |
|
43 |
@@ -62,7 +62,8 b' class AllThreadsView(PostMixin, FileUplo' | |||||
62 | if order == 'bump': |
|
62 | if order == 'bump': | |
63 | threads = threads.order_by('-bump_time') |
|
63 | threads = threads.order_by('-bump_time') | |
64 | else: |
|
64 | else: | |
65 |
threads = threads.filter( |
|
65 | threads = threads.filter(replies__opening=True)\ | |
|
66 | .order_by('-replies__pub_time') | |||
66 | filter = request.GET.get('filter') |
|
67 | filter = request.GET.get('filter') | |
67 | threads = threads.distinct() |
|
68 | threads = threads.distinct() | |
68 |
|
69 | |||
@@ -138,7 +139,6 b' class AllThreadsView(PostMixin, FileUplo' | |||||
138 | text = data[FORM_TEXT] |
|
139 | text = data[FORM_TEXT] | |
139 | file = form.get_file() |
|
140 | file = form.get_file() | |
140 | file_url = form.get_file_url() |
|
141 | file_url = form.get_file_url() | |
141 | threads = data[FORM_THREADS] |
|
|||
142 | images = form.get_images() |
|
142 | images = form.get_images() | |
143 |
|
143 | |||
144 | text = self._remove_invalid_links(text) |
|
144 | text = self._remove_invalid_links(text) | |
@@ -147,7 +147,7 b' class AllThreadsView(PostMixin, FileUplo' | |||||
147 | monochrome = form.is_monochrome() |
|
147 | monochrome = form.is_monochrome() | |
148 |
|
148 | |||
149 | post = Post.objects.create_post(title=title, text=text, file=file, |
|
149 | post = Post.objects.create_post(title=title, text=text, file=file, | |
150 |
ip=ip, tags=tags, |
|
150 | ip=ip, tags=tags, | |
151 | tripcode=form.get_tripcode(), |
|
151 | tripcode=form.get_tripcode(), | |
152 | monochrome=monochrome, images=images, |
|
152 | monochrome=monochrome, images=images, | |
153 | file_url = file_url) |
|
153 | file_url = file_url) |
@@ -60,7 +60,7 b' def api_get_threaddiff(request):' | |||||
60 | PARAMETER_UPDATED: [], |
|
60 | PARAMETER_UPDATED: [], | |
61 | PARAMETER_LAST_UPDATE: None, # TODO Maybe this can be removed already? |
|
61 | PARAMETER_LAST_UPDATE: None, # TODO Maybe this can be removed already? | |
62 | } |
|
62 | } | |
63 |
posts = Post.objects.filter(thread |
|
63 | posts = Post.objects.filter(thread=thread).exclude(uid__in=uids) | |
64 |
|
64 | |||
65 | diff_type = request.GET.get(PARAMETER_DIFF_TYPE, DIFF_TYPE_HTML) |
|
65 | diff_type = request.GET.get(PARAMETER_DIFF_TYPE, DIFF_TYPE_HTML) | |
66 |
|
66 |
@@ -34,8 +34,8 b' class FeedView(PostMixin, BaseBoardView)' | |||||
34 | settings_manager = get_settings_manager(request) |
|
34 | settings_manager = get_settings_manager(request) | |
35 |
|
35 | |||
36 | posts = Post.objects.exclude( |
|
36 | posts = Post.objects.exclude( | |
37 |
thread |
|
37 | thread__tags__in=settings_manager.get_hidden_tags()).order_by( | |
38 |
'-pub_time').prefetch_related('attachments', 'thread' |
|
38 | '-pub_time').prefetch_related('attachments', 'thread') | |
39 | if tripcode: |
|
39 | if tripcode: | |
40 | posts = posts.filter(tripcode=tripcode) |
|
40 | posts = posts.filter(tripcode=tripcode) | |
41 | if favorites: |
|
41 | if favorites: |
@@ -129,7 +129,6 b' class ThreadView(BaseBoardView, PostMixi' | |||||
129 | text = data[FORM_TEXT] |
|
129 | text = data[FORM_TEXT] | |
130 | file = form.get_file() |
|
130 | file = form.get_file() | |
131 | file_url = form.get_file_url() |
|
131 | file_url = form.get_file_url() | |
132 | threads = data[FORM_THREADS] |
|
|||
133 | images = form.get_images() |
|
132 | images = form.get_images() | |
134 |
|
133 | |||
135 | text = self._remove_invalid_links(text) |
|
134 | text = self._remove_invalid_links(text) | |
@@ -138,7 +137,6 b' class ThreadView(BaseBoardView, PostMixi' | |||||
138 |
|
137 | |||
139 | post = Post.objects.create_post(title=title, text=text, file=file, |
|
138 | post = Post.objects.create_post(title=title, text=text, file=file, | |
140 | thread=post_thread, ip=ip, |
|
139 | thread=post_thread, ip=ip, | |
141 | opening_posts=threads, |
|
|||
142 | tripcode=form.get_tripcode(), |
|
140 | tripcode=form.get_tripcode(), | |
143 | images=images, file_url=file_url) |
|
141 | images=images, file_url=file_url) | |
144 | post.notify_clients() |
|
142 | post.notify_clients() |
General Comments 0
You need to be logged in to leave comments.
Login now