Move retention policies enforcement code to the DocumentType model manager. Add corresponding tests (test_auto_trashing and test_auto_delete).

This commit is contained in:
Roberto Rosario
2015-09-27 00:35:56 -04:00
parent 22a29eede3
commit 3e7cd0c1ea
4 changed files with 119 additions and 62 deletions

View File

@@ -1,9 +1,11 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import timedelta
import logging import logging
from django.apps import apps from django.apps import apps
from django.db import models from django.db import models
from django.utils.timezone import now
from .settings import setting_recent_count from .settings import setting_recent_count
@@ -39,6 +41,68 @@ class DocumentTypeManager(models.Manager):
def get_by_natural_key(self, name): def get_by_natural_key(self, name):
return self.get(name=name) return self.get(name=name)
def check_delete_periods(self):
logger.info('Executing')
for document_type in self.all():
logger.info(
'Checking deletion period of document type: %s', document_type
)
if document_type.delete_time_period and document_type.delete_time_unit:
delta = timedelta(
**{
document_type.delete_time_unit: document_type.delete_time_period
}
)
logger.info(
'Document type: %s, has a deletion period delta of: %s',
document_type, delta
)
for document in document_type.deleted_documents.filter(deleted_date_time__lt=now() - delta):
logger.info(
'Document "%s" with id: %d, trashed on: %s, exceded '
'delete period', document, document.pk,
document.deleted_date_time
)
document.delete()
else:
logger.info(
'Document type: %s, has a no retention delta', document_type
)
logger.info('Finshed')
def check_trash_periods(self):
logger.info('Executing')
for document_type in self.all():
logger.info(
'Checking trash period of document type: %s', document_type
)
if document_type.trash_time_period and document_type.trash_time_unit:
delta = timedelta(
**{
document_type.trash_time_unit: document_type.trash_time_period
}
)
logger.info(
'Document type: %s, has a trash period delta of: %s',
document_type, delta
)
for document in document_type.documents.filter(date_added__lt=now() - delta):
logger.info(
'Document "%s" with id: %d, added on: %s, exceded '
'trash period', document, document.pk,
document.date_added
)
document.delete()
else:
logger.info(
'Document type: %s, has a no retention delta', document_type
)
logger.info('Finshed')
class DocumentManager(models.Manager): class DocumentManager(models.Manager):
def get_queryset(self): def get_queryset(self):

View File

@@ -100,6 +100,10 @@ class DocumentType(models.Model):
return super(DocumentType, self).delete(*args, **kwargs) return super(DocumentType, self).delete(*args, **kwargs)
@property
def deleted_documents(self):
return DeletedDocument.objects.filter(document_type=self)
def new_document(self, file_object, label=None, description=None, language=None, _user=None): def new_document(self, file_object, label=None, description=None, language=None, _user=None):
try: try:
with transaction.atomic(): with transaction.atomic():

View File

@@ -24,72 +24,12 @@ logger = logging.getLogger(__name__)
@app.task(ignore_result=True) @app.task(ignore_result=True)
def task_check_delete_periods(): def task_check_delete_periods():
logger.info('Executing') DocumentType.objects.check_delete_periods()
for document_type in DocumentType.objects.all():
logger.info(
'Checking deletion period of document type: %s', document_type
)
if document_type.delete_time_period and document_type.delete_time_unit:
delta = timedelta(
**{
document_type.delete_time_unit: document_type.delete_time_period
}
)
logger.info(
'Document type: %s, has a deletion period delta of: %s',
document_type, delta
)
for document in DeletedDocument.objects.filter(document_type=document_type):
# TODO: Don't iterate, filter documents by expiration
if now() > document.deleted_date_time + delta:
logger.info(
'Document "%s" with id: %d, trashed on: %s, exceded '
'delete period', document, document.pk,
document.deleted_date_time
)
document.delete()
else:
logger.info(
'Document type: %s, has a no retention delta', document_type
)
logger.info('Finshed')
@app.task(ignore_result=True) @app.task(ignore_result=True)
def task_check_trash_periods(): def task_check_trash_periods():
logger.info('Executing') DocumentType.objects.check_trash_periods()
for document_type in DocumentType.objects.all():
logger.info(
'Checking trash period of document type: %s', document_type
)
if document_type.trash_time_period and document_type.trash_time_unit:
delta = timedelta(
**{
document_type.trash_time_unit: document_type.trash_time_period
}
)
logger.info(
'Document type: %s, has a trash period delta of: %s',
document_type, delta
)
for document in Document.objects.filter(document_type=document_type):
# TODO: Don't iterate, filter documents by expiration
if now() > document.date_added + delta:
logger.info(
'Document "%s" with id: %d, added on: %s, exceded '
'trash period', document, document.pk,
document.date_added
)
document.delete()
else:
logger.info(
'Document type: %s, has a no retention delta', document_type
)
logger.info('Finshed')
@app.task(ignore_result=True) @app.task(ignore_result=True)

View File

@@ -5,6 +5,8 @@ import time
from django.core.files import File from django.core.files import File
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from common.literals import TIME_DELTA_UNIT_DAYS
from .literals import ( from .literals import (
TEST_DOCUMENT_TYPE, TEST_DOCUMENT_PATH, TEST_MULTI_PAGE_TIFF_PATH, TEST_DOCUMENT_TYPE, TEST_DOCUMENT_PATH, TEST_MULTI_PAGE_TIFF_PATH,
TEST_OFFICE_DOCUMENT_PATH, TEST_SMALL_DOCUMENT_PATH TEST_OFFICE_DOCUMENT_PATH, TEST_SMALL_DOCUMENT_PATH
@@ -79,6 +81,53 @@ class DocumentTestCase(TestCase):
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
def test_auto_trashing(self):
"""
Test document type trashing policies. Documents are moved to the trash,
x amount of time after being uploaded
"""
self.document_type.trash_time_period = 1
# 'seconds' is not a choice via the model, used here for convenience
self.document_type.trash_time_unit = 'seconds'
self.document_type.save()
time.sleep(1)
self.assertEqual(Document.objects.count(), 1)
self.assertEqual(DeletedDocument.objects.count(), 0)
DocumentType.objects.check_trash_periods()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
def test_auto_delete(self):
"""
Test document type deletion policies. Documents are deleted from the
trash, x amount of time after being trashed
"""
self.document_type.delete_time_period = 1
# 'seconds' is not a choice via the model, used here for convenience
self.document_type.delete_time_unit = 'seconds'
self.document_type.save()
self.assertEqual(Document.objects.count(), 1)
self.assertEqual(DeletedDocument.objects.count(), 0)
self.document.delete()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
time.sleep(1)
DocumentType.objects.check_delete_periods()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 0)
@override_settings(OCR_AUTO_OCR=False) @override_settings(OCR_AUTO_OCR=False)
class OfficeDocumentTestCase(TestCase): class OfficeDocumentTestCase(TestCase):