##// END OF EJS Templates
Fixed get computing. Visually differing get posts in thread.
Fixed get computing. Visually differing get posts in thread.

File last commit:

r42:37e52c98 default
r42:37e52c98 default
Show More
models.py
212 lines | 5.8 KiB | text/x-python | PythonLexer
import os
import re
from django.db import models
from django.utils import timezone
import time
from neboard import settings
from markupfield.fields import MarkupField
import thumbs
NO_PARENT = -1
NO_IP = '0.0.0.0'
UNKNOWN_UA = ''
def update_image_filename(instance, filename):
"""Get unique image filename"""
path = 'images/'
new_name = str(int(time.mktime(time.gmtime()))) + '_' + filename
return os.path.join(path, new_name)
class PostManager(models.Manager):
def create_post(self, title, text, image=None, parent_id=NO_PARENT,
ip=NO_IP, tags=None):
post = self.create(title=title,
text=text,
pub_time=timezone.now(),
parent=parent_id,
image=image,
poster_ip=ip,
poster_user_agent=UNKNOWN_UA,
last_edit_time=timezone.now())
if tags:
for tag in tags:
post.tags.add(tag)
if parent_id != NO_PARENT:
self._bump_thread(parent_id)
else:
self._delete_old_threads()
return post
def delete_post(self, post):
children = self.filter(parent=post.id)
for child in children:
self.delete_post(child)
post.delete()
def delete_posts_by_ip(self, ip):
posts = self.filter(poster_ip=ip)
for post in posts:
self.delete_post(post)
def get_threads(self, tag=None):
if tag:
threads = self.filter(parent=NO_PARENT, tags=tag)
else:
threads = self.filter(parent=NO_PARENT)
threads = list(threads.order_by('-last_edit_time'))
return threads
def get_thread(self, opening_post_id):
opening_post = self.get(id=opening_post_id)
if opening_post.parent == NO_PARENT:
replies = self.filter(parent=opening_post_id)
thread = [opening_post]
thread.extend(replies)
return thread
def exists(self, post_id):
posts = self.filter(id=post_id)
return len(posts) > 0
def _delete_old_threads(self):
"""
Preserves maximum thread count. If there are too many threads,
delete the old ones.
"""
# TODO Try to find a better way to get the active thread count.
# TODO Move old threads to the archive instead of deleting them.
# Maybe make some 'old' field in the model to indicate the thread
# must not be shown and be able for replying.
threads = self.get_threads()
thread_count = len(threads)
if thread_count > settings.MAX_THREAD_COUNT:
num_threads_to_delete = thread_count - settings.MAX_THREAD_COUNT
old_threads = threads[-num_threads_to_delete:]
for thread in old_threads:
self.delete_post(thread)
def _bump_thread(self, thread_id):
thread = self.get(id=thread_id)
replies_count = len(self.get_thread(thread_id))
if replies_count <= settings.MAX_POSTS_PER_THREAD:
thread.last_edit_time = timezone.now()
thread.save()
class TagManager(models.Manager):
def get_not_empty_tags(self):
all_tags = self.all().order_by('name')
tags = []
for tag in all_tags:
if not tag.is_empty():
tags.append(tag)
return tags
class Tag(models.Model):
"""
A tag is a text node assigned to the post. The tag serves as a board
section. There can be multiple tags for each message
"""
objects = TagManager()
name = models.CharField(max_length=100)
# TODO Connect the tag to its posts to check the number of threads for
# the tag.
def __unicode__(self):
return self.name
def is_empty(self):
return self.get_post_count() == 0
def get_post_count(self):
posts_with_tag = Post.objects.get_threads(tag=self)
return len(posts_with_tag)
class Post(models.Model):
"""A post is a message."""
objects = PostManager()
title = models.CharField(max_length=50)
pub_time = models.DateTimeField()
text = MarkupField(default_markup_type='markdown', escape_html=True)
image = thumbs.ImageWithThumbsField(upload_to=update_image_filename,
blank=True, sizes=((200, 150),))
poster_ip = models.IPAddressField()
poster_user_agent = models.TextField()
parent = models.BigIntegerField()
tags = models.ManyToManyField(Tag)
last_edit_time = models.DateTimeField()
def __unicode__(self):
return self.title + ' (' + self.text.raw + ')'
def _get_replies(self):
return Post.objects.filter(parent=self.id)
def get_reply_count(self):
return len(self._get_replies())
def get_images_count(self):
images_count = 1 if self.image else 0
for reply in self._get_replies():
if reply.image:
images_count += 1
return images_count
def get_gets_count(self):
gets_count = 1 if self.is_get() else 0
for reply in self._get_replies():
if reply.is_get():
gets_count += 1
return gets_count
def is_get(self):
"""If the post has pretty id (1, 1000, 77777), than it is called GET"""
first = self.id == 1
# TODO Compile regexes
id_str = str(self.id)
pretty = re.match(r'^\d(0)+$', id_str)
same_digits = re.match(r'^(.)\1+$', id_str)
return first or pretty or same_digits
class Admin(models.Model):
"""
Model for admin users
"""
name = models.CharField(max_length=100)
password = models.CharField(max_length=100)
def __unicode__(self):
return self.name + '/' + '*' * len(self.password)