Complete staging file caching refactor.
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -2,16 +2,13 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.views.decorators.cache import cache_control, patch_cache_control
|
|
||||||
|
|
||||||
from converter.models import Transformation
|
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from .literals import STAGING_FILE_IMAGE_TASK_TIMEOUT
|
from .literals import STAGING_FILE_IMAGE_TASK_TIMEOUT
|
||||||
from .models import StagingFolderSource
|
from .models import StagingFolderSource
|
||||||
from .serializers import StagingFolderFileSerializer, StagingFolderSerializer
|
from .serializers import StagingFolderFileSerializer, StagingFolderSerializer
|
||||||
from .settings import settings_staging_file_image_cache_time
|
|
||||||
from .storages import storage_staging_file_image_cache
|
from .storages import storage_staging_file_image_cache
|
||||||
from .tasks import task_generate_staging_file_image
|
from .tasks import task_generate_staging_file_image
|
||||||
|
|
||||||
@@ -76,8 +73,4 @@ class APIStagingSourceFileImageView(generics.RetrieveAPIView):
|
|||||||
|
|
||||||
with storage_staging_file_image_cache.open(cache_filename) as file_object:
|
with storage_staging_file_image_cache.open(cache_filename) as file_object:
|
||||||
response = HttpResponse(file_object.read(), content_type='image')
|
response = HttpResponse(file_object.read(), content_type='image')
|
||||||
if '_hash' in request.GET:
|
|
||||||
patch_cache_control(
|
|
||||||
response, max_age=settings_staging_file_image_cache_time.value
|
|
||||||
)
|
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ from django.core.files.base import ContentFile
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||||
|
|
||||||
from converter import BaseTransformation, TransformationResize, converter_class
|
from converter import TransformationResize, converter_class
|
||||||
from converter.literals import DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
|
|
||||||
|
|
||||||
from .storages import storage_staging_file_image_cache
|
from .storages import storage_staging_file_image_cache
|
||||||
|
|
||||||
@@ -76,42 +75,30 @@ class StagingFile(object):
|
|||||||
return '{}{}'.format(self.staging_folder.pk, self.encoded_filename)
|
return '{}{}'.format(self.staging_folder.pk, self.encoded_filename)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
#TODO: delete cached files
|
storage_staging_file_image_cache.delete(self.cache_filename)
|
||||||
os.unlink(self.get_full_path())
|
os.unlink(self.get_full_path())
|
||||||
|
|
||||||
def generate_image(self, *args, **kwargs):
|
def generate_image(self, *args, **kwargs):
|
||||||
transformation_list = self.get_combined_transformation_list(*args, **kwargs)
|
transformation_list = self.get_combined_transformation_list(*args, **kwargs)
|
||||||
|
|
||||||
cache_filename = '{}-{}'.format(
|
|
||||||
self.cache_filename, BaseTransformation.combine(transformation_list)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check is transformed image is available
|
# Check is transformed image is available
|
||||||
logger.debug('transformations cache filename: %s', cache_filename)
|
logger.debug('transformations cache filename: %s', self.cache_filename)
|
||||||
|
|
||||||
if storage_staging_file_image_cache.exists(cache_filename):
|
if storage_staging_file_image_cache.exists(self.cache_filename):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'transformations cache file "%s" found', cache_filename
|
'staging file cache file "%s" found', self.cache_filename
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'transformations cache file "%s" not found', cache_filename
|
'staging file cache file "%s" not found', self.cache_filename
|
||||||
)
|
)
|
||||||
image = self.get_image(transformations=transformation_list)
|
image = self.get_image(transformations=transformation_list)
|
||||||
with storage_staging_file_image_cache.open(cache_filename, 'wb+') as file_object:
|
with storage_staging_file_image_cache.open(self.cache_filename, 'wb+') as file_object:
|
||||||
file_object.write(image.getvalue())
|
file_object.write(image.getvalue())
|
||||||
|
|
||||||
#self.cached_images.create(filename=cache_filename)
|
return self.cache_filename
|
||||||
|
|
||||||
return cache_filename
|
|
||||||
|
|
||||||
def get_api_image_url(self, *args, **kwargs):
|
def get_api_image_url(self, *args, **kwargs):
|
||||||
transformations_hash = BaseTransformation.combine(
|
|
||||||
self.get_combined_transformation_list(*args, **kwargs)
|
|
||||||
)
|
|
||||||
|
|
||||||
kwargs.pop('transformations', None)
|
|
||||||
|
|
||||||
final_url = furl()
|
final_url = furl()
|
||||||
final_url.args = kwargs
|
final_url.args = kwargs
|
||||||
final_url.path = reverse(
|
final_url.path = reverse(
|
||||||
@@ -120,7 +107,6 @@ class StagingFile(object):
|
|||||||
self.encoded_filename
|
self.encoded_filename
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
final_url.args['_hash'] = transformations_hash
|
|
||||||
|
|
||||||
return final_url.tostr()
|
return final_url.tostr()
|
||||||
|
|
||||||
@@ -135,8 +121,8 @@ class StagingFile(object):
|
|||||||
|
|
||||||
# Set sensible defaults if the argument is not specified or if the
|
# Set sensible defaults if the argument is not specified or if the
|
||||||
# argument is None
|
# argument is None
|
||||||
width = kwargs.get('width', self.staging_folder.preview_width) or self.staging_folder.preview_width
|
width = self.staging_folder.preview_width
|
||||||
height = kwargs.get('height', self.staging_folder.preview_height) or self.staging_folder.preview_height
|
height = self.staging_folder.preview_height
|
||||||
|
|
||||||
# Generate transformation hash
|
# Generate transformation hash
|
||||||
transformation_list = []
|
transformation_list = []
|
||||||
@@ -161,39 +147,30 @@ class StagingFile(object):
|
|||||||
def get_image(self, transformations=None):
|
def get_image(self, transformations=None):
|
||||||
cache_filename = self.cache_filename
|
cache_filename = self.cache_filename
|
||||||
file_object = None
|
file_object = None
|
||||||
logger.debug('Page cache filename: %s', cache_filename)
|
|
||||||
|
|
||||||
if storage_staging_file_image_cache.exists(cache_filename):
|
try:
|
||||||
logger.debug('Page cache file "%s" found', cache_filename)
|
file_object = open(self.get_full_path())
|
||||||
file_object = storage_staging_file_image_cache.open(cache_filename)
|
|
||||||
converter = converter_class(file_object=file_object)
|
converter = converter_class(file_object=file_object)
|
||||||
|
|
||||||
converter.seek(0)
|
page_image = converter.get_page()
|
||||||
else:
|
|
||||||
logger.debug('Page cache file "%s" not found', cache_filename)
|
|
||||||
try:
|
|
||||||
file_object = open(self.get_full_path())
|
|
||||||
converter = converter_class(file_object=file_object)
|
|
||||||
|
|
||||||
page_image = converter.get_page()
|
# Since open "wb+" doesn't create files, check if the file
|
||||||
|
# exists, if not then create it
|
||||||
|
if not storage_staging_file_image_cache.exists(cache_filename):
|
||||||
|
storage_staging_file_image_cache.save(name=cache_filename, content=ContentFile(content=''))
|
||||||
|
|
||||||
# Since open "wb+" doesn't create files, check if the file
|
with storage_staging_file_image_cache.open(cache_filename, 'wb+') as file_object:
|
||||||
# exists, if not then create it
|
file_object.write(page_image.getvalue())
|
||||||
if not storage_staging_file_image_cache.exists(cache_filename):
|
except Exception as exception:
|
||||||
storage_staging_file_image_cache.save(name=cache_filename, content=ContentFile(content=''))
|
# Cleanup in case of error
|
||||||
|
logger.error(
|
||||||
with storage_staging_file_image_cache.open(cache_filename, 'wb+') as file_object:
|
'Error creating staging file cache "%s"; %s',
|
||||||
file_object.write(page_image.getvalue())
|
cache_filename, exception
|
||||||
except Exception as exception:
|
)
|
||||||
# Cleanup in case of error
|
storage_staging_file_image_cache.delete(cache_filename)
|
||||||
logger.error(
|
if file_object:
|
||||||
'Error creating page cache file "%s"; %s',
|
file_object.close()
|
||||||
cache_filename, exception
|
raise
|
||||||
)
|
|
||||||
storage_staging_file_image_cache.delete(cache_filename)
|
|
||||||
if file_object:
|
|
||||||
file_object.close()
|
|
||||||
raise
|
|
||||||
|
|
||||||
for transformation in transformations:
|
for transformation in transformations:
|
||||||
converter.transform(transformation=transformation)
|
converter.transform(transformation=transformation)
|
||||||
|
|||||||
@@ -31,10 +31,3 @@ setting_staging_file_image_cache_storage_arguments = namespace.add_setting(
|
|||||||
'Arguments to pass to the SOURCES_STAGING_FILE_CACHE_STORAGE_BACKEND.'
|
'Arguments to pass to the SOURCES_STAGING_FILE_CACHE_STORAGE_BACKEND.'
|
||||||
), quoted=True,
|
), quoted=True,
|
||||||
)
|
)
|
||||||
settings_staging_file_image_cache_time = namespace.add_setting(
|
|
||||||
global_name='SOURCES_STAGING_FILE_IMAGE_CACHE_TIME', default='31556926',
|
|
||||||
help_text=_(
|
|
||||||
'Time in seconds that the browser should cache the supplied staging '
|
|
||||||
'file images. The default of 31559626 seconds corresponde to 1 year.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from common.exceptions import NoMIMETypeMatch
|
|||||||
from lock_manager import LockError
|
from lock_manager import LockError
|
||||||
from lock_manager.runtime import locking_backend
|
from lock_manager.runtime import locking_backend
|
||||||
|
|
||||||
from .classes import StagingFile
|
|
||||||
from .literals import (
|
from .literals import (
|
||||||
DEFAULT_SOURCE_LOCK_EXPIRE, DEFAULT_SOURCE_TASK_RETRY_DELAY
|
DEFAULT_SOURCE_LOCK_EXPIRE, DEFAULT_SOURCE_TASK_RETRY_DELAY
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user