##// END OF EJS Templates
Count PPD only once per day if cache exists.
Count PPD only once per day if cache exists.

File last commit:

r417:dc7b6275 default
r417:dc7b6275 default
Show More
post.py
345 lines | 10.3 KiB | text/x-python | PythonLexer
neko259
Show posts per
r407 from datetime import datetime, timedelta
from datetime import time as dtime
neko259
Moved models to a separate module folder. Starting to split up models file
r384 import os
from random import random
import time
import math
neko259
Split up user models
r386 import re
neko259
Use cache for PPD value
r410 from django.core.cache import cache
neko259
Moved models to a separate module folder. Starting to split up models file
r384
from django.db import models
from django.http import Http404
from django.utils import timezone
from markupfield.fields import MarkupField
from neboard import settings
from boards import thumbs
neko259
Use cache for PPD value
r410 APP_LABEL_BOARDS = 'boards'
CACHE_KEY_PPD = 'ppd'
neko259
Get PPD for the last week
r408 POSTS_PER_DAY_RANGE = range(7)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 BAN_REASON_AUTO = 'Auto'
IMAGE_THUMB_SIZE = (200, 150)
TITLE_MAX_LENGTH = 50
DEFAULT_MARKUP_TYPE = 'markdown'
NO_PARENT = -1
NO_IP = '0.0.0.0'
UNKNOWN_UA = ''
ALL_PAGES = -1
IMAGES_DIRECTORY = 'images/'
FILE_EXTENSION_DELIMITER = '.'
SETTING_MODERATE = "moderate"
REGEX_REPLY = re.compile('>>(\d+)')
class PostManager(models.Manager):
neko259
Count PPD only once per day if cache exists.
r417 def clear_ppd_cache_if_old(self):
"""
If new post in the other day then current post, a day has changed
and we need to remove the PPD cache and recalculate PPD including the
previous day
"""
today = datetime.now().date()
posts = self.filter(pub_time__gte=today)
if posts.exists():
cache.delete(CACHE_KEY_PPD)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def create_post(self, title, text, image=None, thread=None,
ip=NO_IP, tags=None, user=None):
neko259
Count PPD only once per day if cache exists.
r417 self.clear_ppd_cache_if_old()
neko259
Use cache for PPD value
r410
neko259
Moved models to a separate module folder. Starting to split up models file
r384 posting_time = timezone.now()
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 if not thread:
thread = Thread.objects.create(bump_time=posting_time,
last_edit_time=posting_time)
else:
thread.bump()
thread.last_edit_time = posting_time
thread.save()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
post = self.create(title=title,
text=text,
pub_time=posting_time,
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread_new=thread,
neko259
Moved models to a separate module folder. Starting to split up models file
r384 image=image,
poster_ip=ip,
neko259
Count PPD only once per day if cache exists.
r417 poster_user_agent=UNKNOWN_UA, # TODO Get UA at last!
neko259
Moved models to a separate module folder. Starting to split up models file
r384 last_edit_time=posting_time,
user=user)
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread.replies.add(post)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 if tags:
linked_tags = []
for tag in tags:
tag_linked_tags = tag.get_linked_tags()
if len(tag_linked_tags) > 0:
linked_tags.extend(tag_linked_tags)
tags.extend(linked_tags)
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 map(thread.add_tag, tags)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 self._delete_old_threads()
neko259
Moved models to a separate module folder. Starting to split up models file
r384 self.connect_replies(post)
return post
def delete_post(self, post):
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread = post.thread_new
thread.last_edit_time = timezone.now()
thread.save()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
post.delete()
def delete_posts_by_ip(self, ip):
posts = self.filter(poster_ip=ip)
map(self.delete_post, posts)
neko259
Fixed some issues with post model migration
r400 # TODO Move this method to thread manager
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def get_threads(self, tag=None, page=ALL_PAGES,
order_by='-bump_time'):
if tag:
threads = tag.threads
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 if not threads.exists():
neko259
Moved models to a separate module folder. Starting to split up models file
r384 raise Http404
else:
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 threads = Thread.objects.all()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
threads = threads.order_by(order_by)
if page != ALL_PAGES:
thread_count = threads.count()
if page < self._get_page_count(thread_count):
start_thread = page * settings.THREADS_PER_PAGE
end_thread = min(start_thread + settings.THREADS_PER_PAGE,
thread_count)
threads = threads[start_thread:end_thread]
return threads
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 # TODO Move this method to thread manager
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def get_thread_page_count(self, tag=None):
if tag:
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 threads = Thread.objects.filter(tags=tag)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 else:
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 threads = Thread.objects.all()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
return self._get_page_count(threads.count())
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 # TODO Move this method to thread manager
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def _delete_old_threads(self):
"""
Preserves maximum thread count. If there are too many threads,
delete the old ones.
"""
# 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.
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 threads = Thread.objects.all()
neko259
Moved models to a separate module folder. Starting to split up models file
r384 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:]
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 map(Thread.delete_with_posts, old_threads)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
def connect_replies(self, post):
"""Connect replies to a post to show them as a refmap"""
for reply_number in re.finditer(REGEX_REPLY, post.text.raw):
post_id = reply_number.group(1)
ref_post = self.filter(id=post_id)
if ref_post.count() > 0:
referenced_post = ref_post[0]
referenced_post.referenced_posts.add(post)
referenced_post.last_edit_time = post.pub_time
referenced_post.save()
def _get_page_count(self, thread_count):
return int(math.ceil(thread_count / float(settings.THREADS_PER_PAGE)))
neko259
Show posts per
r407 def get_posts_per_day(self):
neko259
Count PPD only once per day if cache exists.
r417 """Get average count of posts per day for the last 7 days"""
neko259
Show posts per
r407
neko259
Use cache for PPD value
r410 ppd = cache.get(CACHE_KEY_PPD)
if ppd:
return ppd
neko259
Show posts per
r407 today = datetime.now().date()
neko259
Get PPD for the last week
r408 posts_per_days = []
for i in POSTS_PER_DAY_RANGE:
neko259
Fixed PPD counting. Before this it was count from the future week
r413 day_end = today - timedelta(i + 1)
day_start = today - timedelta(i + 2)
neko259
Use timezone when getting PPD
r412 day_time_start = timezone.make_aware(datetime.combine(day_start,
dtime()), timezone.get_current_timezone())
day_time_end = timezone.make_aware(datetime.combine(day_end,
dtime()), timezone.get_current_timezone())
neko259
Get PPD for the last week
r408
neko259
Use cache for PPD value
r410 posts_per_days.append(float(self.filter(
pub_time__lte=day_time_end,
pub_time__gte=day_time_start).count()))
neko259
Get PPD for the last week
r408
neko259
Use cache for PPD value
r410 ppd = (sum(posts_per_day for posts_per_day in posts_per_days) /
len(posts_per_days))
cache.set(CACHE_KEY_PPD, ppd)
return ppd
neko259
Show posts per
r407
neko259
Moved models to a separate module folder. Starting to split up models file
r384
class Post(models.Model):
"""A post is a message."""
objects = PostManager()
class Meta:
neko259
Use cache for PPD value
r410 app_label = APP_LABEL_BOARDS
neko259
Moved models to a separate module folder. Starting to split up models file
r384
def _update_image_filename(self, filename):
"""Get unique image filename"""
path = IMAGES_DIRECTORY
new_name = str(int(time.mktime(time.gmtime())))
new_name += str(int(random() * 1000))
new_name += FILE_EXTENSION_DELIMITER
new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
return os.path.join(path, new_name)
title = models.CharField(max_length=TITLE_MAX_LENGTH)
pub_time = models.DateTimeField()
text = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE,
escape_html=False)
image_width = models.IntegerField(default=0)
image_height = models.IntegerField(default=0)
image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
blank=True, sizes=(IMAGE_THUMB_SIZE,),
width_field='image_width',
height_field='image_height')
poster_ip = models.GenericIPAddressField()
poster_user_agent = models.TextField()
thread = models.ForeignKey('Post', null=True, default=None)
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread_new = models.ForeignKey('Thread', null=True, default=None)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 last_edit_time = models.DateTimeField()
user = models.ForeignKey('User', null=True, default=None)
referenced_posts = models.ManyToManyField('Post', symmetrical=False,
null=True,
blank=True, related_name='rfp+')
def __unicode__(self):
return '#' + str(self.id) + ' ' + self.title + ' (' + \
self.text.raw[:50] + ')'
def get_title(self):
title = self.title
if len(title) == 0:
title = self.text.raw[:20]
return title
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def get_sorted_referenced_posts(self):
return self.referenced_posts.order_by('id')
def is_referenced(self):
return self.referenced_posts.all().exists()
neko259
Fixed some issues with post model migration
r400 def is_opening(self):
return self.thread_new.get_replies()[0] == self
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398
class Thread(models.Model):
class Meta:
neko259
Use cache for PPD value
r410 app_label = APP_LABEL_BOARDS
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398
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+')
def get_tags(self):
"""Get a sorted tag list"""
return self.tags.order_by('name')
def bump(self):
"""Bump (move to up) thread"""
if self.can_bump():
self.bump_time = timezone.now()
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def get_reply_count(self):
return self.replies.count()
def get_images_count(self):
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 return self.replies.filter(image_width__gt=0).count()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
def can_bump(self):
"""Check if the thread can be bumped by replying"""
post_count = self.get_reply_count()
return post_count <= settings.MAX_POSTS_PER_THREAD
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def delete_with_posts(self):
"""Completely delete thread"""
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 if self.replies.count() > 0:
map(Post.objects.delete_post, self.replies.all())
self.delete()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
def get_last_replies(self):
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 """Get last replies, not including opening post"""
neko259
Moved models to a separate module folder. Starting to split up models file
r384 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,
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 reply_count - 1)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 last_replies = self.replies.all().order_by('pub_time')[
reply_count - reply_count_to_show:]
return last_replies
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def get_replies(self):
"""Get sorted thread posts"""
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 return self.replies.all().order_by('pub_time')
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def add_tag(self, tag):
"""Connect thread to a tag and tag to a thread"""
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 self.tags.add(tag)
tag.threads.add(self)
neko259
Fixed some issues with post model migration
r400 def get_opening_post(self):
return self.get_replies()[0]
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def __unicode__(self):
neko259
Fixed RSS
r402 return str(self.get_replies()[0].id)
def get_pub_time(self):
neko259
Small design changes. Count board speed since yesterday, not today
r411 return self.get_opening_post().pub_time