Initial commit to remove use of eval. gh-issue #151.
This commit is contained in:
@@ -38,11 +38,15 @@ class APIMetadataTypeListView(generics.ListCreateAPIView):
|
||||
mayan_view_permissions = {'POST': [permission_metadata_type_create]}
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Returns a list of all the metadata types."""
|
||||
"""
|
||||
Returns a list of all the metadata types.
|
||||
"""
|
||||
return super(APIMetadataTypeListView, self).get(*args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
"""Create a new metadata type."""
|
||||
"""
|
||||
Create a new metadata type.
|
||||
"""
|
||||
return super(APIMetadataTypeListView, self).post(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -59,19 +63,27 @@ class APIMetadataTypeView(generics.RetrieveUpdateDestroyAPIView):
|
||||
}
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Delete the selected metadata type."""
|
||||
"""
|
||||
Delete the selected metadata type.
|
||||
"""
|
||||
return super(APIMetadataTypeView, self).delete(*args, **kwargs)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Return the details of the selected metadata type."""
|
||||
"""
|
||||
Return the details of the selected metadata type.
|
||||
"""
|
||||
return super(APIMetadataTypeView, self).get(*args, **kwargs)
|
||||
|
||||
def patch(self, *args, **kwargs):
|
||||
"""Edit the selected metadata type."""
|
||||
"""
|
||||
Edit the selected metadata type.
|
||||
"""
|
||||
return super(APIMetadataTypeView, self).patch(*args, **kwargs)
|
||||
|
||||
def put(self, *args, **kwargs):
|
||||
"""Edit the selected metadata type."""
|
||||
"""
|
||||
Edit the selected metadata type.
|
||||
"""
|
||||
return super(APIMetadataTypeView, self).put(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -86,19 +98,31 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView):
|
||||
document = self.get_document()
|
||||
|
||||
if self.request == 'GET':
|
||||
# Make sure the use has the permission to see the metadata for this document
|
||||
# Make sure the use has the permission to see the metadata for
|
||||
# this document
|
||||
try:
|
||||
Permission.check_permissions(self.request.user, [permission_metadata_document_view])
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_metadata_document_view]
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(permission_metadata_document_view, self.request.user, document)
|
||||
AccessControlList.objects.check_access(
|
||||
permission_metadata_document_view, self.request.user,
|
||||
document
|
||||
)
|
||||
else:
|
||||
return document.metadata.all()
|
||||
elif self.request == 'POST':
|
||||
# Make sure the use has the permission to add metadata to this document
|
||||
# Make sure the use has the permission to add metadata to this
|
||||
# document
|
||||
try:
|
||||
Permission.check_permissions(self.request.user, [permission_metadata_document_add])
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_metadata_document_add]
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(permission_metadata_document_add, self.request.user, document)
|
||||
AccessControlList.objects.check_access(
|
||||
permission_metadata_document_add, self.request.user,
|
||||
document
|
||||
)
|
||||
else:
|
||||
return document.metadata.all()
|
||||
|
||||
@@ -106,11 +130,15 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView):
|
||||
serializer.document = self.get_document()
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Returns a list of selected document's metadata types and values."""
|
||||
"""
|
||||
Returns a list of selected document's metadata types and values.
|
||||
"""
|
||||
return super(APIDocumentMetadataListView, self).get(*args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
"""Add an existing metadata type and value to the selected document."""
|
||||
"""
|
||||
Add an existing metadata type and value to the selected document.
|
||||
"""
|
||||
return super(APIDocumentMetadataListView, self).post(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -127,29 +155,53 @@ class APIDocumentMetadataView(generics.RetrieveUpdateDestroyAPIView):
|
||||
}
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Delete the selected document metadata type and value."""
|
||||
"""
|
||||
Delete the selected document metadata type and value.
|
||||
"""
|
||||
try:
|
||||
return super(APIDocumentMetadataView, self).delete(*args, **kwargs)
|
||||
return super(
|
||||
APIDocumentMetadataView, self
|
||||
).delete(*args, **kwargs)
|
||||
except Exception as exception:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={'non_fields_errors': unicode(exception)})
|
||||
return Response(
|
||||
status=status.HTTP_400_BAD_REQUEST, data={
|
||||
'non_fields_errors': unicode(exception)
|
||||
}
|
||||
)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Return the details of the selected document metadata type and value."""
|
||||
"""
|
||||
Return the details of the selected document metadata type and value.
|
||||
"""
|
||||
return super(APIDocumentMetadataView, self).get(*args, **kwargs)
|
||||
|
||||
def patch(self, *args, **kwargs):
|
||||
"""Edit the selected document metadata type and value."""
|
||||
"""
|
||||
Edit the selected document metadata type and value.
|
||||
"""
|
||||
try:
|
||||
return super(APIDocumentMetadataView, self).patch(*args, **kwargs)
|
||||
return super(
|
||||
APIDocumentMetadataView, self
|
||||
).patch(*args, **kwargs)
|
||||
except Exception as exception:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={'non_fields_errors': unicode(exception)})
|
||||
return Response(
|
||||
status=status.HTTP_400_BAD_REQUEST, data={
|
||||
'non_fields_errors': unicode(exception)
|
||||
}
|
||||
)
|
||||
|
||||
def put(self, *args, **kwargs):
|
||||
"""Edit the selected document metadata type and value."""
|
||||
"""
|
||||
Edit the selected document metadata type and value.
|
||||
"""
|
||||
try:
|
||||
return super(APIDocumentMetadataView, self).put(*args, **kwargs)
|
||||
except Exception as exception:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={'non_fields_errors': unicode(exception)})
|
||||
return Response(
|
||||
status=status.HTTP_400_BAD_REQUEST, data={
|
||||
'non_fields_errors': unicode(exception)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class APIDocumentTypeMetadataTypeOptionalListView(generics.ListCreateAPIView):
|
||||
@@ -160,17 +212,28 @@ class APIDocumentTypeMetadataTypeOptionalListView(generics.ListCreateAPIView):
|
||||
required_metadata = False
|
||||
|
||||
def get_queryset(self):
|
||||
document_type = get_object_or_404(DocumentType, pk=self.kwargs['document_type_pk'])
|
||||
document_type = get_object_or_404(
|
||||
DocumentType, pk=self.kwargs['document_type_pk']
|
||||
)
|
||||
try:
|
||||
Permission.check_permissions(self.request.user, [permission_document_type_view])
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_document_type_view]
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(permission_document_type_view, self.request.user, document_type)
|
||||
AccessControlList.objects.check_access(
|
||||
permission_document_type_view, self.request.user,
|
||||
document_type
|
||||
)
|
||||
|
||||
return document_type.metadata.filter(required=self.required_metadata)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Returns a list of selected document type's optional metadata types."""
|
||||
return super(APIDocumentTypeMetadataTypeOptionalListView, self).get(*args, **kwargs)
|
||||
"""
|
||||
Returns a list of selected document type's optional metadata types.
|
||||
"""
|
||||
return super(
|
||||
APIDocumentTypeMetadataTypeOptionalListView, self
|
||||
).get(*args, **kwargs)
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.request.method == 'GET':
|
||||
@@ -182,18 +245,29 @@ class APIDocumentTypeMetadataTypeOptionalListView(generics.ListCreateAPIView):
|
||||
"""
|
||||
Add an optional metadata type to a document type.
|
||||
"""
|
||||
document_type = get_object_or_404(DocumentType, pk=self.kwargs['document_type_pk'])
|
||||
document_type = get_object_or_404(
|
||||
DocumentType, pk=self.kwargs['document_type_pk']
|
||||
)
|
||||
|
||||
try:
|
||||
Permission.check_permissions(self.request.user, [permission_document_type_edit])
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_document_type_edit]
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(permission_document_type_edit, self.request.user, document_type)
|
||||
AccessControlList.objects.check_access(
|
||||
permission_document_type_edit, self.request.user,
|
||||
document_type
|
||||
)
|
||||
|
||||
serializer = self.get_serializer(data=self.request.POST)
|
||||
|
||||
if serializer.is_valid():
|
||||
metadata_type = get_object_or_404(MetadataType, pk=serializer.data['metadata_type_pk'])
|
||||
document_type.metadata_type.add(metadata_type, required=self.required_metadata)
|
||||
metadata_type = get_object_or_404(
|
||||
MetadataType, pk=serializer.data['metadata_type_pk']
|
||||
)
|
||||
document_type.metadata_type.add(
|
||||
metadata_type, required=self.required_metadata
|
||||
)
|
||||
return Response(status=status.HTTP_201_CREATED)
|
||||
else:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
@@ -203,14 +277,21 @@ class APIDocumentTypeMetadataTypeRequiredListView(APIDocumentTypeMetadataTypeOpt
|
||||
required_metadata = True
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Returns a list of the selected document type's required metadata types."""
|
||||
return super(APIDocumentTypeMetadataTypeRequiredListView, self).get(*args, **kwargs)
|
||||
"""
|
||||
Returns a list of the selected document type's required metadata
|
||||
types.
|
||||
"""
|
||||
return super(
|
||||
APIDocumentTypeMetadataTypeRequiredListView, self
|
||||
).get(*args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
Add a required metadata type to a document type.
|
||||
"""
|
||||
return super(APIDocumentTypeMetadataTypeRequiredListView, self).get(*args, **kwargs)
|
||||
return super(
|
||||
APIDocumentTypeMetadataTypeRequiredListView, self
|
||||
).get(*args, **kwargs)
|
||||
|
||||
|
||||
class APIDocumentTypeMetadataTypeRequiredView(views.APIView):
|
||||
@@ -219,12 +300,21 @@ class APIDocumentTypeMetadataTypeRequiredView(views.APIView):
|
||||
Remove a metadata type from a document type.
|
||||
"""
|
||||
|
||||
document_type = get_object_or_404(DocumentType, pk=self.kwargs['document_type_pk'])
|
||||
document_type = get_object_or_404(
|
||||
DocumentType, pk=self.kwargs['document_type_pk']
|
||||
)
|
||||
try:
|
||||
Permission.check_permissions(self.request.user, [permission_document_type_edit])
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_document_type_edit]
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(permission_document_type_edit, self.request.user, document_type)
|
||||
AccessControlList.objects.check_access(
|
||||
permission_document_type_edit, self.request.user,
|
||||
document_type
|
||||
)
|
||||
|
||||
metadata_type = get_object_or_404(MetadataType, pk=self.kwargs['metadata_type_pk'])
|
||||
metadata_type = get_object_or_404(
|
||||
MetadataType, pk=self.kwargs['metadata_type_pk']
|
||||
)
|
||||
document_type.metadata_type.remove(metadata_type)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@@ -31,10 +31,12 @@ from .handlers import (
|
||||
from .links import (
|
||||
link_metadata_add, link_metadata_edit, link_metadata_multiple_add,
|
||||
link_metadata_multiple_edit, link_metadata_multiple_remove,
|
||||
link_metadata_remove, link_metadata_view, link_setup_document_type_metadata,
|
||||
link_setup_document_type_metadata_required, link_setup_metadata_type_create,
|
||||
link_setup_metadata_type_delete, link_setup_metadata_type_edit,
|
||||
link_setup_metadata_type_list, link_documents_missing_required_metadata
|
||||
link_metadata_remove, link_metadata_view,
|
||||
link_setup_document_type_metadata,
|
||||
link_setup_document_type_metadata_required,
|
||||
link_setup_metadata_type_create, link_setup_metadata_type_delete,
|
||||
link_setup_metadata_type_edit, link_setup_metadata_type_list,
|
||||
link_documents_missing_required_metadata
|
||||
)
|
||||
from .models import DocumentTypeMetadataType, MetadataType
|
||||
from .permissions import (
|
||||
@@ -54,21 +56,47 @@ class MetadataApp(MayanAppConfig):
|
||||
|
||||
APIEndPoint('metadata')
|
||||
|
||||
Document.add_to_class('metadata_value_of', DocumentMetadataHelper.constructor)
|
||||
Document.add_to_class(
|
||||
'metadata_value_of', DocumentMetadataHelper.constructor
|
||||
)
|
||||
|
||||
ModelAttribute(Document, 'metadata', type_name='related', description=_('Queryset containing a MetadataType instance reference and a value for that metadata type'))
|
||||
ModelAttribute(Document, 'metadata__metadata_type__name', label=_('Metadata type name'), type_name='query')
|
||||
ModelAttribute(Document, 'metadata__value', label=_('Metadata type value'), type_name='query')
|
||||
ModelAttribute(Document, 'metadata_value_of', label=_('Value of a metadata'), description=_('Return the value of a specific document metadata'), type_name=['property', 'indexing'])
|
||||
ModelAttribute(
|
||||
Document, 'metadata', type_name='related',
|
||||
description=_(
|
||||
'Queryset containing a MetadataType instance reference and a value for that metadata type'
|
||||
)
|
||||
)
|
||||
ModelAttribute(
|
||||
Document, 'metadata__metadata_type__name',
|
||||
label=_('Metadata type name'), type_name='query'
|
||||
)
|
||||
ModelAttribute(
|
||||
Document, 'metadata__value', label=_('Metadata type value'),
|
||||
type_name='query'
|
||||
)
|
||||
ModelAttribute(
|
||||
Document, 'metadata_value_of', label=_('Value of a metadata'),
|
||||
description=_(
|
||||
'Return the value of a specific document metadata'
|
||||
),
|
||||
type_name=['property', 'indexing']
|
||||
)
|
||||
|
||||
ModelPermission.register(
|
||||
model=Document, permissions=(
|
||||
permission_metadata_document_add, permission_metadata_document_edit,
|
||||
permission_metadata_document_remove, permission_metadata_document_view,
|
||||
permission_metadata_document_add,
|
||||
permission_metadata_document_edit,
|
||||
permission_metadata_document_remove,
|
||||
permission_metadata_document_view,
|
||||
)
|
||||
)
|
||||
|
||||
SourceColumn(source=Document, label=_('Metadata'), attribute=encapsulate(lambda document: get_metadata_string(document)))
|
||||
SourceColumn(
|
||||
source=Document, label=_('Metadata'),
|
||||
attribute=encapsulate(
|
||||
lambda document: get_metadata_string(document)
|
||||
)
|
||||
)
|
||||
|
||||
app.conf.CELERY_QUEUES.append(
|
||||
Queue('metadata', Exchange('metadata'), routing_key='metadata'),
|
||||
@@ -85,18 +113,66 @@ class MetadataApp(MayanAppConfig):
|
||||
}
|
||||
)
|
||||
|
||||
document_search.add_model_field(field='metadata__metadata_type__name', label=_('Metadata type'))
|
||||
document_search.add_model_field(field='metadata__value', label=_('Metadata value'))
|
||||
document_search.add_model_field(
|
||||
field='metadata__metadata_type__name', label=_('Metadata type')
|
||||
)
|
||||
document_search.add_model_field(
|
||||
field='metadata__value', label=_('Metadata value')
|
||||
)
|
||||
|
||||
menu_facet.bind_links(links=[link_metadata_view], sources=[Document])
|
||||
menu_multi_item.bind_links(links=[link_metadata_multiple_add, link_metadata_multiple_edit, link_metadata_multiple_remove], sources=[Document])
|
||||
menu_object.bind_links(links=[link_setup_document_type_metadata, link_setup_document_type_metadata_required], sources=[DocumentType])
|
||||
menu_object.bind_links(links=[link_setup_metadata_type_edit, link_setup_metadata_type_delete], sources=[MetadataType])
|
||||
menu_secondary.bind_links(links=[link_setup_metadata_type_list, link_setup_metadata_type_create], sources=[MetadataType, 'metadata:setup_metadata_type_list', 'metadata:setup_metadata_type_create'])
|
||||
menu_multi_item.bind_links(
|
||||
links=[
|
||||
link_metadata_multiple_add, link_metadata_multiple_edit,
|
||||
link_metadata_multiple_remove
|
||||
], sources=[Document]
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=[
|
||||
link_setup_document_type_metadata,
|
||||
link_setup_document_type_metadata_required
|
||||
], sources=[DocumentType]
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=[
|
||||
link_setup_metadata_type_edit,
|
||||
link_setup_metadata_type_delete
|
||||
], sources=[MetadataType]
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
links=[
|
||||
link_setup_metadata_type_list,
|
||||
link_setup_metadata_type_create
|
||||
], sources=[
|
||||
MetadataType, 'metadata:setup_metadata_type_list',
|
||||
'metadata:setup_metadata_type_create'
|
||||
]
|
||||
)
|
||||
menu_setup.bind_links(links=[link_setup_metadata_type_list])
|
||||
menu_sidebar.bind_links(links=[link_metadata_add, link_metadata_edit, link_metadata_remove], sources=['metadata:metadata_add', 'metadata:metadata_edit', 'metadata:metadata_remove', 'metadata:metadata_view'])
|
||||
menu_tools.bind_links(links=[link_documents_missing_required_metadata])
|
||||
menu_sidebar.bind_links(
|
||||
links=[
|
||||
link_metadata_add, link_metadata_edit, link_metadata_remove
|
||||
], sources=[
|
||||
'metadata:metadata_add', 'metadata:metadata_edit',
|
||||
'metadata:metadata_remove', 'metadata:metadata_view'
|
||||
]
|
||||
)
|
||||
menu_tools.bind_links(
|
||||
links=[link_documents_missing_required_metadata]
|
||||
)
|
||||
|
||||
post_delete.connect(post_document_type_metadata_type_delete, dispatch_uid='post_document_type_metadata_type_delete', sender=DocumentTypeMetadataType)
|
||||
post_document_type_change.connect(post_post_document_type_change_metadata, dispatch_uid='post_post_document_type_change_metadata', sender=Document)
|
||||
post_save.connect(post_document_type_metadata_type_add, dispatch_uid='post_document_type_metadata_type_add', sender=DocumentTypeMetadataType)
|
||||
post_delete.connect(
|
||||
post_document_type_metadata_type_delete,
|
||||
dispatch_uid='post_document_type_metadata_type_delete',
|
||||
sender=DocumentTypeMetadataType
|
||||
)
|
||||
post_document_type_change.connect(
|
||||
post_post_document_type_change_metadata,
|
||||
dispatch_uid='post_post_document_type_change_metadata',
|
||||
sender=Document
|
||||
)
|
||||
post_save.connect(
|
||||
post_document_type_metadata_type_add,
|
||||
dispatch_uid='post_document_type_metadata_type_add',
|
||||
sender=DocumentTypeMetadataType
|
||||
)
|
||||
|
||||
@@ -3,11 +3,11 @@ from __future__ import unicode_literals
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms.formsets import formset_factory
|
||||
from django.template import Context, Template
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .models import MetadataType
|
||||
from .settings import setting_available_functions, setting_available_models
|
||||
|
||||
|
||||
class MetadataForm(forms.Form):
|
||||
@@ -35,14 +35,19 @@ class MetadataForm(forms.Form):
|
||||
except AttributeError:
|
||||
message = unicode(exception)
|
||||
|
||||
raise ValidationError(_('Invalid value: %(message)s'), params={'message': message}, code='invalid')
|
||||
raise ValidationError(
|
||||
_('Invalid value: %(message)s'), params={
|
||||
'message': message
|
||||
}, code='invalid'
|
||||
)
|
||||
else:
|
||||
# Return the result if it was a parsing function
|
||||
# If it was a validation function and passed correctly we return
|
||||
# the original input value
|
||||
# If it was a validation function and passed correctly
|
||||
# we return the original input value
|
||||
return result or self.cleaned_data['value']
|
||||
else:
|
||||
# If a validator was never specified we return the original value
|
||||
# If a validator was never specified we return the original
|
||||
# value
|
||||
return self.cleaned_data['value']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -60,12 +65,16 @@ class MetadataForm(forms.Form):
|
||||
else:
|
||||
self.fields['value'].required = False
|
||||
|
||||
self.fields['name'].initial = '%s%s' % ((self.metadata_type.label if self.metadata_type.label else self.metadata_type.name), required_string)
|
||||
self.fields['name'].initial = '%s%s' % (
|
||||
(self.metadata_type.label if self.metadata_type.label else self.metadata_type.name),
|
||||
required_string
|
||||
)
|
||||
self.fields['id'].initial = self.metadata_type.pk
|
||||
|
||||
if self.metadata_type.lookup:
|
||||
try:
|
||||
choices = eval(self.metadata_type.lookup, setting_available_models.value)
|
||||
#choices = eval(self.metadata_type.lookup, setting_available_models.value) #####
|
||||
choices = []
|
||||
self.fields['value'] = forms.ChoiceField(label=self.fields['value'].label)
|
||||
choices = zip(choices, choices)
|
||||
if not required:
|
||||
@@ -74,25 +83,39 @@ class MetadataForm(forms.Form):
|
||||
self.fields['value'].required = required
|
||||
except Exception as exception:
|
||||
self.fields['value'].initial = exception
|
||||
self.fields['value'].widget = forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
self.fields['value'].widget = forms.TextInput(
|
||||
attrs={'readonly': 'readonly'}
|
||||
)
|
||||
|
||||
if self.metadata_type.default:
|
||||
try:
|
||||
self.fields['value'].initial = eval(self.metadata_type.default, setting_available_functions.value)
|
||||
template = Template(self.metadata_type.default)
|
||||
context = Context()
|
||||
result = template.render(context=context)
|
||||
self.fields['value'].initial = result
|
||||
except Exception as exception:
|
||||
self.fields['value'].initial = exception
|
||||
self.fields['value'].initial = _(
|
||||
'Error: %s'
|
||||
) % exception
|
||||
|
||||
id = forms.CharField(label=_('ID'), widget=forms.HiddenInput)
|
||||
|
||||
name = forms.CharField(label=_('Name'), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||
name = forms.CharField(
|
||||
label=_('Name'), required=False,
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'})
|
||||
)
|
||||
value = forms.CharField(label=_('Value'), required=False)
|
||||
update = forms.BooleanField(initial=True, label=_('Update'), required=False)
|
||||
update = forms.BooleanField(
|
||||
initial=True, label=_('Update'), required=False
|
||||
)
|
||||
|
||||
MetadataFormSet = formset_factory(MetadataForm, extra=0)
|
||||
|
||||
|
||||
class AddMetadataForm(forms.Form):
|
||||
metadata_type = forms.ModelChoiceField(queryset=MetadataType.objects.all(), label=_('Metadata type'))
|
||||
metadata_type = forms.ModelChoiceField(
|
||||
queryset=MetadataType.objects.all(), label=_('Metadata type')
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
document_type = kwargs.pop('document_type')
|
||||
@@ -101,7 +124,9 @@ class AddMetadataForm(forms.Form):
|
||||
|
||||
|
||||
class MetadataRemoveForm(MetadataForm):
|
||||
update = forms.BooleanField(initial=False, label=_('Remove'), required=False)
|
||||
update = forms.BooleanField(
|
||||
initial=False, label=_('Remove'), required=False
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MetadataRemoveForm, self).__init__(*args, **kwargs)
|
||||
|
||||
@@ -12,12 +12,22 @@ def post_document_type_metadata_type_add(sender, instance, created, **kwargs):
|
||||
logger.debug('instance: %s', instance)
|
||||
|
||||
if created and instance.required:
|
||||
task_add_required_metadata_type.apply_async(kwargs={'document_type_id': instance.document_type.pk, 'metadata_type_id': instance.metadata_type.pk})
|
||||
task_add_required_metadata_type.apply_async(
|
||||
kwargs={
|
||||
'document_type_id': instance.document_type.pk,
|
||||
'metadata_type_id': instance.metadata_type.pk
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def post_document_type_metadata_type_delete(sender, instance, **kwargs):
|
||||
logger.debug('instance: %s', instance)
|
||||
task_remove_metadata_type.apply_async(kwargs={'document_type_id': instance.document_type.pk, 'metadata_type_id': instance.metadata_type.pk})
|
||||
task_remove_metadata_type.apply_async(
|
||||
kwargs={
|
||||
'document_type_id': instance.document_type.pk,
|
||||
'metadata_type_id': instance.metadata_type.pk
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def post_post_document_type_change_metadata(sender, instance, **kwargs):
|
||||
@@ -29,4 +39,8 @@ def post_post_document_type_change_metadata(sender, instance, **kwargs):
|
||||
|
||||
# Add new document type metadata types to document
|
||||
for document_type_metadata_type in instance.document_type.metadata.filter(required=True):
|
||||
DocumentMetadata.objects.create(document=instance, metadata_type=document_type_metadata_type.metadata_type, value=None)
|
||||
DocumentMetadata.objects.create(
|
||||
document=instance,
|
||||
metadata_type=document_type_metadata_type.metadata_type,
|
||||
value=None
|
||||
)
|
||||
|
||||
@@ -12,7 +12,10 @@ from .settings import setting_available_validators
|
||||
|
||||
|
||||
def validation_choices():
|
||||
return zip(setting_available_validators.value, setting_available_validators.value)
|
||||
return zip(
|
||||
setting_available_validators.value,
|
||||
setting_available_validators.value
|
||||
)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
@@ -20,13 +23,28 @@ class MetadataType(models.Model):
|
||||
"""
|
||||
Define a type of metadata
|
||||
"""
|
||||
name = models.CharField(max_length=48, help_text=_('Do not use python reserved words, or spaces.'), unique=True, verbose_name=_('Name'))
|
||||
name = models.CharField(
|
||||
max_length=48,
|
||||
help_text=_('Name used by other apps to reference this value. Do not use python reserved words, or spaces.'),
|
||||
unique=True, verbose_name=_('Name')
|
||||
)
|
||||
label = models.CharField(max_length=48, verbose_name=_('Label'))
|
||||
default = models.CharField(blank=True, max_length=128, null=True, help_text=_('Enter a string to be evaluated.'), verbose_name=_('Default'))
|
||||
default = models.CharField(
|
||||
blank=True, max_length=128, null=True,
|
||||
help_text=_('Enter a template to render. Use Django\'s default templating language (https://docs.djangoproject.com/en/1.7/ref/templates/builtins/)'),
|
||||
verbose_name=_('Default')
|
||||
)
|
||||
# TODO: Add enable_lookup boolean to allow users to switch the lookup on and
|
||||
# off without losing the lookup expression
|
||||
lookup = models.TextField(blank=True, null=True, help_text=_('Enter a string to be evaluated that returns an iterable.'), verbose_name=_('Lookup'))
|
||||
validation = models.CharField(blank=True, choices=validation_choices(), max_length=64, verbose_name=_('Validation function name'))
|
||||
lookup = models.TextField(
|
||||
blank=True, null=True,
|
||||
help_text=_('Enter a string to be evaluated that returns an iterable.'),
|
||||
verbose_name=_('Lookup')
|
||||
)
|
||||
validation = models.CharField(
|
||||
blank=True, choices=validation_choices(), max_length=64,
|
||||
verbose_name=_('Validation function name')
|
||||
)
|
||||
# TODO: Find a different way to let users know what models and functions are
|
||||
# available now that we removed these from the help_text
|
||||
objects = MetadataTypeManager()
|
||||
@@ -49,22 +67,31 @@ class DocumentMetadata(models.Model):
|
||||
Link a document to a specific instance of a metadata type with it's
|
||||
current value
|
||||
"""
|
||||
document = models.ForeignKey(Document, related_name='metadata', verbose_name=_('Document'))
|
||||
document = models.ForeignKey(
|
||||
Document, related_name='metadata', verbose_name=_('Document')
|
||||
)
|
||||
metadata_type = models.ForeignKey(MetadataType, verbose_name=_('Type'))
|
||||
value = models.CharField(blank=True, db_index=True, max_length=255, null=True, verbose_name=_('Value'))
|
||||
value = models.CharField(
|
||||
blank=True, db_index=True, max_length=255, null=True,
|
||||
verbose_name=_('Value')
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self.metadata_type)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.metadata_type.pk not in self.document.document_type.metadata.values_list('metadata_type', flat=True):
|
||||
raise ValidationError(_('Metadata type is not valid for this document type.'))
|
||||
raise ValidationError(
|
||||
_('Metadata type is not valid for this document type.')
|
||||
)
|
||||
|
||||
return super(DocumentMetadata, self).save(*args, **kwargs)
|
||||
|
||||
def delete(self, enforce_required=True, *args, **kwargs):
|
||||
if enforce_required and self.metadata_type.pk in self.document.document_type.metadata.filter(required=True).values_list('metadata_type', flat=True):
|
||||
raise ValidationError(_('Metadata type is required for this document type.'))
|
||||
raise ValidationError(
|
||||
_('Metadata type is required for this document type.')
|
||||
)
|
||||
|
||||
return super(DocumentMetadata, self).delete(*args, **kwargs)
|
||||
|
||||
@@ -76,8 +103,13 @@ class DocumentMetadata(models.Model):
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DocumentTypeMetadataType(models.Model):
|
||||
document_type = models.ForeignKey(DocumentType, related_name='metadata', verbose_name=_('Document type'))
|
||||
metadata_type = models.ForeignKey(MetadataType, verbose_name=_('Metadata type'))
|
||||
document_type = models.ForeignKey(
|
||||
DocumentType, related_name='metadata',
|
||||
verbose_name=_('Document type')
|
||||
)
|
||||
metadata_type = models.ForeignKey(
|
||||
MetadataType, verbose_name=_('Metadata type')
|
||||
)
|
||||
required = models.BooleanField(default=False, verbose_name=_('Required'))
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -28,9 +28,16 @@ class DocumentTypeMetadataTypeSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class DocumentNewMetadataSerializer(serializers.Serializer):
|
||||
metadata_type = serializers.IntegerField(help_text=_('Primary key of the metadata type to be added.'))
|
||||
value = serializers.CharField(max_length=255, help_text=_('Value of the corresponding metadata type instance.'))
|
||||
metadata_type = serializers.IntegerField(
|
||||
help_text=_('Primary key of the metadata type to be added.')
|
||||
)
|
||||
value = serializers.CharField(
|
||||
max_length=255,
|
||||
help_text=_('Value of the corresponding metadata type instance.')
|
||||
)
|
||||
|
||||
|
||||
class DocumentTypeNewMetadataTypeSerializer(serializers.Serializer):
|
||||
metadata_type = serializers.IntegerField(help_text=_('Primary key of the metadata type to be added.'))
|
||||
metadata_type = serializers.IntegerField(
|
||||
help_text=_('Primary key of the metadata type to be added.')
|
||||
)
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from smart_settings import Namespace
|
||||
|
||||
from .validators import MetadataValidator
|
||||
|
||||
default_available_functions = {
|
||||
'current_date': now().date,
|
||||
}
|
||||
|
||||
default_available_models = {
|
||||
'User': User
|
||||
}
|
||||
|
||||
namespace = Namespace(name='metadata', label=_('Metadata'))
|
||||
setting_available_validators = namespace.add_setting(global_name='METADATA_AVAILABLE_VALIDATORS', default=MetadataValidator.get_import_paths())
|
||||
setting_available_functions = namespace.add_setting(global_name='METADATA_AVAILABLE_FUNCTIONS', default=default_available_functions)
|
||||
setting_available_models = namespace.add_setting(global_name='METADATA_AVAILABLE_MODELS', default=default_available_models)
|
||||
setting_available_validators = namespace.add_setting(
|
||||
global_name='METADATA_AVAILABLE_VALIDATORS',
|
||||
default=MetadataValidator.get_import_paths()
|
||||
)
|
||||
|
||||
@@ -11,7 +11,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
@app.task(ignore_result=True)
|
||||
def task_remove_metadata_type(document_type_id, metadata_type_id):
|
||||
DocumentMetadata.objects.filter(document__document_type__id=document_type_id, metadata_type__id=metadata_type_id).delete()
|
||||
DocumentMetadata.objects.filter(
|
||||
document__document_type__id=document_type_id,
|
||||
metadata_type__id=metadata_type_id
|
||||
).delete()
|
||||
|
||||
|
||||
@app.task(ignore_result=True)
|
||||
|
||||
@@ -12,37 +12,101 @@ from .api_views import (
|
||||
from .views import (
|
||||
MetadataTypeCreateView, MetadataTypeDeleteView, MetadataTypeEditView,
|
||||
MetadataTypeListView, MissingRequiredMetadataDocumentListView,
|
||||
SetupDocumentTypeMetadataOptionalView, SetupDocumentTypeMetadataRequiredView
|
||||
SetupDocumentTypeMetadataOptionalView,
|
||||
SetupDocumentTypeMetadataRequiredView
|
||||
)
|
||||
|
||||
urlpatterns = patterns(
|
||||
'metadata.views',
|
||||
url(r'^(?P<pk>\d+)/edit/$', 'metadata_edit', name='metadata_edit'),
|
||||
url(r'^(?P<document_id>\d+)/view/$', 'metadata_view', name='metadata_view'),
|
||||
url(r'^multiple/edit/$', 'metadata_multiple_edit', name='metadata_multiple_edit'),
|
||||
url(
|
||||
r'^(?P<document_id>\d+)/view/$', 'metadata_view',
|
||||
name='metadata_view'
|
||||
),
|
||||
url(
|
||||
r'^multiple/edit/$', 'metadata_multiple_edit',
|
||||
name='metadata_multiple_edit'
|
||||
),
|
||||
url(r'^(?P<document_id>\d+)/add/$', 'metadata_add', name='metadata_add'),
|
||||
url(r'^multiple/add/$', 'metadata_multiple_add', name='metadata_multiple_add'),
|
||||
url(r'^(?P<document_id>\d+)/remove/$', 'metadata_remove', name='metadata_remove'),
|
||||
url(r'^multiple/remove/$', 'metadata_multiple_remove', name='metadata_multiple_remove'),
|
||||
url(
|
||||
r'^multiple/add/$', 'metadata_multiple_add',
|
||||
name='metadata_multiple_add'
|
||||
),
|
||||
url(
|
||||
r'^(?P<document_id>\d+)/remove/$', 'metadata_remove',
|
||||
name='metadata_remove'
|
||||
),
|
||||
url(
|
||||
r'^multiple/remove/$', 'metadata_multiple_remove',
|
||||
name='metadata_multiple_remove'
|
||||
),
|
||||
|
||||
url(r'^setup/type/list/$', MetadataTypeListView.as_view(), name='setup_metadata_type_list'),
|
||||
url(r'^setup/type/create/$', MetadataTypeCreateView.as_view(), name='setup_metadata_type_create'),
|
||||
url(r'^setup/type/(?P<pk>\d+)/edit/$', MetadataTypeEditView.as_view(), name='setup_metadata_type_edit'),
|
||||
url(r'^setup/type/(?P<pk>\d+)/delete/$', MetadataTypeDeleteView.as_view(), name='setup_metadata_type_delete'),
|
||||
url(
|
||||
r'^setup/type/list/$', MetadataTypeListView.as_view(),
|
||||
name='setup_metadata_type_list'
|
||||
),
|
||||
url(
|
||||
r'^setup/type/create/$', MetadataTypeCreateView.as_view(),
|
||||
name='setup_metadata_type_create'
|
||||
),
|
||||
url(
|
||||
r'^setup/type/(?P<pk>\d+)/edit/$', MetadataTypeEditView.as_view(),
|
||||
name='setup_metadata_type_edit'
|
||||
),
|
||||
url(
|
||||
r'^setup/type/(?P<pk>\d+)/delete/$',
|
||||
MetadataTypeDeleteView.as_view(), name='setup_metadata_type_delete'
|
||||
),
|
||||
|
||||
url(r'^setup/document/type/(?P<pk>\d+)/metadata/edit/$', SetupDocumentTypeMetadataOptionalView.as_view(), name='setup_document_type_metadata'),
|
||||
url(r'^setup/document/type/(?P<pk>\d+)/metadata/edit/required/$', SetupDocumentTypeMetadataRequiredView.as_view(), name='setup_document_type_metadata_required'),
|
||||
url(
|
||||
r'^setup/document/type/(?P<pk>\d+)/metadata/edit/$',
|
||||
SetupDocumentTypeMetadataOptionalView.as_view(),
|
||||
name='setup_document_type_metadata'
|
||||
),
|
||||
url(
|
||||
r'^setup/document/type/(?P<pk>\d+)/metadata/edit/required/$',
|
||||
SetupDocumentTypeMetadataRequiredView.as_view(),
|
||||
name='setup_document_type_metadata_required'
|
||||
),
|
||||
|
||||
url(r'^tools/missing_required_metadata/$', MissingRequiredMetadataDocumentListView.as_view(), name='documents_missing_required_metadata'),
|
||||
url(
|
||||
r'^tools/missing_required_metadata/$',
|
||||
MissingRequiredMetadataDocumentListView.as_view(),
|
||||
name='documents_missing_required_metadata'
|
||||
),
|
||||
)
|
||||
|
||||
api_urls = patterns(
|
||||
'',
|
||||
url(r'^metadatatypes/$', APIMetadataTypeListView.as_view(), name='metadatatype-list'),
|
||||
url(r'^metadatatypes/(?P<pk>[0-9]+)/$', APIMetadataTypeView.as_view(), name='metadatatype-detail'),
|
||||
url(r'^document/metadata/(?P<pk>[0-9]+)/$', APIDocumentMetadataView.as_view(), name='documentmetadata-detail'),
|
||||
url(r'^document/(?P<document_pk>[0-9]+)/metadata/$', APIDocumentMetadataListView.as_view(), name='documentmetadata-list'),
|
||||
url(r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/optional/$', APIDocumentTypeMetadataTypeOptionalListView.as_view(), name='documenttypemetadatatype-list'),
|
||||
url(r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/required/$', APIDocumentTypeMetadataTypeRequiredListView.as_view(), name='documenttypemetadatatype-list'),
|
||||
url(r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/(?P<metadata_type_pk>[0-9]+)/$', APIDocumentTypeMetadataTypeRequiredView.as_view(), name='documenttypemetadatatype-detail'),
|
||||
url(
|
||||
r'^metadatatypes/$', APIMetadataTypeListView.as_view(),
|
||||
name='metadatatype-list'
|
||||
),
|
||||
url(
|
||||
r'^metadatatypes/(?P<pk>[0-9]+)/$', APIMetadataTypeView.as_view(),
|
||||
name='metadatatype-detail'
|
||||
),
|
||||
url(
|
||||
r'^document/metadata/(?P<pk>[0-9]+)/$',
|
||||
APIDocumentMetadataView.as_view(), name='documentmetadata-detail'
|
||||
),
|
||||
url(
|
||||
r'^document/(?P<document_pk>[0-9]+)/metadata/$',
|
||||
APIDocumentMetadataListView.as_view(), name='documentmetadata-list'
|
||||
),
|
||||
url(
|
||||
r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/optional/$',
|
||||
APIDocumentTypeMetadataTypeOptionalListView.as_view(),
|
||||
name='documenttypemetadatatype-list'
|
||||
),
|
||||
url(
|
||||
r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/required/$',
|
||||
APIDocumentTypeMetadataTypeRequiredListView.as_view(),
|
||||
name='documenttypemetadatatype-list'
|
||||
),
|
||||
url(
|
||||
r'^document_type/(?P<document_type_pk>[0-9]+)/metadatatypes/(?P<metadata_type_pk>[0-9]+)/$',
|
||||
APIDocumentTypeMetadataTypeRequiredView.as_view(),
|
||||
name='documenttypemetadatatype-detail'
|
||||
),
|
||||
)
|
||||
|
||||
@@ -41,30 +41,47 @@ class MissingRequiredMetadataDocumentListView(DocumentListView):
|
||||
}
|
||||
|
||||
def get_document_queryset(self):
|
||||
return Document.objects.filter(document_type__metadata__required=True, metadata__value__isnull=True)
|
||||
return Document.objects.filter(
|
||||
document_type__metadata__required=True,
|
||||
metadata__value__isnull=True
|
||||
)
|
||||
|
||||
|
||||
def metadata_edit(request, document_id=None, document_id_list=None):
|
||||
if document_id:
|
||||
document_id_list = unicode(document_id)
|
||||
|
||||
documents = Document.objects.select_related('metadata').filter(pk__in=document_id_list.split(','))
|
||||
documents = Document.objects.select_related('metadata').filter(
|
||||
pk__in=document_id_list.split(',')
|
||||
)
|
||||
|
||||
try:
|
||||
Permission.check_permissions(request.user, [permission_metadata_document_edit])
|
||||
Permission.check_permissions(
|
||||
request.user, [permission_metadata_document_edit]
|
||||
)
|
||||
except PermissionDenied:
|
||||
documents = AccessControlList.objects.filter_by_access(permission_metadata_document_edit, request.user, documents)
|
||||
documents = AccessControlList.objects.filter_by_access(
|
||||
permission_metadata_document_edit, request.user, documents
|
||||
)
|
||||
|
||||
if not documents:
|
||||
if document_id:
|
||||
raise Http404
|
||||
else:
|
||||
messages.error(request, _('Must provide at least one document.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
if len(set([document.document_type.pk for document in documents])) > 1:
|
||||
messages.error(request, _('Only select documents of the same type.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
if set(documents.values_list('metadata__value', flat=True)) == set([None]):
|
||||
message = ungettext(
|
||||
@@ -73,11 +90,19 @@ def metadata_edit(request, document_id=None, document_id_list=None):
|
||||
len(documents)
|
||||
)
|
||||
messages.warning(request, message)
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
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)))
|
||||
next = request.POST.get(
|
||||
'next', request.GET.get(
|
||||
'next', request.META.get('HTTP_REFERER', post_action_redirect)
|
||||
)
|
||||
)
|
||||
|
||||
metadata = {}
|
||||
initial = []
|
||||
@@ -97,7 +122,9 @@ def metadata_edit(request, document_id=None, document_id_list=None):
|
||||
initial.append({
|
||||
'metadata_type': key,
|
||||
'value': ', '.join(value) if value else '',
|
||||
'required': key in document.document_type.metadata.filter(required=True),
|
||||
'required': key in document.document_type.metadata.filter(
|
||||
required=True
|
||||
),
|
||||
})
|
||||
|
||||
formset = MetadataFormSet(initial=initial)
|
||||
@@ -119,10 +146,19 @@ def metadata_edit(request, document_id=None, document_id_list=None):
|
||||
if settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
messages.error(request, _('Error editing metadata for document %(document)s; %(exception)s.') % {
|
||||
'document': document, 'exception': ', '.join(exception.messages)})
|
||||
messages.error(
|
||||
request, _(
|
||||
'Error editing metadata for document %(document)s; %(exception)s.'
|
||||
) % {
|
||||
'document': document,
|
||||
'exception': ', '.join(exception.messages)
|
||||
}
|
||||
)
|
||||
else:
|
||||
messages.success(request, _('Metadata for document %s edited successfully.') % document)
|
||||
messages.success(
|
||||
request,
|
||||
_('Metadata for document %s edited successfully.') % document
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
@@ -146,54 +182,102 @@ def metadata_edit(request, document_id=None, document_id_list=None):
|
||||
|
||||
|
||||
def metadata_multiple_edit(request):
|
||||
return metadata_edit(request, document_id_list=request.GET.get('id_list', ''))
|
||||
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.objects.select_related('document_type'), pk=document_id) for document_id in document_id_list.split(',')]
|
||||
documents = [
|
||||
get_object_or_404(Document.objects.select_related('document_type'), pk=document_id) for document_id in document_id_list.split(',')
|
||||
]
|
||||
if len(set([document.document_type.pk for document in documents])) > 1:
|
||||
messages.error(request, _('Only select documents of the same type.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
messages.error(
|
||||
request, _('Only select documents of the same type.')
|
||||
)
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
Permission.check_permissions(request.user, [permission_metadata_document_add])
|
||||
Permission.check_permissions(
|
||||
request.user, [permission_metadata_document_add]
|
||||
)
|
||||
except PermissionDenied:
|
||||
documents = AccessControlList.objects.filter_by_access(permission_metadata_document_add, request.user, documents)
|
||||
documents = AccessControlList.objects.filter_by_access(
|
||||
permission_metadata_document_add, request.user, documents
|
||||
)
|
||||
|
||||
if not documents:
|
||||
messages.error(request, _('Must provide at least one document.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
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)))
|
||||
next = request.POST.get(
|
||||
'next',
|
||||
request.GET.get(
|
||||
'next', request.META.get('HTTP_REFERER', post_action_redirect)
|
||||
)
|
||||
)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = AddMetadataForm(data=request.POST, document_type=document.document_type)
|
||||
form = AddMetadataForm(
|
||||
data=request.POST, document_type=document.document_type
|
||||
)
|
||||
if form.is_valid():
|
||||
metadata_type = form.cleaned_data['metadata_type']
|
||||
for document in documents:
|
||||
try:
|
||||
document_metadata, created = DocumentMetadata.objects.get_or_create(document=document, metadata_type=metadata_type.metadata_type, defaults={'value': ''})
|
||||
document_metadata, created = DocumentMetadata.objects.get_or_create(
|
||||
document=document,
|
||||
metadata_type=metadata_type.metadata_type,
|
||||
defaults={'value': ''}
|
||||
)
|
||||
except Exception as exception:
|
||||
if getattr(settings, 'DEBUG', False):
|
||||
raise
|
||||
else:
|
||||
messages.error(request, _('Error adding metadata type "%(metadata_type)s" to document: %(document)s; %(exception)s') % {
|
||||
'metadata_type': metadata_type, 'document': document, 'exception': ', '.join(getattr(exception, 'messages', exception))})
|
||||
messages.error(
|
||||
request,
|
||||
_(
|
||||
'Error adding metadata type "%(metadata_type)s" to document: %(document)s; %(exception)s'
|
||||
) % {
|
||||
'metadata_type': metadata_type,
|
||||
'document': document,
|
||||
'exception': ', '.join(getattr(exception, 'messages', exception))
|
||||
}
|
||||
)
|
||||
else:
|
||||
if created:
|
||||
messages.success(request, _('Metadata type: %(metadata_type)s successfully added to document %(document)s.') % {
|
||||
'metadata_type': metadata_type, 'document': document})
|
||||
messages.success(
|
||||
request,
|
||||
_(
|
||||
'Metadata type: %(metadata_type)s successfully added to document %(document)s.'
|
||||
) % {
|
||||
'metadata_type': metadata_type, 'document': document
|
||||
}
|
||||
)
|
||||
else:
|
||||
messages.warning(request, _('Metadata type: %(metadata_type)s already present in document %(document)s.') % {
|
||||
'metadata_type': metadata_type, 'document': document})
|
||||
messages.warning(
|
||||
request, _(
|
||||
'Metadata type: %(metadata_type)s already present in document %(document)s.'
|
||||
) % {
|
||||
'metadata_type': metadata_type, 'document': document
|
||||
}
|
||||
)
|
||||
|
||||
if len(documents) == 1:
|
||||
return HttpResponseRedirect('%s?%s' % (
|
||||
@@ -228,30 +312,46 @@ def metadata_add(request, document_id=None, document_id_list=None):
|
||||
|
||||
|
||||
def metadata_multiple_add(request):
|
||||
return metadata_add(request, document_id_list=request.GET.get('id_list', []))
|
||||
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:
|
||||
document_id_list = unicode(document_id)
|
||||
|
||||
documents = Document.objects.select_related('metadata').filter(pk__in=document_id_list.split(','))
|
||||
documents = Document.objects.select_related('metadata').filter(
|
||||
pk__in=document_id_list.split(',')
|
||||
)
|
||||
|
||||
try:
|
||||
Permission.check_permissions(request.user, [permission_metadata_document_remove])
|
||||
Permission.check_permissions(
|
||||
request.user, [permission_metadata_document_remove]
|
||||
)
|
||||
except PermissionDenied:
|
||||
documents = AccessControlList.objects.filter_by_access(permission_metadata_document_remove, request.user, documents)
|
||||
documents = AccessControlList.objects.filter_by_access(
|
||||
permission_metadata_document_remove, request.user, documents
|
||||
)
|
||||
|
||||
if not documents:
|
||||
if document_id:
|
||||
raise Http404
|
||||
else:
|
||||
messages.error(request, _('Must provide at least one document.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
if len(set([document.document_type.pk for document in documents])) > 1:
|
||||
messages.error(request, _('Only select documents of the same type.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
if set(documents.values_list('metadata__value', flat=True)) == set([None]):
|
||||
message = ungettext(
|
||||
@@ -260,7 +360,11 @@ def metadata_remove(request, document_id=None, document_id_list=None):
|
||||
len(documents)
|
||||
)
|
||||
messages.warning(request, message)
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
|
||||
return HttpResponseRedirect(
|
||||
request.META.get(
|
||||
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
|
||||
)
|
||||
)
|
||||
|
||||
post_action_redirect = reverse('documents:document_list_recent')
|
||||
|
||||
@@ -413,20 +517,36 @@ class SetupDocumentTypeMetadataOptionalView(AssignRemoveView):
|
||||
return get_object_or_404(DocumentType, pk=self.kwargs['pk'])
|
||||
|
||||
def left_list(self):
|
||||
return AssignRemoveView.generate_choices(set(MetadataType.objects.all()) - set(MetadataType.objects.filter(id__in=self.get_object().metadata.values_list('metadata_type', flat=True))))
|
||||
return AssignRemoveView.generate_choices(
|
||||
set(MetadataType.objects.all()) - set(
|
||||
MetadataType.objects.filter(
|
||||
id__in=self.get_object().metadata.values_list(
|
||||
'metadata_type', flat=True
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def right_list(self):
|
||||
return AssignRemoveView.generate_choices(self.get_object().metadata.filter(required=False))
|
||||
return AssignRemoveView.generate_choices(
|
||||
self.get_object().metadata.filter(required=False)
|
||||
)
|
||||
|
||||
def remove(self, item):
|
||||
item.delete()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
data = super(SetupDocumentTypeMetadataOptionalView, self).get_context_data(**kwargs)
|
||||
data.update({
|
||||
'object': self.get_object(),
|
||||
'title': _('Optional metadata types for document type: %s') % self.get_object(),
|
||||
})
|
||||
data = super(
|
||||
SetupDocumentTypeMetadataOptionalView, self
|
||||
).get_context_data(**kwargs)
|
||||
data.update(
|
||||
{
|
||||
'object': self.get_object(),
|
||||
'title': _(
|
||||
'Optional metadata types for document type: %s'
|
||||
) % self.get_object(),
|
||||
}
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
@@ -436,13 +556,21 @@ class SetupDocumentTypeMetadataRequiredView(SetupDocumentTypeMetadataOptionalVie
|
||||
self.get_object().metadata.create(metadata_type=item, required=True)
|
||||
|
||||
def right_list(self):
|
||||
return AssignRemoveView.generate_choices(self.get_object().metadata.filter(required=True))
|
||||
return AssignRemoveView.generate_choices(
|
||||
self.get_object().metadata.filter(required=True)
|
||||
)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
data = super(SetupDocumentTypeMetadataRequiredView, self).get_context_data(**kwargs)
|
||||
data.update({
|
||||
'object': self.get_object(),
|
||||
'title': _('Required metadata types for document type: %s') % self.get_object(),
|
||||
})
|
||||
data = super(
|
||||
SetupDocumentTypeMetadataRequiredView, self
|
||||
).get_context_data(**kwargs)
|
||||
data.update(
|
||||
{
|
||||
'object': self.get_object(),
|
||||
'title': _(
|
||||
'Required metadata types for document type: %s'
|
||||
) % self.get_object(),
|
||||
}
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user