Merge branch 'development' into feature/document_states

This commit is contained in:
Roberto Rosario
2015-01-14 17:00:08 -04:00
8 changed files with 136 additions and 23 deletions

View File

@@ -17,16 +17,26 @@
{% endif %}
{% if form_display_mode_table %}
<div class="flash">
{% for field in form.visible_fields %}
{% for error in field.errors %}
<div class="message error">
<p>{{ error }}</p>
</div>
{% endfor %}
{% endfor %}
</div>
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<tr class="{% cycle 'odd' 'even2' %}">
{% for field in form.visible_fields %}
<td title="{% if field.errors %}{% for error in field.errors %}{{ error }}{% if not forloop.last %} | {% endif %}{% endfor %}{% else %}{{ field.help_text }}{% endif %}">
{% if field.errors %}<div class="flash"><div class="error">{% endif %}
<td title="{% if field.errors %}{% for error in field.errors %}{{ error }}{% if not forloop.last %} | {% endif %}{% endfor %}{% else %}{{ field.help_text }}{% endif %}">
{% if field.errors %}<div class="error">{% endif %}
{{ field }}
{% if field.errors %}</div></div>{% endif %}
</td>
{% if field.errors %}</div>{% endif %}
</td>
{% endfor %}
</tr>
{% else %}

View File

@@ -6,7 +6,7 @@ from .models import MetadataType
class MetadataTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'title', 'default', 'lookup')
list_display = ('name', 'title', 'default', 'lookup', 'validation')
admin.site.register(MetadataType, MetadataTypeAdmin)

View File

@@ -1,6 +1,7 @@
from __future__ import absolute_import
from django import forms
from django.core.exceptions import ValidationError
from django.forms.formsets import formset_factory
from django.utils.translation import ugettext_lazy as _
@@ -11,15 +12,42 @@ from .settings import AVAILABLE_FUNCTIONS, AVAILABLE_MODELS, AVAILABLE_VALIDATOR
class MetadataForm(forms.Form):
def clean_value(self):
value = self.cleaned_data['value']
metadata_id = self.cleaned_data['id']
metadata_type = MetadataType.objects.get(pk=metadata_id)
if metadata_type.lookup and metadata_type.lookup in AVAILABLE_VALIDATORS:
val_func = AVAILABLE_VALIDATORS[metadata_type.lookup]
new_value = val_func(value)
if new_value:
value = new_value
return value
metadata_type = MetadataType.objects.get(pk=self.cleaned_data['id'])
try:
validation_function = AVAILABLE_VALIDATORS[metadata_type.validation]
except KeyError:
# User entered a validation function name, but was not found
# Return value entered as is
return self.cleaned_data['value']
else:
try:
# If it is a parsing function we should get a value
# If it is a validation function we get nothing on success
result = validation_function(self.cleaned_data['value'])
except Exception as exception:
# If it is a validation function and an exception is raise
# we wrap that into a new ValidationError exception
# If the function exception is a ValidationError itself the
# error messages will be in a 'messages' property, so we
# contatenate them.
# Otherwise we extract whatever single message the exception
# included.
try:
message = u', '.join(exception.messages)
except AttributeError:
message = unicode(exception)
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
return result or self.cleaned_data['value']
# If a validation function was never specified we return the original
# value
return self.cleaned_data['value']
def __init__(self, *args, **kwargs):
super(MetadataForm, self).__init__(*args, **kwargs)
@@ -39,7 +67,7 @@ class MetadataForm(forms.Form):
self.fields['name'].initial = '%s%s' % ((self.metadata_type.title if self.metadata_type.title else self.metadata_type.name), required_string)
self.fields['id'].initial = self.metadata_type.pk
if self.metadata_type.lookup and self.metadata_type.lookup not in AVAILABLE_VALIDATORS:
if self.metadata_type.lookup:
try:
choices = eval(self.metadata_type.lookup, AVAILABLE_MODELS)
self.fields['value'] = forms.ChoiceField(label=self.fields['value'].label)
@@ -68,22 +96,26 @@ MetadataFormSet = formset_factory(MetadataForm, extra=0)
class AddMetadataForm(forms.Form):
metadata_type = forms.ModelChoiceField(queryset=MetadataType.objects.all(), label=_(u'Metadata type'))
def __init__(self, *args, **kwargs):
document_type = kwargs.pop('document_type')
super(AddMetadataForm, self).__init__(*args, **kwargs)
self.fields['metadata_type'].queryset = document_type.metadata.all()
metadata_type = forms.ModelChoiceField(queryset=MetadataType.objects.all(), label=_(u'Metadata type'))
class MetadataRemoveForm(MetadataForm):
update = forms.BooleanField(initial=False, label=_(u'Remove'), required=False)
def __init__(self, *args, **kwargs):
super(MetadataRemoveForm, self).__init__(*args, **kwargs)
self.fields.pop('value')
MetadataRemoveFormSet = formset_factory(MetadataRemoveForm, extra=0)
class MetadataTypeForm(forms.ModelForm):
class Meta:
fields = ('name', 'title', 'default', 'lookup')
fields = ('name', 'title', 'default', 'lookup', 'validation')
model = MetadataType

