Added document preview link and download link
This commit is contained in:
@@ -5,4 +5,22 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'generic_list_subtemplate.html' %}
|
{% include 'generic_list_subtemplate.html' %}
|
||||||
|
|
||||||
|
{% for subtemplate in subtemplates_dict %}
|
||||||
|
{% with subtemplate.title as title %}
|
||||||
|
{% with subtemplate.object_list as object_list %}
|
||||||
|
{% with subtemplate.extra_columns as extra_columns %}
|
||||||
|
{% with subtemplate.hide_object as hide_object %}
|
||||||
|
{% with subtemplate.main_object as main_object %}
|
||||||
|
{% with subtemplate.hide_link as hide_link %}
|
||||||
|
{% include subtemplate.name %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ document_create_multiple = {'text':_('upload multiple documents'), 'view':'docum
|
|||||||
document_view = {'text':_('details'), 'view':'document_view', 'args':'object.id', 'famfam':'page'}
|
document_view = {'text':_('details'), 'view':'document_view', 'args':'object.id', 'famfam':'page'}
|
||||||
document_delete = {'text':_('delete'), 'view':'document_delete', 'args':'object.id', 'famfam':'page_delete'}
|
document_delete = {'text':_('delete'), 'view':'document_delete', 'args':'object.id', 'famfam':'page_delete'}
|
||||||
document_edit = {'text':_('edit'), 'view':'document_edit', 'args':'object.id', 'famfam':'page_edit'}
|
document_edit = {'text':_('edit'), 'view':'document_edit', 'args':'object.id', 'famfam':'page_edit'}
|
||||||
|
document_preview = {'text':_('preview'), 'class':'fancybox', 'view':'document_preview', 'args':'object.id', 'famfam':'magnifier'}
|
||||||
|
document_download = {'text':_('download'), 'view':'document_download', 'args':'object.id', 'famfam':'page_save'}
|
||||||
|
|
||||||
staging_file_preview = {'class':'fancybox', 'text':_('preview'), 'view':'staging_file_preview', 'args':'object.id', 'famfam':'drive_magnify'}
|
staging_file_preview = {'text':_('preview'), 'class':'fancybox', 'view':'staging_file_preview', 'args':'object.id', 'famfam':'drive_magnify'}
|
||||||
|
|
||||||
register_links(Document, [document_view, document_edit, document_delete])
|
register_links(Document, [document_view, document_edit, document_delete, document_preview, document_download])
|
||||||
register_links(Document, [document_list, document_create, document_create_multiple], menu_name='sidebar')
|
register_links(Document, [document_list, document_create, document_create_multiple], menu_name='sidebar')
|
||||||
register_links(['document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list, document_create, document_create_multiple], menu_name='sidebar')
|
register_links(['document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list, document_create, document_create_multiple], menu_name='sidebar')
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ USE_STAGING_DIRECTORY = getattr(settings, 'DOCUMENTS_USE_STAGING_DIRECTORY', Fal
|
|||||||
STAGING_DIRECTORY = getattr(settings, 'DOCUMENTS_STAGING_DIRECTORY', u'/tmp/mayan/staging')
|
STAGING_DIRECTORY = getattr(settings, 'DOCUMENTS_STAGING_DIRECTORY', u'/tmp/mayan/staging')
|
||||||
DELETE_STAGING_FILE_AFTER_UPLOAD = getattr(settings, 'DOCUMENTS_DELETE_STAGING_FILE_AFTER_UPLOAD', False)
|
DELETE_STAGING_FILE_AFTER_UPLOAD = getattr(settings, 'DOCUMENTS_DELETE_STAGING_FILE_AFTER_UPLOAD', False)
|
||||||
STAGING_FILES_PREVIEW_SIZE = getattr(settings, 'DOCUMENTS_STAGING_FILES_PREVIEW_SIZE', '640x480')
|
STAGING_FILES_PREVIEW_SIZE = getattr(settings, 'DOCUMENTS_STAGING_FILES_PREVIEW_SIZE', '640x480')
|
||||||
|
|
||||||
DELETE_LOCAL_ORIGINAL = getattr(settings, 'DOCUMENTS_DELETE_LOCAL_ORIGINAL', False)
|
DELETE_LOCAL_ORIGINAL = getattr(settings, 'DOCUMENTS_DELETE_LOCAL_ORIGINAL', False)
|
||||||
# Saving
|
# Saving
|
||||||
CHECKSUM_FUNCTION = getattr(settings, 'DOCUMENTS_CHECKSUM_FUNCTION', lambda x: hashlib.sha256(x).hexdigest())
|
CHECKSUM_FUNCTION = getattr(settings, 'DOCUMENTS_CHECKSUM_FUNCTION', lambda x: hashlib.sha256(x).hexdigest())
|
||||||
@@ -31,6 +30,8 @@ UUID_FUNCTION = getattr(settings, 'DOCUMENTS_UUID_FUNTION', lambda:unicode(uuid.
|
|||||||
# Storage
|
# Storage
|
||||||
STORAGE_BACKEND = getattr(settings, 'DOCUMENTS_STORAGE_BACKEND', DocumentStorage)
|
STORAGE_BACKEND = getattr(settings, 'DOCUMENTS_STORAGE_BACKEND', DocumentStorage)
|
||||||
STORAGE_DIRECTORY_NAME = getattr(settings, 'DOCUMENTS_STORAGE_DIRECTORY_NAME', 'documents')
|
STORAGE_DIRECTORY_NAME = getattr(settings, 'DOCUMENTS_STORAGE_DIRECTORY_NAME', 'documents')
|
||||||
|
# Usage
|
||||||
|
PREVIEW_SIZE = getattr(settings, 'DOCUMENTS_PREVIEW_SIZE', '640x480')
|
||||||
# Serving
|
# Serving
|
||||||
FILESYSTEM_FILESERVING_ENABLE = getattr(settings, 'DOCUMENTS_FILESYSTEM_FILESERVING_ENABLE', True)
|
FILESYSTEM_FILESERVING_ENABLE = getattr(settings, 'DOCUMENTS_FILESYSTEM_FILESERVING_ENABLE', True)
|
||||||
FILESYSTEM_FILESERVING_PATH = getattr(settings, 'DOCUMENTS_FILESERVING_PATH', u'/tmp/mayan/documents')
|
FILESYSTEM_FILESERVING_PATH = getattr(settings, 'DOCUMENTS_FILESERVING_PATH', u'/tmp/mayan/documents')
|
||||||
|
|||||||
@@ -6,6 +6,19 @@ import tempfile
|
|||||||
#from django.core.files.base import File
|
#from django.core.files.base import File
|
||||||
from documents.conf.settings import TEMPORARY_DIRECTORY
|
from documents.conf.settings import TEMPORARY_DIRECTORY
|
||||||
|
|
||||||
|
|
||||||
|
def in_cache(input_filepath, size, page=0, format='jpg'):
|
||||||
|
temp_directory = TEMPORARY_DIRECTORY if TEMPORARY_DIRECTORY else tempfile.mkdtemp()
|
||||||
|
temp_filename, separator = os.path.splitext(os.path.basename(input_filepath))
|
||||||
|
temp_path = os.path.join(temp_directory, temp_filename)
|
||||||
|
output_arg = '%s_%s%s%s' % (temp_path, size, os.extsep, format)
|
||||||
|
input_arg = '%s[%s]' % (input_filepath, page)
|
||||||
|
if os.path.exists(output_arg):
|
||||||
|
return output_arg
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def convert(input_filepath, size, cache=True, page=0, format='jpg'):
|
def convert(input_filepath, size, cache=True, page=0, format='jpg'):
|
||||||
temp_directory = TEMPORARY_DIRECTORY if TEMPORARY_DIRECTORY else tempfile.mkdtemp()
|
temp_directory = TEMPORARY_DIRECTORY if TEMPORARY_DIRECTORY else tempfile.mkdtemp()
|
||||||
#TODO: generate output file using lightweight hash function on
|
#TODO: generate output file using lightweight hash function on
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ class Document(models.Model):
|
|||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return '%s.%s' % (self.file_filename, self.file_extension)
|
return '%s.%s' % (self.file_filename, self.file_extension)
|
||||||
|
|
||||||
|
def get_fullname(self):
|
||||||
|
return os.extsep.join([self.file_filename, self.file_extension])
|
||||||
|
|
||||||
@models.permalink
|
@models.permalink
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return ('document_view', [self.id])
|
return ('document_view', [self.id])
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ urlpatterns = patterns('documents.views',
|
|||||||
url(r'^document/(?P<document_id>\d+)/$', 'document_view', (), 'document_view'),
|
url(r'^document/(?P<document_id>\d+)/$', 'document_view', (), 'document_view'),
|
||||||
url(r'^document/(?P<document_id>\d+)/delete/$', 'document_delete', (), 'document_delete'),
|
url(r'^document/(?P<document_id>\d+)/delete/$', 'document_delete', (), 'document_delete'),
|
||||||
url(r'^document/(?P<document_id>\d+)/edit/$', 'document_edit', (), 'document_edit'),
|
url(r'^document/(?P<document_id>\d+)/edit/$', 'document_edit', (), 'document_edit'),
|
||||||
|
url(r'^document/(?P<document_id>\d+)/preview/$', 'document_preview', (), 'document_preview'),
|
||||||
|
url(r'^document/(?P<document_id>\d+)/download/$', 'document_download', (), 'document_download'),
|
||||||
|
|
||||||
url(r'^staging_file/(?P<staging_file_id>\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'),
|
url(r'^staging_file/(?P<staging_file_id>\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'),
|
||||||
|
|
||||||
|
|||||||
61
apps/documents/utils.py
Normal file
61
apps/documents/utils.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
from documents.conf.settings import TEMPORARY_DIRECTORY
|
||||||
|
|
||||||
|
|
||||||
|
#http://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python
|
||||||
|
def copyfile(source, dest, buffer_size=1024*1024):
|
||||||
|
"""
|
||||||
|
Copy a file from source to dest. source and dest
|
||||||
|
can either be strings or any object with a read or
|
||||||
|
write method, like StringIO for example.
|
||||||
|
"""
|
||||||
|
if not hasattr(source, 'read'):
|
||||||
|
source = open(source, 'rb')
|
||||||
|
if not hasattr(dest, 'write'):
|
||||||
|
dest = open(dest, 'wb')
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
copy_buffer = source.read(buffer_size)
|
||||||
|
if copy_buffer:
|
||||||
|
dest.write(copy_buffer)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
source.close()
|
||||||
|
dest.close()
|
||||||
|
|
||||||
|
|
||||||
|
def from_descriptor_to_tempfile(input_descriptor, filename, buffer_size=1024*1024):
|
||||||
|
path = os.path.join(TEMPORARY_DIRECTORY, filename)
|
||||||
|
|
||||||
|
output_descriptor = open(path, 'wb')
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
copy_buffer = input_descriptor.read(buffer_size)
|
||||||
|
if copy_buffer:
|
||||||
|
output_descriptor.write(copy_buffer)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
input_descriptor.close()
|
||||||
|
output_descriptor.close()
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def from_descriptor_to_new_tempfile(input_descriptor, buffer_size=1024*1024):
|
||||||
|
output_descriptor, tmp_filename = tempfile.mkstemp()
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
copy_buffer = input_descriptor.read(buffer_size)
|
||||||
|
if copy_buffer:
|
||||||
|
#output_descriptor.write(copy_buffer)
|
||||||
|
os.write(output_descriptor, copy_buffer)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
input_descriptor.close()
|
||||||
|
os.close(output_descriptor)
|
||||||
|
return tmp_filename
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
from urlparse import urlparse
|
|
||||||
from urllib import unquote_plus
|
from urllib import unquote_plus
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
@@ -14,7 +13,8 @@ from django.core.files.base import File
|
|||||||
|
|
||||||
from filetransfers.api import serve_file
|
from filetransfers.api import serve_file
|
||||||
|
|
||||||
from convert import convert
|
from convert import convert, in_cache
|
||||||
|
from utils import from_descriptor_to_tempfile
|
||||||
|
|
||||||
from models import Document, DocumentMetadata, DocumentType, MetadataType
|
from models import Document, DocumentMetadata, DocumentType, MetadataType
|
||||||
from forms import DocumentTypeSelectForm, DocumentCreateWizard, \
|
from forms import DocumentTypeSelectForm, DocumentCreateWizard, \
|
||||||
@@ -27,6 +27,7 @@ from documents.conf.settings import DELETE_STAGING_FILE_AFTER_UPLOAD
|
|||||||
from documents.conf.settings import USE_STAGING_DIRECTORY
|
from documents.conf.settings import USE_STAGING_DIRECTORY
|
||||||
from documents.conf.settings import FILESYSTEM_FILESERVING_ENABLE
|
from documents.conf.settings import FILESYSTEM_FILESERVING_ENABLE
|
||||||
from documents.conf.settings import STAGING_FILES_PREVIEW_SIZE
|
from documents.conf.settings import STAGING_FILES_PREVIEW_SIZE
|
||||||
|
from documents.conf.settings import PREVIEW_SIZE
|
||||||
|
|
||||||
def document_list(request):
|
def document_list(request):
|
||||||
return object_list(
|
return object_list(
|
||||||
@@ -39,10 +40,14 @@ def document_list(request):
|
|||||||
{'name':_(u'mimetype'), 'attribute':'file_mimetype'},
|
{'name':_(u'mimetype'), 'attribute':'file_mimetype'},
|
||||||
{'name':_(u'added'), 'attribute':lambda x: x.date_added.date()},
|
{'name':_(u'added'), 'attribute':lambda x: x.date_added.date()},
|
||||||
],
|
],
|
||||||
|
'subtemplates_dict':[
|
||||||
|
{
|
||||||
|
'name':'fancybox.html',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def document_create(request, multiple=True):
|
def document_create(request, multiple=True):
|
||||||
MetadataFormSet = formset_factory(MetadataForm, extra=0)
|
MetadataFormSet = formset_factory(MetadataForm, extra=0)
|
||||||
wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataFormSet], multiple=multiple)
|
wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataFormSet], multiple=multiple)
|
||||||
@@ -198,6 +203,9 @@ def document_view(request, document_id):
|
|||||||
])
|
])
|
||||||
|
|
||||||
subtemplates_dict = [
|
subtemplates_dict = [
|
||||||
|
{
|
||||||
|
'name':'fancybox.html',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'name':'generic_list_subtemplate.html',
|
'name':'generic_list_subtemplate.html',
|
||||||
'title':_(u'metadata'),
|
'title':_(u'metadata'),
|
||||||
@@ -274,6 +282,37 @@ def document_edit(request, document_id):
|
|||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
|
def document_preview(request, document_id):
|
||||||
|
document = get_object_or_404(Document, pk=document_id)
|
||||||
|
|
||||||
|
filepath = in_cache(document.uuid, PREVIEW_SIZE)
|
||||||
|
|
||||||
|
if filepath:
|
||||||
|
return serve_file(request, File(file=open(filepath, 'r')))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
document.file.open()
|
||||||
|
desc = document.file.storage.open(document.file.path)
|
||||||
|
filepath = from_descriptor_to_tempfile(desc, document.uuid)
|
||||||
|
output_file = convert(filepath, PREVIEW_SIZE)
|
||||||
|
return serve_file(request, File(file=open(output_file, 'r')))
|
||||||
|
except Exception, e:
|
||||||
|
#messages.error(request, e)
|
||||||
|
return HttpResponse(e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def document_download(request, document_id):
|
||||||
|
document = get_object_or_404(Document, pk=document_id)
|
||||||
|
try:
|
||||||
|
#Test permissions and trigger exception
|
||||||
|
document.file.open()
|
||||||
|
return serve_file(request, document.file, save_as=document.get_fullname())
|
||||||
|
except Exception, e:
|
||||||
|
messages.error(request, e)
|
||||||
|
return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
||||||
|
|
||||||
|
|
||||||
def staging_file_preview(request, staging_file_id):
|
def staging_file_preview(request, staging_file_id):
|
||||||
try:
|
try:
|
||||||
filepath = StagingFile.get(staging_file_id).filepath
|
filepath = StagingFile.get(staging_file_id).filepath
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ LOGIN_EXEMPT_URLS = (
|
|||||||
#DOCUMENTS_UUID_FUNCTION = lambda:unicode(uuid.uuid4())
|
#DOCUMENTS_UUID_FUNCTION = lambda:unicode(uuid.uuid4())
|
||||||
# Storage
|
# Storage
|
||||||
#DOCUMENTS_STORAGE_DIRECTORY_NAME = 'documents'
|
#DOCUMENTS_STORAGE_DIRECTORY_NAME = 'documents'
|
||||||
|
# Usage
|
||||||
|
#DOCUMENTS_PREVIEW_SIZE = '640x480'
|
||||||
# Serving
|
# Serving
|
||||||
#DOCUMENTS_FILESYSTEM_FILESERVING_ENABLE = True
|
#DOCUMENTS_FILESYSTEM_FILESERVING_ENABLE = True
|
||||||
#DOCUMENTS_FILESYSTEM_FILESERVING_PATH = u'/tmp/mayan/documents'
|
#DOCUMENTS_FILESYSTEM_FILESERVING_PATH = u'/tmp/mayan/documents'
|
||||||
|
|||||||
Reference in New Issue
Block a user