Add file caching app
Convert document image cache to use file cache manager app. Add setting DOCUMENTS_CACHE_MAXIMUM_SIZE defaults to 500 MB. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -7,11 +7,11 @@ import shutil
|
||||
import uuid
|
||||
|
||||
from django.apps import apps
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db import models, transaction
|
||||
from django.template import Template, Context
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.converter.exceptions import InvalidOfficeFormat, PageCountError
|
||||
@@ -21,10 +21,11 @@ from mayan.apps.converter.utils import get_converter_class
|
||||
from mayan.apps.mimetype.api import get_mimetype
|
||||
|
||||
from ..events import event_document_new_version, event_document_version_revert
|
||||
from ..literals import DOCUMENT_IMAGES_CACHE_NAME
|
||||
from ..managers import DocumentVersionManager
|
||||
from ..settings import setting_fix_orientation, setting_hash_block_size
|
||||
from ..signals import post_document_created, post_version_upload
|
||||
from ..storages import storage_documentversion, storage_documentimagecache
|
||||
from ..storages import storage_documentversion
|
||||
|
||||
from .document_models import Document
|
||||
|
||||
@@ -61,14 +62,6 @@ class DocumentVersion(models.Model):
|
||||
_pre_open_hooks = {}
|
||||
_post_save_hooks = {}
|
||||
|
||||
@classmethod
|
||||
def register_pre_open_hook(cls, order, func):
|
||||
cls._pre_open_hooks[order] = func
|
||||
|
||||
@classmethod
|
||||
def register_post_save_hook(cls, order, func):
|
||||
cls._post_save_hooks[order] = func
|
||||
|
||||
document = models.ForeignKey(
|
||||
on_delete=models.CASCADE, related_name='versions', to=Document,
|
||||
verbose_name=_('Document')
|
||||
@@ -118,12 +111,28 @@ class DocumentVersion(models.Model):
|
||||
|
||||
objects = DocumentVersionManager()
|
||||
|
||||
@classmethod
|
||||
def register_pre_open_hook(cls, order, func):
|
||||
cls._pre_open_hooks[order] = func
|
||||
|
||||
@classmethod
|
||||
def register_post_save_hook(cls, order, func):
|
||||
cls._post_save_hooks[order] = func
|
||||
|
||||
def __str__(self):
|
||||
return self.get_rendered_string()
|
||||
|
||||
@property
|
||||
def cache_filename(self):
|
||||
return 'document-version-{}'.format(self.uuid)
|
||||
@cached_property
|
||||
def cache(self):
|
||||
Cache = apps.get_model(app_label='file_caching', model_name='Cache')
|
||||
return Cache.objects.get(name=DOCUMENT_IMAGES_CACHE_NAME)
|
||||
|
||||
@cached_property
|
||||
def cache_partition(self):
|
||||
partition, created = self.cache.partitions.get_or_create(
|
||||
name='version-{}'.format(self.uuid)
|
||||
)
|
||||
return partition
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
for page in self.pages.all():
|
||||
@@ -164,43 +173,36 @@ class DocumentVersion(models.Model):
|
||||
return first_page.get_api_image_url(*args, **kwargs)
|
||||
|
||||
def get_intermediate_file(self):
|
||||
cache_filename = self.cache_filename
|
||||
logger.debug('Intermidiate filename: %s', cache_filename)
|
||||
|
||||
if storage_documentimagecache.exists(cache_filename):
|
||||
logger.debug('Intermidiate file "%s" found.', cache_filename)
|
||||
|
||||
return storage_documentimagecache.open(cache_filename)
|
||||
cache_filename = 'intermediate_file'
|
||||
cache_file = self.cache_partition.get_file(filename=cache_filename)
|
||||
if cache_file:
|
||||
logger.debug('Intermidiate file found.')
|
||||
return cache_file.open()
|
||||
else:
|
||||
logger.debug('Intermidiate file "%s" not found.', cache_filename)
|
||||
logger.debug('Intermidiate file not found.')
|
||||
|
||||
try:
|
||||
with self.open() as version_file_object:
|
||||
converter = get_converter_class()(file_object=version_file_object)
|
||||
converter = get_converter_class()(
|
||||
file_object=version_file_object
|
||||
)
|
||||
with converter.to_pdf() as pdf_file_object:
|
||||
|
||||
# Since open "wb+" doesn't create files, check if the file
|
||||
# exists, if not then create it
|
||||
if not storage_documentimagecache.exists(cache_filename):
|
||||
storage_documentimagecache.save(
|
||||
name=cache_filename, content=ContentFile(content='')
|
||||
)
|
||||
|
||||
with storage_documentimagecache.open(cache_filename, mode='wb+') as file_object:
|
||||
with self.cache_partition.create_file(filename=cache_filename) as file_object:
|
||||
shutil.copyfileobj(
|
||||
fsrc=pdf_file_object, fdst=file_object
|
||||
)
|
||||
|
||||
return storage_documentimagecache.open(cache_filename)
|
||||
return self.cache_partition.get_file(filename=cache_filename).open()
|
||||
except InvalidOfficeFormat:
|
||||
return self.open()
|
||||
except Exception as exception:
|
||||
# Cleanup in case of error
|
||||
logger.error(
|
||||
'Error creating intermediate file "%s"; %s.',
|
||||
cache_filename, exception
|
||||
)
|
||||
storage_documentimagecache.delete(cache_filename)
|
||||
cache_file = self.cache_partition.get_file(filename=cache_filename)
|
||||
if cache_file:
|
||||
cache_file.delete()
|
||||
raise
|
||||
|
||||
def get_rendered_string(self, preserve_extension=False):
|
||||
@@ -224,7 +226,7 @@ class DocumentVersion(models.Model):
|
||||
natural_key.dependencies = ['documents.Document']
|
||||
|
||||
def invalidate_cache(self):
|
||||
storage_documentimagecache.delete(self.cache_filename)
|
||||
self.cache_partition.purge()
|
||||
for page in self.pages.all():
|
||||
page.invalidate_cache()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user