View File

@@ -7,6 +7,7 @@ from django.utils.translation import ugettext_lazy as _
from documents.models import Document, DocumentType
from .managers import MetadataTypeManager
from .settings import AVAILABLE_VALIDATORS
class MetadataType(models.Model):
@@ -24,7 +25,7 @@ class MetadataType(models.Model):
lookup = models.TextField(blank=True, null=True,
verbose_name=_(u'Lookup'),
help_text=_(u'Enter a string to be evaluated that returns an iterable.'))
# TODO: Add datatype choice: Date, Time, String, Number
validation = models.CharField(blank=True, choices=zip(AVAILABLE_VALIDATORS, AVAILABLE_VALIDATORS), max_length=64, verbose_name=_(u'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()

View File

@@ -1,11 +1,12 @@
"""Configuration options for the metadata app"""
from dateutil.parser import parse
from django.contrib.auth.models import User
from django.utils.timezone import now
from smart_settings.api import register_settings
default_available_functions = {
'current_date': now().date,
}
@@ -15,6 +16,7 @@ default_available_models = {
}
default_available_validators = {
'parse_date': lambda input: parse(input).isoformat()
}
register_settings(

View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'MetadataType.validation'
db.add_column(u'metadata_metadatatype', 'validation',
self.gf('django.db.models.fields.CharField')(default='', max_length=64),
keep_default=False)
def backwards(self, orm):
# Deleting field 'MetadataType.validation'
db.delete_column(u'metadata_metadatatype', 'validation')
models = {
u'documents.document': {
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
'date_added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': u"orm['documents.DocumentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'default': "u'Uninitialized document'", 'max_length': '255', 'db_index': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "u'eng'", 'max_length': '8'}),
'uuid': ('django.db.models.fields.CharField', [], {'default': "u'8fd13d23-fcd0-438c-a1b3-7421a1d0eed5'", 'max_length': '48'})
},
u'documents.documenttype': {
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}),
'ocr': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'metadata.documentmetadata': {
'Meta': {'unique_together': "(('document', 'metadata_type'),)", 'object_name': 'DocumentMetadata'},
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': u"orm['documents.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'metadata_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['metadata.MetadataType']"}),
'value': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'})
},
u'metadata.documenttypemetadatatype': {
'Meta': {'unique_together': "(('document_type', 'metadata_type'),)", 'object_name': 'DocumentTypeMetadataType'},
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'metadata'", 'to': u"orm['documents.DocumentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'metadata_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['metadata.MetadataType']"}),
'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
u'metadata.metadatatype': {
'Meta': {'ordering': "('title',)", 'object_name': 'MetadataType'},
'default': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'lookup': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '48'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '48'}),
'validation': ('django.db.models.fields.CharField', [], {'max_length': '64'})
}
}
complete_apps = ['metadata']

View File

@@ -156,10 +156,13 @@ def metadata_add(request, document_id=None, document_id_list=None):
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, defaults={'value': u''})
document_metadata, created = DocumentMetadata.objects.get_or_create(document=document, metadata_type=metadata_type.metadata_type, defaults={'value': u''})
except Exception as exception:
messages.error(request, _(u'Error adding metadata type "%(metadata_type)s" to document: %(document)s; %(exception)s') % {
'metadata_type': metadata_type, 'document': document, 'exception': ', '.join(exception.messages)})
if getattr(settings, 'DEBUG', False):
raise
else:
messages.error(request, _(u'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, _(u'Metadata type: %(metadata_type)s successfully added to document %(document)s.') % {

View File

@@ -23,6 +23,7 @@ pdfminer==20110227
psutil==2.1.3
pycountry==1.8
pytz==2014.4
python-dateutil==2.4.0
python-gnupg==0.3.6
python-hkp==0.1.3
python-magic==0.4.6