##// END OF EJS Templates
Refactored thread views
Refactored thread views

File last commit:

r1180:e46298a6 default
r1185:ef257c39 default
Show More
thread.py
243 lines | 7.2 KiB | text/x-python | PythonLexer
neko259
Moved thread model to a separate module
r691 import logging
neko259
Refactored websockets notifications and updating threads when updating posts
r1088 from adjacent import Client
neko259
Started work on the method caching decorator (BB-57)
r957
neko259
Use aggregation to get the thread images count
r891 from django.db.models import Count, Sum
neko259
Moved thread model to a separate module
r691 from django.utils import timezone
from django.db import models
neko259
Started work on the method caching decorator (BB-57)
r957
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 from boards import settings
neko259
Refactoring
r1027 import boards
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 from boards.utils import cached_result, datetime_to_epoch
neko259
Removed unecessary connection of a thread to its replies, cause posts are...
r958 from boards.models.post import Post
neko259
Added type hints to some models and managers
r1083 from boards.models.tag import Tag
neko259
Started work on the method caching decorator (BB-57)
r957
neko259
Moved thread model to a separate module
r691
__author__ = 'neko259'
logger = logging.getLogger(__name__)
neko259
Refactored websockets notifications and updating threads when updating posts
r1088 WS_NOTIFICATION_TYPE_NEW_POST = 'new_post'
WS_NOTIFICATION_TYPE = 'notification_type'
WS_CHANNEL_THREAD = "thread:"
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 class ThreadManager(models.Manager):
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 def process_oldest_threads(self):
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 """
Preserves maximum thread count. If there are too many threads,
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 archive or delete the old ones.
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 """
threads = Thread.objects.filter(archived=False).order_by('-bump_time')
thread_count = threads.count()
neko259
Implemented ini settings parser
r1153 max_thread_count = settings.get_int('Messages', 'MaxThreadCount')
if thread_count > max_thread_count:
num_threads_to_delete = thread_count - max_thread_count
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 old_threads = threads[thread_count - num_threads_to_delete:]
for thread in old_threads:
neko259
Implemented ini settings parser
r1153 if settings.get_bool('Storage', 'ArchiveThreads'):
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 self._archive_thread(thread)
else:
neko259
Use own search form and view
r718 thread.delete()
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716
logger.info('Processed %d old threads' % num_threads_to_delete)
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 def _archive_thread(self, thread):
thread.archived = True
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863 thread.bumpable = False
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 thread.last_edit_time = timezone.now()
neko259
Update all posts in thread diff when the thread become not bumpable (BB-66)
r1029 thread.update_posts_time()
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863 thread.save(update_fields=['archived', 'last_edit_time', 'bumpable'])
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715
neko259
Fixed thread max posts to not create new migration each time it changes in settings
r1136 def get_thread_max_posts():
neko259
Implemented ini settings parser
r1153 return settings.get_int('Messages', 'MaxPostsPerThread')
neko259
Fixed thread max posts to not create new migration each time it changes in settings
r1136
neko259
Moved thread model to a separate module
r691 class Thread(models.Model):
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 objects = ThreadManager()
neko259
Moved thread model to a separate module
r691
class Meta:
app_label = 'boards'
tags = models.ManyToManyField('Tag')
neko259
Added index to thread bump time as sorts on it happen often
r966 bump_time = models.DateTimeField(db_index=True)
neko259
Moved thread model to a separate module
r691 last_edit_time = models.DateTimeField()
archived = models.BooleanField(default=False)
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863 bumpable = models.BooleanField(default=True)
neko259
Fixed thread max posts to not create new migration each time it changes in settings
r1136 max_posts = models.IntegerField(default=get_thread_max_posts)
neko259
Moved thread model to a separate module
r691
neko259
Added type hints to some models and managers
r1083 def get_tags(self) -> list:
neko259
Moved thread model to a separate module
r691 """
Gets a sorted tag list.
"""
return self.tags.order_by('name')
def bump(self):
"""
Bumps (moves to up) thread if possible.
"""
if self.can_bump():
neko259
Update all posts in thread diff when the thread become not bumpable (BB-66)
r1029 self.bump_time = self.last_edit_time
neko259
Moved thread model to a separate module
r691
neko259
If we are replying a multi-thread post, update all its threads and their...
r1046 self.update_bump_status()
neko259
Bump thread only after adding post to it
r885
neko259
Moved thread model to a separate module
r691 logger.info('Bumped thread %d' % self.id)
neko259
Added type hints to some models and managers
r1083 def has_post_limit(self) -> bool:
neko259
Added ability to disable bump limit of a thread
r1055 return self.max_posts > 0
neko259
Fixed moving thread to bump limit. Fixed multipost in the not bumpable thread
r1134 def update_bump_status(self, exclude_posts=None):
neko259
Added ability to disable bump limit of a thread
r1055 if self.has_post_limit() and self.get_reply_count() >= self.max_posts:
neko259
If we are replying a multi-thread post, update all its threads and their...
r1046 self.bumpable = False
neko259
Fixed moving thread to bump limit. Fixed multipost in the not bumpable thread
r1134 self.update_posts_time(exclude_posts=exclude_posts)
neko259
If we are replying a multi-thread post, update all its threads and their...
r1046
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 def _get_cache_key(self):
return [datetime_to_epoch(self.last_edit_time)]
@cached_result(key_method=_get_cache_key)
neko259
Added type hints to some models and managers
r1083 def get_reply_count(self) -> int:
neko259
Removed unecessary connection of a thread to its replies, cause posts are...
r958 return self.get_replies().count()
neko259
Moved thread model to a separate module
r691
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 @cached_result(key_method=_get_cache_key)
neko259
Added type hints to some models and managers
r1083 def get_images_count(self) -> int:
neko259
Removed unecessary connection of a thread to its replies, cause posts are...
r958 return self.get_replies().annotate(images_count=Count(
neko259
Refactored post and thread models
r1091 'images')).aggregate(Sum('images_count'))['images_count__sum']
neko259
Moved thread model to a separate module
r691
neko259
Added type hints to some models and managers
r1083 def can_bump(self) -> bool:
neko259
Moved thread model to a separate module
r691 """
Checks if the thread can be bumped by replying to it.
"""
neko259
Small thread code refactoring
r1026 return self.bumpable and not self.archived
neko259
Moved thread model to a separate module
r691
neko259
Added type hints to some models and managers
r1083 def get_last_replies(self) -> list:
neko259
Moved thread model to a separate module
r691 """
Gets several last replies, not including opening post
"""
neko259
Implemented ini settings parser
r1153 last_replies_count = settings.get_int('View', 'LastRepliesCount')
if last_replies_count > 0:
neko259
Moved thread model to a separate module
r691 reply_count = self.get_reply_count()
if reply_count > 0:
neko259
Implemented ini settings parser
r1153 reply_count_to_show = min(last_replies_count,
neko259
Moved thread model to a separate module
r691 reply_count - 1)
neko259
Optimized loading post images in post template
r694 replies = self.get_replies()
neko259
Backed out changeset 68e7bfc6c078
r987 last_replies = replies[reply_count - reply_count_to_show:]
neko259
Moved thread model to a separate module
r691
return last_replies
neko259
Added type hints to some models and managers
r1083 def get_skipped_replies_count(self) -> int:
neko259
Moved thread model to a separate module
r691 """
Gets number of posts between opening post and last replies.
"""
reply_count = self.get_reply_count()
neko259
Implemented ini settings parser
r1153 last_replies_count = min(settings.get_int('View', 'LastRepliesCount'),
neko259
Moved thread model to a separate module
r691 reply_count - 1)
return reply_count - last_replies_count - 1
neko259
Added type hints to some models and managers
r1083 def get_replies(self, view_fields_only=False) -> list:
neko259
Moved thread model to a separate module
r691 """
Gets sorted thread posts
"""
neko259
Allow connecting post to many threads
r979 query = Post.objects.filter(threads__in=[self])
neko259
Always show main thread for post in post link. Prefetch thread replies' thread and threads
r984 query = query.order_by('pub_time').prefetch_related('images', 'thread', 'threads')
neko259
Moved thread model to a separate module
r691 if view_fields_only:
neko259
Fixed issue with deferring a field no more exists
r1079 query = query.defer('poster_ip')
neko259
Moved thread model to a separate module
r691 return query.all()
neko259
Added tree mode for the thread
r1180 def get_top_level_replies(self):
return self.get_replies().exclude(refposts__threads__in=[self])
neko259
Added type hints to some models and managers
r1083 def get_replies_with_images(self, view_fields_only=False) -> list:
neko259
Delete replies properly when deleting a thread. Delete thread directly, not by...
r950 """
Gets replies that have at least one image attached
"""
neko259
Moved post image to a separate model. Each post (as of model) can contain multiple images now. The image shown to the user is got with get_first_image method
r693 return self.get_replies(view_fields_only).annotate(images_count=Count(
'images')).filter(images_count__gt=0)
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 # TODO Do we still need this?
neko259
Added type hints to some models and managers
r1083 def add_tag(self, tag: Tag):
neko259
Moved thread model to a separate module
r691 """
Connects thread to a tag and tag to a thread
"""
self.tags.add(tag)
neko259
Added type hints to some models and managers
r1083 def get_opening_post(self, only_id=False) -> Post:
neko259
Moved thread model to a separate module
r691 """
Gets the first post of the thread
"""
neko259
Removed unecessary connection of a thread to its replies, cause posts are...
r958 query = self.get_replies().order_by('pub_time')
neko259
Backed out changeset a37f5ca1da43
r949 if only_id:
query = query.only('id')
opening_post = query.first()
return opening_post
neko259
Moved thread model to a separate module
r691
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 @cached_result()
neko259
Added type hints to some models and managers
r1083 def get_opening_post_id(self) -> int:
neko259
Moved thread model to a separate module
r691 """
Gets ID of the first thread post.
"""
neko259
Started work on the method caching decorator (BB-57)
r957 return self.get_opening_post(only_id=True).id
neko259
Moved thread model to a separate module
r691
def get_pub_time(self):
"""
Gets opening post's pub time because thread does not have its own one.
"""
neko259
Backed out changeset a37f5ca1da43
r949 return self.get_opening_post().pub_time
neko259
Use own search form and view
r718
def delete(self, using=None):
neko259
Delete replies properly when deleting a thread. Delete thread directly, not by...
r950 """
Deletes thread with all replies.
"""
neko259
Fixed creating new thread that was broken after messing up dependencies in...
r959 for reply in self.get_replies().all():
neko259
Delete replies properly when deleting a thread. Delete thread directly, not by...
r950 reply.delete()
neko259
Use own search form and view
r718
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863 super(Thread, self).delete(using)
neko259
Show thread, post and tag names in admin with python3
r875
def __str__(self):
neko259
Delete replies properly when deleting a thread. Delete thread directly, not by...
r950 return 'T#{}/{}'.format(self.id, self.get_opening_post_id())
neko259
Refactoring
r1027
neko259
Added type hints to some models and managers
r1083 def get_tag_url_list(self) -> list:
neko259
Update all posts in thread diff when the thread become not bumpable (BB-66)
r1029 return boards.models.Tag.objects.get_tag_url_list(self.get_tags())
neko259
Fixed moving thread to bump limit. Fixed multipost in the not bumpable thread
r1134 def update_posts_time(self, exclude_posts=None):
neko259
If we are replying a multi-thread post, update all its threads and their...
r1046 for post in self.post_set.all():
neko259
Fixed moving thread to bump limit. Fixed multipost in the not bumpable thread
r1134 if exclude_posts is not None and post not in exclude_posts:
# Manual update is required because uids are generated on save
post.last_edit_time = self.last_edit_time
post.save(update_fields=['last_edit_time'])
neko259
Added index on post. Update post uids when the thread reaches bumplimit
r1120
neko259
Fixed moving thread to bump limit. Fixed multipost in the not bumpable thread
r1134 post.threads.update(last_edit_time=self.last_edit_time)
neko259
Refactored websockets notifications and updating threads when updating posts
r1088
neko259
Refactored post and thread models
r1091 def notify_clients(self):
neko259
Implemented ini settings parser
r1153 if not settings.get_bool('External', 'WebsocketsEnabled'):
neko259
Refactored websockets notifications and updating threads when updating posts
r1088 return
client = Client()
channel_name = WS_CHANNEL_THREAD + str(self.get_opening_post_id())
client.publish(channel_name, {
WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST,
})
neko259
Added ability to cache method result with additional arguments. Cache thread...
r1106 client.send()
neko259
Added ability to show multiple banners. Added "view on site" link for the post...
r1149
def get_absolute_url(self):
return self.get_opening_post().get_absolute_url()