Initial commit to modernize staging file handling including preview generation

This commit is contained in:
Roberto Rosario
2014-07-08 12:35:53 -04:00
parent be5525496e
commit 429d8c07ee
13 changed files with 309 additions and 231 deletions

View File

@@ -143,24 +143,37 @@
});
$("a.fancybox").fancybox({
openEffect : 'elastic',
closeEffect : 'elastic',
'openEffect' : 'elastic',
'closeEffect' : 'elastic',
prevEffect : 'none',
nextEffect : 'none',
'titleShow' : true,
'type' : 'image',
'autoResize': true
'autoResize': true,
});
$("a.fancybox-staging").fancybox({
openEffect : 'elastic',
closeEffect : 'elastic',
prevEffect : 'none',
nextEffect : 'none',
'titleShow' : true,
'type' : 'image',
'autoResize': true
});
$("a.fancybox-staging").click(function(e) {
var $this = $(this);
$.get($this.attr('href'), function( result ) {
if (result.status == 'success') {
$.fancybox.open([
{
href : result.data,
title : $this.attr('title'),
'openEffect' : 'elastic',
'closeEffect' : 'elastic',
prevEffect : 'none',
nextEffect : 'none',
'titleShow' : true,
'type' : 'image',
'autoResize': true,
},
]);
}
})
e.preventDefault();
})
$("a.fancybox-noscaling").fancybox({
openEffect : 'elastic',

View File

@@ -7,6 +7,7 @@ from documents.models import Document
from navigation.api import register_links, register_model_list_columns
from project_setup.api import register_setup
from .classes import StagingFile
from .links import (document_create_multiple, document_create_siblings,
staging_file_delete, setup_sources, setup_web_form_list,
setup_staging_folder_list, setup_watch_folder_list,
@@ -16,23 +17,19 @@ from .links import (document_create_multiple, document_create_siblings,
upload_version)
from .models import (WebForm, StagingFolder, SourceTransformation,
WatchFolder)
from .staging import StagingFile
from .widgets import staging_file_thumbnail
register_links(StagingFile, [staging_file_delete])
register_links([StagingFile], [staging_file_delete])
register_links(SourceTransformation, [setup_source_transformation_edit, setup_source_transformation_delete])
# register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header')
register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list], menu_name='form_header')
# register_links(WebForm, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header')
register_links(WebForm, [setup_web_form_list, setup_staging_folder_list], menu_name='form_header')
register_links(WebForm, [setup_source_transformation_list, setup_source_edit, setup_source_delete])
register_links(['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_edit', 'setup_source_delete', 'setup_source_create'], [setup_sources, setup_source_create], menu_name='sidebar')
# register_links(StagingFolder, [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list], menu_name='form_header')
register_links(StagingFolder, [setup_web_form_list, setup_staging_folder_list], menu_name='form_header')
register_links(StagingFolder, [setup_source_transformation_list, setup_source_edit, setup_source_delete])
@@ -48,7 +45,7 @@ source_views = ['setup_web_form_list', 'setup_staging_folder_list', 'setup_watch
register_model_list_columns(StagingFile, [
{'name': _(u'thumbnail'), 'attribute':
encapsulate(lambda x: staging_file_thumbnail(x))
encapsulate(lambda x: staging_file_thumbnail(x, gallery_name='staging_list', title=x.filename, size='100'))
},
])

79
mayan/apps/sources/api.py Normal file
View File

@@ -0,0 +1,79 @@
from __future__ import absolute_import
import logging
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404
from rest_framework import generics
from rest_framework.response import Response
from converter.exceptions import UnkownConvertError, UnknownFileFormat
from converter.literals import DEFAULT_PAGE_NUMBER, DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
from documents.conf.settings import DISPLAY_SIZE, ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL
#from acls.models import AccessEntry
#from permissions.models import Permission
from .classes import StagingFile
from .resources import SerializerStagingFolder, SerializerStagingFolderFile
from .models import StagingFolder
#from .permissions import PERMISSION_DOCUMENT_VIEW
logger = logging.getLogger(__name__)
# API Views
class APIStagingSourceFileView(generics.GenericAPIView):
def get(self, request, staging_folder_pk, filename):
staging_folder = get_object_or_404(StagingFolder, pk=staging_folder_pk)
return Response(SerializerStagingFolderFile(staging_folder.get_file(filename)).data)
class APIStagingSourceListView(generics.ListAPIView):
serializer_class = SerializerStagingFolder
queryset = StagingFolder.objects.all()
class APIStagingSourceView(generics.RetrieveAPIView):
serializer_class = SerializerStagingFolder
queryset = StagingFolder.objects.all()
class APIStagingSourceFileImageView(generics.GenericAPIView):
def get(self, request, staging_folder_pk, filename):
staging_folder = get_object_or_404(StagingFolder, pk=staging_folder_pk)
staging_file = staging_folder.get_file(filename)
#try:
# Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
#except PermissionDenied:
# AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document)
# Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION])
size = request.GET.get('size', DISPLAY_SIZE)
page = int(request.GET.get('page', DEFAULT_PAGE_NUMBER))
zoom = int(request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
if request.GET.get('as_base64', False):
base64_version = True
if zoom < ZOOM_MIN_LEVEL:
zoom = ZOOM_MIN_LEVEL
if zoom > ZOOM_MAX_LEVEL:
zoom = ZOOM_MAX_LEVEL
rotation = int(request.GET.get('rotation', DEFAULT_ROTATION)) % 360
try:
return Response({'status': 'success',
'data': staging_file.get_image(size=size, page=page, zoom=zoom, rotation=rotation, as_base64=True)
})
except UnknownFileFormat as exception:
return Response({'status': 'error', 'detail': 'unknown_file_format', 'message': unicode(exception)})
except UnkownConvertError as exception:
return Response({'status': 'error', 'detail': 'converter_error', 'message': unicode(exception)})

View File

@@ -0,0 +1,60 @@
from __future__ import absolute_import
import base64
import errno
import os
from django.core.exceptions import ObjectDoesNotExist
from django.core.files import File
from django.core.files.storage import FileSystemStorage
from django.utils.encoding import smart_str
from django.utils.translation import ugettext
from converter.api import convert, cache_cleanup
from converter.literals import (DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION,
DEFAULT_PAGE_NUMBER, DEFAULT_FILE_FORMAT_MIMETYPE)
from documents.conf.settings import DISPLAY_SIZE, THUMBNAIL_SIZE
from mimetype.api import get_mimetype
class StagingFile(object):
"""
Simple class to extend the File class to add preview capabilities
files in a directory on a storage
"""
def __init__(self, staging_folder, filename):
self.staging_folder = staging_folder
self.filename = filename
def __unicode__(self):
return unicode(self.filename)
def open(self):
return open(self.get_full_path(), mode='rb')
#return File(file=descriptor, name=filename)
def get_full_path(self):
return os.path.join(self.staging_folder.folder_path, self.filename)
def get_image(self, size, page, zoom, rotation, as_base64=True):
#return self.get_valid_image(size=size, transformations=transformations)
converted_file_path = convert(self.get_full_path(), size=size)#, cleanup_files=True)#, transformations=transformations)
if as_base64:
mimetype = get_mimetype(open(converted_file_path, 'r'), converted_file_path, mimetype_only=True)[0]
image = open(converted_file_path, 'r')
base64_data = base64.b64encode(image.read())
image.close()
return u'data:%s;base64,%s' % (mimetype, base64_data)
else:
return file_path
#def delete(self, preview_size, transformations):
# cache_cleanup(self.filepath, size=preview_size, transformations=transformations)
# try:
# os.unlink(self.filepath)
# except OSError, exc:
# if exc.errno == errno.ENOENT:
# pass
# else:
# raise Exception(ugettext(u'Unable to delete staging file: %s') % exc)

View File

@@ -1,5 +1,7 @@
from __future__ import absolute_import
import logging
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
@@ -11,6 +13,8 @@ from .models import (WebForm, StagingFolder, SourceTransformation,
from .widgets import FamFamRadioSelect
from .utils import validate_whitelist_blacklist
logger = logging.getLogger(__name__)
class StagingDocumentForm(DocumentForm):
"""
@@ -18,15 +22,16 @@ class StagingDocumentForm(DocumentForm):
StagingFile class passed as 'cls' argument
"""
def __init__(self, *args, **kwargs):
cls = kwargs.pop('cls')
show_expand = kwargs.pop('show_expand', False)
self.source = kwargs.pop('source')
super(StagingDocumentForm, self).__init__(*args, **kwargs)
try:
self.fields['staging_file_id'].choices = [
(staging_file.id, staging_file) for staging_file in cls.get_all()
(hash(staging_file), unicode(staging_file)) for staging_file in self.source.get_files()
]
except:
except Exception as exception:
logger.error('exception: %s' % exception)
pass
if show_expand:

View File

@@ -13,8 +13,7 @@ from .permissions import (PERMISSION_SOURCES_SETUP_VIEW,
document_create_multiple = {'text': _(u'upload new documents'), 'view': 'document_create_multiple', 'famfam': 'page_add', 'permissions': [PERMISSION_DOCUMENT_CREATE], 'children_view_regex': [r'upload_interactive']}
document_create_siblings = {'text': _(u'clone metadata'), 'view': 'document_create_siblings', 'args': 'object.id', 'famfam': 'page_copy', 'permissions': [PERMISSION_DOCUMENT_CREATE]}
staging_file_preview = {'text': _(u'preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'zoom', 'permissions': [PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE]}
staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'delete', 'keep_query': True, 'permissions': [PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE]}
staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': ['source.pk', 'object.filename'], 'famfam': 'delete', 'keep_query': True, 'permissions': [PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE]}
setup_sources = {'text': _(u'sources'), 'view': 'setup_web_form_list', 'famfam': 'application_form', 'icon': 'application_form.png', 'children_classes': [WebForm], 'permissions': [PERMISSION_SOURCES_SETUP_VIEW], 'children_view_regex': [r'setup_web_form', r'setup_staging_folder', r'setup_source_']}
setup_web_form_list = {'text': _(u'web forms'), 'view': 'setup_web_form_list', 'famfam': 'application_form', 'icon': 'application_form.png', 'children_classes': [WebForm], 'permissions': [PERMISSION_SOURCES_SETUP_VIEW]}

View File

@@ -2,10 +2,12 @@ from __future__ import absolute_import
from ast import literal_eval
import logging
import os
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.files.storage import FileSystemStorage
from django.db import models, transaction
from django.utils.translation import ugettext_lazy as _
@@ -20,6 +22,7 @@ from history.api import create_history
from metadata.api import save_metadata_list
from scheduler.api import register_interval_job, remove_job
from .classes import StagingFile
from .literals import (SOURCE_CHOICES, SOURCE_CHOICES_PLURAL,
SOURCE_INTERACTIVE_UNCOMPRESS_CHOICES, SOURCE_CHOICE_WEB_FORM,
SOURCE_CHOICE_STAGING, SOURCE_ICON_DISK, SOURCE_ICON_DRIVE,
@@ -166,6 +169,16 @@ class StagingFolder(InteractiveBaseModel):
return DIMENSION_SEPARATOR.join(dimensions)
def get_file(self, filename):
return StagingFile(staging_folder=self, filename=filename)
def get_files(self):
try:
for entry in sorted([os.path.normcase(f) for f in os.listdir(self.folder_path) if os.path.isfile(os.path.join(self.folder_path, f))]):
yield self.get_file(filename=entry)
except OSError as exception:
raise Exception(ugettext(u'Unable get list of staging files: %s') % exception)
class Meta(InteractiveBaseModel.Meta):
verbose_name = _(u'staging folder')
verbose_name_plural = _(u'staging folders')

View File

@@ -1,6 +1,14 @@
from __future__ import absolute_import
from django.conf.urls import url
from .cleanup import cleanup
cleanup_functions = [cleanup]
#version_0_api_services = [
# #{'urlpattern': url(r'^staging_file/(?P<pk>[0-9]+)/image/$', APIStagingSourceView.as_view(), name='staging-file-image'), 'description': 'Return a base64 image of the staging file', 'url': 'staging_file/<staging file ID>/image/?page=<page number>&zoom=<zoom percent>&rotate=<rotation degrees>'},
# {'urlpattern': url(r'^staging_folder/(?P<pk>[0-9]+)/$', APIStagingSourceView.as_view(), name='staging-source-list'), 'description': '', 'url': 'staging_file/<staging file ID>/image/?page=<page number>&zoom=<zoom percent>&rotate=<rotation degrees>'},
#]

View File

@@ -0,0 +1,29 @@
from __future__ import absolute_import
from rest_framework import serializers
from rest_framework.reverse import reverse
from .classes import StagingFile
from .models import StagingFolder
class SerializerStagingFolderFile(serializers.Serializer):
url = serializers.SerializerMethodField('get_url')
image_url = serializers.SerializerMethodField('get_image_url')
filename = serializers.CharField(max_length=255)
def get_url(self, obj):
return reverse('stagingfolderfile-detail', args=[obj.staging_folder.pk, obj.filename], request=self.context.get('request'))
def get_image_url(self, obj):
return reverse('stagingfolderfile-image-view', args=[obj.staging_folder.pk, obj.filename], request=self.context.get('request'))
class SerializerStagingFolder(serializers.HyperlinkedModelSerializer):
files = serializers.SerializerMethodField('get_files')
def get_files(self, obj):
return [SerializerStagingFolderFile(entry).data for entry in obj.get_files()]
class Meta:
model = StagingFolder

View File

@@ -1,134 +0,0 @@
from __future__ import absolute_import
import errno
import hashlib
import os
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.base import File
from django.utils.encoding import smart_str
from django.utils.translation import ugettext
from converter.api import convert, cache_cleanup
from converter.exceptions import UnknownFileFormat, UnkownConvertError
from documents.conf.settings import THUMBNAIL_SIZE
from mimetype.api import (get_icon_file_path, get_error_icon_file_path,
get_mimetype)
DEFAULT_STAGING_DIRECTORY = u'/tmp'
HASH_FUNCTION = lambda x: hashlib.sha256(x).hexdigest()
def get_all_files(path):
try:
return sorted([os.path.normcase(f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))])
except OSError, exc:
raise Exception(ugettext(u'Unable get list of staging files: %s') % exc)
def _return_new_class():
return type('StagingFile', (StagingFile,), dict(StagingFile.__dict__))
def create_staging_file_class(request, directory_path, source=None):
cls = _return_new_class()
# cls.set_path(evaluate_user_staging_path(request, source))
cls.set_path(directory_path)
if source is not None:
cls.set_source(source)
return cls
class StagingFile(object):
"""
Simple class to encapsulate the files in a directory and hide the
specifics to the view
"""
path = DEFAULT_STAGING_DIRECTORY
source = None
@classmethod
def set_path(cls, path):
cls.path = path
@classmethod
def set_source(cls, source):
cls.source = source
@classmethod
def get_all(cls):
"""
Return a list of StagingFile instances corresponding to the
current path
"""
staging_files = []
for filename in get_all_files(cls.path):
staging_files.append(StagingFile(
filepath=os.path.join(cls.path, filename), source=cls.source))
return staging_files
@classmethod
def get(cls, id):
"""
Return a single StagingFile instance corresponding to the id
given as argument
"""
files_dict = dict([(file.id, file) for file in cls.get_all()])
if id in files_dict:
return files_dict[id]
else:
raise ObjectDoesNotExist
def __init__(self, filepath, source=None):
self.source = source
self.filepath = filepath
self.filename = os.path.basename(filepath)
self._id = HASH_FUNCTION(smart_str(filepath))
def __unicode__(self):
return self.filename
def __repr__(self):
return self.__unicode__()
def __getattr__(self, name):
if name == 'id':
return self._id
else:
raise AttributeError
def upload(self):
"""
Return a StagingFile encapsulated in a File class instance to
allow for easier upload of staging files
"""
try:
return File(file(self.filepath, 'rb'), name=self.filename)
except Exception, exc:
raise Exception(ugettext(u'Unable to upload staging file: %s') % exc)
def delete(self, preview_size, transformations):
cache_cleanup(self.filepath, size=preview_size, transformations=transformations)
try:
os.unlink(self.filepath)
except OSError, exc:
if exc.errno == errno.ENOENT:
pass
else:
raise Exception(ugettext(u'Unable to delete staging file: %s') % exc)
def get_valid_image(self, size=THUMBNAIL_SIZE, transformations=None):
return convert(self.filepath, size=size, cleanup_files=False, transformations=transformations)
def get_image(self, size, transformations):
try:
return self.get_valid_image(size=size, transformations=transformations)
# return convert(self.filepath, size=size, cleanup_files=False, transformations=transformations)
except UnknownFileFormat:
mimetype, encoding = get_mimetype(open(self.filepath, 'rb'), self.filepath)
return get_icon_file_path(mimetype)
except UnkownConvertError:
return get_error_icon_file_path()

View File

@@ -2,14 +2,13 @@ from __future__ import absolute_import
from django.conf.urls import patterns, url
from .api import APIStagingSourceListView,APIStagingSourceView, APIStagingSourceFileView, APIStagingSourceFileImageView
from .literals import (SOURCE_CHOICE_WEB_FORM, SOURCE_CHOICE_STAGING,
SOURCE_CHOICE_WATCH)
from .wizards import DocumentCreateWizard
urlpatterns = patterns('sources.views',
url(r'^staging_file/type/(?P<source_type>\w+)/(?P<source_id>\d+)/(?P<staging_file_id>\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'),
url(r'^staging_file/type/(?P<source_type>\w+)/(?P<source_id>\d+)/(?P<staging_file_id>\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'),
url(r'^staging_file/type/staging_folder/(?P<source_id>\d+)/(?P<staging_file_id>\w+)/thumbnail/$', 'staging_file_thumbnail', (), 'staging_file_thumbnail'),
url(r'^staging_file/(?P<staging_folder_pk>\d+)/(?P<filename>[0-9_\.\w-]+)/delete/$', 'staging_file_delete', name='staging_file_delete'),
url(r'^upload/document/new/interactive/(?P<source_type>\w+)/(?P<source_id>\d+)/$', 'upload_interactive', (), 'upload_interactive'),
url(r'^upload/document/new/interactive/$', 'upload_interactive', (), 'upload_interactive'),
@@ -37,4 +36,13 @@ urlpatterns = patterns('sources.views',
url(r'^create/from/local/multiple/$', DocumentCreateWizard.as_view(), name='document_create_multiple'),
url(r'^(?P<document_id>\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'),
#version_0_api_services = [
url(r'^api/staging_folder/file/(?P<staging_folder_pk>[0-9]+)/(?P<filename>[0-9_\.\w-]+)/image/$', APIStagingSourceFileImageView.as_view(), name='stagingfolderfile-image-view'),
url(r'^api/staging_folder/file/(?P<staging_folder_pk>[0-9]+)/(?P<filename>[0-9_\.\w-]+)/$', APIStagingSourceFileView.as_view(), name='stagingfolderfile-detail'),
url(r'^api/staging_folder/$', APIStagingSourceListView.as_view(), name='stagingfolder-list'),
url(r'^api/staging_folder/(?P<pk>[0-9]+)/$', APIStagingSourceView.as_view(), name='stagingfolder-detail')
#]
)

View File

@@ -3,6 +3,7 @@ from __future__ import absolute_import
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
@@ -219,10 +220,10 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No
elif source_type == SOURCE_CHOICE_STAGING:
staging_folder = get_object_or_404(StagingFolder, pk=source_id)
context['source'] = staging_folder
StagingFile = create_staging_file_class(request, staging_folder.folder_path, source=staging_folder)
if request.method == 'POST':
form = StagingDocumentForm(request.POST, request.FILES,
cls=StagingFile, document_type=document_type,
document_type=document_type,
show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document,
source=staging_folder,
instance=document
@@ -280,15 +281,14 @@ def upload_interactive(request, source_type=None, source_id=None, document_pk=No
raise
messages.error(request, _(u'Unhandled exception: %s') % e)
else:
form = StagingDocumentForm(cls=StagingFile,
document_type=document_type,
form = StagingDocumentForm(document_type=document_type,
show_expand=(staging_folder.uncompress == SOURCE_UNCOMPRESS_CHOICE_ASK) and not document,
source=staging_folder,
instance=document
)
try:
staging_filelist = StagingFile.get_all()
except Exception, e:
staging_filelist = list(staging_folder.get_files())
except Exception as e:
messages.error(request, e)
staging_filelist = []
finally:
@@ -374,63 +374,20 @@ def get_form_filename(form):
return filename
def staging_file_preview(request, source_type, source_id, staging_file_id):
def staging_file_delete(request, staging_folder_pk, filename):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION])
staging_folder = get_object_or_404(StagingFolder, pk=source_id)
StagingFile = create_staging_file_class(request, staging_folder.folder_path)
transformations, errors = SourceTransformation.transformations.get_for_object_as_list(staging_folder)
staging_folder = get_object_or_404(StagingFolder, pk=staging_folder_pk)
output_file = StagingFile.get(staging_file_id).get_image(
size=staging_folder.get_preview_size(),
transformations=transformations
)
if errors and (request.user.is_staff or request.user.is_superuser):
for error in errors:
messages.warning(request, _(u'Staging file transformation error: %(error)s') % {
'error': error
})
return sendfile.sendfile(request, output_file)
def staging_file_thumbnail(request, source_id, staging_file_id):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION])
staging_folder = get_object_or_404(StagingFolder, pk=source_id)
StagingFile = create_staging_file_class(request, staging_folder.folder_path, source=staging_folder)
transformations, errors = SourceTransformation.transformations.get_for_object_as_list(staging_folder)
output_file = StagingFile.get(staging_file_id).get_image(
size=THUMBNAIL_SIZE,
transformations=transformations
)
if errors and (request.user.is_staff or request.user.is_superuser):
for error in errors:
messages.warning(request, _(u'Staging file transformation error: %(error)s') % {
'error': error
})
return sendfile.sendfile(request, output_file)
def staging_file_delete(request, source_type, source_id, staging_file_id):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION])
staging_folder = get_object_or_404(StagingFolder, pk=source_id)
StagingFile = create_staging_file_class(request, staging_folder.folder_path)
staging_file = StagingFile.get(staging_file_id)
staging_file = staging_folder.get_file(filename)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
try:
transformations, errors = SourceTransformation.transformations.get_for_object_as_list(staging_folder)
staging_file.delete(
preview_size=staging_folder.get_preview_size(),
transformations=transformations
)
staging_file.delete()
messages.success(request, _(u'Staging file delete successfully.'))
except Exception, e:
messages.error(request, _(u'Staging file delete error; %s.') % e)
except Exception as exception:
messages.error(request, _(u'Staging file delete error; %s.') % exception)
return HttpResponseRedirect(next)
results = get_active_tab_links()

View File

@@ -1,9 +1,15 @@
from django import forms
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.utils.encoding import force_unicode
from django.utils.html import strip_tags
from django.utils.http import urlencode
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from converter.literals import DEFAULT_PAGE_NUMBER, DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
from documents.conf.settings import (THUMBNAIL_SIZE, PREVIEW_SIZE,
DISPLAY_SIZE, MULTIPAGE_PREVIEW_SIZE)
class FamFamRadioFieldRenderer(forms.widgets.RadioFieldRenderer):
@@ -25,17 +31,55 @@ class FamFamRadioSelect(forms.widgets.RadioSelect):
renderer = FamFamRadioFieldRenderer
def staging_file_thumbnail(staging_file):
try:
staging_file.get_valid_image()
template = u'<a class="fancybox-staging" href="%(url)s" title="%(filename)s" rel="staging")><img class="lazy-load" data-href="%(thumbnail)s" src="%(static_url)simages/ajax-loader.gif" alt="%(string)s" /><noscript><img src="%(thumbnail)s" alt="%(string)s" /></noscript></a>'
except:
template = u'<img class="lazy-load" data-href="%(thumbnail)s" src="%(static_url)simages/ajax-loader.gif" alt="%(string)s" /><noscript><img src="%(thumbnail)s" alt="%(string)s" /></noscript>'
def staging_file_thumbnail(staging_file, **kwargs):
return staging_file_html_widget(staging_file, click_view='stagingfolderfile-image-view', **kwargs)
return mark_safe(template % {
'url': reverse('staging_file_preview', args=[staging_file.source.source_type, staging_file.source.pk, staging_file.id]),
'thumbnail': reverse('staging_file_thumbnail', args=[staging_file.source.pk, staging_file.id]),
'static_url': settings.STATIC_URL,
'string': _(u'thumbnail'),
'filename': staging_file.filename
})
def staging_file_html_widget(staging_file, click_view=None, page=DEFAULT_PAGE_NUMBER, zoom=DEFAULT_ZOOM_LEVEL, rotation=DEFAULT_ROTATION, gallery_name=None, fancybox_class='fancybox-staging', image_class='lazy-load', title=None, size=THUMBNAIL_SIZE, nolazyload=False):
result = []
alt_text = _(u'staging file page image')
query_dict = {
'page': page,
'zoom': zoom,
'rotation': rotation,
'size': size,
}
if gallery_name:
gallery_template = u'rel="%s"' % gallery_name
else:
gallery_template = u''
query_string = urlencode(query_dict)
preview_view = u'%s?%s' % (reverse('stagingfolderfile-image-view', args=[staging_file.staging_folder.pk, staging_file.filename]), query_string)
plain_template = []
plain_template.append(u'<img src="%s" alt="%s" />' % (preview_view, alt_text))
result.append(u'<div class="tc" id="staging_file-%s-%d">' % (staging_file.filename, page if page else DEFAULT_PAGE_NUMBER))
if title:
title_template = u'title="%s"' % strip_tags(title)
else:
title_template = u''
if click_view:
# TODO: fix this hack
query_dict['size'] = PREVIEW_SIZE
query_string = urlencode(query_dict)
result.append(u'<a %s class="%s" href="%s" %s>' % (gallery_template, fancybox_class, u'%s?%s' % (reverse(click_view, args=[staging_file.staging_folder.pk, staging_file.filename]), query_string), title_template))
if nolazyload:
result.append(u'<img style="border: 1px solid black;" src="%s" alt="%s" />' % (preview_view, alt_text))
else:
result.append(u'<img class="thin_border %s" data-original="%s" src="%simages/ajax-loader.gif" alt="%s" />' % (image_class, preview_view, settings.STATIC_URL, alt_text))
result.append(u'<noscript><img style="border: 1px solid black;" src="%s" alt="%s" /></noscript>' % (preview_view, alt_text))
if click_view:
result.append(u'</a>')
result.append(u'</div>')
return mark_safe(u''.join(result))