diff --git a/apps/common/templates/generic_detail.html b/apps/common/templates/generic_detail.html index cfe69c7c35..8a7f200ceb 100755 --- a/apps/common/templates/generic_detail.html +++ b/apps/common/templates/generic_detail.html @@ -17,6 +17,28 @@ {% for subtemplate in sidebar_subtemplates %} {% include subtemplate %} {% endfor %} + + {% for subtemplate in sidebar_subtemplates_dict %} + {% with subtemplate.title as title %} + {% with subtemplate.object_list as object_list %} + {% with subtemplate.extra_columns as extra_columns %} + {% with subtemplate.hide_object as hide_object %} + {% with subtemplate.main_object as main_object %} + {% with subtemplate.hide_link as hide_link %} + {% with subtemplate.hide_header as hide_header %} + {% with subtemplate.hide_columns as hide_columns %} + {% with "true" as side_bar %} + {% include subtemplate.name %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endwith %} + {% endfor %} {% endblock %} {% block stylesheets %} diff --git a/apps/common/templates/generic_list_subtemplate.html b/apps/common/templates/generic_list_subtemplate.html index d7d481d681..2e8d626918 100755 --- a/apps/common/templates/generic_list_subtemplate.html +++ b/apps/common/templates/generic_list_subtemplate.html @@ -54,10 +54,11 @@ {% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %} {% endif %} {% endif %} + {% if not hide_columns %} {% for column in object|get_model_list_columns %} {{ object|object_property:column.attribute|safe }} {% endfor %} - + {% endif %} {% for column in extra_columns %} {{ object|object_property:column.attribute|safe }} {% endfor %} diff --git a/apps/documents/admin.py b/apps/documents/admin.py index 3347d39e8d..ee067e2295 100755 --- a/apps/documents/admin.py +++ b/apps/documents/admin.py @@ -2,7 +2,8 @@ from django.contrib import admin from models import MetadataType, DocumentType, Document, \ DocumentTypeMetadataType, DocumentMetadata, DocumentTypeFilename, \ - MetadataIndex, DocumentMetadataIndex, DocumentPage + MetadataIndex, DocumentMetadataIndex, DocumentPage, MetadataGroup, \ + MetadataGroupItem class MetadataTypeAdmin(admin.ModelAdmin): @@ -59,12 +60,22 @@ class DocumentPageInline(admin.StackedInline): class DocumentAdmin(admin.ModelAdmin): inlines = [DocumentMetadataInline, DocumentMetadataIndexInline, DocumentPageInline] list_display = ('uuid', 'file_filename', 'file_extension') + + +class MetadataGroupItemInline(admin.StackedInline): + model = MetadataGroupItem + extra = 1 + classes = ('collapse-open',) + allow_add = True - - - +class MetadataGroupAdmin(admin.ModelAdmin): + inlines = [MetadataGroupItemInline] + filter_horizontal = ['document_type'] + + admin.site.register(MetadataType, MetadataTypeAdmin) admin.site.register(DocumentType, DocumentTypeAdmin) admin.site.register(Document, DocumentAdmin) +admin.site.register(MetadataGroup, MetadataGroupAdmin) diff --git a/apps/documents/models.py b/apps/documents/models.py index 8182eaaf64..9336ef5526 100755 --- a/apps/documents/models.py +++ b/apps/documents/models.py @@ -303,8 +303,8 @@ class DocumentTypeFilename(models.Model): class Meta: ordering = ['filename'] - verbose_name = _(u'document type filename') - verbose_name_plural = _(u'document types filenames') + verbose_name = _(u'document type quick rename filename') + verbose_name_plural = _(u'document types quick rename filenames') class DocumentPage(models.Model): @@ -321,4 +321,51 @@ class DocumentPage(models.Model): verbose_name_plural = _(u'document pages') +class MetadataGroup(models.Model): + document_type = models.ManyToManyField(DocumentType, null=True, blank=True, + verbose_name=_(u'document type'), help_text=_(u'If left blank, all document types will be matched.')) + name = models.CharField(max_length=32, verbose_name=_(u'name')) + label = models.CharField(max_length=32, verbose_name=_(u'label')) + + def __unicode__(self): + return self.label if self.label else self.name + + class Meta: + verbose_name = _(u'metadata document group') + verbose_name_plural = _(u'metadata document groups') + + + +INCLUSION_AND = '&' +INCLUSION_OR = '|' + +INCLUSION_CHOICES = ( + (INCLUSION_AND, _(u'and')), + (INCLUSION_OR, _(u'or')), +) + +OPERATOR_EQUAL = ' ' +OPERATOR_IS_NOT_EQUAL = '~' + +OPERATOR_CHOCIES = ( + (OPERATOR_EQUAL, _(u'is equal')), + (OPERATOR_IS_NOT_EQUAL, _(u'is not equal')), +) + +class MetadataGroupItem(models.Model): + metadata_group = models.ForeignKey(MetadataGroup, verbose_name=_(u'metadata group')) + inclusion = models.CharField(default=INCLUSION_AND, max_length=16, choices=INCLUSION_CHOICES) + metadata_type = models.ForeignKey(MetadataType, verbose_name=_(u'metadata type'), help_text=_(u'This represents the metadata of all other documents.')) + operator = models.CharField(max_length=16, choices=OPERATOR_CHOCIES) + expression = models.CharField(max_length=64, + verbose_name=_(u'expression'), help_text=_(u'This expression will be evaluated against the current seleted document. The document metadata is available as variables of the same name but with the "metadata_" prefix added their name.')) + + def __unicode__(self): + return '%s %s %s %s' % (self.get_inclusion_display(), self.metadata_type, self.get_operator_display(), self.expression) + + class Meta: + verbose_name = _(u'metadata group item') + verbose_name_plural = _(u'metadata group items') + + register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_filename', 'file_extension', 'documentmetadata__value', 'documentpage__content']) diff --git a/apps/documents/views.py b/apps/documents/views.py index 5f9af90ecf..a26a2bf1a8 100755 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -192,7 +192,12 @@ def upload_document_with_type(request, document_type_id, multiple=True): return render_to_response('generic_form.html', context, context_instance=RequestContext(request)) +from django.db.models import Q +from models import MetadataGroup + +from models import INCLUSION_AND, INCLUSION_OR, OPERATOR_EQUAL, OPERATOR_IS_NOT_EQUAL + def document_view(request, document_id): document = get_object_or_404(Document, pk=document_id) form = DocumentForm_view(instance=document, extra_fields=[ @@ -207,7 +212,44 @@ def document_view(request, document_id): {'label':_(u'Checksum'), 'field':'checksum'}, {'label':_(u'UUID'), 'field':'uuid'}, ]) - + + metadata_groups = {} + if MetadataGroup.objects.all().count(): + metadata_dict = {} + for document_metadata in document.documentmetadata_set.all(): + metadata_dict['metadata_%s' % document_metadata.metadata_type.name] = document_metadata.value + + for group in MetadataGroup.objects.filter(Q(document_type=document.document_type) | Q(document_type=None)): + total_query = None + for count, item in enumerate(group.metadatagroupitem_set.all()): + try: + expression_result = eval(item.expression, metadata_dict) + + if item.operator == OPERATOR_EQUAL: + value_query = Q(documentmetadata__value=expression_result) + elif item.operator == OPERATOR_IS_NOT_EQUAL: + value_query = ~Q(documentmetadata__value=expression_result) + + query = (Q(documentmetadata__metadata_type__id=item.metadata_type.id) & value_query) + if count == 0: + total_query = query + else: + if item.inclusion == INCLUSION_AND: + total_query &= query + elif item.inclusion == INCLUSION_AND: + total_query |= query + except Exception, e: + if request.user.is_staff: + messages.warning(request, _(u'Metadata group query error: %s' % e)) + else: + pass + + + if total_query: + print 'total_query',total_query + metadata_groups[group] = Document.objects.filter(total_query) + print 'documents',Document.objects.filter(total_query) + preview_form = DocumentPreviewForm(document=document) form_list = [ { @@ -239,11 +281,22 @@ def document_view(request, document_id): 'title':_(u'index links'), 'object_list':document.documentmetadataindex_set.all(), 'hide_link':True}) - + + sidebar_groups = [] + for group, data in metadata_groups.items(): + sidebar_groups.append({ + 'title':group.label, + 'name':'generic_list_subtemplate.html', + 'object_list':data, + 'hide_columns':True, + 'hide_header':True, + }) + 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))