diff --git a/mayan/apps/main/templates/base.html b/mayan/apps/main/templates/base.html index ca3e3cc88d..ff9c7055b0 100644 --- a/mayan/apps/main/templates/base.html +++ b/mayan/apps/main/templates/base.html @@ -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', diff --git a/mayan/apps/sources/__init__.py b/mayan/apps/sources/__init__.py index 4aabeeb182..f9e36d9604 100644 --- a/mayan/apps/sources/__init__.py +++ b/mayan/apps/sources/__init__.py @@ -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')) }, ]) diff --git a/mayan/apps/sources/api.py b/mayan/apps/sources/api.py new file mode 100644 index 0000000000..415b2d2960 --- /dev/null +++ b/mayan/apps/sources/api.py @@ -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)}) + diff --git a/mayan/apps/sources/classes.py b/mayan/apps/sources/classes.py new file mode 100644 index 0000000000..b8fce53c8e --- /dev/null +++ b/mayan/apps/sources/classes.py @@ -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) diff --git a/mayan/apps/sources/forms.py b/mayan/apps/sources/forms.py index 714343530b..2263102e30 100644 --- a/mayan/apps/sources/forms.py +++ b/mayan/apps/sources/forms.py @@ -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: diff --git a/mayan/apps/sources/links.py b/mayan/apps/sources/links.py index f62dfd9076..38b666f465 100644 --- a/mayan/apps/sources/links.py +++ b/mayan/apps/sources/links.py @@ -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]} diff --git a/mayan/apps/sources/models.py b/mayan/apps/sources/models.py index 8c8dcab399..b4ea42f645 100644 --- a/mayan/apps/sources/models.py +++ b/mayan/apps/sources/models.py @@ -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') diff --git a/mayan/apps/sources/registry.py b/mayan/apps/sources/registry.py index 520ea4d909..2e4b6bdd54 100644 --- a/mayan/apps/sources/registry.py +++ b/mayan/apps/sources/registry.py @@ -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[0-9]+)/image/$', APIStagingSourceView.as_view(), name='staging-file-image'), 'description': 'Return a base64 image of the staging file', 'url': 'staging_file//image/?page=&zoom=&rotate='}, +# {'urlpattern': url(r'^staging_folder/(?P[0-9]+)/$', APIStagingSourceView.as_view(), name='staging-source-list'), 'description': '', 'url': 'staging_file//image/?page=&zoom=&rotate='}, +#] + diff --git a/mayan/apps/sources/resources.py b/mayan/apps/sources/resources.py new file mode 100644 index 0000000000..5728fe92d5 --- /dev/null +++ b/mayan/apps/sources/resources.py @@ -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 diff --git a/mayan/apps/sources/staging.py b/mayan/apps/sources/staging.py deleted file mode 100644 index da06d140b1..0000000000 --- a/mayan/apps/sources/staging.py +++ /dev/null @@ -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() diff --git a/mayan/apps/sources/urls.py b/mayan/apps/sources/urls.py index 2936597e10..9487eb1da5 100644 --- a/mayan/apps/sources/urls.py +++ b/mayan/apps/sources/urls.py @@ -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\w+)/(?P\d+)/(?P\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'), - url(r'^staging_file/type/(?P\w+)/(?P\d+)/(?P\w+)/delete/$', 'staging_file_delete', (), 'staging_file_delete'), - url(r'^staging_file/type/staging_folder/(?P\d+)/(?P\w+)/thumbnail/$', 'staging_file_thumbnail', (), 'staging_file_thumbnail'), + url(r'^staging_file/(?P\d+)/(?P[0-9_\.\w-]+)/delete/$', 'staging_file_delete', name='staging_file_delete'), url(r'^upload/document/new/interactive/(?P\w+)/(?P\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\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'), + + +#version_0_api_services = [ + url(r'^api/staging_folder/file/(?P[0-9]+)/(?P[0-9_\.\w-]+)/image/$', APIStagingSourceFileImageView.as_view(), name='stagingfolderfile-image-view'), + url(r'^api/staging_folder/file/(?P[0-9]+)/(?P[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[0-9]+)/$', APIStagingSourceView.as_view(), name='stagingfolder-detail') +#] + ) diff --git a/mayan/apps/sources/views.py b/mayan/apps/sources/views.py index 2cc55de94b..7567b318cd 100644 --- a/mayan/apps/sources/views.py +++ b/mayan/apps/sources/views.py @@ -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() diff --git a/mayan/apps/sources/widgets.py b/mayan/apps/sources/widgets.py index f55223290a..2d7fdb77a9 100644 --- a/mayan/apps/sources/widgets.py +++ b/mayan/apps/sources/widgets.py @@ -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'%(string)s' - except: - template = u'%(string)s' +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'%s' % (preview_view, alt_text)) + + result.append(u'
' % (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'' % (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'%s' % (preview_view, alt_text)) + else: + result.append(u'%s' % (image_class, preview_view, settings.STATIC_URL, alt_text)) + result.append(u'' % (preview_view, alt_text)) + + if click_view: + result.append(u'') + result.append(u'
') + + return mark_safe(u''.join(result))