import zipfile from django.utils.translation import ugettext as _ from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.shortcuts import render_to_response, get_object_or_404, redirect from django.template import RequestContext from django.contrib import messages from django.views.generic.list_detail import object_detail, object_list from django.core.urlresolvers import reverse from django.views.generic.create_update import create_object, delete_object, update_object from django.core.files.base import File from django.conf import settings from django.utils.http import urlencode from django.template.defaultfilters import slugify from django.core.exceptions import ObjectDoesNotExist from django.core.files.uploadedfile import SimpleUploadedFile import sendfile from common.utils import pretty_size from converter.api import convert, in_image_cache, QUALITY_DEFAULT from converter.exceptions import UnkownConvertError, UnknownFormat from converter import TRANFORMATION_CHOICES from filetransfers.api import serve_file from filesystem_serving.api import document_create_fs_links, document_delete_fs_links from filesystem_serving.conf.settings import FILESERVING_ENABLE from permissions.api import check_permissions from ocr.views import submit_document_to_queue from documents.conf.settings import DELETE_STAGING_FILE_AFTER_UPLOAD from documents.conf.settings import USE_STAGING_DIRECTORY from documents.conf.settings import STAGING_FILES_PREVIEW_SIZE from documents.conf.settings import PREVIEW_SIZE from documents.conf.settings import THUMBNAIL_SIZE from documents.conf.settings import TRANFORMATION_PREVIEW_SIZE from documents.conf.settings import GROUP_MAX_RESULTS from documents.conf.settings import GROUP_SHOW_EMPTY from documents.conf.settings import GROUP_SHOW_THUMBNAIL from documents.conf.settings import DEFAULT_TRANSFORMATIONS from documents.conf.settings import AUTOMATIC_OCR from documents.conf.settings import UNCOMPRESS_COMPRESSED_LOCAL_FILES from documents.conf.settings import UNCOMPRESS_COMPRESSED_STAGING_FILES from documents.conf.settings import STORAGE_BACKEND from documents import PERMISSION_DOCUMENT_CREATE, \ PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_PROPERTIES_EDIT, \ PERMISSION_DOCUMENT_METADATA_EDIT, PERMISSION_DOCUMENT_VIEW, \ PERMISSION_DOCUMENT_DELETE, PERMISSION_DOCUMENT_DOWNLOAD, \ PERMISSION_DOCUMENT_TRANSFORM, PERMISSION_DOCUMENT_TOOLS from forms import DocumentTypeSelectForm, DocumentCreateWizard, \ MetadataForm, DocumentForm, DocumentForm_edit, DocumentForm_view, \ StagingDocumentForm, DocumentTypeMetadataType, DocumentPreviewForm, \ MetadataFormSet, DocumentPageForm, DocumentPageTransformationForm, \ DocumentContentForm from metadata import save_metadata, save_metadata_list, \ decode_metadata_from_url, metadata_repr_as_list from models import Document, DocumentMetadata, DocumentType, MetadataType, \ DocumentPage, DocumentPageTransformation from staging import StagingFile from utils import document_save_to_temp_dir PICTURE_ERROR_SMALL = u'picture_error.png' PICTURE_ERROR_MEDIUM = u'1297211435_error.png' PICTURE_UNKNOWN_SMALL = u'1299549572_unknown2.png' PICTURE_UNKNOWN_MEDIUM = u'1299549805_unknown.png' def document_list(request): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) return object_list( request, queryset=Document.objects.only('file_filename', 'file_extension').all(), template_name='generic_list.html', extra_context={ 'title':_(u'documents'), 'multi_select_as_buttons':True, }, ) def document_create(request, multiple=True): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) if DocumentType.objects.all().count() == 1: wizard = DocumentCreateWizard( document_type=DocumentType.objects.all()[0], form_list=[MetadataFormSet], multiple=multiple, step_titles = [ _(u'document metadata'), ]) else: wizard = DocumentCreateWizard(form_list=[DocumentTypeSelectForm, MetadataFormSet], multiple=multiple) return wizard(request) def document_create_sibling(request, document_id, multiple=True): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) document = get_object_or_404(Document, pk=document_id) urldata = [] for id, metadata in enumerate(document.documentmetadata_set.all()): if hasattr(metadata, 'value'): urldata.append(('metadata%s_id' % id, metadata.metadata_type_id)) urldata.append(('metadata%s_value' % id, metadata.value)) if multiple: view = 'upload_multiple_documents_with_type' else: view = 'upload_document_with_type' url = reverse(view, args=[document.document_type_id]) return HttpResponseRedirect('%s?%s' % (url, urlencode(urldata))) def _handle_save_document(request, document, form=None): #TODO: move this to OCR app as a post_save signal on create==True if AUTOMATIC_OCR: submit_document_to_queue(request, document) if form and 'document_type_available_filenames' in form.cleaned_data: if form.cleaned_data['document_type_available_filenames']: document.file_filename = form.cleaned_data['document_type_available_filenames'].filename document.save() save_metadata_list(decode_metadata_from_url(request.GET), document) try: warnings = document_create_fs_links(document) if request.user.is_staff or request.user.is_superuser: for warning in warnings: messages.warning(request, warning) except Exception, e: messages.error(request, e) def _handle_zip_file(request, uploaded_file, document_type): filename = getattr(uploaded_file, 'filename', getattr(uploaded_file, 'name', '')) if filename.lower().endswith('zip'): zfobj = zipfile.ZipFile(uploaded_file) for filename in zfobj.namelist(): if not filename.endswith('/'): zip_document = Document(file=SimpleUploadedFile( name=filename, content=zfobj.read(filename)), document_type=document_type) zip_document.save() _handle_save_document(request, zip_document) messages.success(request, _(u'Extracted file: %s, uploaded successfully.') % filename) #Signal that uploaded file was a zip file return True else: #Otherwise tell parent to handle file return False def upload_document_with_type(request, document_type_id, multiple=True): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_CREATE]) document_type = get_object_or_404(DocumentType, pk=document_type_id) local_form = DocumentForm(prefix='local', initial={'document_type':document_type}) if USE_STAGING_DIRECTORY: staging_form = StagingDocumentForm(prefix='staging', initial={'document_type':document_type}) if request.method == 'POST': if 'local-submit' in request.POST.keys(): local_form = DocumentForm(request.POST, request.FILES, prefix='local', initial={'document_type':document_type}) if local_form.is_valid(): try: if (not UNCOMPRESS_COMPRESSED_LOCAL_FILES) or (UNCOMPRESS_COMPRESSED_LOCAL_FILES and not _handle_zip_file(request, request.FILES['local-file'], document_type)): instance = local_form.save() _handle_save_document(request, instance, local_form) messages.success(request, _(u'Document uploaded successfully.')) except Exception, e: messages.error(request, e) if multiple: return HttpResponseRedirect(request.get_full_path()) else: return HttpResponseRedirect(reverse('document_list')) elif 'staging-submit' in request.POST.keys() and USE_STAGING_DIRECTORY: staging_form = StagingDocumentForm(request.POST, request.FILES, prefix='staging', initial={'document_type':document_type}) if staging_form.is_valid(): try: staging_file = StagingFile.get(staging_form.cleaned_data['staging_file_id']) if (not UNCOMPRESS_COMPRESSED_STAGING_FILES) or (UNCOMPRESS_COMPRESSED_STAGING_FILES and not _handle_zip_file(request, staging_file.upload(), document_type)): document = Document(file=staging_file.upload(), document_type=document_type) document.save() _handle_save_document(request, document, staging_form) messages.success(request, _(u'Staging file: %s, uploaded successfully.') % staging_file.filename) if DELETE_STAGING_FILE_AFTER_UPLOAD: staging_file.delete() messages.success(request, _(u'Staging file: %s, deleted successfully.') % staging_file.filename) except Exception, e: messages.error(request, e) if multiple: return HttpResponseRedirect(request.META['HTTP_REFERER']) else: return HttpResponseRedirect(reverse('document_list')) context = { 'document_type_id':document_type_id, 'form_list':[ { 'form':local_form, 'title':_(u'upload a local document'), 'grid':6, 'grid_clear':False if USE_STAGING_DIRECTORY else True, }, ], } if USE_STAGING_DIRECTORY: try: filelist = StagingFile.get_all() except Exception, e: messages.error(request, e) filelist = [] finally: context.update({ 'subtemplates_dict':[ { 'name':'generic_list_subtemplate.html', 'title':_(u'files in staging'), 'object_list':filelist, 'hide_link':True, }, ], }) context['form_list'].append( { 'form':staging_form, 'title':_(u'upload a document from staging'), 'grid':6, 'grid_clear':True, }, ) context.update({ 'sidebar_subtemplates_list':[ { 'title':_(u'Current metadata'), 'name':'generic_subtemplate.html', #'content':metadata_repr(decode_metadata_from_url(request.GET)), 'paragraphs':metadata_repr_as_list(decode_metadata_from_url(request.GET)) }] }) return render_to_response('generic_form.html', context, context_instance=RequestContext(request)) def document_view(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document.objects.select_related(), pk=document_id) form = DocumentForm_view(instance=document, extra_fields=[ {'label':_(u'Filename'), 'field':'file_filename'}, {'label':_(u'File extension'), 'field':'file_extension'}, {'label':_(u'File mimetype'), 'field':'file_mimetype'}, {'label':_(u'File mime encoding'), 'field':'file_mime_encoding'}, {'label':_(u'File size'), 'field':lambda x: pretty_size(x.file.storage.size(x.file.path)) if x.exists() else '-'}, {'label':_(u'Exists in storage'), 'field':'exists'}, {'label':_(u'File path in storage'), 'field':'file'}, {'label':_(u'Date added'), 'field':lambda x: x.date_added.date()}, {'label':_(u'Time added'), 'field':lambda x: unicode(x.date_added.time()).split('.')[0]}, {'label':_(u'Checksum'), 'field':'checksum'}, {'label':_(u'UUID'), 'field':'uuid'}, {'label':_(u'Pages'), 'field':lambda x: x.documentpage_set.count()}, ]) metadata_groups, errors = document.get_metadata_groups() if (request.user.is_staff or request.user.is_superuser) and errors: for error in errors: messages.warning(request, _(u'Metadata group query error: %s' % error)) preview_form = DocumentPreviewForm(document=document) form_list = [ { 'form':form, 'object':document, 'grid':6, }, { 'form':preview_form, 'title':_(u'document preview'), 'object':document, 'grid':6, 'grid_clear':True, }, ] subtemplates_dict = [ { 'name':'generic_list_subtemplate.html', 'title':_(u'metadata'), 'object_list':document.documentmetadata_set.all(), 'extra_columns':[{'name':_(u'value'), 'attribute':'value'}], 'hide_link':True, }, ] if FILESERVING_ENABLE: subtemplates_dict.append({ 'name':'generic_list_subtemplate.html', 'title':_(u'index links'), 'object_list':document.documentmetadataindex_set.all(), 'hide_link':True}) sidebar_groups = [] for group, data in metadata_groups.items(): if len(data) or GROUP_SHOW_EMPTY: if len(data): if len(data) > GROUP_MAX_RESULTS: total_string = '(%s out of %s)' % (GROUP_MAX_RESULTS, len(data)) else: total_string = '(%s)' % len(data) else: total_string = '' extra_columns = [{'name':'current','attribute':lambda x: '' if x == document else ''}] if GROUP_SHOW_THUMBNAIL: extra_columns.append({'name':_(u'thumbnail'), 'attribute': lambda x: '' % (reverse('document_preview', args=[x.id]), reverse('document_thumbnail', args=[x.id]))}) sidebar_groups.append({ 'title':'%s %s' % (group.label, total_string), 'name':'generic_list_subtemplate.html', 'object_list':data[:GROUP_MAX_RESULTS], 'hide_columns':True, 'hide_header':True, 'extra_columns':extra_columns, }) return render_to_response('generic_detail.html', { 'form_list':form_list, 'object':document, 'subtemplates_dict':subtemplates_dict, 'sidebar_subtemplates_dict':sidebar_groups, }, context_instance=RequestContext(request)) def document_delete(request, document_id=None, document_id_list=None): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_DELETE]) post_action_redirect = None 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(',')] else: messages.error(request, _(u'Must provide at least one document.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/'))) if request.method == 'POST': for document in documents: try: document_delete_fs_links(document) document.delete() messages.success(request, _(u'Document: %s deleted successfully.') % document) except Exception, e: messages.error(request, _(u'Document: %s delete error: %s') % (document, e)) return HttpResponseRedirect(next) context = { 'object_name':_(u'document'), 'delete_view':True, 'previous':previous, 'next':next, } if len(documents) == 1: context['object'] = documents[0] context['title'] = _(u'Are you sure you with to delete the document: %s?') % ', '.join([unicode(d) for d in documents]) elif len(documents) > 1: context['title'] = _(u'Are you sure you with to delete the documents: %s?') % ', '.join([unicode(d) for d in documents]) return render_to_response('generic_confirm.html', context, context_instance=RequestContext(request)) def document_multiple_delete(request): return document_delete(request, document_id_list=request.GET.get('id_list', [])) def document_edit(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_PROPERTIES_EDIT]) document = get_object_or_404(Document, pk=document_id) if request.method == 'POST': form = DocumentForm_edit(request.POST, initial={'document_type':document.document_type}) if form.is_valid(): try: document_delete_fs_links(document) except Exception, e: messages.error(request, e) return HttpResponseRedirect(reverse('document_list')) document.file_filename = form.cleaned_data['new_filename'] if 'document_type_available_filenames' in form.cleaned_data: if form.cleaned_data['document_type_available_filenames']: document.file_filename = form.cleaned_data['document_type_available_filenames'].filename document.save() messages.success(request, _(u'Document %s edited successfully.') % document) try: warnings = document_create_fs_links(document) if request.user.is_staff or request.user.is_superuser: for warning in warnings: messages.warning(request, warning) messages.success(request, _(u'Document filesystem links updated successfully.')) except Exception, e: messages.error(request, e) return HttpResponseRedirect(document.get_absolute_url()) return HttpResponseRedirect(document.get_absolute_url()) else: form = DocumentForm_edit(instance=document, initial={ 'new_filename':document.file_filename, 'document_type':document.document_type}) return render_to_response('generic_form.html', { 'form':form, 'object':document, }, context_instance=RequestContext(request)) def document_edit_metadata(request, document_id=None, document_id_list=None): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_METADATA_EDIT]) if document_id: documents = [get_object_or_404(Document, pk=document_id)] elif document_id_list: documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] if len(set([document.document_type for document in documents])) > 1: messages.error(request, _(u'All documents must be from the same type.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) else: messages.error(request, _(u'Must provide at least one document.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) metadata={} for document in documents: for item in DocumentTypeMetadataType.objects.filter(document_type=document.document_type): value = document.documentmetadata_set.get(metadata_type=item.metadata_type).value if document.documentmetadata_set.filter(metadata_type=item.metadata_type) else u'' if item.metadata_type in metadata: if value not in metadata[item.metadata_type]: metadata[item.metadata_type].append(value) else: metadata[item.metadata_type] = [value] initial=[] for key, value in metadata.items(): initial.append({ 'metadata_type':key, 'document_type':document.document_type, 'value': u', '.join(value) }) formset = MetadataFormSet(initial=initial) if request.method == 'POST': formset = MetadataFormSet(request.POST) if formset.is_valid(): for document in documents: save_metadata_list(formset.cleaned_data, document) try: document_delete_fs_links(document) except Exception, e: messages.error(request, _(u'Error deleting filesystem links for document: %(document)s; %(error)s') % { 'document':document, 'error':e}) messages.success(request, _(u'Metadata for document %s edited successfully.') % document) try: warnings = document_create_fs_links(document) if request.user.is_staff or request.user.is_superuser: for warning in warnings: messages.warning(request, warning) messages.success(request, _(u'Filesystem links updated successfully for document: %s.') % document) except Exception, e: messages.error(request, _('Error creating filesystem links for document: %(document)s; %(error)s') % { 'document':document, 'error':e}) if len(documents) == 1: return HttpResponseRedirect(document.get_absolute_url()) elif len(documents) > 1: return HttpResponseRedirect(reverse('document_list')) context = { 'form_display_mode_table':True, 'form':formset, } if len(documents) == 1: context['object'] = documents[0] context['title'] = _(u'Edit metadata for document: %s?') % ', '.join([unicode(d) for d in documents]) elif len(documents) > 1: context['title'] = _(u'Edit metadata for documents: %s?') % ', '.join([unicode(d) for d in documents]) return render_to_response('generic_form.html', context, context_instance=RequestContext(request)) def document_multiple_edit_metadata(request): return document_edit_metadata(request, document_id_list=request.GET.get('id_list', [])) def get_document_image(request, document_id, size=PREVIEW_SIZE, quality=QUALITY_DEFAULT): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document, pk=document_id) page = int(request.GET.get('page', 1)) transformation_list = [] try: #Catch invalid or non existing pages document_page = DocumentPage.objects.get(document=document, page_number=page) for page_transformation in document_page.documentpagetransformation_set.all(): try: if page_transformation.transformation in TRANFORMATION_CHOICES: output = TRANFORMATION_CHOICES[page_transformation.transformation] % eval(page_transformation.arguments) transformation_list.append(output) except Exception, e: if request.user.is_staff: messages.warning(request, _(u'Error for transformation %(transformation)s:, %(error)s') % {'transformation':page_transformation.get_transformation_display(), 'error':e}) else: pass except ObjectDoesNotExist: pass tranformation_string = ' '.join(transformation_list) try: filepath = in_image_cache(document.checksum, size=size, quality=quality, extra_options=tranformation_string, page=page-1) if filepath: return sendfile.sendfile(request, filename=filepath) #Save to a temporary location filepath = document_save_to_temp_dir(document, filename=document.checksum) output_file = convert(filepath, size=size, format='jpg', quality=quality, extra_options=tranformation_string, page=page-1) return sendfile.sendfile(request, filename=output_file) except UnkownConvertError, e: if request.user.is_staff or request.user.is_superuser: messages.error(request, e) if size == THUMBNAIL_SIZE: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_SMALL)) else: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_MEDIUM)) except UnknownFormat: if size == THUMBNAIL_SIZE: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_UNKNOWN_SMALL)) else: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_UNKNOWN_MEDIUM)) except Exception, e: if request.user.is_staff or request.user.is_superuser: messages.error(request, e) if size == THUMBNAIL_SIZE: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_SMALL)) else: return sendfile.sendfile(request, filename='%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_MEDIUM)) def document_download(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_DOWNLOAD]) document = get_object_or_404(Document, pk=document_id) try: #Test permissions and trigger exception document.open() return serve_file(request, document.file, save_as='%s' % document.get_fullname(), content_type='image/jpeg') except Exception, e: messages.error(request, e) return HttpResponseRedirect(request.META['HTTP_REFERER']) #TODO: Need permission def staging_file_preview(request, staging_file_id): transformation_list = [] for page_transformation in DEFAULT_TRANSFORMATIONS: try: if page_transformation['name'] in TRANFORMATION_CHOICES: output = TRANFORMATION_CHOICES[page_transformation['name']] % eval(page_transformation['arguments']) transformation_list.append(output) except Exception, e: if request.user.is_staff: messages.warning(request, _(u'Error for transformation %(transformation)s:, %(error)s') % {'transformation':page_transformation.get_transformation_display(), 'error':e}) else: pass tranformation_string = ' '.join(transformation_list) try: filepath = StagingFile.get(staging_file_id).filepath output_file = convert(filepath, size=STAGING_FILES_PREVIEW_SIZE, extra_options=tranformation_string, cleanup_files=False) return serve_file(request, File(file=open(output_file, 'r')), content_type='image/jpeg') except UnkownConvertError, e: if request.user.is_staff or request.user.is_superuser: messages.error(request, e) return serve_file(request, File(file=open(u'%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_MEDIUM), 'r'))) except UnknownFormat: return serve_file(request, File(file=open(u'%simages/%s' % (settings.MEDIA_ROOT, PICTURE_UNKNOWN_MEDIUM), 'r'))) except Exception, e: if request.user.is_staff or request.user.is_superuser: messages.error(request, e) return serve_file(request, File(file=open(u'%simages/%s' % (settings.MEDIA_ROOT, PICTURE_ERROR_MEDIUM), 'r'))) #TODO: Need permission def staging_file_delete(request, staging_file_id): staging_file = StagingFile.get(staging_file_id) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', None))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None))) if request.method == 'POST': try: staging_file.delete() messages.success(request, _(u'Staging file delete successfully.')) except Exception, e: messages.error(request, e) return HttpResponseRedirect(next) return render_to_response('generic_confirm.html', { 'delete_view':True, 'object':staging_file, 'next':next, 'previous':previous, }, context_instance=RequestContext(request)) def document_page_view(request, document_page_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document_page = get_object_or_404(DocumentPage, pk=document_page_id) document_page_form = DocumentPageForm(instance=document_page) form_list = [ { 'form':document_page_form, 'title':_(u'details for document page: %s') % document_page.page_number, 'object':document_page, 'grid':6, }, ] subtemplates_dict = [ { 'name':'generic_list_subtemplate.html', 'title':_(u'transformations'), 'object_list':document_page.documentpagetransformation_set.all(), 'extra_columns':[ {'name':_(u'order'), 'attribute':'order'}, {'name':_(u'transformation'), 'attribute':lambda x: x.get_transformation_display()}, {'name':_(u'arguments'), 'attribute':'arguments'} ], 'hide_link':True, 'hide_object':True, 'grid':6, 'grid_clear':True, 'hide_header':True, }, ] return render_to_response('generic_detail.html', { 'form_list':form_list, 'object':document_page, 'subtemplates_dict':subtemplates_dict, }, context_instance=RequestContext(request)) def document_page_transformation_create(request, document_page_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_TRANSFORM]) document_page = get_object_or_404(DocumentPage, pk=document_page_id) if request.method == 'POST': form = DocumentPageTransformationForm(request.POST, initial={'document_page':document_page}) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('document_page_view', args=[document_page_id])) else: form = DocumentPageTransformationForm(initial={'document_page':document_page}) return render_to_response('generic_form.html', { 'form':form, 'object':document_page, 'title':_(u'Create new transformation for page: %(page)s of document: %(document)s') % { 'page':document_page.page_number, 'document':document_page.document}, }, context_instance=RequestContext(request)) def document_page_transformation_edit(request, document_page_transformation_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_TRANSFORM]) document_page_transformation = get_object_or_404(DocumentPageTransformation, pk=document_page_transformation_id) return update_object(request, template_name='generic_form.html', form_class=DocumentPageTransformationForm, object_id=document_page_transformation_id, post_save_redirect=reverse('document_page_view', args=[document_page_transformation.document_page_id]), extra_context={ 'object_name':_(u'transformation')} ) return render_to_response('generic_form.html', { 'form':form, 'object':document_page_transformation.document_page, 'title':_(u'Edit transformation "%(transformation)s" for page: %(page)s of document: %(document)s') % { 'transformation':document_page_transformation.get_transformation_display(), 'page':document_page_transformation.document_page.page_number, 'document':document_page_transformation.document_page.document}, }, context_instance=RequestContext(request)) def document_page_transformation_delete(request, document_page_transformation_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_TRANSFORM]) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None))) document_page_transformation = get_object_or_404(DocumentPageTransformation, pk=document_page_transformation_id) return delete_object(request, model=DocumentPageTransformation, object_id=document_page_transformation_id, template_name='generic_confirm.html', post_delete_redirect=reverse('document_page_view', args=[document_page_transformation.document_page_id]), extra_context={ 'delete_view':True, 'object':document_page_transformation, 'object_name':_(u'document transformation'), 'title':_(u'Are you sure you wish to delete transformation "%(transformation)s" for page: %(page)s of document: %(document)s') % { 'transformation':document_page_transformation.get_transformation_display(), 'page':document_page_transformation.document_page.page_number, 'document':document_page_transformation.document_page.document}, 'previous':previous, }) def document_find_duplicates(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document, pk=document_id) return _find_duplicate_list(request, [document], include_source=True, confirmation=False) def _find_duplicate_list(request, source_document_list=Document.objects.all(), include_source=False, confirmation=True): previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None))) if confirmation and request.method != 'POST': return render_to_response('generic_confirm.html', { 'previous':previous, 'message':_(u'On large databases this operation may take some time to execute.'), }, context_instance=RequestContext(request)) else: duplicated = [] for document in source_document_list: if document.pk not in duplicated: results = Document.objects.filter(checksum=document.checksum).exclude(id__in=duplicated).exclude(pk=document.pk).values_list('pk', flat=True) duplicated.extend(results) if include_source and results: duplicated.append(document.pk) return render_to_response('generic_list.html', { 'object_list':Document.objects.filter(pk__in=duplicated), 'title':_(u'duplicated documents'), }, context_instance=RequestContext(request)) def document_find_all_duplicates(request): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) return _find_duplicate_list(request, include_source=True) def document_clear_transformations(request, document_id=None, document_id_list=None): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_TRANSFORM]) if document_id: documents = [get_object_or_404(Document.objects, pk=document_id)] post_redirect = reverse('document_view', args=[documents[0].pk]) elif document_id_list: documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] post_redirect = None else: messages.error(request, _(u'Must provide at least one document.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', post_redirect or reverse('document_list')))) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_redirect or reverse('document_list')))) if request.method == 'POST': for document in documents: try: for document_page in document.documentpage_set.all(): for transformation in document_page.documentpagetransformation_set.all(): transformation.delete() messages.success(request, _(u'All the page transformations for document: %s, have been deleted successfully.') % document) except Exception, e: messages.error(request, _(u'Error deleting the page transformations for document: %s; %s.') % (document, e)) return HttpResponseRedirect(next) context = { 'object_name':_(u'document transformation'), 'delete_view':True, 'previous':previous, 'next':next, } if len(documents) == 1: context['object'] = documents[0] context['title'] = _(u'Are you sure you with to clear all the page transformations for document: %s?') % ', '.join([unicode(d) for d in documents]) elif len(documents) > 1: context['title'] = _(u'Are you sure you with to clear all the page transformations for documents: %s?') % ', '.join([unicode(d) for d in documents]) return render_to_response('generic_confirm.html', context, context_instance=RequestContext(request)) def document_multiple_clear_transformations(request): return document_clear_transformations(request, document_id_list=request.GET.get('id_list', [])) def document_view_simple(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) document = get_object_or_404(Document.objects.select_related(), pk=document_id) content_form = DocumentContentForm(document=document) metadata_groups, errors = document.get_metadata_groups() if (request.user.is_staff or request.user.is_superuser) and errors: for error in errors: messages.warning(request, _(u'Metadata group query error: %s' % error)) preview_form = DocumentPreviewForm(document=document, hide_detail_link=True) form_list = [ { 'form':content_form, 'object':document, 'grid':6, }, { 'form':preview_form, 'title':_(u'document preview'), 'object':document, 'grid':6, 'grid_clear':True, }, ] subtemplates_dict = [ { 'name':'generic_list_subtemplate.html', 'title':_(u'metadata'), 'object_list':document.documentmetadata_set.all(), 'extra_columns':[{'name':_(u'value'), 'attribute':'value'}], 'hide_link':True, }, ] sidebar_groups = [] for group, data in metadata_groups.items(): if len(data) or GROUP_SHOW_EMPTY: if len(data): if len(data) > GROUP_MAX_RESULTS: total_string = '(%s out of %s)' % (GROUP_MAX_RESULTS, len(data)) else: total_string = '(%s)' % len(data) else: total_string = '' extra_columns = [{'name':'current','attribute':lambda x: '' if x == document else ''}] if GROUP_SHOW_THUMBNAIL: extra_columns.append({'name':_(u'thumbnail'), 'attribute': lambda x: '' % (reverse('document_preview', args=[x.id]), reverse('document_thumbnail', args=[x.id]))}) sidebar_groups.append({ 'title':'%s %s' % (group.label, total_string), 'name':'generic_list_subtemplate.html', 'object_list':data[:GROUP_MAX_RESULTS], 'hide_columns':True, 'hide_header':True, 'extra_columns':extra_columns, }) return render_to_response('generic_detail.html', { 'form_list':form_list, 'object':document, 'subtemplates_dict':subtemplates_dict, 'sidebar_subtemplates_dict':sidebar_groups, }, context_instance=RequestContext(request)) def document_missing_list(request): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW]) missing_id_list = [] for document in Document.objects.only('id',): if not STORAGE_BACKEND().exists(document.file): missing_id_list.append(document.pk) return render_to_response('generic_list.html', { 'object_list':Document.objects.in_bulk(missing_id_list).values(), 'title':_(u'missing documents'), }, context_instance=RequestContext(request))