Merge branch 'feature/bulk_download' into development
This commit is contained in:
84
apps/common/compressed_files.py
Normal file
84
apps/common/compressed_files.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import os, tempfile, zipfile
|
||||
|
||||
try:
|
||||
import zlib
|
||||
COMPRESSION = zipfile.ZIP_DEFLATED
|
||||
except:
|
||||
COMPRESSION = zipfile.ZIP_STORED
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
|
||||
|
||||
class NotACompressedFile(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CompressedFile(object):
|
||||
def __init__(self, file_input=None):
|
||||
if file_input:
|
||||
self._open(file_input)
|
||||
else:
|
||||
self._create()
|
||||
|
||||
def _create(self):
|
||||
self.descriptor = StringIO()
|
||||
self.zf = zipfile.ZipFile(self.descriptor, mode='w')
|
||||
|
||||
def _open(self, file_input):
|
||||
try:
|
||||
# Is it a file like object?
|
||||
file_input.seek(0)
|
||||
except AttributeError:
|
||||
# If not, try open it.
|
||||
self.descriptor = open(file_input, 'r+b')
|
||||
else:
|
||||
self.descriptor = file_input
|
||||
|
||||
try:
|
||||
test = zipfile.ZipFile(self.descriptor, mode='r')
|
||||
except zipfile.BadZipfile:
|
||||
raise NotACompressedFile
|
||||
else:
|
||||
test.close()
|
||||
self.descriptor.seek(0)
|
||||
self.zf = zipfile.ZipFile(self.descriptor, mode='a')
|
||||
|
||||
def add_file(self, file_input, arcname=None):
|
||||
try:
|
||||
# Is it a file like object?
|
||||
file_input.seek(0)
|
||||
except AttributeError:
|
||||
# If not, keep it
|
||||
self.zf.write(filename, arcname=arcname, compress_type=COMPRESSION)
|
||||
else:
|
||||
self.zf.writestr(arcname, file_input.read())
|
||||
|
||||
def contents(self):
|
||||
return [filename for filename in self.zf.namelist() if not filename.endswith('/')]
|
||||
|
||||
def get_content(self, filename):
|
||||
return self.zf.read(filename)
|
||||
|
||||
def write(self, filename=None):
|
||||
# fix for Linux zip files read in Windows
|
||||
for file in self.zf.filelist:
|
||||
file.create_system = 0
|
||||
|
||||
self.descriptor.seek(0)
|
||||
|
||||
if filename:
|
||||
descriptor = open(filename, 'w')
|
||||
descriptor.write(self.descriptor.read())
|
||||
else:
|
||||
return self.descriptor
|
||||
|
||||
def as_file(self, filename):
|
||||
return SimpleUploadedFile(name=filename, content=self.write().read())
|
||||
|
||||
def close(self):
|
||||
self.zf.close()
|
||||
@@ -5,9 +5,9 @@ import tempfile
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common.utils import validate_path, encapsulate
|
||||
from navigation.api import register_links, register_top_menu, \
|
||||
register_model_list_columns, register_multi_item_links, \
|
||||
register_sidebar_template
|
||||
from navigation.api import (register_links, register_top_menu,
|
||||
register_model_list_columns, register_multi_item_links,
|
||||
register_sidebar_template)
|
||||
from main.api import register_diagnostic, register_maintenance_links
|
||||
from tags.widgets import get_tags_inline_widget_simple
|
||||
from history.api import register_history_type
|
||||
@@ -70,6 +70,7 @@ document_multiple_delete = {'text': _(u'delete'), 'view': 'document_multiple_del
|
||||
document_edit = {'text': _(u'edit'), 'view': 'document_edit', 'args': 'object.id', 'famfam': 'page_edit', 'permissions': [PERMISSION_DOCUMENT_PROPERTIES_EDIT]}
|
||||
document_preview = {'text': _(u'preview'), 'class': 'fancybox', 'view': 'document_preview', 'args': 'object.id', 'famfam': 'magnifier', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
|
||||
document_download = {'text': _(u'download'), 'view': 'document_download', 'args': 'object.id', 'famfam': 'page_save', 'permissions': [PERMISSION_DOCUMENT_DOWNLOAD]}
|
||||
document_multiple_download = {'text': _(u'download'), 'view': 'document_multiple_download', 'famfam': 'page_save', 'permissions': [PERMISSION_DOCUMENT_DOWNLOAD]}
|
||||
document_version_download = {'text': _(u'download'), 'view': 'document_version_download', 'args': 'object.pk', 'famfam': 'page_save', 'permissions': [PERMISSION_DOCUMENT_DOWNLOAD]}
|
||||
document_find_duplicates = {'text': _(u'find duplicates'), 'view': 'document_find_duplicates', 'args': 'object.id', 'famfam': 'page_white_copy', 'permissions': [PERMISSION_DOCUMENT_VIEW]}
|
||||
document_find_all_duplicates = {'text': _(u'find all duplicates'), 'view': 'document_find_all_duplicates', 'famfam': 'page_white_copy', 'permissions': [PERMISSION_DOCUMENT_VIEW], 'description': _(u'Search all the documents\' checksums and return a list of the exact matches.')}
|
||||
@@ -130,7 +131,7 @@ register_links(['document_type_filename_create', 'document_type_filename_list',
|
||||
|
||||
# Register document links
|
||||
register_links(Document, [document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations, document_create_siblings])
|
||||
register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete])
|
||||
register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete, document_multiple_download])
|
||||
|
||||
# Document Version links
|
||||
register_links(DocumentVersion, [document_version_revert, document_version_download])
|
||||
|
||||
@@ -29,6 +29,7 @@ urlpatterns = patterns('documents.views',
|
||||
url(r'^(?P<document_id>\d+)/display/thumbnail/base64/$', 'get_document_image', {'size': THUMBNAIL_SIZE, 'base64_version': True}, 'document_thumbnail_base64'),
|
||||
|
||||
url(r'^(?P<document_id>\d+)/download/$', 'document_download', (), 'document_download'),
|
||||
url(r'^multiple/download/$', 'document_multiple_download', (), 'document_multiple_download'),
|
||||
url(r'^(?P<document_id>\d+)/create/siblings/$', 'document_create_siblings', (), 'document_create_siblings'),
|
||||
url(r'^(?P<document_id>\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'),
|
||||
url(r'^(?P<document_id>\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'),
|
||||
|
||||
@@ -13,6 +13,7 @@ from django.views.generic.list_detail import object_list
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.http import urlencode
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.conf import settings
|
||||
|
||||
import sendfile
|
||||
from common.utils import pretty_size, parse_range, urlquote, \
|
||||
@@ -31,6 +32,7 @@ from permissions.models import Permission
|
||||
from document_indexing.api import update_indexes, delete_indexes
|
||||
from history.api import create_history
|
||||
from acls.models import AccessEntry
|
||||
from common.compressed_files import CompressedFile
|
||||
|
||||
from .conf.settings import (PREVIEW_SIZE, STORAGE_BACKEND, ZOOM_PERCENT_STEP,
|
||||
ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL, ROTATION_STEP, PRINT_SIZE,
|
||||
@@ -317,31 +319,72 @@ def get_document_image(request, document_id, size=PREVIEW_SIZE, base64_version=F
|
||||
return sendfile.sendfile(request, document.get_image(size=size, page=page, zoom=zoom, rotation=rotation, version=version), mimetype=DEFAULT_FILE_FORMAT_MIMETYPE)
|
||||
|
||||
|
||||
def document_download(request, document_id=None, document_version_pk=None):
|
||||
if document_version_pk:
|
||||
def document_download(request, document_id=None, document_id_list=None, document_version_pk=None):
|
||||
document_version = None
|
||||
documents = []
|
||||
|
||||
if document_id:
|
||||
documents = [get_object_or_404(Document, pk=document_id)]
|
||||
post_action_redirect = reverse('document_list')
|
||||
elif document_id_list:
|
||||
documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')]
|
||||
elif document_version_pk:
|
||||
document_version = get_object_or_404(DocumentVersion, pk=document_version_pk)
|
||||
else:
|
||||
document_version = get_object_or_404(Document, pk=document_id).latest_version
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_DOWNLOAD])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_DOWNLOAD, request.user, document_version.document)
|
||||
|
||||
try:
|
||||
# Test permissions and trigger exception
|
||||
fd = document_version.open()
|
||||
fd.close()
|
||||
return serve_file(
|
||||
request,
|
||||
document_version.file,
|
||||
save_as=u'"%s"' % document_version.filename,
|
||||
content_type=document_version.mimetype if document_version.mimetype else 'application/octet-stream'
|
||||
)
|
||||
except Exception, e:
|
||||
messages.error(request, e)
|
||||
return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
||||
documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_DOWNLOAD, request.user, documents, exception_on_empty=True)
|
||||
|
||||
if len(documents) == 1:
|
||||
document_version = documents[0].latest_version
|
||||
|
||||
if document_version:
|
||||
try:
|
||||
# Test permissions and trigger exception
|
||||
fd = document_version.open()
|
||||
fd.close()
|
||||
return serve_file(
|
||||
request,
|
||||
document_version.file,
|
||||
save_as=u'"%s"' % document_version.filename,
|
||||
content_type=document_version.mimetype if document_version.mimetype else 'application/octet-stream'
|
||||
)
|
||||
except Exception, e:
|
||||
if settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
messages.error(request, e)
|
||||
return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
||||
else:
|
||||
try:
|
||||
compressed_file = CompressedFile()
|
||||
for document in documents:
|
||||
descriptor = document.open()
|
||||
compressed_file.add_file(descriptor, arcname=document.filename)
|
||||
descriptor.close()
|
||||
|
||||
compressed_file.close()
|
||||
|
||||
return serve_file(
|
||||
request,
|
||||
compressed_file.as_file('document_bundle.zip'),
|
||||
save_as=u'"document_bundle.zip"',
|
||||
content_type='application/zip'
|
||||
)
|
||||
# TODO: DO a redirection afterwards
|
||||
except Exception, e:
|
||||
if settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
messages.error(request, e)
|
||||
return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
||||
|
||||
|
||||
def document_multiple_download(request):
|
||||
return document_download(
|
||||
request, document_id_list=request.GET.get('id_list', [])
|
||||
)
|
||||
|
||||
def document_page_transformation_list(request, document_page_id):
|
||||
document_page = get_object_or_404(DocumentPage, pk=document_page_id)
|
||||
|
||||
Reference in New Issue
Block a user