Added support for showing a staging file's thumbnail

This commit is contained in:
Roberto Rosario
2011-07-24 05:15:56 -04:00
parent 8aa72a954b
commit 37677e89f0
6 changed files with 84 additions and 37 deletions

View File

@@ -38,6 +38,7 @@ mimetype_icons = {
'application/vnd.ms-powerpoint': 'file_extension_pps.png', 'application/vnd.ms-powerpoint': 'file_extension_pps.png',
'application/wav' : 'file_extension_wav.png', 'application/wav' : 'file_extension_wav.png',
'application/x-wav' : 'file_extension_wav.png', 'application/x-wav' : 'file_extension_wav.png',
'application/vnd.oasis.opendocument.text' : 'ODF_textdocument_32x32.png',
'image/jpeg' : 'file_extension_jpeg.png', 'image/jpeg' : 'file_extension_jpeg.png',
'image/png' : 'file_extension_png.png', 'image/png' : 'file_extension_png.png',
@@ -89,7 +90,7 @@ def get_mimetype(filepath):
if USE_PYTHON_MAGIC: if USE_PYTHON_MAGIC:
if os.path.exists(filepath): if os.path.exists(filepath):
try: try:
source = open(filepath, 'r') source = open(filepath, 'rb')
mime = magic.Magic(mime=True) mime = magic.Magic(mime=True)
file_mimetype = mime.from_buffer(source.read()) file_mimetype = mime.from_buffer(source.read())
source.seek(0) source.seek(0)

View File

@@ -7,6 +7,7 @@ from permissions.api import register_permission, set_namespace_title
from sources.staging import StagingFile from sources.staging import StagingFile
from sources.models import WebForm, StagingFolder, SourceTransformation from sources.models import WebForm, StagingFolder, SourceTransformation
from sources.widgets import staging_file_thumbnail
PERMISSION_SOURCES_SETUP_VIEW = {'namespace': 'sources_setup', 'name': 'sources_setup_view', 'label': _(u'View existing document sources')} PERMISSION_SOURCES_SETUP_VIEW = {'namespace': 'sources_setup', 'name': 'sources_setup_view', 'label': _(u'View existing document sources')}
PERMISSION_SOURCES_SETUP_EDIT = {'namespace': 'sources_setup', 'name': 'sources_setup_edit', 'label': _(u'Edit document sources')} PERMISSION_SOURCES_SETUP_EDIT = {'namespace': 'sources_setup', 'name': 'sources_setup_edit', 'label': _(u'Edit document sources')}
@@ -19,7 +20,6 @@ register_permission(PERMISSION_SOURCES_SETUP_EDIT)
register_permission(PERMISSION_SOURCES_SETUP_DELETE) register_permission(PERMISSION_SOURCES_SETUP_DELETE)
register_permission(PERMISSION_SOURCES_SETUP_CREATE) register_permission(PERMISSION_SOURCES_SETUP_CREATE)
staging_file_preview = {'text': _(u'preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'zoom'} staging_file_preview = {'text': _(u'preview'), 'class': 'fancybox-noscaling', 'view': 'staging_file_preview', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'zoom'}
staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'delete', 'keep_query': True} staging_file_delete = {'text': _(u'delete'), 'view': 'staging_file_delete', 'args': ['source.source_type', 'source.pk', 'object.id'], 'famfam': 'delete', 'keep_query': True}
@@ -37,7 +37,7 @@ setup_source_transformation_delete = {'text': _(u'delete'), 'view': 'setup_sourc
source_list = {'text': _(u'Document sources'), 'view': 'setup_web_form_list', 'famfam': 'page_add', 'children_url_regex': [r'sources/setup']} source_list = {'text': _(u'Document sources'), 'view': 'setup_web_form_list', 'famfam': 'page_add', 'children_url_regex': [r'sources/setup']}
register_links(StagingFile, [staging_file_preview, staging_file_delete]) register_links(StagingFile, [staging_file_delete])
register_links(SourceTransformation, [setup_source_transformation_edit, setup_source_transformation_delete]) register_links(SourceTransformation, [setup_source_transformation_edit, setup_source_transformation_delete])
@@ -54,3 +54,9 @@ register_links(StagingFolder, [setup_source_transformation_list, setup_source_ed
register_links(['setup_source_transformation_create', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_list'], [setup_source_transformation_create], menu_name='sidebar') register_links(['setup_source_transformation_create', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_list'], [setup_source_transformation_create], menu_name='sidebar')
source_views = ['setup_web_form_list', 'setup_staging_folder_list', 'setup_source_edit', 'setup_source_delete', 'setup_source_create', 'setup_source_transformation_list', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_create'] source_views = ['setup_web_form_list', 'setup_staging_folder_list', 'setup_source_edit', 'setup_source_delete', 'setup_source_create', 'setup_source_transformation_list', 'setup_source_transformation_edit', 'setup_source_transformation_delete', 'setup_source_transformation_create']
register_model_list_columns(StagingFile, [
{'name':_(u'thumbnail'), 'attribute':
lambda x: staging_file_thumbnail(x)
},
])

View File

@@ -7,7 +7,11 @@ from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mimetype.api import get_icon_file_path, get_error_icon_file_path, \
get_mimetype
from converter.api import convert, cache_cleanup from converter.api import convert, cache_cleanup
from converter.exceptions import UnknownFormat, UnkownConvertError
DEFAULT_STAGING_DIRECTORY = u'/tmp' DEFAULT_STAGING_DIRECTORY = u'/tmp'
@@ -41,10 +45,12 @@ def _return_new_class():
return type('StagingFile', (StagingFile,), dict(StagingFile.__dict__)) return type('StagingFile', (StagingFile,), dict(StagingFile.__dict__))
def create_staging_file_class(request, source): def create_staging_file_class(request, directory_path, source=None):
cls = _return_new_class() cls = _return_new_class()
#cls.set_path(evaluate_user_staging_path(request, source)) #cls.set_path(evaluate_user_staging_path(request, source))
cls.set_path(source) cls.set_path(directory_path)
if source is not None:
cls.set_source(source)
return cls return cls
@@ -54,11 +60,16 @@ class StagingFile(object):
specifics to the view specifics to the view
""" """
path = DEFAULT_STAGING_DIRECTORY path = DEFAULT_STAGING_DIRECTORY
source = None
@classmethod @classmethod
def set_path(cls, path): def set_path(cls, path):
cls.path = path cls.path = path
@classmethod
def set_source(cls, source):
cls.source = source
@classmethod @classmethod
def get_all(cls): def get_all(cls):
""" """
@@ -68,7 +79,7 @@ class StagingFile(object):
staging_files = [] staging_files = []
for filename in get_all_files(cls.path): for filename in get_all_files(cls.path):
staging_files.append(StagingFile( staging_files.append(StagingFile(
filepath=os.path.join(cls.path, filename))) filepath=os.path.join(cls.path, filename), source=cls.source))
return staging_files return staging_files
@@ -84,10 +95,13 @@ class StagingFile(object):
else: else:
raise ObjectDoesNotExist raise ObjectDoesNotExist
def __init__(self, filepath): def __init__(self, filepath, source=None):
self.source = source
self.filepath = filepath self.filepath = filepath
self.filename = os.path.basename(filepath) self.filename = os.path.basename(filepath)
self._id = HASH_FUNCTION(open(filepath).read()) fd = open(filepath, 'rb')
self._id = HASH_FUNCTION(fd.read())
fd.close()
def __unicode__(self): def __unicode__(self):
return self.filename return self.filename
@@ -121,7 +135,10 @@ class StagingFile(object):
else: else:
raise OSError(ugettext(u'Unable to delete staging file: %s') % exc) raise OSError(ugettext(u'Unable to delete staging file: %s') % exc)
def preview(self, preview_size, transformations): def get_image(self, size, transformations):
errors = [] try:
output_file = convert(self.filepath, size=preview_size, cleanup_files=False, transformations=transformations) return convert(self.filepath, size=size, cleanup_files=False, transformations=transformations)
return output_file, errors except UnknownFormat:
return get_icon_file_path(get_mimetype(self.filepath))
except UnkownConvertError:
return get_error_icon_file_path()

View File

@@ -5,6 +5,7 @@ from sources.models import SOURCE_CHOICE_WEB_FORM, SOURCE_CHOICE_STAGING
urlpatterns = patterns('sources.views', 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+)/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/(?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'^upload/interactive/(?P<source_type>\w+)/(?P<source_id>\d+)/$', 'upload_interactive', (), 'upload_interactive'), url(r'^upload/interactive/(?P<source_type>\w+)/(?P<source_id>\d+)/$', 'upload_interactive', (), 'upload_interactive'),
url(r'^upload/interactive/$', 'upload_interactive', (), 'upload_interactive'), url(r'^upload/interactive/$', 'upload_interactive', (), 'upload_interactive'),

View File

@@ -17,6 +17,7 @@ from documents.literals import PERMISSION_DOCUMENT_CREATE
from documents.literals import HISTORY_DOCUMENT_CREATED from documents.literals import HISTORY_DOCUMENT_CREATED
from documents.models import RecentDocument, Document, DocumentType from documents.models import RecentDocument, Document, DocumentType
from document_indexing.api import update_indexes from document_indexing.api import update_indexes
from documents.conf.settings import THUMBNAIL_SIZE
from history.api import create_history from history.api import create_history
from metadata.api import save_metadata_list, \ from metadata.api import save_metadata_list, \
decode_metadata_from_url, metadata_repr_as_list decode_metadata_from_url, metadata_repr_as_list
@@ -161,7 +162,7 @@ def upload_interactive(request, source_type=None, source_id=None):
elif source_type == SOURCE_CHOICE_STAGING: elif source_type == SOURCE_CHOICE_STAGING:
staging_folder = get_object_or_404(StagingFolder, pk=source_id) staging_folder = get_object_or_404(StagingFolder, pk=source_id)
context['source'] = staging_folder context['source'] = staging_folder
StagingFile = create_staging_file_class(request, staging_folder.folder_path) StagingFile = create_staging_file_class(request, staging_folder.folder_path, source=staging_folder)
if request.method == 'POST': if request.method == 'POST':
form = StagingDocumentForm(request.POST, request.FILES, form = StagingDocumentForm(request.POST, request.FILES,
cls=StagingFile, document_type=document_type, cls=StagingFile, document_type=document_type,
@@ -290,11 +291,10 @@ def staging_file_preview(request, source_type, source_id, staging_file_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE]) check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE])
staging_folder = get_object_or_404(StagingFolder, pk=source_id) staging_folder = get_object_or_404(StagingFolder, pk=source_id)
StagingFile = create_staging_file_class(request, staging_folder.folder_path) StagingFile = create_staging_file_class(request, staging_folder.folder_path)
try:
transformations, errors = SourceTransformation.objects.get_for_object_as_list(staging_folder) transformations, errors = SourceTransformation.objects.get_for_object_as_list(staging_folder)
output_file, errors = StagingFile.get(staging_file_id).preview( output_file = StagingFile.get(staging_file_id).get_image(
preview_size=staging_folder.get_preview_size(), size=staging_folder.get_preview_size(),
transformations=transformations transformations=transformations
) )
if errors and (request.user.is_staff or request.user.is_superuser): if errors and (request.user.is_staff or request.user.is_superuser):
@@ -303,18 +303,25 @@ def staging_file_preview(request, source_type, source_id, staging_file_id):
'error': error 'error': error
}) })
except UnkownConvertError, e: return sendfile.sendfile(request, output_file)
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
def staging_file_thumbnail(request, source_id, staging_file_id):
check_permissions(request.user, [PERMISSION_DOCUMENT_CREATE])
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.objects.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
})
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
except UnknownFormat:
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_UNKNOWN_MEDIUM)
except Exception, e:
if request.user.is_staff or request.user.is_superuser:
messages.error(request, e)
output_file = os.path.join(settings.MEDIA_ROOT, u'images', PICTURE_ERROR_MEDIUM)
finally:
return sendfile.sendfile(request, output_file) return sendfile.sendfile(request, output_file)

View File

@@ -1,6 +1,9 @@
from django import forms from django import forms
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode 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
class FamFamRadioFieldRenderer(forms.widgets.RadioFieldRenderer): class FamFamRadioFieldRenderer(forms.widgets.RadioFieldRenderer):
@@ -20,3 +23,15 @@ class FamFamRadioFieldRenderer(forms.widgets.RadioFieldRenderer):
class FamFamRadioSelect(forms.widgets.RadioSelect): class FamFamRadioSelect(forms.widgets.RadioSelect):
renderer = FamFamRadioFieldRenderer renderer = FamFamRadioFieldRenderer
def staging_file_thumbnail(staging_file):
#try:
return mark_safe(u'<a class="fancybox" href="%(url)s"><img class="lazy-load" data-href="%(thumbnail)s" src="%(media_url)s/images/ajax-loader.gif" alt="%(string)s" /><noscript><img src="%(thumbnail)s" alt="%(string)s" /></noscript></a>' % {
'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]),
'media_url': settings.MEDIA_URL,
'string': _(u'thumbnail')
})
# except:
# return u''