Merge branch 'feature/indexing_refactor' into development
This commit is contained in:
@@ -8,17 +8,43 @@ from navigation.api import register_top_menu, register_sidebar_template, \
|
||||
from main.api import register_maintenance_links
|
||||
from documents.permissions import PERMISSION_DOCUMENT_VIEW
|
||||
from documents.models import Document
|
||||
from project_setup.api import register_setup
|
||||
|
||||
from .models import IndexInstance
|
||||
from .models import (Index, IndexTemplateNode, IndexInstanceNode)
|
||||
from .permissions import (PERMISSION_DOCUMENT_INDEXING_VIEW,
|
||||
PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES)
|
||||
PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES,
|
||||
PERMISSION_DOCUMENT_INDEXING_SETUP,
|
||||
PERMISSION_DOCUMENT_INDEXING_CREATE,
|
||||
PERMISSION_DOCUMENT_INDEXING_EDIT,
|
||||
PERMISSION_DOCUMENT_INDEXING_DELETE
|
||||
)
|
||||
|
||||
|
||||
index_list = {'text': _(u'index list'), 'view': 'index_instance_list', 'famfam': 'folder_page', 'permissions': [PERMISSION_DOCUMENT_INDEXING_VIEW]}
|
||||
index_parent = {'text': _(u'go up one level'), 'view': 'index_instance_list', 'args': 'object.parent.pk', 'famfam': 'arrow_up', 'permissions': [PERMISSION_DOCUMENT_INDEXING_VIEW], 'dont_mark_active': True}
|
||||
def is_root_node(context):
|
||||
return context['node'].parent is None
|
||||
|
||||
|
||||
def is_not_instance_root_node(context):
|
||||
return context['object'].parent is not None
|
||||
|
||||
|
||||
index_setup = {'text': _(u'indexes'), 'view': 'index_setup_list', 'icon': 'tab.png', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP]}
|
||||
index_setup_list = {'text': _(u'index list'), 'view': 'index_setup_list', 'famfam': 'tab', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP]}
|
||||
index_setup_create = {'text': _(u'create index'), 'view': 'index_setup_create', 'famfam': 'tab_add', 'permissions': [PERMISSION_DOCUMENT_INDEXING_CREATE]}
|
||||
index_setup_edit = {'text': _(u'edit'), 'view': 'index_setup_edit', 'args': 'index.pk', 'famfam': 'tab_edit', 'permissions': [PERMISSION_DOCUMENT_INDEXING_EDIT]}
|
||||
index_setup_delete = {'text': _(u'delete'), 'view': 'index_setup_delete', 'args': 'index.pk', 'famfam': 'tab_delete', 'permissions': [PERMISSION_DOCUMENT_INDEXING_DELETE]}
|
||||
index_setup_view = {'text': _(u'tree template'), 'view': 'index_setup_view', 'args': 'index.pk', 'famfam': 'textfield', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP]}
|
||||
|
||||
template_node_create = {'text': _(u'new child node'), 'view': 'template_node_create', 'args': 'node.pk', 'famfam': 'textfield_add', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP]}
|
||||
template_node_edit = {'text': _(u'edit'), 'view': 'template_node_edit', 'args': 'node.pk', 'famfam': 'textfield', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP], 'conditional_disable': is_root_node}
|
||||
template_node_delete = {'text': _(u'delete'), 'view': 'template_node_delete', 'args': 'node.pk', 'famfam': 'textfield_delete', 'permissions': [PERMISSION_DOCUMENT_INDEXING_SETUP], 'conditional_disable': is_root_node}
|
||||
|
||||
index_list = {'text': _(u'index list'), 'view': 'index_list', 'famfam': 'folder_page', 'permissions': [PERMISSION_DOCUMENT_INDEXING_VIEW]}
|
||||
|
||||
index_parent = {'text': _(u'go up one level'), 'view': 'index_instance_node_view', 'args': 'object.parent.pk', 'famfam': 'arrow_up', 'permissions': [PERMISSION_DOCUMENT_INDEXING_VIEW], 'dont_mark_active': True, 'condition': is_not_instance_root_node}
|
||||
document_index_list = {'text': _(u'indexes'), 'view': 'document_index_list', 'args': 'object.pk', 'famfam': 'folder_page', 'permissions': [PERMISSION_DOCUMENT_INDEXING_VIEW, PERMISSION_DOCUMENT_VIEW]}
|
||||
|
||||
register_top_menu('indexes', link={'text': _('indexes'), 'famfam': 'folder_page', 'view': 'index_instance_list'})
|
||||
register_top_menu('indexes', link={'text': _('indexes'), 'famfam': 'folder_page', 'view': 'index_list'})
|
||||
|
||||
rebuild_index_instances = {'text': _('rebuild indexes'), 'view': 'rebuild_index_instances', 'famfam': 'folder_page', 'permissions': [PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES], 'description': _(u'Deletes and creates from scratch all the document indexes.')}
|
||||
|
||||
@@ -26,6 +52,14 @@ register_maintenance_links([rebuild_index_instances], namespace='document_indexi
|
||||
|
||||
register_sidebar_template(['index_instance_list'], 'indexing_help.html')
|
||||
|
||||
register_links(IndexInstance, [index_parent])
|
||||
register_links(IndexInstanceNode, [index_parent])
|
||||
|
||||
register_links(Document, [document_index_list], menu_name='form_header')
|
||||
|
||||
register_setup(index_setup)
|
||||
|
||||
register_links([Index, 'index_setup_list', 'index_setup_create', 'template_node_edit', 'template_node_delete'], [index_setup_list, index_setup_create], menu_name='secondary_menu')
|
||||
|
||||
register_links(Index, [index_setup_edit, index_setup_delete, index_setup_view])
|
||||
|
||||
register_links(IndexTemplateNode, [template_node_create, template_node_edit, template_node_delete])
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from mptt.admin import MPTTModelAdmin
|
||||
|
||||
from document_indexing.models import Index, IndexInstance, \
|
||||
DocumentRenameCount
|
||||
from .models import (Index, IndexTemplateNode, IndexInstanceNode,
|
||||
DocumentRenameCount)
|
||||
|
||||
|
||||
class IndexInstanceInline(admin.StackedInline):
|
||||
model = IndexInstance
|
||||
extra = 1
|
||||
classes = ('collapse-open',)
|
||||
allow_add = True
|
||||
|
||||
|
||||
class IndexAdmin(MPTTModelAdmin):
|
||||
class IndexTemplateNodeAdmin(MPTTModelAdmin):
|
||||
list_display = ('expression', 'enabled', 'link_documents')
|
||||
|
||||
|
||||
class IndexInstanceAdmin(MPTTModelAdmin):
|
||||
model = IndexInstance
|
||||
list_display = ('value', 'index', 'get_document_list_display')
|
||||
class IndexInstanceNodeAdmin(MPTTModelAdmin):
|
||||
model = IndexInstanceNode
|
||||
list_display = ('value',)
|
||||
|
||||
|
||||
admin.site.register(Index, IndexAdmin)
|
||||
admin.site.register(IndexInstance, IndexInstanceAdmin)
|
||||
admin.site.register(Index)
|
||||
admin.site.register(IndexTemplateNode, IndexTemplateNodeAdmin)
|
||||
admin.site.register(IndexInstanceNode, IndexInstanceNodeAdmin)
|
||||
admin.site.register(DocumentRenameCount)
|
||||
|
||||
@@ -3,19 +3,18 @@ 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.utils.safestring import mark_safe
|
||||
from django.template.defaultfilters import slugify
|
||||
|
||||
from documents.models import Document
|
||||
from metadata.classes import MetadataObject
|
||||
from metadata.classes import MetadataClass
|
||||
|
||||
from .models import (Index, IndexInstance, DocumentRenameCount)
|
||||
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)
|
||||
from .os_specifics import assemble_suffixed_filename
|
||||
fs_delete_index_directory, assemble_suffixed_filename)
|
||||
from .exceptions import MaxSuffixCountReached
|
||||
|
||||
if SLUGIFY_PATHS == False:
|
||||
# Do not slugify path or filenames and extensions
|
||||
@@ -24,10 +23,6 @@ else:
|
||||
SLUGIFY_FUNCTION = slugify
|
||||
|
||||
|
||||
class MaxSuffixCountReached(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# External functions
|
||||
def update_indexes(document):
|
||||
"""
|
||||
@@ -38,11 +33,13 @@ def update_indexes(document):
|
||||
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)
|
||||
eval_dict['metadata'] = MetadataClass(document_metadata_dict)
|
||||
|
||||
for root in Index.objects.filter(parent=None):
|
||||
index_warnings = _evaluate_index(eval_dict, document, root)
|
||||
warnings.extend(index_warnings)
|
||||
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 = cascade_eval(eval_dict, document, template_node, root_instance)
|
||||
warnings.extend(index_warnings)
|
||||
|
||||
return warnings
|
||||
|
||||
@@ -53,136 +50,80 @@ def delete_indexes(document):
|
||||
"""
|
||||
warnings = []
|
||||
|
||||
for index_instance in document.indexinstance_set.all():
|
||||
index_warnings = _remove_document_from_index_instance(document, index_instance)
|
||||
for index_instance in document.indexinstancenode_set.all():
|
||||
index_warnings = cascade_document_remove(document, index_instance)
|
||||
warnings.extend(index_warnings)
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
def get_instance_link(index_instance=None, text=None, simple=False):
|
||||
"""
|
||||
Return an HTML anchor to an index instance
|
||||
"""
|
||||
|
||||
if simple:
|
||||
# Just display the instance's value or overrided text, no
|
||||
# HTML anchor
|
||||
template = u'%(value)s'
|
||||
else:
|
||||
template = u'<a href="%(url)s">%(value)s</a>'
|
||||
if index_instance:
|
||||
return template % {
|
||||
'url': index_instance.get_absolute_url(),
|
||||
'value': text if text else index_instance
|
||||
}
|
||||
else:
|
||||
# Root node
|
||||
return template % {
|
||||
'url': reverse('index_instance_list'),
|
||||
'value': ugettext(u'root')
|
||||
}
|
||||
|
||||
|
||||
def get_breadcrumbs(index_instance, simple=False, single_link=False, include_count=False):
|
||||
"""
|
||||
Return a joined string of HTML anchors to every index instance's
|
||||
parent from the root of the tree to the index instance
|
||||
"""
|
||||
result = []
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
simple = True
|
||||
|
||||
result.append(get_instance_link(simple=simple))
|
||||
|
||||
for instance in index_instance.get_ancestors():
|
||||
result.append(get_instance_link(instance, simple=simple))
|
||||
|
||||
result.append(get_instance_link(index_instance, simple=simple))
|
||||
|
||||
output = []
|
||||
|
||||
if include_count:
|
||||
output.append(u'(%d)' % index_instance.documents.count())
|
||||
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
output.insert(0, get_instance_link(index_instance=index_instance, text=(u' / '.join(result))))
|
||||
return mark_safe(u' '.join(output))
|
||||
else:
|
||||
output.insert(0, u' / '.join(result))
|
||||
return mark_safe(u' '.join(output))
|
||||
|
||||
|
||||
def do_rebuild_all_indexes():
|
||||
fs_delete_directory_recusive()
|
||||
IndexInstance.objects.all().delete()
|
||||
DocumentRenameCount.objects.all().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=index_instance)#.filter(document__file_extension=document.file_extension)
|
||||
index_instance_documents = DocumentRenameCount.objects.filter(index_instance_node=index_instance)
|
||||
files_list = []
|
||||
for index_instance_document in index_instance_documents:
|
||||
files_list.append(assemble_suffixed_filename(index_instance_document.document.file.name, index_instance_document.suffix))
|
||||
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.name, suffix) not in files_list:
|
||||
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, node, parent_index_instance=None):
|
||||
def cascade_eval(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 node.enabled:
|
||||
if template_node.enabled:
|
||||
try:
|
||||
result = eval(node.expression, eval_dict, AVAILABLE_INDEXING_FUNCTIONS)
|
||||
result = eval(template_node.expression, eval_dict, AVAILABLE_INDEXING_FUNCTIONS)
|
||||
except (NameError, AttributeError), exc:
|
||||
warnings.append(_(u'Error in document indexing update expression: %(expression)s; %(exception)s') % {
|
||||
'expression': template_node.expression, 'exception': exc})
|
||||
else:
|
||||
if result:
|
||||
index_instance, created = IndexInstance.objects.get_or_create(index=node, value=result, parent=parent_index_instance)
|
||||
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 node.link_documents:
|
||||
try:
|
||||
fs_create_index_directory(index_instance)
|
||||
except Exception, exc:
|
||||
warnings.append(_(u'Error updating document index, expression: %(expression)s; %(exception)s') % {
|
||||
'expression': template_node.expression, 'exception': exc})
|
||||
|
||||
if template_node.link_documents:
|
||||
suffix = find_lowest_available_suffix(index_instance, document)
|
||||
document_count = DocumentRenameCount(
|
||||
index_instance=index_instance,
|
||||
index_instance_node=index_instance,
|
||||
document=document,
|
||||
suffix=suffix
|
||||
)
|
||||
document_count.save()
|
||||
|
||||
fs_create_document_link(index_instance, document, suffix)
|
||||
try:
|
||||
fs_create_document_link(index_instance, document, suffix)
|
||||
except Exception, exc:
|
||||
warnings.append(_(u'Error updating document index, expression: %(expression)s; %(exception)s') % {
|
||||
'expression': template_node.expression, 'exception': exc})
|
||||
|
||||
index_instance.documents.add(document)
|
||||
|
||||
for children in node.get_children():
|
||||
children_warnings = _evaluate_index(
|
||||
eval_dict, document, children, index_instance
|
||||
for child in template_node.get_children():
|
||||
children_warnings = cascade_eval(
|
||||
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': node.expression, 'exception': exc})
|
||||
except Exception, exc:
|
||||
warnings.append(_(u'Error updating document index, expression: %(expression)s; %(exception)s') % {
|
||||
'expression': node.expression, 'exception': exc})
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
def _remove_document_from_index_instance(document, index_instance):
|
||||
def cascade_document_remove(document, index_instance):
|
||||
"""
|
||||
Delete a documents reference from an index instance and call itself
|
||||
recusively deleting documents and empty index instances up to the
|
||||
@@ -190,7 +131,7 @@ def _remove_document_from_index_instance(document, index_instance):
|
||||
"""
|
||||
warnings = []
|
||||
try:
|
||||
document_rename_count = DocumentRenameCount.objects.get(index_instance=index_instance, document=document)
|
||||
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)
|
||||
@@ -200,7 +141,7 @@ def _remove_document_from_index_instance(document, index_instance):
|
||||
parent = index_instance.parent
|
||||
fs_delete_index_directory(index_instance)
|
||||
index_instance.delete()
|
||||
parent_warnings = _remove_document_from_index_instance(
|
||||
parent_warnings = cascade_document_remove(
|
||||
document, parent
|
||||
)
|
||||
warnings.extend(parent_warnings)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Configuration options for the document_indexing app"""
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common.utils import proper_name
|
||||
from smart_settings.api import register_settings
|
||||
|
||||
@@ -17,7 +19,6 @@ register_settings(
|
||||
# Filesystem serving
|
||||
{'name': u'SLUGIFY_PATHS', 'global_name': u'DOCUMENT_INDEXING_FILESYSTEM_SLUGIFY_PATHS', 'default': False},
|
||||
{'name': u'MAX_SUFFIX_COUNT', 'global_name': u'DOCUMENT_INDEXING_FILESYSTEM_MAX_SUFFIX_COUNT', 'default': 1000},
|
||||
{'name': u'FILESERVING_PATH', 'global_name': u'DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_PATH', 'default': u'/tmp/mayan/documents', 'exists': True},
|
||||
{'name': u'FILESERVING_ENABLE', 'global_name': u'DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_ENABLE', 'default': True}
|
||||
{'name': u'FILESYSTEM_SERVING', 'global_name': u'DOCUMENT_INDEXING_FILESYSTEM_SERVING', 'default': {}, 'description': _(u'A dictionary that maps the index name and where on the filesystem that index will be mirrored.')}
|
||||
]
|
||||
)
|
||||
|
||||
6
apps/document_indexing/exceptions.py
Normal file
6
apps/document_indexing/exceptions.py
Normal file
@@ -0,0 +1,6 @@
|
||||
class MaxSuffixCountReached(Exception):
|
||||
"""
|
||||
Raised when there are too many documents with the same filename in the
|
||||
same node/directory
|
||||
"""
|
||||
pass
|
||||
@@ -5,9 +5,24 @@ import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .os_specifics import (assemble_suffixed_filename,
|
||||
assemble_path_from_list)
|
||||
from .conf.settings import (FILESERVING_ENABLE, FILESERVING_PATH)
|
||||
from .conf.settings import (FILESYSTEM_SERVING, SUFFIX_SEPARATOR)
|
||||
|
||||
|
||||
def assemble_suffixed_filename(filename, suffix=0):
|
||||
"""
|
||||
Split document filename, to attach suffix to the name part then
|
||||
re attacht the extension
|
||||
"""
|
||||
|
||||
if suffix:
|
||||
name, extension = os.path.splitext(filename)
|
||||
return SUFFIX_SEPARATOR.join([name, unicode(suffix), os.extsep, extension])
|
||||
else:
|
||||
return filename
|
||||
|
||||
|
||||
def assemble_path_from_list(directory_list):
|
||||
return os.sep.join(directory_list)
|
||||
|
||||
|
||||
def get_instance_path(index_instance):
|
||||
@@ -25,8 +40,8 @@ def get_instance_path(index_instance):
|
||||
|
||||
|
||||
def fs_create_index_directory(index_instance):
|
||||
if FILESERVING_ENABLE:
|
||||
target_directory = assemble_path_from_list([FILESERVING_PATH, get_instance_path(index_instance)])
|
||||
if index_instance.index_template_node.index.name in FILESYSTEM_SERVING:
|
||||
target_directory = assemble_path_from_list([FILESYSTEM_SERVING[index_instance.index_template_node.index.name], get_instance_path(index_instance)])
|
||||
try:
|
||||
os.mkdir(target_directory)
|
||||
except OSError, exc:
|
||||
@@ -37,9 +52,9 @@ def fs_create_index_directory(index_instance):
|
||||
|
||||
|
||||
def fs_create_document_link(index_instance, document, suffix=0):
|
||||
if FILESERVING_ENABLE:
|
||||
filename = assemble_suffixed_filename(document.file.name, suffix)
|
||||
filepath = assemble_path_from_list([FILESERVING_PATH, get_instance_path(index_instance), filename])
|
||||
if index_instance.index_template_node.index.name in FILESYSTEM_SERVING:
|
||||
filename = assemble_suffixed_filename(document.file_filename, suffix)
|
||||
filepath = assemble_path_from_list([FILESYSTEM_SERVING[index_instance.index_template_node.index.name], get_instance_path(index_instance), filename])
|
||||
|
||||
try:
|
||||
os.symlink(document.file.path, filepath)
|
||||
@@ -57,9 +72,9 @@ def fs_create_document_link(index_instance, document, suffix=0):
|
||||
|
||||
|
||||
def fs_delete_document_link(index_instance, document, suffix=0):
|
||||
if FILESERVING_ENABLE:
|
||||
filename = assemble_suffixed_filename(document.file.name, suffix)
|
||||
filepath = assemble_path_from_list([FILESERVING_PATH, get_instance_path(index_instance), filename])
|
||||
if index_instance.index_template_node.index.name in FILESYSTEM_SERVING:
|
||||
filename = assemble_suffixed_filename(document.file_filename, suffix)
|
||||
filepath = assemble_path_from_list([FILESYSTEM_SERVING[index_instance.index_template_node.index.name], get_instance_path(index_instance), filename])
|
||||
|
||||
try:
|
||||
os.unlink(filepath)
|
||||
@@ -70,8 +85,8 @@ def fs_delete_document_link(index_instance, document, suffix=0):
|
||||
|
||||
|
||||
def fs_delete_index_directory(index_instance):
|
||||
if FILESERVING_ENABLE:
|
||||
target_directory = assemble_path_from_list([FILESERVING_PATH, get_instance_path(index_instance)])
|
||||
if index_instance.index_template_node.index.name in FILESYSTEM_SERVING:
|
||||
target_directory = assemble_path_from_list([FILESYSTEM_SERVING[index_instance.index_template_node.index.name], get_instance_path(index_instance)])
|
||||
try:
|
||||
os.removedirs(target_directory)
|
||||
except OSError, exc:
|
||||
@@ -81,8 +96,9 @@ def fs_delete_index_directory(index_instance):
|
||||
raise Exception(_(u'Unable to delete indexing directory; %s') % exc)
|
||||
|
||||
|
||||
def fs_delete_directory_recusive(path=FILESERVING_PATH):
|
||||
if FILESERVING_ENABLE:
|
||||
def fs_delete_directory_recusive(index):
|
||||
if index.name in FILESYSTEM_SERVING:
|
||||
path = FILESYSTEM_SERVING[index.name]
|
||||
for dirpath, dirnames, filenames in os.walk(path, topdown=False):
|
||||
for filename in filenames:
|
||||
os.unlink(os.path.join(dirpath, filename))
|
||||
|
||||
27
apps/document_indexing/forms.py
Normal file
27
apps/document_indexing/forms.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .models import Index, IndexTemplateNode
|
||||
|
||||
|
||||
class IndexForm(forms.ModelForm):
|
||||
"""
|
||||
A standard model form to allow users to create a new index
|
||||
"""
|
||||
class Meta:
|
||||
model = Index
|
||||
|
||||
|
||||
class IndexTemplateNodeForm(forms.ModelForm):
|
||||
"""
|
||||
A standard model form to allow users to create a new index template node
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(IndexTemplateNodeForm, self).__init__(*args, **kwargs)
|
||||
self.fields['index'].widget = forms.widgets.HiddenInput()
|
||||
self.fields['parent'].widget = forms.widgets.HiddenInput()
|
||||
|
||||
class Meta:
|
||||
model = IndexTemplateNode
|
||||
189
apps/document_indexing/migrations/0001_initial.py
Normal file
189
apps/document_indexing/migrations/0001_initial.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Index'
|
||||
db.create_table('document_indexing_index', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='index_meta_class', null=True, to=orm['document_indexing.Index'])),
|
||||
('expression', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('link_documents', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['Index'])
|
||||
|
||||
# Adding model 'IndexInstance'
|
||||
db.create_table('document_indexing_indexinstance', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='index_meta_instance', null=True, to=orm['document_indexing.IndexInstance'])),
|
||||
('index', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.Index'])),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)),
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['IndexInstance'])
|
||||
|
||||
# Adding M2M table for field documents on 'IndexInstance'
|
||||
db.create_table('document_indexing_indexinstance_documents', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('indexinstance', models.ForeignKey(orm['document_indexing.indexinstance'], null=False)),
|
||||
('document', models.ForeignKey(orm['documents.document'], null=False))
|
||||
))
|
||||
db.create_unique('document_indexing_indexinstance_documents', ['indexinstance_id', 'document_id'])
|
||||
|
||||
# Adding model 'DocumentRenameCount'
|
||||
db.create_table('document_indexing_documentrenamecount', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('index_instance', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.IndexInstance'])),
|
||||
('document', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['documents.Document'])),
|
||||
('suffix', self.gf('django.db.models.fields.PositiveIntegerField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['DocumentRenameCount'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Index'
|
||||
db.delete_table('document_indexing_index')
|
||||
|
||||
# Deleting model 'IndexInstance'
|
||||
db.delete_table('document_indexing_indexinstance')
|
||||
|
||||
# Removing M2M table for field documents on 'IndexInstance'
|
||||
db.delete_table('document_indexing_indexinstance_documents')
|
||||
|
||||
# Deleting model 'DocumentRenameCount'
|
||||
db.delete_table('document_indexing_documentrenamecount')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'comments.comment': {
|
||||
'Meta': {'ordering': "('submit_date',)", 'object_name': 'Comment', 'db_table': "'django_comments'"},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'content_type_set_for_comment'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
|
||||
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_removed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'object_pk': ('django.db.models.fields.TextField', [], {}),
|
||||
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
|
||||
'submit_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comment_comments'", 'null': 'True', 'to': "orm['auth.User']"}),
|
||||
'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'user_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'user_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'document_indexing.documentrenamecount': {
|
||||
'Meta': {'object_name': 'DocumentRenameCount'},
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.Document']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexInstance']"}),
|
||||
'suffix': ('django.db.models.fields.PositiveIntegerField', [], {'blank': 'True'})
|
||||
},
|
||||
'document_indexing.index': {
|
||||
'Meta': {'object_name': 'Index'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'link_documents': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_meta_class'", 'null': 'True', 'to': "orm['document_indexing.Index']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
|
||||
},
|
||||
'document_indexing.indexinstance': {
|
||||
'Meta': {'object_name': 'IndexInstance'},
|
||||
'documents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['documents.Document']", 'symmetrical': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.Index']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_meta_instance'", 'null': 'True', 'to': "orm['document_indexing.IndexInstance']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'})
|
||||
},
|
||||
'documents.document': {
|
||||
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
|
||||
'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '48', 'blank': 'True'})
|
||||
},
|
||||
'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
|
||||
},
|
||||
'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['document_indexing']
|
||||
@@ -0,0 +1,75 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Deleting model 'DocumentRenameCount'
|
||||
db.delete_table('document_indexing_documentrenamecount')
|
||||
|
||||
# Deleting model 'IndexInstance'
|
||||
db.delete_table('document_indexing_indexinstance')
|
||||
|
||||
# Removing M2M table for field documents on 'IndexInstance'
|
||||
db.delete_table('document_indexing_indexinstance_documents')
|
||||
|
||||
# Deleting model 'Index'
|
||||
db.delete_table('document_indexing_index')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Adding model 'DocumentRenameCount'
|
||||
db.create_table('document_indexing_documentrenamecount', (
|
||||
('suffix', self.gf('django.db.models.fields.PositiveIntegerField')(blank=True)),
|
||||
('index_instance', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.IndexInstance'])),
|
||||
('document', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['documents.Document'])),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['DocumentRenameCount'])
|
||||
|
||||
# Adding model 'IndexInstance'
|
||||
db.create_table('document_indexing_indexinstance', (
|
||||
('index', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.Index'])),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(related_name='index_meta_instance', null=True, to=orm['document_indexing.IndexInstance'], blank=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['IndexInstance'])
|
||||
|
||||
# Adding M2M table for field documents on 'IndexInstance'
|
||||
db.create_table('document_indexing_indexinstance_documents', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('indexinstance', models.ForeignKey(orm['document_indexing.indexinstance'], null=False)),
|
||||
('document', models.ForeignKey(orm['documents.document'], null=False))
|
||||
))
|
||||
db.create_unique('document_indexing_indexinstance_documents', ['indexinstance_id', 'document_id'])
|
||||
|
||||
# Adding model 'Index'
|
||||
db.create_table('document_indexing_index', (
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(related_name='index_meta_class', null=True, to=orm['document_indexing.Index'], blank=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('link_documents', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('expression', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['Index'])
|
||||
|
||||
|
||||
models = {
|
||||
|
||||
}
|
||||
|
||||
complete_apps = ['document_indexing']
|
||||
@@ -0,0 +1,191 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'IndexTemplateNode'
|
||||
db.create_table('document_indexing_indextemplatenode', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='index_template_node', null=True, to=orm['document_indexing.IndexTemplateNode'])),
|
||||
('index', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.Index'])),
|
||||
('expression', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('link_documents', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['IndexTemplateNode'])
|
||||
|
||||
# Adding model 'IndexInstanceNode'
|
||||
db.create_table('document_indexing_indexinstancenode', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='index_instance_node', null=True, to=orm['document_indexing.IndexInstanceNode'])),
|
||||
('index_template_node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.IndexTemplateNode'])),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)),
|
||||
('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['IndexInstanceNode'])
|
||||
|
||||
# Adding M2M table for field documents on 'IndexInstanceNode'
|
||||
db.create_table('document_indexing_indexinstancenode_documents', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('indexinstancenode', models.ForeignKey(orm['document_indexing.indexinstancenode'], null=False)),
|
||||
('document', models.ForeignKey(orm['documents.document'], null=False))
|
||||
))
|
||||
db.create_unique('document_indexing_indexinstancenode_documents', ['indexinstancenode_id', 'document_id'])
|
||||
|
||||
# Adding model 'Index'
|
||||
db.create_table('document_indexing_index', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
('title', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['Index'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'IndexTemplateNode'
|
||||
db.delete_table('document_indexing_indextemplatenode')
|
||||
|
||||
# Deleting model 'IndexInstanceNode'
|
||||
db.delete_table('document_indexing_indexinstancenode')
|
||||
|
||||
# Removing M2M table for field documents on 'IndexInstanceNode'
|
||||
db.delete_table('document_indexing_indexinstancenode_documents')
|
||||
|
||||
# Deleting model 'Index'
|
||||
db.delete_table('document_indexing_index')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'comments.comment': {
|
||||
'Meta': {'ordering': "('submit_date',)", 'object_name': 'Comment', 'db_table': "'django_comments'"},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'content_type_set_for_comment'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
|
||||
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_removed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'object_pk': ('django.db.models.fields.TextField', [], {}),
|
||||
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
|
||||
'submit_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comment_comments'", 'null': 'True', 'to': "orm['auth.User']"}),
|
||||
'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'user_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'user_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'document_indexing.index': {
|
||||
'Meta': {'object_name': 'Index'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||
},
|
||||
'document_indexing.indexinstancenode': {
|
||||
'Meta': {'object_name': 'IndexInstanceNode'},
|
||||
'documents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['documents.Document']", 'symmetrical': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_template_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_instance_node'", 'null': 'True', 'to': "orm['document_indexing.IndexInstanceNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'})
|
||||
},
|
||||
'document_indexing.indextemplatenode': {
|
||||
'Meta': {'object_name': 'IndexTemplateNode'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.Index']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'link_documents': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_template_node'", 'null': 'True', 'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
|
||||
},
|
||||
'documents.document': {
|
||||
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
|
||||
'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '48', 'blank': 'True'})
|
||||
},
|
||||
'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
|
||||
},
|
||||
'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['document_indexing']
|
||||
@@ -0,0 +1,153 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'DocumentRenameCount'
|
||||
db.create_table('document_indexing_documentrenamecount', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('index_instance_node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['document_indexing.IndexInstanceNode'])),
|
||||
('document', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['documents.Document'])),
|
||||
('suffix', self.gf('django.db.models.fields.PositiveIntegerField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('document_indexing', ['DocumentRenameCount'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'DocumentRenameCount'
|
||||
db.delete_table('document_indexing_documentrenamecount')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'comments.comment': {
|
||||
'Meta': {'ordering': "('submit_date',)", 'object_name': 'Comment', 'db_table': "'django_comments'"},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'content_type_set_for_comment'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
|
||||
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_removed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'object_pk': ('django.db.models.fields.TextField', [], {}),
|
||||
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
|
||||
'submit_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comment_comments'", 'null': 'True', 'to': "orm['auth.User']"}),
|
||||
'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'user_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'user_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'document_indexing.documentrenamecount': {
|
||||
'Meta': {'object_name': 'DocumentRenameCount'},
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.Document']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_instance_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexInstanceNode']"}),
|
||||
'suffix': ('django.db.models.fields.PositiveIntegerField', [], {'blank': 'True'})
|
||||
},
|
||||
'document_indexing.index': {
|
||||
'Meta': {'object_name': 'Index'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||
},
|
||||
'document_indexing.indexinstancenode': {
|
||||
'Meta': {'object_name': 'IndexInstanceNode'},
|
||||
'documents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['documents.Document']", 'symmetrical': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_template_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_instance_node'", 'null': 'True', 'to': "orm['document_indexing.IndexInstanceNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'})
|
||||
},
|
||||
'document_indexing.indextemplatenode': {
|
||||
'Meta': {'object_name': 'IndexTemplateNode'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.Index']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'link_documents': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_template_node'", 'null': 'True', 'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
|
||||
},
|
||||
'documents.document': {
|
||||
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
|
||||
'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '48', 'blank': 'True'})
|
||||
},
|
||||
'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
|
||||
},
|
||||
'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['document_indexing']
|
||||
@@ -0,0 +1,153 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding unique constraint on 'Index', fields ['name']
|
||||
db.create_unique('document_indexing_index', ['name'])
|
||||
|
||||
# Adding unique constraint on 'Index', fields ['title']
|
||||
db.create_unique('document_indexing_index', ['title'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'Index', fields ['title']
|
||||
db.delete_unique('document_indexing_index', ['title'])
|
||||
|
||||
# Removing unique constraint on 'Index', fields ['name']
|
||||
db.delete_unique('document_indexing_index', ['name'])
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'comments.comment': {
|
||||
'Meta': {'ordering': "('submit_date',)", 'object_name': 'Comment', 'db_table': "'django_comments'"},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'content_type_set_for_comment'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}),
|
||||
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_removed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'object_pk': ('django.db.models.fields.TextField', [], {}),
|
||||
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
|
||||
'submit_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comment_comments'", 'null': 'True', 'to': "orm['auth.User']"}),
|
||||
'user_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'user_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'user_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'document_indexing.documentrenamecount': {
|
||||
'Meta': {'object_name': 'DocumentRenameCount'},
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.Document']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_instance_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexInstanceNode']"}),
|
||||
'suffix': ('django.db.models.fields.PositiveIntegerField', [], {'blank': 'True'})
|
||||
},
|
||||
'document_indexing.index': {
|
||||
'Meta': {'object_name': 'Index'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
|
||||
},
|
||||
'document_indexing.indexinstancenode': {
|
||||
'Meta': {'object_name': 'IndexInstanceNode'},
|
||||
'documents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['documents.Document']", 'symmetrical': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index_template_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_instance_node'", 'null': 'True', 'to': "orm['document_indexing.IndexInstanceNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'})
|
||||
},
|
||||
'document_indexing.indextemplatenode': {
|
||||
'Meta': {'object_name': 'IndexTemplateNode'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'index': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['document_indexing.Index']"}),
|
||||
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'link_documents': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'index_template_node'", 'null': 'True', 'to': "orm['document_indexing.IndexTemplateNode']"}),
|
||||
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
|
||||
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
|
||||
},
|
||||
'documents.document': {
|
||||
'Meta': {'ordering': "['-date_added']", 'object_name': 'Document'},
|
||||
'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '48', 'blank': 'True'})
|
||||
},
|
||||
'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
|
||||
},
|
||||
'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['document_indexing']
|
||||
0
apps/document_indexing/migrations/__init__.py
Normal file
0
apps/document_indexing/migrations/__init__.py
Normal file
@@ -13,24 +13,54 @@ from .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''
|
||||
|
||||
|
||||
class Index(MPTTModel):
|
||||
parent = TreeForeignKey('self', null=True, blank=True, related_name='index_meta_class')
|
||||
expression = models.CharField(max_length=128, verbose_name=_(u'indexing expression'), help_text=_(u'Enter a python string expression to be evaluated.'))
|
||||
# % available_indexing_functions_string)
|
||||
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'))
|
||||
link_documents = models.BooleanField(default=False, verbose_name=_(u'link documents'))
|
||||
class Index(models.Model):
|
||||
name = models.CharField(unique=True, max_length=64, verbose_name=_(u'name'), help_text=_(u'Internal name used to reference this index.'))
|
||||
title = models.CharField(unique=True, max_length=128, verbose_name=_(u'title'), help_text=_(u'The name that will be visible to users.'))
|
||||
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'), help_text=_(u'Causes this index to be visible and updated when document data changes.'))
|
||||
|
||||
@property
|
||||
def template_root(self):
|
||||
return self.indextemplatenode_set.get(parent=None)
|
||||
|
||||
@property
|
||||
def instance_root(self):
|
||||
return self.template_root.indexinstancenode_set.get()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.expression if not self.link_documents else u'%s/[document]' % self.expression
|
||||
return self.title
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self):
|
||||
return ('index_instance_node_view', [self.instance_root.pk])
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(Index, self).save(*args, **kwargs)
|
||||
index_template_node_root, created = IndexTemplateNode.objects.get_or_create(parent=None, index=self)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'index')
|
||||
verbose_name_plural = _(u'indexes')
|
||||
|
||||
|
||||
class IndexInstance(MPTTModel):
|
||||
parent = TreeForeignKey('self', null=True, blank=True, related_name='index_meta_instance')
|
||||
class IndexTemplateNode(MPTTModel):
|
||||
parent = TreeForeignKey('self', null=True, blank=True, related_name='index_template_node')
|
||||
index = models.ForeignKey(Index, verbose_name=_(u'index'))
|
||||
expression = models.CharField(max_length=128, verbose_name=_(u'indexing expression'), help_text=_(u'Enter a python string expression to be evaluated.'))
|
||||
# % available_indexing_functions_string)
|
||||
enabled = models.BooleanField(default=True, verbose_name=_(u'enabled'), help_text=_(u'Causes this node to be visible and updated when document data changes.'))
|
||||
link_documents = models.BooleanField(default=False, verbose_name=_(u'link documents'), help_text=_(u'Check this option to have this node act as a container for documents and not as a parent for further nodes.'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.expression if not self.link_documents else u'%s/[document]' % self.expression
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'index template node')
|
||||
verbose_name_plural = _(u'indexes template nodes')
|
||||
|
||||
|
||||
class IndexInstanceNode(MPTTModel):
|
||||
parent = TreeForeignKey('self', null=True, blank=True, related_name='index_instance_node')
|
||||
index_template_node = models.ForeignKey(IndexTemplateNode, verbose_name=_(u'index template node'))
|
||||
value = models.CharField(max_length=128, blank=True, verbose_name=_(u'value'))
|
||||
documents = models.ManyToManyField(Document, verbose_name=_(u'documents'))
|
||||
|
||||
@@ -39,23 +69,20 @@ class IndexInstance(MPTTModel):
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self):
|
||||
return ('index_instance_list', [self.pk])
|
||||
|
||||
def get_document_list_display(self):
|
||||
return u', '.join([d.file_filename for d in self.documents.all()])
|
||||
return ('index_instance_node_view', [self.pk])
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'index instance')
|
||||
verbose_name_plural = _(u'indexes instances')
|
||||
verbose_name = _(u'index instance node')
|
||||
verbose_name_plural = _(u'indexes instance nodes')
|
||||
|
||||
|
||||
class DocumentRenameCount(models.Model):
|
||||
index_instance = models.ForeignKey(IndexInstance, verbose_name=_(u'index instance'))
|
||||
index_instance_node = models.ForeignKey(IndexInstanceNode, verbose_name=_(u'index instance'))
|
||||
document = models.ForeignKey(Document, verbose_name=_(u'document'))
|
||||
suffix = models.PositiveIntegerField(blank=True, verbose_name=(u'suffix'))
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s - %s - %s' % (self.index_instance, self.document, self.suffix or u'0')
|
||||
return u'%s - %s - %s' % (self.index_instance_node, self.document, self.suffix or u'0')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'document rename count')
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
|
||||
from .conf.settings import SUFFIX_SEPARATOR
|
||||
|
||||
|
||||
def assemble_suffixed_filename(filename, suffix=0):
|
||||
"""
|
||||
Split document filename, to attach suffix to the name part then
|
||||
re attacht the extension
|
||||
"""
|
||||
|
||||
if suffix:
|
||||
name, extension = filename.split(os.split(os.extsep))
|
||||
return SUFFIX_SEPARATOR.join([name, unicode(suffix), os.extsep, extension])
|
||||
else:
|
||||
return filename
|
||||
|
||||
|
||||
def assemble_path_from_list(directory_list):
|
||||
return os.sep.join(directory_list)
|
||||
@@ -6,5 +6,10 @@ from permissions.models import PermissionNamespace, Permission
|
||||
|
||||
document_indexing_namespace = PermissionNamespace('document_indexing', _(u'Indexing'))
|
||||
|
||||
PERMISSION_DOCUMENT_INDEXING_SETUP = Permission.objects.register(document_indexing_namespace, 'document_index_setup', _(u'Configure document indexes'))
|
||||
PERMISSION_DOCUMENT_INDEXING_CREATE = Permission.objects.register(document_indexing_namespace, 'document_index_create', _(u'Create new document indexes'))
|
||||
PERMISSION_DOCUMENT_INDEXING_EDIT = Permission.objects.register(document_indexing_namespace, 'document_index_edit', _(u'Edit document indexes'))
|
||||
PERMISSION_DOCUMENT_INDEXING_DELETE = Permission.objects.register(document_indexing_namespace, 'document_index_delete', _(u'Delete document indexes'))
|
||||
|
||||
PERMISSION_DOCUMENT_INDEXING_VIEW = Permission.objects.register(document_indexing_namespace, 'document_index_view', _(u'View document indexes'))
|
||||
PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES = Permission.objects.register(document_indexing_namespace, 'document_rebuild_indexes', _(u'Rebuild document indexes'))
|
||||
|
||||
BIN
apps/document_indexing/static/images/icons/tab.png
Normal file
BIN
apps/document_indexing/static/images/icons/tab.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 578 B |
BIN
apps/document_indexing/static/images/icons/tab_delete.png
Normal file
BIN
apps/document_indexing/static/images/icons/tab_delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
apps/document_indexing/static/images/icons/textfield_delete.png
Normal file
BIN
apps/document_indexing/static/images/icons/textfield_delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
19
apps/document_indexing/tools.py
Normal file
19
apps/document_indexing/tools.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from documents.models import Document
|
||||
|
||||
from .models import Index, IndexInstanceNode, DocumentRenameCount
|
||||
from .filesystem import fs_delete_directory_recusive
|
||||
from .api import update_indexes
|
||||
|
||||
|
||||
def do_rebuild_all_indexes():
|
||||
for index in Index.objects.all():
|
||||
fs_delete_directory_recusive(index)
|
||||
|
||||
IndexInstanceNode.objects.all().delete()
|
||||
DocumentRenameCount.objects.all().delete()
|
||||
for document in Document.objects.all():
|
||||
update_indexes(document)
|
||||
|
||||
return [] # Warnings - None
|
||||
@@ -1,9 +1,19 @@
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('document_indexing.views',
|
||||
url(r'^(?P<index_id>\d+)/list/$', 'index_instance_list', (), 'index_instance_list'),
|
||||
url(r'^list/$', 'index_instance_list', (), 'index_instance_list'),
|
||||
url(r'^rebuild/all/$', 'rebuild_index_instances', (), 'rebuild_index_instances'),
|
||||
url(r'^setup/index/list/$', 'index_setup_list', (), 'index_setup_list'),
|
||||
url(r'^setup/index/create/$', 'index_setup_create', (), 'index_setup_create'),
|
||||
url(r'^setup/index/(?P<index_pk>\d+)/edit/$', 'index_setup_edit', (), 'index_setup_edit'),
|
||||
url(r'^setup/index/(?P<index_pk>\d+)/delete/$', 'index_setup_delete', (), 'index_setup_delete'),
|
||||
url(r'^setup/index/(?P<index_pk>\d+)/view/$', 'index_setup_view', (), 'index_setup_view'),
|
||||
|
||||
url(r'^setup/template/node/(?P<parent_pk>\d+)/create/child/$', 'template_node_create', (), 'template_node_create'),
|
||||
url(r'^setup/template/node/(?P<node_pk>\d+)/edit/$', 'template_node_edit', (), 'template_node_edit'),
|
||||
url(r'^setup/template/node/(?P<node_pk>\d+)/delete/$', 'template_node_delete', (), 'template_node_delete'),
|
||||
|
||||
url(r'^index/list/$', 'index_list', (), 'index_list'),
|
||||
url(r'^instance/node/(?P<index_instance_node_pk>\d+)/$', 'index_instance_node_view', (), 'index_instance_node_view'),
|
||||
|
||||
url(r'^rebuild/all/$', 'rebuild_index_instances', (), 'rebuild_index_instances'),
|
||||
url(r'^list/for/document/(?P<document_id>\d+)/$', 'document_index_list', (), 'document_index_list'),
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
@@ -5,46 +7,319 @@ from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.contrib import messages
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.html import conditional_escape, mark_safe
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from permissions.models import Permission
|
||||
from documents.permissions import PERMISSION_DOCUMENT_VIEW
|
||||
from documents.models import Document
|
||||
from documents.views import document_list
|
||||
from common.utils import encapsulate
|
||||
from acls.utils import apply_default_acls
|
||||
from acls.models import AccessEntry
|
||||
|
||||
from .forms import IndexForm, IndexTemplateNodeForm
|
||||
from .models import (Index, IndexTemplateNode, IndexInstanceNode)
|
||||
from .tools import do_rebuild_all_indexes
|
||||
from .widgets import (index_instance_item_link, get_breadcrumbs)
|
||||
from .permissions import (PERMISSION_DOCUMENT_INDEXING_VIEW,
|
||||
PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES)
|
||||
from .models import IndexInstance
|
||||
from .api import (get_breadcrumbs, get_instance_link,
|
||||
do_rebuild_all_indexes)
|
||||
from .widgets import index_instance_item_link
|
||||
PERMISSION_DOCUMENT_INDEXING_REBUILD_INDEXES,
|
||||
PERMISSION_DOCUMENT_INDEXING_SETUP,
|
||||
PERMISSION_DOCUMENT_INDEXING_CREATE,
|
||||
PERMISSION_DOCUMENT_INDEXING_EDIT,
|
||||
PERMISSION_DOCUMENT_INDEXING_DELETE
|
||||
)
|
||||
|
||||
|
||||
def index_instance_list(request, index_id=None):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_VIEW])
|
||||
# Setup views
|
||||
def index_setup_list(request):
|
||||
context = {
|
||||
'title': _(u'indexes'),
|
||||
'hide_object': True,
|
||||
'list_object_variable_name': 'index',
|
||||
'extra_columns': [
|
||||
{'name': _(u'name'), 'attribute': 'name'},
|
||||
{'name': _(u'title'), 'attribute': 'title'},
|
||||
]
|
||||
}
|
||||
|
||||
if index_id:
|
||||
index_instance = get_object_or_404(IndexInstance, pk=index_id)
|
||||
index_instance_list = [index for index in index_instance.get_children().order_by('value')]
|
||||
breadcrumbs = get_breadcrumbs(index_instance)
|
||||
if index_instance.documents.count():
|
||||
for document in index_instance.documents.all().order_by('file_filename'):
|
||||
index_instance_list.append(document)
|
||||
queryset = Index.objects.all()
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_SETUP])
|
||||
except PermissionDenied:
|
||||
queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_INDEXING_SETUP, request.user, queryset)
|
||||
|
||||
context['object_list'] = queryset
|
||||
|
||||
return render_to_response('generic_list.html',
|
||||
context,
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
||||
|
||||
def index_setup_create(request):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_CREATE])
|
||||
|
||||
if request.method == 'POST':
|
||||
form = IndexForm(request.POST)
|
||||
if form.is_valid():
|
||||
index = form.save()
|
||||
apply_default_acls(index, request.user)
|
||||
messages.success(request, _(u'Index created successfully.'))
|
||||
return HttpResponseRedirect(reverse('index_setup_list'))
|
||||
else:
|
||||
index_instance_list = IndexInstance.objects.filter(parent=None)
|
||||
breadcrumbs = get_instance_link()
|
||||
index_instance = None
|
||||
form = IndexForm()
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'create index'),
|
||||
'form': form,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def index_setup_edit(request, index_pk):
|
||||
index = get_object_or_404(Index, pk=index_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_EDIT])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_CREATE, request.user, index)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = IndexForm(request.POST, instance=index)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _(u'Index edited successfully'))
|
||||
return HttpResponseRedirect(reverse('index_setup_list'))
|
||||
else:
|
||||
form = IndexForm(instance=index)
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'edit index: %s') % index,
|
||||
'form': form,
|
||||
'index': index,
|
||||
'object_name': _(u'index'),
|
||||
'navigation_object_name': 'index',
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def index_setup_delete(request, index_pk):
|
||||
index = get_object_or_404(Index, pk=index_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_DELETE])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_DELETE, request.user, index)
|
||||
|
||||
post_action_redirect = reverse('index_setup_list')
|
||||
|
||||
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
|
||||
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
index.delete()
|
||||
messages.success(request, _(u'Index: %s deleted successfully.') % index)
|
||||
except Exception, e:
|
||||
messages.error(request, _(u'Index: %(index)s delete error: %(error)s') % {
|
||||
'index': index, 'error': e})
|
||||
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
context = {
|
||||
'index': index,
|
||||
'object_name': _(u'index'),
|
||||
'navigation_object_name': 'index',
|
||||
'delete_view': True,
|
||||
'previous': previous,
|
||||
'next': next,
|
||||
'title': _(u'Are you sure you with to delete the index: %s?') % index,
|
||||
'form_icon': u'tab_delete.png',
|
||||
}
|
||||
|
||||
return render_to_response('generic_confirm.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def index_setup_view(request, index_pk):
|
||||
index = get_object_or_404(Index, pk=index_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_SETUP])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_SETUP, request.user, index)
|
||||
|
||||
root, created = IndexTemplateNode.objects.get_or_create(parent=None, index=index)
|
||||
object_list = root.get_descendants(include_self=True)
|
||||
|
||||
context = {
|
||||
'object_list': object_list,
|
||||
'index': index,
|
||||
'object_name': _(u'index'),
|
||||
'list_object_variable_name': 'node',
|
||||
'navigation_object_name': 'index',
|
||||
'title': _(u'tree template nodes for index: %s') % index,
|
||||
'hide_object': True,
|
||||
'extra_columns': [
|
||||
{'name': _(u'level'), 'attribute': encapsulate(lambda x: u''.join([mark_safe(conditional_escape(u'--') * (getattr(x, x._mptt_meta.level_attr) - 0)), unicode(x if x.parent else 'root') ] ))},
|
||||
],
|
||||
}
|
||||
|
||||
return render_to_response('generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
# Node views
|
||||
def template_node_create(request, parent_pk):
|
||||
parent_node = get_object_or_404(IndexTemplateNode, pk=parent_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_SETUP])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_SETUP, request.user, parent_node.index)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = IndexTemplateNodeForm(request.POST)
|
||||
if form.is_valid():
|
||||
node = form.save()
|
||||
messages.success(request, _(u'Index template node created successfully.'))
|
||||
return HttpResponseRedirect(reverse('index_setup_view', args=[node.index.pk]))
|
||||
else:
|
||||
form = IndexTemplateNodeForm(initial={'index': parent_node.index, 'parent': parent_node})
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'create child node'),
|
||||
'form': form,
|
||||
'index': parent_node.index,
|
||||
'object_name': _(u'index'),
|
||||
'navigation_object_name': 'index',
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def template_node_edit(request, node_pk):
|
||||
node = get_object_or_404(IndexTemplateNode, pk=node_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_SETUP])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_SETUP, request.user, node.index)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = IndexTemplateNodeForm(request.POST, instance=node)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _(u'Index template node edited successfully'))
|
||||
return HttpResponseRedirect(reverse('index_setup_view', args=[node.index.pk]))
|
||||
else:
|
||||
form = IndexTemplateNodeForm(instance=node)
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'edit index template node: %s') % node,
|
||||
'form': form,
|
||||
'index': node.index,
|
||||
'node': node,
|
||||
|
||||
'navigation_object_list': [
|
||||
{'object': 'index', 'name': _(u'index')},
|
||||
{'object': 'node', 'name': _(u'node')}
|
||||
],
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def template_node_delete(request, node_pk):
|
||||
node = get_object_or_404(IndexTemplateNode, pk=node_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_SETUP])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_SETUP, request.user, node.index)
|
||||
|
||||
post_action_redirect = reverse('index_setup_view', args=[node.index.pk])
|
||||
|
||||
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
|
||||
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
node.delete()
|
||||
messages.success(request, _(u'Node: %s deleted successfully.') % node)
|
||||
except Exception, e:
|
||||
messages.error(request, _(u'Node: %(node)s delete error: %(error)s') % {
|
||||
'node': node, 'error': e})
|
||||
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
context = {
|
||||
'delete_view': True,
|
||||
'previous': previous,
|
||||
'next': next,
|
||||
'title': _(u'Are you sure you with to delete the index template node: %s?') % node,
|
||||
'form_icon': u'textfield_delete.png',
|
||||
'index': node.index,
|
||||
'node': node,
|
||||
|
||||
'navigation_object_list': [
|
||||
{'object': 'index', 'name': _(u'index')},
|
||||
{'object': 'node', 'name': _(u'node')}
|
||||
],
|
||||
}
|
||||
|
||||
return render_to_response('generic_confirm.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def index_list(request):
|
||||
context = {
|
||||
'title': _(u'indexes'),
|
||||
#'hide_object': True,
|
||||
#'list_object_variable_name': 'index',
|
||||
#'extra_columns': [
|
||||
# {'name': _(u'elements'), 'attribute': 'root'},
|
||||
# {'name': _(u'name'), 'attribute': 'name'},
|
||||
# {'name': _(u'title'), 'attribute': 'title'},
|
||||
#],
|
||||
'overrided_object_links': [{}],
|
||||
}
|
||||
|
||||
queryset = Index.objects.filter(enabled=True)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_VIEW])
|
||||
except PermissionDenied:
|
||||
queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_INDEXING_VIEW, request.user, queryset)
|
||||
|
||||
context['object_list'] = queryset
|
||||
|
||||
return render_to_response('generic_list.html',
|
||||
context,
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
||||
|
||||
def index_instance_node_view(request, index_instance_node_pk):
|
||||
index_instance = get_object_or_404(IndexInstanceNode, pk=index_instance_node_pk)
|
||||
index_instance_list = [index for index in index_instance.get_children().order_by('value')]
|
||||
breadcrumbs = get_breadcrumbs(index_instance)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_INDEXING_VIEW])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_INDEXING_VIEW, request.user, index_instance.index)
|
||||
|
||||
title = mark_safe(_(u'contents for index: %s') % breadcrumbs)
|
||||
|
||||
if index_instance:
|
||||
if index_instance.index.link_documents:
|
||||
if index_instance.index_template_node.link_documents:
|
||||
# Document list, use the document_list view for consistency
|
||||
return document_list(
|
||||
request,
|
||||
title=title,
|
||||
object_list=index_instance_list,
|
||||
object_list=index_instance.documents.all(),
|
||||
extra_context={
|
||||
'object': index_instance
|
||||
}
|
||||
@@ -54,12 +329,12 @@ def index_instance_list(request, index_id=None):
|
||||
'object_list': index_instance_list,
|
||||
'extra_columns_preffixed': [
|
||||
{
|
||||
'name': _(u'index'),
|
||||
'name': _(u'node'),
|
||||
'attribute': encapsulate(lambda x: index_instance_item_link(x))
|
||||
},
|
||||
{
|
||||
'name': _(u'items'),
|
||||
'attribute': encapsulate(lambda x: x.documents.count() if x.index.link_documents else x.get_children().count())
|
||||
'attribute': encapsulate(lambda x: x.documents.count() if x.index_template_node.link_documents else x.get_children().count())
|
||||
}
|
||||
],
|
||||
'title': title,
|
||||
@@ -98,12 +373,16 @@ def rebuild_index_instances(request):
|
||||
|
||||
|
||||
def document_index_list(request, document_id):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW, PERMISSION_DOCUMENT_INDEXING_VIEW])
|
||||
document = get_object_or_404(Document, pk=document_id)
|
||||
|
||||
object_list = []
|
||||
|
||||
for index_instance in document.indexinstance_set.all():
|
||||
queryset = document.indexinstancenode_set.all()
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW, PERMISSION_DOCUMENT_INDEXING_VIEW])
|
||||
except PermissionDenied:
|
||||
queryset = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_INDEXING_VIEW, request.user, queryset)
|
||||
|
||||
for index_instance in queryset:
|
||||
object_list.append(get_breadcrumbs(index_instance, single_link=True, include_count=True))
|
||||
|
||||
return render_to_response('generic_list.html', {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from document_indexing.models import IndexInstance
|
||||
from .models import IndexInstanceNode
|
||||
|
||||
FOLDER_W_DOCUMENTS = u'folder_page'
|
||||
FOLDER_ICON = u'folder'
|
||||
|
||||
|
||||
def index_instance_item_link(index_instance_item):
|
||||
if isinstance(index_instance_item, IndexInstance):
|
||||
if index_instance_item.index.link_documents:
|
||||
if isinstance(index_instance_item, IndexInstanceNode):
|
||||
if index_instance_item.index_template_node.link_documents:
|
||||
icon = FOLDER_W_DOCUMENTS
|
||||
else:
|
||||
icon = FOLDER_ICON
|
||||
@@ -20,3 +22,52 @@ def index_instance_item_link(index_instance_item):
|
||||
'icon_template': icon_template,
|
||||
'text': index_instance_item
|
||||
})
|
||||
|
||||
|
||||
def get_instance_link(index_instance_node, text=None, simple=False):
|
||||
"""
|
||||
Return an HTML anchor to an index instance
|
||||
"""
|
||||
|
||||
if simple:
|
||||
# Just display the instance's value or overrided text, no
|
||||
# HTML anchor
|
||||
template = u'%(value)s'
|
||||
else:
|
||||
template = u'<a href="%(url)s">%(value)s</a>'
|
||||
|
||||
return template % {
|
||||
'url': index_instance_node.get_absolute_url(),
|
||||
'value': text if text else (index_instance_node if index_instance_node.parent else index_instance_node.index_template_node.index)
|
||||
}
|
||||
|
||||
|
||||
def get_breadcrumbs(index_instance, simple=False, single_link=False, include_count=False):
|
||||
"""
|
||||
Return a joined string of HTML anchors to every index instance's
|
||||
parent from the root of the tree to the index instance
|
||||
"""
|
||||
result = []
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
simple = True
|
||||
|
||||
#result.append(get_instance_link(index_instance.get_root(), simple=simple))
|
||||
|
||||
for instance in index_instance.get_ancestors():
|
||||
result.append(get_instance_link(instance, simple=simple))
|
||||
|
||||
result.append(get_instance_link(index_instance, simple=simple))
|
||||
|
||||
output = []
|
||||
|
||||
if include_count:
|
||||
output.append(u'(%d)' % index_instance.documents.count())
|
||||
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
output.insert(0, get_instance_link(index_instance_node=index_instance, text=(u' / '.join(result))))
|
||||
return mark_safe(u' '.join(output))
|
||||
else:
|
||||
output.insert(0, u' / '.join(result))
|
||||
return mark_safe(u' '.join(output))
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import absolute_import
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
||||
from metadata.classes import MetadataObject
|
||||
from metadata.classes import MetadataClass
|
||||
from documents.models import Document
|
||||
|
||||
from .literals import INCLUSION_AND, INCLUSION_OR
|
||||
@@ -18,7 +18,7 @@ class SmartLinkManager(models.Manager):
|
||||
metadata_dict[document_metadata.metadata_type.name] = document_metadata.value
|
||||
eval_dict = {}
|
||||
eval_dict['document'] = document
|
||||
eval_dict['metadata'] = MetadataObject(metadata_dict)
|
||||
eval_dict['metadata'] = MetadataClass(metadata_dict)
|
||||
|
||||
if smart_link_obj:
|
||||
smart_link_qs = self.model.objects.filter(Q(enabled=True) & Q(pk=smart_link_obj.pk))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class MetadataObject(object):
|
||||
class MetadataClass(object):
|
||||
def __init__(self, dictionary):
|
||||
self.dictionary = dictionary
|
||||
|
||||
|
||||
@@ -122,6 +122,19 @@ column after those is ignored.
|
||||
* The ``--skip-repeated`` tells the importedr to not stop when finding
|
||||
that a user already exists in the database.
|
||||
|
||||
Refactored document indexing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The document indexing functionality has been improved and moved from experimental
|
||||
stage to beta stage. Index configuration menus are now available on the
|
||||
``Setup`` menu and allows administrators to create a skeleton tree that will
|
||||
be populated with document links depending on their metadata and properties.
|
||||
This populated tree can also be mirrored on the physical filesystem and shared
|
||||
using Samba or another filesharing server giving users a structured view
|
||||
of the documents contained within **Mayan EDMS** from the ``Indexes`` tab
|
||||
or from a mirrored index shared via the network. A new configuration option
|
||||
has been added, :setting:`DOCUMENT_INDEXING_FILESYSTEM_SERVING`, which maps
|
||||
the index internal name with the physical directory where such index will be
|
||||
mirrored on disk.
|
||||
|
||||
Upgrading from a previous version
|
||||
=================================
|
||||
@@ -191,15 +204,21 @@ so write down your role permission setup before upgrading.
|
||||
Bugs fixed
|
||||
==========
|
||||
* Issue #17, special thanks to Dave Herring for all the help including
|
||||
access to a machine suffering with the issue.
|
||||
access to a machine suffering with the issue, and to Сергей Глита for
|
||||
his research and eventual find of the core cause.
|
||||
* Statistics fixes.
|
||||
* Fixed get_image_cache_name regression in the OCR app.
|
||||
|
||||
Stuff removed
|
||||
=============
|
||||
* Removal of the OCR_CACHE_URI configuration option.
|
||||
* Support for Celery and Sentry has been drop
|
||||
for now.
|
||||
* Removed the 'db_index' argument from Text fields definition and
|
||||
migrations as it was causing error messages for MySQL users, thanks to
|
||||
Сергей Глита for reporting this one.
|
||||
* Configuration options removed:
|
||||
|
||||
* OCR_CACHE_URI
|
||||
* DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_PATH - Use the newest :setting:`DOCUMENT_INDEXING_FILESYSTEM_SERVING`
|
||||
* DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_ENABLE - Use the newest :setting:`DOCUMENT_INDEXING_FILESYSTEM_SERVING`
|
||||
|
||||
|
||||
@@ -297,21 +297,15 @@ DOCUMENT_INDEXING_FILESYSTEM_MAX_SUFFIX_COUNT
|
||||
Default: ``1000``
|
||||
|
||||
|
||||
.. setting:: DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_PATH
|
||||
.. setting:: DOCUMENT_INDEXING_FILESYSTEM_SERVING
|
||||
|
||||
DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_PATH
|
||||
---------------------------------------------
|
||||
|
||||
Default: ``/tmp/mayan/documents``
|
||||
|
||||
|
||||
.. setting:: DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_ENABLE
|
||||
DOCUMENT_INDEXING_FILESYSTEM_SERVING
|
||||
------------------------------------
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
A dictionary that maps the index name and where on the filesystem that index will be mirrored.
|
||||
|
||||
DOCUMENT_INDEXING_FILESYSTEM_FILESERVING_ENABLE
|
||||
-----------------------------------------------
|
||||
|
||||
Default: ``True``
|
||||
|
||||
|
||||
OCR
|
||||
===
|
||||
|
||||
Reference in New Issue
Block a user