bgneal@922: """Signal handlers for the downloads application.
bgneal@922: 
bgneal@203: We use signals to compute the denormalized category counts whenever a download
bgneal@922: is saved.
bgneal@922: 
bgneal@922: """
bgneal@203: from django.db.models.signals import post_save
bgneal@203: from django.db.models.signals import post_delete
bgneal@203: 
bgneal@664: from downloads.models import Category, Download, PendingDownload
bgneal@203: 
bgneal@203: 
bgneal@203: def on_download_save(sender, **kwargs):
bgneal@203:     """This function updates the count field for all categories.
bgneal@203:     It is called whenever a download is saved via a signal.
bgneal@203:     """
bgneal@203:     if kwargs['created']:
bgneal@203:         # we only have to update the parent category
bgneal@203:         download = kwargs['instance']
bgneal@203:         cat = download.category
bgneal@203:         cat.count = Download.public_objects.filter(category=cat).count()
bgneal@203:         cat.save()
bgneal@203:     else:
bgneal@203:         # update all categories just to be safe (an existing download could
bgneal@203:         # have been moved from one category to another
bgneal@203:         cats = Category.objects.all()
bgneal@203:         for cat in cats:
bgneal@203:             cat.count = Download.public_objects.filter(category=cat).count()
bgneal@203:             cat.save()
bgneal@203: 
bgneal@203: 
bgneal@203: def on_download_delete(sender, **kwargs):
bgneal@203:     """This function updates the count field for the download's parent
bgneal@203:     category. It is called when a download is deleted via a signal.
bgneal@664: 
bgneal@664:     We now delete the uploaded file when the download is deleted.
bgneal@203:     """
bgneal@203:     # update the parent category
bgneal@203:     download = kwargs['instance']
bgneal@203:     cat = download.category
bgneal@203:     cat.count = Download.public_objects.filter(category=cat).count()
bgneal@203:     cat.save()
bgneal@203: 
bgneal@664:     # delete the actual file
bgneal@664:     if download.file:
bgneal@664:         download.file.delete(save=False)
bgneal@664: 
bgneal@664: 
bgneal@664: def on_pending_download_delete(sender, **kwargs):
bgneal@664:     """Delete the uploaded file if it exists."""
bgneal@664: 
bgneal@664:     download = kwargs['instance']
bgneal@664:     # delete the actual file
bgneal@664:     if download.file:
bgneal@664:         download.file.delete(save=False)
bgneal@664: 
bgneal@203: 
bgneal@260: post_save.connect(on_download_save, sender=Download,
bgneal@922:         dispatch_uid='downloads.receivers')
bgneal@260: post_delete.connect(on_download_delete, sender=Download,
bgneal@922:         dispatch_uid='downloads.receivers')
bgneal@664: post_delete.connect(on_pending_download_delete, sender=PendingDownload,
bgneal@922:         dispatch_uid='downloads.receivers')