import os import re from django.db.models.signals import post_save, pre_save, pre_delete, \ post_delete from django.dispatch import receiver from django.utils import timezone from boards import thumbs from boards.abstracts.constants import REGEX_REPLY, THUMB_SIZES from boards.mdx_neboard import get_parser from boards.models import Post, GlobalId, Attachment from boards.models.attachment.viewers import FILE_TYPES_IMAGE from boards.models.post import REGEX_NOTIFICATION, REGEX_GLOBAL_REPLY from boards.models.post.manager import post_import_deps from boards.models.user import Notification from neboard.settings import MEDIA_ROOT @receiver(post_save, sender=Post) def connect_replies(instance, **kwargs): if not kwargs['update_fields']: for reply_number in re.finditer(REGEX_REPLY, instance.get_raw_text()): post_id = reply_number.group(1) try: referenced_post = Post.objects.get(id=post_id) 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 @receiver(post_save, sender=Post) @receiver(post_import_deps, sender=Post) def connect_global_replies(instance, **kwargs): 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) 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 @receiver(post_save, sender=Post) def connect_notifications(instance, **kwargs): 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) @receiver(pre_save, sender=Post) @receiver(post_import_deps, sender=Post) def parse_text(instance, **kwargs): 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() @receiver(post_delete, sender=Post) def delete_global_id(instance, **kwargs): if instance.global_id and instance.global_id.id: instance.global_id.delete() @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_) @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']) @receiver(post_delete, sender=Attachment) def delete_file(instance, **kwargs): if instance.is_internal(): file = MEDIA_ROOT + instance.file.name try: os.remove(file) except FileNotFoundError: pass if instance.mimetype in FILE_TYPES_IMAGE: for size in THUMB_SIZES: file_name_parts = instance.file.name.split('.') thumb_file = MEDIA_ROOT + '{}.{}x{}.{}'.format(file_name_parts[0], size[0], size[1], file_name_parts[1]) try: os.remove(thumb_file) except FileNotFoundError: pass