diff --git a/apps/iiif/manifests/admin.py b/apps/iiif/manifests/admin.py index 98e544cc..2b9d77d5 100644 --- a/apps/iiif/manifests/admin.py +++ b/apps/iiif/manifests/admin.py @@ -1,4 +1,4 @@ -"""Django admin module for maninfests""" +"""Django admin module for manifests""" from django.contrib import admin from django.http import HttpResponseRedirect from django.http.request import HttpRequest @@ -85,12 +85,6 @@ def get_urls(self): ] return my_urls + urls - def save_model(self, request, obj, form, change): - # Add/update Volume in the Elasticsearch index. - index = ManifestDocument() - index.update(obj, True, 'index') - super().save_model(request, obj, form, change) - class NoteAdmin(admin.ModelAdmin): """Django admin configuration for a note.""" class Meta: # pylint: disable=too-few-public-methods, missing-class-docstring diff --git a/apps/iiif/manifests/models.py b/apps/iiif/manifests/models.py index 33aa37bd..b38836de 100644 --- a/apps/iiif/manifests/models.py +++ b/apps/iiif/manifests/models.py @@ -1,4 +1,5 @@ """Django models for IIIF manifests""" +from os import environ from uuid import uuid4, UUID from json import JSONEncoder from boto3 import resource @@ -16,6 +17,8 @@ from ..choices import Choices from ..kollections.models import Collection from..models import IiifBase +from .tasks import index_manifest_task, de_index_manifest_task + JSONEncoder_olddefault = JSONEncoder.default # pylint: disable = invalid-name def JSONEncoder_newdefault(self, o): # pylint: disable = invalid-name @@ -357,9 +360,15 @@ def save(self, *args, **kwargs): # pylint: disable = arguments-differ collection.modified_at = self.modified_at collection.save() + if environ["DJANGO_ENV"] != 'test': # pragma: no cover + index_manifest_task.apply_async(args=[str(self.id)]) + else: + index_manifest_task(str(self.id)) + + def delete(self, *args, **kwargs): """ - When a manifest is delted, the related canvas objects are deleted (`on_delete`=models.CASCADE). + When a manifest is deleted, the related canvas objects are deleted (`on_delete`=models.CASCADE). However, the `delete` method is not called on the canvas objects. We need to do that so the files can be cleaned up. https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.CASCADE @@ -367,13 +376,13 @@ def delete(self, *args, **kwargs): for canvas in self.canvas_set.all(): canvas.delete() - # Delete from Elasticsearch index - from .documents import ManifestDocument - index = ManifestDocument() - index.update(self, True, 'delete') - super().delete(*args, **kwargs) + # if environ["DJANGO_ENV"] != 'test': # pragma: no cover + # de_index_manifest_task.apply_async(args=[str(self.id)]) + # else: + # de_index_manifest_task(str(self.id)) + def __rename_s3_objects(self): original_pid = self.get_dirty_fields()['pid'] diff --git a/apps/iiif/manifests/tasks.py b/apps/iiif/manifests/tasks.py new file mode 100644 index 00000000..2f3a9542 --- /dev/null +++ b/apps/iiif/manifests/tasks.py @@ -0,0 +1,33 @@ +from celery import Celery +from django.apps import apps + +app = Celery('apps.iiif.manifests', result_extended=True) + +@app.task(name='index_manifest', autoretry_for=(Exception,), retry_backoff=True, max_retries=20) +def index_manifest_task(manifest_id): + """Background task index Manifest after save. + + :param manifest_id: Primary key for .models.Manifest object + :type manifest_id: UUID + + """ + from .models import Manifest + from .documents import ManifestDocument + index = ManifestDocument() + manifest = Manifest.objects.get(pk=manifest_id) + index.update(manifest, True, 'index') + + +@app.task(name='de-index_manifest', autoretry_for=(Exception,), retry_backoff=True, max_retries=20) +def de_index_manifest_task(manifest_id): + """Background task to de-index Manifest after delete. + + :param manifest_id: Primary key for .models.Manifest object + :type manifest_id: UUID + + """ + from .models import Manifest + from .documents import ManifestDocument + index = ManifestDocument() + manifest = Manifest.objects.get(pk=manifest_id) + index.update(manifest, True, 'delete')