thread.py
154 lines
| 4.0 KiB
| text/x-python
|
PythonLexer
neko259
|
r691 | import logging | |
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): | |||
return self.replies.filter(image_width__gt=0).count() | |||
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) | |||
replies = self.replies.order_by('pub_time').defer( | |||
'image_hash', 'poster_user_agent', 'text_markup_type') | |||
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 | |||
""" | |||
query = self.replies.order_by('pub_time') | |||
if view_fields_only: | |||
query = query.defer( | |||
'image_hash', 'poster_user_agent', 'text_markup_type') | |||
return query.all() | |||
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. | |||
""" | |||
return self.get_opening_post().pub_time |