Initial commit to modernize staging file handling including preview generation
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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
79
mayan/apps/sources/api.py
Normal 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)})
|
||||
|
||||
60
mayan/apps/sources/classes.py
Normal file
60
mayan/apps/sources/classes.py
Normal 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)
|
||||
@@ -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:
|
||||
|
||||
@@ -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]}
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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>'},
|
||||
#]
|
||||
|
||||
|
||||
29
mayan/apps/sources/resources.py
Normal file
29
mayan/apps/sources/resources.py
Normal 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
|
||||
@@ -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()
|
||||
@@ -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')
|
||||
#]
|
||||
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user