extensions-website/extensions/signals.py

90 lines
3.0 KiB
Python

from typing import Union
from django.db.models.signals import pre_save, post_save, post_delete
from django.dispatch import receiver
import django.dispatch
import extensions.models
import extensions.tasks
import files.models
version_changed = django.dispatch.Signal()
version_uploaded = django.dispatch.Signal()
@receiver(post_delete, sender=extensions.models.Preview)
def _delete_file(sender: object, instance: extensions.models.Preview, **kwargs: object) -> None:
instance.file.delete()
@receiver(pre_save, sender=extensions.models.Extension)
@receiver(pre_save, sender=extensions.models.Version)
def _record_changes(
sender: object,
instance: Union[extensions.models.Extension, extensions.models.Version],
**kwargs: object,
) -> None:
was_changed, old_state = instance.pre_save_record()
if hasattr(instance, 'name'):
instance.sanitize('name', was_changed, old_state, **kwargs)
if hasattr(instance, 'description'):
instance.sanitize('description', was_changed, old_state, **kwargs)
instance.record_status_change(was_changed, old_state, **kwargs)
@receiver(post_save, sender=extensions.models.Extension)
def _update_search_index(sender, instance, **kw):
pass # TODO: update search index
def send_notifications(sender=None, instance=None, signal=None, **kw):
pass # TODO: send email notification about new version upload
def extension_should_be_listed(extension):
return (
extension.latest_version is not None
and extension.latest_version.is_listed
and extension.latest_version.date_deleted is None
and extension.status == extension.STATUSES.APPROVED
)
@receiver(post_save, sender=extensions.models.Extension)
@receiver(post_save, sender=extensions.models.Version)
@receiver(post_save, sender=files.models.File)
def _set_is_listed(
sender: object,
instance: Union[extensions.models.Extension, extensions.models.Version, files.models.File],
*args: object,
**kwargs: object,
) -> None:
if isinstance(instance, extensions.models.Extension):
extension = instance
elif isinstance(instance, extensions.models.Version):
extension = instance.extension
else:
# Some file types (e.g., image or video) have no version associated to them.
# But also files which were created but have not yet being related to the versions.
# Since signals is called very early on, we can't assume file.extension will be available.
if not hasattr(instance, 'version'):
return
extension = instance.extension
old_is_listed = extension.is_listed
new_is_listed = extension_should_be_listed(extension)
if old_is_listed == new_is_listed:
return
if extension.status == extensions.models.Extension.STATUSES.APPROVED and not new_is_listed:
extension.status = extensions.models.Extension.STATUSES.INCOMPLETE
extension.is_listed = new_is_listed
extension.save()
version_uploaded.connect(send_notifications, dispatch_uid='send_notifications')