Initial commit of the new MPTT based document indexing app

This commit is contained in:
Roberto Rosario
2011-05-17 04:27:43 -04:00
parent 1bd75a1d24
commit e83529ae2e
11 changed files with 121 additions and 66 deletions

View File

@@ -0,0 +1 @@

View File

@@ -1,23 +1,25 @@
from django.contrib import admin from django.contrib import admin
from document_indexing.models import DocumentIndex from mptt.admin import MPTTModelAdmin
#from filesystem_serving.admin import DocumentMetadataIndexInline from document_indexing.models import Index, IndexInstance
#class MetadataIndexInline(admin.StackedInline): class IndexInstanceInline(admin.StackedInline):
# model = MetadataIndex model = IndexInstance
# extra = 1 extra = 1
# classes = ('collapse-open',) classes = ('collapse-open',)
# allow_add = True allow_add = True
class DocumentIndexAdmin(admin.ModelAdmin): class IndexAdmin(MPTTModelAdmin):
pass list_display = ('expression', 'enabled', 'link_document')
#inlines = [
# DocumentMetadataIndexInline,
#
class IndexInstanceAdmin(MPTTModelAdmin):
model = IndexInstance
list_display = ('value', 'index', 'get_document_list_display')
admin.site.register(DocumentIndex, DocumentIndexAdmin)
admin.site.register(Index, IndexAdmin)
admin.site.register(IndexInstance, IndexInstanceAdmin)

View File

@@ -0,0 +1,53 @@
from django.utils.translation import ugettext_lazy as _
from metadata.classes import MetadataObject
#from filesystem_serving.conf.settings import MAX_RENAME_COUNT
from document_indexing.models import Index, IndexInstance
from document_indexing.conf.settings import AVAILABLE_INDEXING_FUNCTIONS
def evaluate_index(eval_dict, document, node, parent_index_instance=None):
warnings = []
if node.enabled:
try:
result = eval(node.expression, eval_dict, AVAILABLE_INDEXING_FUNCTIONS)
index_instance, created = IndexInstance.objects.get_or_create(index=node, value=result, parent=parent_index_instance)
if node.link_document:
index_instance.documents.add(document)
for children in node.get_children():
children_warnings = evaluate_index(eval_dict, document, children, index_instance)
warnings.extend(children_warnings)
except NameError, exc:
warnings.append(_(u'Error in metadata indexing expression: %s') % exc)
#raise NameError()
#This should be a warning not an error
#pass
except Exception, exc:
warnings.append(_(u'Unable to create metadata indexing directory: %s') % exc)
return warnings
def update_indexes(document):
print 'update_indexes'
warnings = []
eval_dict = {}
eval_dict['document'] = document
metadata_dict = dict([(metadata.metadata_type.name, metadata.value) for metadata in document.documentmetadata_set.all() if metadata.value])
eval_dict['metadata'] = MetadataObject(metadata_dict)
for root in Index.objects.filter(parent=None):
#for node in root.get_children():
index_warnings = evaluate_index(eval_dict, document, root)
warnings.extend(index_warnings)
return warnings
def delete_indexes(document):
print 'delete_indexes'

View File

@@ -1,20 +1,48 @@
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey
from documents.models import Document
from document_indexing.conf.settings import AVAILABLE_INDEXING_FUNCTIONS from document_indexing.conf.settings import AVAILABLE_INDEXING_FUNCTIONS
available_indexing_functions_string = (_(u'Available functions: %s') % u','.join([u'%s()' % name for name, function in AVAILABLE_INDEXING_FUNCTIONS.items()])) if AVAILABLE_INDEXING_FUNCTIONS else u'' available_indexing_functions_string = (_(u'Available functions: %s') % u','.join([u'%s()' % name for name, function in AVAILABLE_INDEXING_FUNCTIONS.items()])) if AVAILABLE_INDEXING_FUNCTIONS else u''
class DocumentIndex(models.Model): class Index(MPTTModel):
expression = models.CharField(max_length=128, parent = TreeForeignKey('self', null=True, blank=True, related_name='index_meta_class')
verbose_name=_(u'indexing expression'), expression = models.CharField(max_length=128, verbose_name=_(u'indexing expression'), help_text=_(u'Enter a python string expression to be evaluated.'))
help_text=_(u'Enter a python string expression to be evaluated. The slash caracter "/" acts as a directory delimiter.%s') % available_indexing_functions_string) # % available_indexing_functions_string)
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled')) enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'))
link_document = models.BooleanField(default=False, verbose_name=_(u'link document'))
def __unicode__(self): def __unicode__(self):
return unicode(self.expression) return self.expression if not self.link_document else u'%s/[document]' % self.expression
class Meta: class Meta:
verbose_name = _(u'metadata index') verbose_name = _(u'index')
verbose_name_plural = _(u'metadata indexes') verbose_name_plural = _(u'indexes')
class IndexInstance(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='index_meta_instance')
index = models.ForeignKey(Index, verbose_name=_(u'index'))
value = models.CharField(max_length=128, blank=True, verbose_name=_(u'value'))
documents = models.ManyToManyField(Document, verbose_name=_(u'documents'))
def __unicode__(self):
return self.value
def get_document_list_display(self):
return u', '.join([d.file_filename for d in self.documents.all()])
class Meta:
verbose_name = _(u'index instance')
verbose_name_plural = _(u'indexes instances')
# TODO
# class DocumentRenameCount
# FK=IndexInstance

