##// END OF EJS Templates
If there is no post update time, use pub time
If there is no post update time, use pub time

File last commit:

r2008:5d3c1f7e default
r2098:c4ac6a57 default
Show More
signals.py
136 lines | 5.0 KiB | text/x-python | PythonLexer
neko259
Refactorings, refactorings...
r2008 import os
neko259
Define signals outside of the post model
r1512 import re
neko259
Remove file after the attachment was removed
r1784 from django.db.models.signals import post_save, pre_save, pre_delete, \
post_delete
from django.dispatch import receiver
from django.utils import timezone
neko259
Store images as regular attachments instead of separate model
r1590 from boards import thumbs
neko259
Refactorings, refactorings...
r2008 from boards.abstracts.constants import REGEX_REPLY, THUMB_SIZES
neko259
Define signals outside of the post model
r1512 from boards.mdx_neboard import get_parser
neko259
Refactorings, refactorings...
r2008 from boards.models import Post, GlobalId, Attachment
neko259
Store images as regular attachments instead of separate model
r1590 from boards.models.attachment.viewers import FILE_TYPES_IMAGE
neko259
Unify thread and post creation into one method inside post manager, that can be called from almost anywhere (one step closer to ajax thread creation)
r1997 from boards.models.post import REGEX_NOTIFICATION, REGEX_GLOBAL_REPLY
neko259
Added support for partial import: when the reply is imported but the original post is not, the reply will be connected after the original post is ready
r1588 from boards.models.post.manager import post_import_deps
neko259
Define signals outside of the post model
r1512 from boards.models.user import Notification
neko259
Remove file after the attachment was removed
r1784 from neboard.settings import MEDIA_ROOT
neko259
Define signals outside of the post model
r1512
@receiver(post_save, sender=Post)
def connect_replies(instance, **kwargs):
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 if not kwargs['update_fields']:
for reply_number in re.finditer(REGEX_REPLY, instance.get_raw_text()):
post_id = reply_number.group(1)
neko259
Define signals outside of the post model
r1512
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 try:
referenced_post = Post.objects.get(id=post_id)
neko259
Define signals outside of the post model
r1512
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 if not referenced_post.referenced_posts.filter(
id=instance.id).exists():
referenced_post.referenced_posts.add(instance)
referenced_post.last_edit_time = instance.pub_time
referenced_post.build_refmap()
referenced_post.save(update_fields=['refmap', 'last_edit_time'])
except Post.DoesNotExist:
pass
neko259
Define signals outside of the post model
r1512
@receiver(post_save, sender=Post)
neko259
Added support for partial import: when the reply is imported but the original post is not, the reply will be connected after the original post is ready
r1588 @receiver(post_import_deps, sender=Post)
neko259
Parse global id reflinks
r1515 def connect_global_replies(instance, **kwargs):
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 if not kwargs['update_fields']:
for reply_number in re.finditer(REGEX_GLOBAL_REPLY, instance.get_raw_text()):
key_type = reply_number.group(1)
key = reply_number.group(2)
local_id = reply_number.group(3)
neko259
Parse global id reflinks
r1515
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 try:
global_id = GlobalId.objects.get(key_type=key_type, key=key,
local_id=local_id)
referenced_post = Post.objects.get(global_id=global_id)
referenced_post.referenced_posts.add(instance)
referenced_post.last_edit_time = instance.pub_time
referenced_post.build_refmap()
referenced_post.save(update_fields=['refmap', 'last_edit_time'])
except (GlobalId.DoesNotExist, Post.DoesNotExist):
pass
neko259
Parse global id reflinks
r1515
@receiver(post_save, sender=Post)
neko259
Define signals outside of the post model
r1512 def connect_notifications(instance, **kwargs):
neko259
Connect replies only if this is a generic save, not some specific fields update
r1837 if not kwargs['update_fields']:
for reply_number in re.finditer(REGEX_NOTIFICATION, instance.get_raw_text()):
user_name = reply_number.group(1).lower()
Notification.objects.get_or_create(name=user_name, post=instance)
neko259
Define signals outside of the post model
r1512
@receiver(pre_save, sender=Post)
neko259
Added support for partial import: when the reply is imported but the original post is not, the reply will be connected after the original post is ready
r1588 @receiver(post_import_deps, sender=Post)
def parse_text(instance, **kwargs):
neko259
Define signals outside of the post model
r1512 instance._text_rendered = get_parser().parse(instance.get_raw_text())
@receiver(pre_delete, sender=Post)
def delete_attachments(instance, **kwargs):
for attachment in instance.attachments.all():
attachment_refs_count = attachment.attachment_posts.count()
if attachment_refs_count == 1:
attachment.delete()
@receiver(post_delete, sender=Post)
def update_thread_on_delete(instance, **kwargs):
thread = instance.get_thread()
thread.last_edit_time = timezone.now()
thread.save()
neko259
Delete global ID when deleting post. Cache model's content XML tag into global ID
r1520
@receiver(post_delete, sender=Post)
def delete_global_id(instance, **kwargs):
if instance.global_id and instance.global_id.id:
instance.global_id.delete()
neko259
Store images as regular attachments instead of separate model
r1590
@receiver(post_save, sender=Attachment)
def generate_thumb(instance, **kwargs):
if instance.mimetype in FILE_TYPES_IMAGE:
for size in THUMB_SIZES:
(w, h) = size
split = instance.file.name.rsplit('.', 1)
thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1])
if not instance.file.storage.exists(thumb_name):
# you can use another thumbnailing function if you like
thumb_content = thumbs.generate_thumb(instance.file, size, split[1])
thumb_name_ = instance.file.storage.save(thumb_name, thumb_content)
if not thumb_name == thumb_name_:
raise ValueError(
'There is already a file named %s' % thumb_name_)
neko259
Rebuild refmap after post from it was deleted
r1619
@receiver(pre_delete, sender=Post)
def rebuild_refmap(instance, **kwargs):
for referenced_post in instance.refposts.all():
referenced_post.build_refmap(excluded_ids=[instance.id])
referenced_post.save(update_fields=['refmap'])
neko259
Remove file after the attachment was removed
r1784
@receiver(post_delete, sender=Attachment)
def delete_file(instance, **kwargs):
if instance.is_internal():
file = MEDIA_ROOT + instance.file.name
neko259
Allow deleting attachments with their files already deleted
r1879 try:
os.remove(file)
except FileNotFoundError:
pass
neko259
Remove file after the attachment was removed
r1784 if instance.mimetype in FILE_TYPES_IMAGE:
for size in THUMB_SIZES:
file_name_parts = instance.file.name.split('.')
Fix Python 3.3 compatibility
r1829 thumb_file = MEDIA_ROOT + '{}.{}x{}.{}'.format(file_name_parts[0], size[0], size[1], file_name_parts[1])
neko259
Allow deleting attachments with their files already deleted
r1879 try:
os.remove(thumb_file)
except FileNotFoundError:
pass
neko259
Remove file after the attachment was removed
r1784