##// END OF EJS Templates
Fixed issue in thread diff
Fixed issue in thread diff

File last commit:

r891:72a58333 default
r893:e7cc348c default
Show More
thread.py
187 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
from django.core.cache import cache
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__)
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):
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)
tag.threads.add(self)
def remove_tag(self, tag):
self.tags.remove(tag)
tag.threads.remove(self)
def get_opening_post(self, only_id=False):
"""
Gets the first post of the thread
"""
query = self.replies.order_by('pub_time')
if only_id:
query = query.only('id')
opening_post = query.first()
return opening_post
def get_opening_post_id(self):
"""
Gets ID of the first thread post.
"""
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
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
Optimized loading post images in post template
r694 return self.get_opening_post().pub_time
neko259
Use own search form and view
r718
def delete(self, using=None):
if self.replies.exists():
self.replies.all().delete()
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
Use more clean naming of admin entities
r878 return 'T#{}/{}'.format(self.id, self.get_opening_post_id())