Files
mayan-edms/apps/document_indexing/api.py
2012-02-02 09:22:40 -04:00

161 lines
6.4 KiB
Python

from __future__ import absolute_import
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from documents.models import Document
from metadata.classes import MetadataObject
from .models import (Index, IndexTemplateNode, IndexInstanceNode,
DocumentRenameCount)
from .conf.settings import (AVAILABLE_INDEXING_FUNCTIONS,
MAX_SUFFIX_COUNT, SLUGIFY_PATHS)
from .filesystem import (fs_create_index_directory,
fs_create_document_link, fs_delete_document_link,
fs_delete_index_directory, fs_delete_directory_recusive,
assemble_suffixed_filename)
from .widgets import get_instance_link
from .exceptions import MaxSuffixCountReached
if SLUGIFY_PATHS == False:
# Do not slugify path or filenames and extensions
SLUGIFY_FUNCTION = lambda x: x
else:
SLUGIFY_FUNCTION = slugify
# External functions
def update_indexes(document):
"""
Update or create all the index instances related to a document
"""
warnings = []
eval_dict = {}
document_metadata_dict = dict([(metadata.metadata_type.name, metadata.value) for metadata in document.documentmetadata_set.all() if metadata.value])
eval_dict['document'] = document
eval_dict['metadata'] = MetadataObject(document_metadata_dict)
for index in Index.objects.filter(enabled=True):
root_instance, created = IndexInstanceNode.objects.get_or_create(index_template_node=index.template_root, parent=None)
for template_node in index.template_root.get_children():
index_warnings = _evaluate_index(eval_dict, document, template_node, root_instance)
warnings.extend(index_warnings)
return warnings
def delete_indexes(document):
"""
Delete all the index instances related to a document
"""
warnings = []
for index_instance in document.indexinstancenode_set.all():
index_warnings = _remove_document_from_index_instance(document, index_instance)
warnings.extend(index_warnings)
return warnings
def do_rebuild_all_indexes():
fs_delete_directory_recusive()
IndexInstanceNone.objects.delete()
DocumentRenameCount.objects.delete()
for document in Document.objects.all():
update_indexes(document)
return [] # Warnings - None
# Internal functions
def find_lowest_available_suffix(index_instance, document):
# TODO: verify extension's role in query
index_instance_documents = DocumentRenameCount.objects.filter(index_instance_node=index_instance)#.filter(document__file_extension=document.file_extension)
files_list = []
for index_instance_document in index_instance_documents:
files_list.append(assemble_suffixed_filename(index_instance_document.document.file_filename, index_instance_document.suffix))
for suffix in xrange(MAX_SUFFIX_COUNT):
if assemble_suffixed_filename(document.file_filename, suffix) not in files_list:
return suffix
raise MaxSuffixCountReached(ugettext(u'Maximum suffix (%s) count reached.') % MAX_SUFFIX_COUNT)
def _evaluate_index(eval_dict, document, template_node, parent_index_instance=None):
"""
Evaluate an enabled index expression and update or create all the
related index instances also recursively calling itself to evaluate
all the index's children
"""
warnings = []
if template_node.enabled:
try:
result = eval(template_node.expression, eval_dict, AVAILABLE_INDEXING_FUNCTIONS)
if result:
index_instance, created = IndexInstanceNode.objects.get_or_create(index_template_node=template_node)
index_instance.value = result
index_instance.parent = parent_index_instance
index_instance.save()
#if created:
#fs_create_index_directory(index_instance)
if template_node.link_documents:
suffix = find_lowest_available_suffix(index_instance, document)
document_count = DocumentRenameCount(
index_instance_node=index_instance,
document=document,
suffix=suffix
)
document_count.save()
#fs_create_document_link(index_instance, document, suffix)
index_instance.documents.add(document)
for child in template_node.get_children():
children_warnings = _evaluate_index(
eval_dict, document, child, index_instance
)
warnings.extend(children_warnings)
except (NameError, AttributeError), exc:
warnings.append(_(u'Error in document indexing update expression: %(expression)s; %(exception)s') % {
'expression': template_node.expression, 'exception': exc})
except Exception, exc:
warnings.append(_(u'Error updating document index, expression: %(expression)s; %(exception)s') % {
'expression': template_node.expression, 'exception': exc})
return warnings
def _remove_document_from_index_instance(document, index_instance):
"""
Delete a documents reference from an index instance and call itself
recusively deleting documents and empty index instances up to the
root of the tree
"""
warnings = []
try:
document_rename_count = DocumentRenameCount.objects.get(index_instance_node=index_instance, document=document)
#fs_delete_document_link(index_instance, document, document_rename_count.suffix)
document_rename_count.delete()
index_instance.documents.remove(document)
if index_instance.documents.count() == 0 and index_instance.get_children().count() == 0:
# if there are no more documents and no children, delete
# node and check parent for the same conditions
parent = index_instance.parent
#fs_delete_index_directory(index_instance)
index_instance.delete()
parent_warnings = _remove_document_from_index_instance(
document, parent
)
warnings.extend(parent_warnings)
except DocumentRenameCount.DoesNotExist:
return warnings
except Exception, exc:
warnings.append(_(u'Unable to delete document indexing node; %s') % exc)
return warnings