View File

@@ -6,8 +6,6 @@ from documents.models import DocumentType, Document, \
DocumentTypeFilename, DocumentPage, \ DocumentTypeFilename, DocumentPage, \
DocumentPageTransformation, RecentDocument DocumentPageTransformation, RecentDocument
from filesystem_serving.admin import DocumentMetadataIndexInline
class DocumentTypeFilenameInline(admin.StackedInline): class DocumentTypeFilenameInline(admin.StackedInline):
model = DocumentTypeFilename model = DocumentTypeFilename
@@ -35,8 +33,7 @@ class DocumentPageInline(admin.StackedInline):
class DocumentAdmin(admin.ModelAdmin): class DocumentAdmin(admin.ModelAdmin):
inlines = [ inlines = [
DocumentMetadataInline, DocumentMetadataIndexInline, DocumentMetadataInline, DocumentPageInline
DocumentPageInline
] ]
list_display = ('uuid', 'file_filename', 'file_extension') list_display = ('uuid', 'file_filename', 'file_extension')

View File

@@ -5,7 +5,6 @@ import uuid
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import proper_name
from storage.backends.filebasedstorage import FileBasedStorage from storage.backends.filebasedstorage import FileBasedStorage
from smart_settings.api import register_settings from smart_settings.api import register_settings
@@ -23,16 +22,10 @@ available_transformations = {
'rotate': {'label': _(u'Rotate [degrees]'), 'arguments': [{'name': 'degrees'}]} 'rotate': {'label': _(u'Rotate [degrees]'), 'arguments': [{'name': 'degrees'}]}
} }
available_indexing_functions = {
'proper_name': proper_name
}
register_settings( register_settings(
namespace=u'documents', namespace=u'documents',
module=u'documents.conf.settings', module=u'documents.conf.settings',
settings=[ settings=[
# Definition
{'name': u'AVAILABLE_INDEXING_FUNCTIONS', 'global_name': u'DOCUMENTS_INDEXING_AVAILABLE_FUNCTIONS', 'default': available_indexing_functions},
# Upload # Upload
{'name': u'USE_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_USE_STAGING_DIRECTORY', 'default': False}, {'name': u'USE_STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_USE_STAGING_DIRECTORY', 'default': False},
{'name': u'STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_STAGING_DIRECTORY', 'default': u'/tmp/mayan/staging', 'exists': True}, {'name': u'STAGING_DIRECTORY', 'global_name': u'DOCUMENTS_STAGING_DIRECTORY', 'default': u'/tmp/mayan/staging', 'exists': True},

View File

@@ -1,11 +1 @@
from django.contrib import admin
from filesystem_serving.models import DocumentMetadataIndex
class DocumentMetadataIndexInline(admin.StackedInline):
model = DocumentMetadataIndex
extra = 1
classes = ('collapse-open',)
allow_add = True
readonly_fields = ('suffix', 'metadata_index', 'filename')

View File

@@ -4,7 +4,8 @@ import os
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from documents.conf.settings import AVAILABLE_INDEXING_FUNCTIONS from document_indexing.models import IndexInstance
from metadata.classes import MetadataObject from metadata.classes import MetadataObject
from filesystem_serving.conf.settings import FILESERVING_ENABLE from filesystem_serving.conf.settings import FILESERVING_ENABLE
@@ -12,7 +13,7 @@ from filesystem_serving.conf.settings import FILESERVING_PATH
from filesystem_serving.conf.settings import SLUGIFY_PATHS from filesystem_serving.conf.settings import SLUGIFY_PATHS
from filesystem_serving.conf.settings import MAX_RENAME_COUNT from filesystem_serving.conf.settings import MAX_RENAME_COUNT
from filesystem_serving.models import DocumentMetadataIndex, Document #from filesystem_serving.models import DocumentMetadataIndex, Document
if SLUGIFY_PATHS == False: if SLUGIFY_PATHS == False:
#Do not slugify path or filenames and extensions #Do not slugify path or filenames and extensions
@@ -24,6 +25,8 @@ else:
def document_create_fs_links(document): def document_create_fs_links(document):
warnings = [] warnings = []
if FILESERVING_ENABLE: if FILESERVING_ENABLE:
pass
'''
if not document.exists(): if not document.exists():
raise Exception(_(u'Not creating metadata indexing, document not found in document storage')) raise Exception(_(u'Not creating metadata indexing, document not found in document storage'))
eval_dict = {} eval_dict = {}
@@ -52,12 +55,14 @@ def document_create_fs_links(document):
#pass #pass
except Exception, exc: except Exception, exc:
warnings.append(_(u'Unable to create metadata indexing directory: %s') % exc) warnings.append(_(u'Unable to create metadata indexing directory: %s') % exc)
'''
return warnings return warnings
def document_delete_fs_links(document): def document_delete_fs_links(document):
if FILESERVING_ENABLE: if FILESERVING_ENABLE:
pass
'''
for document_metadata_index in document.documentmetadataindex_set.all(): for document_metadata_index in document.documentmetadataindex_set.all():
try: try:
os.unlink(document_metadata_index.filename) os.unlink(document_metadata_index.filename)
@@ -99,6 +104,7 @@ def document_delete_fs_links(document):
os.removedirs(path) os.removedirs(path)
except: except:
pass pass
'''
def next_available_filename(document, metadata_index, path, filename, extension, suffix=0): def next_available_filename(document, metadata_index, path, filename, extension, suffix=0):

View File

@@ -1,19 +1 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from documents.models import Document
from document_indexing.models import DocumentIndex
class DocumentMetadataIndex(models.Model):
document = models.ForeignKey(Document, verbose_name=_(u'document'))
metadata_index = models.ForeignKey(DocumentIndex, verbose_name=_(u'document index'))
filename = models.CharField(max_length=255, verbose_name=_(u'filename'))
suffix = models.PositiveIntegerField(default=0, verbose_name=_(u'suffix'))
def __unicode__(self):
return unicode(self.filename)
class Meta:
verbose_name = _(u'document metadata index')
verbose_name_plural = _(u'document metadata indexes')

View File

@@ -10,6 +10,7 @@ from django.utils.http import urlencode
from documents.models import Document, RecentDocument from documents.models import Document, RecentDocument
from permissions.api import check_permissions from permissions.api import check_permissions
from filesystem_serving.api import document_create_fs_links, document_delete_fs_links from filesystem_serving.api import document_create_fs_links, document_delete_fs_links
from document_indexing.api import update_indexes, delete_indexes
from metadata import PERMISSION_METADATA_DOCUMENT_EDIT, \ from metadata import PERMISSION_METADATA_DOCUMENT_EDIT, \
PERMISSION_METADATA_DOCUMENT_ADD, PERMISSION_METADATA_DOCUMENT_REMOVE PERMISSION_METADATA_DOCUMENT_ADD, PERMISSION_METADATA_DOCUMENT_REMOVE
@@ -56,6 +57,7 @@ def metadata_edit(request, document_id=None, document_id_list=None):
formset = MetadataFormSet(request.POST) formset = MetadataFormSet(request.POST)
if formset.is_valid(): if formset.is_valid():
for document in documents: for document in documents:
delete_indexes(document)
try: try:
document_delete_fs_links(document) document_delete_fs_links(document)
except Exception, e: except Exception, e:
@@ -70,7 +72,7 @@ def metadata_edit(request, document_id=None, document_id_list=None):
except Exception, e: except Exception, e:
messages.error(request, _(u'Error editing metadata for document %(document)s; %(error)s.') % { messages.error(request, _(u'Error editing metadata for document %(document)s; %(error)s.') % {
'document': document, 'error': e}) 'document': document, 'error': e})
update_indexes(document)
try: try:
warnings = document_create_fs_links(document) warnings = document_create_fs_links(document)

View File

@@ -148,6 +148,7 @@ INSTALLED_APPS = (
'documents', 'documents',
'grouping', 'grouping',
'document_indexing', 'document_indexing',
'mptt',
) )
TEMPLATE_CONTEXT_PROCESSORS = ( TEMPLATE_CONTEXT_PROCESSORS = (