thread.py
163 lines
| 4.3 KiB
| text/x-python
|
PythonLexer
neko259
|
r691 | import logging | ||
neko259
|
r693 | from django.db.models import Count | ||
neko259
|
r691 | from django.utils import timezone | ||
from django.core.cache import cache | ||||
from django.db import models | ||||
from neboard import settings | ||||
__author__ = 'neko259' | ||||
logger = logging.getLogger(__name__) | ||||
CACHE_KEY_OPENING_POST = 'opening_post_id' | ||||
class Thread(models.Model): | ||||
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) | ||||
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() | ||||
logger.info('Bumped thread %d' % self.id) | ||||
def get_reply_count(self): | ||||
return self.replies.count() | ||||
def get_images_count(self): | ||||
neko259
|
r693 | # TODO Use sum | ||
total_count = 0 | ||||
for post_with_image in self.replies.annotate(images_count=Count( | ||||
'images')): | ||||
total_count += post_with_image.images_count | ||||
return total_count | ||||
neko259
|
r691 | |||
def can_bump(self): | ||||
""" | ||||
Checks if the thread can be bumped by replying to it. | ||||
""" | ||||
if self.archived: | ||||
return False | ||||
post_count = self.get_reply_count() | ||||
return post_count < settings.MAX_POSTS_PER_THREAD | ||||
def delete_with_posts(self): | ||||
""" | ||||
Completely deletes thread and all its posts | ||||
""" | ||||
if self.replies.exists(): | ||||
self.replies.all().delete() | ||||
self.delete() | ||||
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
|
r694 | replies = self.get_replies() | ||
neko259
|
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
|
r694 | query = self.replies.order_by('pub_time').prefetch_related('images') | ||
neko259
|
r691 | if view_fields_only: | ||
neko259
|
r693 | query = query.defer('poster_user_agent', 'text_markup_type') | ||
neko259
|
r691 | return query.all() | ||
neko259
|
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
|
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
|
r694 | return self.get_opening_post().pub_time | ||