Files
mayan-edms/mayan/apps/metadata/views.py
Roberto Rosario eb878c165b Revert "Issue #56, #8, now that metadata types are automatically added to a document upon type change, there is no more need for the document metadata add and remove code, view, API"
This reverts commit c390fc21d7.

Re adding this feature, only required metadata should be automatically added, optional metadata would be added by the user
2014-10-29 20:17:19 -04:00

439 lines
18 KiB
Python

from __future__ import absolute_import
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _
from acls.models import AccessEntry
from documents.models import Document, DocumentType
from documents.permissions import PERMISSION_DOCUMENT_TYPE_EDIT
from permissions.models import Permission
from common.utils import get_object_name
from common.views import assign_remove
from .api import save_metadata_list
from .classes import MetadataObjectWrapper
from .forms import (AddMetadataForm, MetadataFormSet, MetadataRemoveFormSet,
MetadataTypeForm)
from .models import DocumentMetadata, DocumentTypeDefaults, MetadataType
from .permissions import (PERMISSION_METADATA_DOCUMENT_ADD,
PERMISSION_METADATA_DOCUMENT_EDIT,
PERMISSION_METADATA_DOCUMENT_REMOVE,
PERMISSION_METADATA_DOCUMENT_VIEW,
PERMISSION_METADATA_TYPE_CREATE,
PERMISSION_METADATA_TYPE_DELETE,
PERMISSION_METADATA_TYPE_EDIT,
PERMISSION_METADATA_TYPE_VIEW)
def metadata_edit(request, document_id=None, document_id_list=None):
if document_id:
documents = [get_object_or_404(Document, pk=document_id)]
if documents[0].metadata.count() == 0:
messages.warning(request, _(u'The selected document doesn\'t have any metadata.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('main:home')))
elif document_id_list:
documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')]
try:
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_EDIT])
except PermissionDenied:
documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_METADATA_DOCUMENT_EDIT, request.user, documents)
if not documents:
messages.error(request, _(u'Must provide at least one document.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('main:home')))
post_action_redirect = reverse('documents:document_list_recent')
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_action_redirect)))
metadata = {}
for document in documents:
document.add_as_recent_document_for_user(request.user)
for item in document.metadata.all():
value = item.value
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] if value else []
initial = []
for key, value in metadata.items():
initial.append({
'metadata_type': key,
'value': u', '.join(value)
})
formset = MetadataFormSet(initial=initial)
if request.method == 'POST':
formset = MetadataFormSet(request.POST)
if formset.is_valid():
for document in documents:
errors = []
for form in formset.forms:
if form.cleaned_data['update']:
try:
save_metadata_list([form.cleaned_data], document)
except Exception as exception:
errors.append(exception)
if errors:
for error in errors:
messages.error(request, _(u'Error editing metadata for document %(document)s; %(error)s.') % {
'document': document, 'error': error})
else:
messages.success(request, _(u'Metadata for document %s edited successfully.') % document)
return HttpResponseRedirect(next)
context = {
'form_display_mode_table': True,
'form': formset,
'next': next,
}
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('main/generic_form.html', context,
context_instance=RequestContext(request))
def metadata_multiple_edit(request):
return metadata_edit(request, document_id_list=request.GET.get('id_list', ''))
def metadata_add(request, document_id=None, document_id_list=None):
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(',')]
try:
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_ADD])
except PermissionDenied:
documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_METADATA_DOCUMENT_ADD, request.user, documents)
if not documents:
messages.error(request, _(u'Must provide at least one document.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('main:home')))
for document in documents:
document.add_as_recent_document_for_user(request.user)
post_action_redirect = reverse('documents:document_list_recent')
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_action_redirect)))
if request.method == 'POST':
form = AddMetadataForm(request.POST)
if form.is_valid():
metadata_type = form.cleaned_data['metadata_type']
for document in documents:
document_metadata, created = DocumentMetadata.objects.get_or_create(document=document, metadata_type=metadata_type, defaults={'value': u''})
if created:
messages.success(request, _(u'Metadata type: %(metadata_type)s successfully added to document %(document)s.') % {
'metadata_type': metadata_type, 'document': document})
else:
messages.warning(request, _(u'Metadata type: %(metadata_type)s already present in document %(document)s.') % {
'metadata_type': metadata_type, 'document': document})
if len(documents) == 1:
return HttpResponseRedirect(u'%s?%s' % (
reverse('metadata:metadata_edit', args=[document.pk]),
urlencode({'next': next}))
)
elif len(documents) > 1:
return HttpResponseRedirect(u'%s?%s' % (
reverse('metadata:metadata_multiple_edit'),
urlencode({'id_list': document_id_list, 'next': next}))
)
else:
form = AddMetadataForm()
context = {
'form': form,
'next': next,
}
if len(documents) == 1:
context['object'] = documents[0]
context['title'] = _(u'Add metadata type to document: %s') % ', '.join([unicode(d) for d in documents])
elif len(documents) > 1:
context['title'] = _(u'Add metadata type to documents: %s') % ', '.join([unicode(d) for d in documents])
return render_to_response('main/generic_form.html', context,
context_instance=RequestContext(request))
def metadata_multiple_add(request):
return metadata_add(request, document_id_list=request.GET.get('id_list', []))
def metadata_remove(request, document_id=None, document_id_list=None):
if document_id:
documents = [get_object_or_404(Document, pk=document_id)]
if documents[0].metadata.count() == 0:
messages.warning(request, _(u'The selected document doesn\'t have any metadata.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('main:home')))
elif document_id_list:
documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')]
try:
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_REMOVE])
except PermissionDenied:
documents = AccessEntry.objects.filter_objects_by_access(PERMISSION_METADATA_DOCUMENT_REMOVE, request.user, documents)
if not documents:
messages.error(request, _(u'Must provide at least one document.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('main:home')))
post_action_redirect = reverse('documents:document_list_recent')
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_action_redirect)))
metadata = {}
for document in documents:
document.add_as_recent_document_for_user(request.user)
for item in document.metadata.all():
value = item.value
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] if value else u''
initial = []
for key, value in metadata.items():
initial.append({
'metadata_type': key,
'value': u', '.join(value)
})
formset = MetadataRemoveFormSet(initial=initial)
if request.method == 'POST':
formset = MetadataRemoveFormSet(request.POST)
if formset.is_valid():
for document in documents:
for form in formset.forms:
if form.cleaned_data['update']:
metadata_type = get_object_or_404(MetadataType, pk=form.cleaned_data['id'])
try:
document_metadata = DocumentMetadata.objects.get(document=document, metadata_type=metadata_type)
document_metadata.delete()
messages.success(request, _(u'Successfully remove metadata type: %(metadata_type)s from document: %(document)s.') % {
'metadata_type': metadata_type, 'document': document})
except:
messages.error(request, _(u'Error removing metadata type: %(metadata_type)s from document: %(document)s.') % {
'metadata_type': metadata_type, 'document': document})
return HttpResponseRedirect(next)
context = {
'form_display_mode_table': True,
'form': formset,
'next': next,
}
if len(documents) == 1:
context['object'] = documents[0]
context['title'] = _(u'Remove metadata types from document: %s') % ', '.join([unicode(d) for d in documents])
elif len(documents) > 1:
context['title'] = _(u'Remove metadata types from documents: %s') % ', '.join([unicode(d) for d in documents])
return render_to_response('main/generic_form.html', context,
context_instance=RequestContext(request))
def metadata_multiple_remove(request):
return metadata_remove(request, document_id_list=request.GET.get('id_list', []))
def metadata_view(request, document_id):
document = get_object_or_404(Document, pk=document_id)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_DOCUMENT_VIEW])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_METADATA_DOCUMENT_VIEW, request.user, document)
return render_to_response('main/generic_list.html', {
'title': _(u'Metadata for: %s') % document,
'object_list': document.metadata.all(),
'extra_columns': [{'name': _(u'Value'), 'attribute': 'value'}],
'hide_link': True,
'object': document,
}, context_instance=RequestContext(request))
# Setup views
def setup_metadata_type_list(request):
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_VIEW])
context = {
'object_list': MetadataType.objects.all(),
'title': _(u'Metadata types'),
'hide_link': True,
'extra_columns': [
{
'name': _(u'Internal name'),
'attribute': 'name',
},
]
}
return render_to_response('main/generic_list.html', context,
context_instance=RequestContext(request))
def setup_metadata_type_edit(request, metadatatype_id):
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_EDIT])
metadata_type = get_object_or_404(MetadataType, pk=metadatatype_id)
if request.method == 'POST':
form = MetadataTypeForm(instance=metadata_type, data=request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, _(u'Metadata type edited successfully'))
return HttpResponseRedirect(reverse('metadata:setup_metadata_type_list'))
except Exception as exception:
messages.error(request, _(u'Error editing metadata type; %s') % exception)
pass
else:
form = MetadataTypeForm(instance=metadata_type)
return render_to_response('main/generic_form.html', {
'title': _(u'Edit metadata type: %s') % metadata_type,
'form': form,
'object': metadata_type,
}, context_instance=RequestContext(request))
def setup_metadata_type_create(request):
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_CREATE])
if request.method == 'POST':
form = MetadataTypeForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, _(u'Metadata type created successfully'))
return HttpResponseRedirect(reverse('metadata:setup_metadata_type_list'))
else:
form = MetadataTypeForm()
return render_to_response('main/generic_form.html', {
'title': _(u'Create metadata type'),
'form': form,
}, context_instance=RequestContext(request))
def setup_metadata_type_delete(request, metadatatype_id):
Permission.objects.check_permissions(request.user, [PERMISSION_METADATA_TYPE_DELETE])
metadata_type = get_object_or_404(MetadataType, pk=metadatatype_id)
post_action_redirect = reverse('metadata:setup_metadata_type_list')
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', post_action_redirect)))
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_action_redirect)))
if request.method == 'POST':
try:
metadata_type.delete()
messages.success(request, _(u'Metadata type: %s deleted successfully.') % metadata_type)
except Exception as exception:
messages.error(request, _(u'Metadata type: %(metadata_type)s delete error: %(error)s') % {
'metadata_type': metadata_type, 'error': exception})
return HttpResponseRedirect(next)
context = {
'delete_view': True,
'next': next,
'previous': previous,
'object': metadata_type,
'title': _(u'Are you sure you wish to delete the metadata type: %s?') % metadata_type,
}
return render_to_response('main/generic_confirm.html', context,
context_instance=RequestContext(request))
def _as_choice_list(items):
return sorted([(MetadataObjectWrapper.encapsulate(item).gid, get_object_name(item, display_object_type=False)) for item in items], key=lambda x: x[1])
def get_document_type_metadata_non_members(document_type):
metadata_types = get_document_type_metadata_members(document_type, separate=True)
metadata_types = set(MetadataType.objects.all()) - set(metadata_types)
non_members = []
if metadata_types:
non_members.append((_(u'Metadata types'), _as_choice_list(list(metadata_types))))
return non_members
def get_document_type_metadata_members(document_type, separate=False):
metadata_types = set(document_type.documenttypedefaults_set.get().default_metadata.all())
if separate:
return metadata_types
else:
members = []
if metadata_types:
members.append((_(u'Metadata types'), _as_choice_list(list(metadata_types))))
return members
def add_document_type_metadata(document_type, selection):
metadata_object = MetadataObjectWrapper.get(selection).source_object
document_type.documenttypedefaults_set.get().default_metadata.add(metadata_object)
def remove_document_type_metadata(document_type, selection):
metadata_object = MetadataObjectWrapper.get(selection).source_object
document_type.documenttypedefaults_set.get().default_metadata.remove(metadata_object)
def setup_document_type_metadata(request, document_type_id):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_TYPE_EDIT])
document_type = get_object_or_404(DocumentType, pk=document_type_id)
# Initialize defaults
DocumentTypeDefaults.objects.get_or_create(document_type=document_type)
return assign_remove(
request,
left_list=lambda: get_document_type_metadata_non_members(document_type),
right_list=lambda: get_document_type_metadata_members(document_type),
add_method=lambda x: add_document_type_metadata(document_type, x),
remove_method=lambda x: remove_document_type_metadata(document_type, x),
left_list_title=_(u'Non members of document type: %s') % document_type,
right_list_title=_(u'Members of document type: %s') % document_type,
extra_context={
'document_type': document_type,
'navigation_object_name': 'document_type',
},
grouped=True,
)