##// END OF EJS Templates
Delete replies properly when deleting a thread. Delete thread directly, not by...
Delete replies properly when deleting a thread. Delete thread directly, not by deleting its OP

File last commit:

r950:e663371b default
r950:e663371b default
Show More
thread.py
190 lines | 5.3 KiB | text/x-python | PythonLexer
neko259
Moved thread model to a separate module
r691 import logging
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
neko259
Backed out changeset a37f5ca1da43
r949 from django.core.cache import cache
neko259
Moved thread model to a separate module
r691 from django.db import models
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 from boards import settings
neko259
Moved thread model to a separate module
r691
__author__ = 'neko259'
logger = logging.getLogger(__name__)
neko259
Backed out changeset a37f5ca1da43
r949 CACHE_KEY_OPENING_POST = 'opening_post_id'
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()
if thread_count > settings.MAX_THREAD_COUNT:
num_threads_to_delete = thread_count - settings.MAX_THREAD_COUNT
old_threads = threads[thread_count - num_threads_to_delete:]
for thread in old_threads:
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 if settings.ARCHIVE_THREADS:
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
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
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')
bump_time = models.DateTimeField()
last_edit_time = models.DateTimeField()
replies = models.ManyToManyField('Post', symmetrical=False, null=True,
blank=True, related_name='tre+')
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
Moved thread model to a separate module
r691
def get_tags(self):
"""
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():
self.bump_time = timezone.now()
neko259
Bump thread only after adding post to it
r885 if self.get_reply_count() >= settings.MAX_POSTS_PER_THREAD:
self.bumpable = False
neko259
Moved thread model to a separate module
r691 logger.info('Bumped thread %d' % self.id)
def get_reply_count(self):
return self.replies.count()
def get_images_count(self):
neko259
Use aggregation to get the thread images count
r891 return self.replies.annotate(images_count=Count(
'images')).aggregate(Sum('images_count'))['images_count__sum']
neko259
Moved thread model to a separate module
r691
def can_bump(self):
"""
Checks if the thread can be bumped by replying to it.
"""
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863 return self.bumpable
neko259
Moved thread model to a separate module
r691
def get_last_replies(self):
"""
Gets several last replies, not including opening post
"""
if settings.LAST_REPLIES_COUNT > 0:
reply_count = self.get_reply_count()
if reply_count > 0:
reply_count_to_show = min(settings.LAST_REPLIES_COUNT,
reply_count - 1)
neko259
Optimized loading post images in post template
r694 replies = self.get_replies()
neko259
Moved thread model to a separate module
r691 last_replies = replies[reply_count - reply_count_to_show:]
return last_replies
def get_skipped_replies_count(self):
"""
Gets number of posts between opening post and last replies.
"""
reply_count = self.get_reply_count()
last_replies_count = min(settings.LAST_REPLIES_COUNT,
reply_count - 1)
return reply_count - last_replies_count - 1
def get_replies(self, view_fields_only=False):
"""
Gets sorted thread posts
"""
neko259
Optimized loading post images in post template
r694 query = self.replies.order_by('pub_time').prefetch_related('images')
neko259
Moved thread model to a separate module
r691 if view_fields_only:
neko259
Fixed thread gallery view
r889 query = query.defer('poster_user_agent')
neko259
Moved thread model to a separate module
r691 return query.all()
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 def get_replies_with_images(self, view_fields_only=False):
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
Moved thread model to a separate module
r691 def add_tag(self, tag):
"""
Connects thread to a tag and tag to a thread
"""
self.tags.add(tag)
neko259
Backed out changeset a37f5ca1da43
r949 def get_opening_post(self, only_id=False):
neko259
Moved thread model to a separate module
r691 """
Gets the first post of the thread
"""
neko259
Backed out changeset a37f5ca1da43
r949 query = self.replies.order_by('pub_time')
if only_id:
query = query.only('id')
opening_post = query.first()
return opening_post
neko259
Moved thread model to a separate module
r691
def get_opening_post_id(self):
"""
Gets ID of the first thread post.
"""
neko259
Backed out changeset a37f5ca1da43
r949 cache_key = CACHE_KEY_OPENING_POST + str(self.id)
opening_post_id = cache.get(cache_key)
if not opening_post_id:
opening_post_id = self.get_opening_post(only_id=True).id
cache.set(cache_key, opening_post_id)
return opening_post_id
neko259
Moved thread model to a separate module
r691
def __unicode__(self):
return str(self.id)
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.
"""
for reply in self.replies.all():
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())