Merge branch 'new_metadata'

Conflicts:
	requirements/development.txt
	requirements/production.txt
	settings.py
This commit is contained in:
Roberto Rosario
2011-05-21 00:13:38 -04:00
186 changed files with 2614 additions and 21837 deletions

View File

@@ -1,16 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from permissions.api import register_permissions
from main.api import register_tool
FILESYSTEM_SERVING_RECREATE_LINKS = 'recreate_links'
register_permissions('filesystem_serving', [
{'name': FILESYSTEM_SERVING_RECREATE_LINKS, 'label':_(u'Recreate filesystem links.')},
])
filesystem_serving_recreate_all_links = {'text': _('recreate index links'), 'view': 'recreate_all_links', 'famfam': 'page_link', 'permissions': {'namespace': 'filesystem_serving', 'permissions': [FILESYSTEM_SERVING_RECREATE_LINKS]}, 'description': _(u'Deletes and creates from scratch all the file system indexing links.')}
register_tool(filesystem_serving_recreate_all_links, namespace='filesystem_serving', title=_(u'Filesystem'))

View File

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

View File

@@ -1,160 +0,0 @@
import errno
import os
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from documents.conf.settings import AVAILABLE_INDEXING_FUNCTIONS
from filesystem_serving.conf.settings import FILESERVING_ENABLE
from filesystem_serving.conf.settings import FILESERVING_PATH
from filesystem_serving.conf.settings import SLUGIFY_PATHS
from filesystem_serving.conf.settings import MAX_RENAME_COUNT
from filesystem_serving.models import DocumentMetadataIndex, Document
if SLUGIFY_PATHS == False:
#Do not slugify path or filenames and extensions
SLUGIFY_FUNCTION = lambda x: x
else:
SLUGIFY_FUNCTION = slugify
def document_create_fs_links(document):
warnings = []
if FILESERVING_ENABLE:
if not document.exists():
raise Exception(_(u'Not creating metadata indexing, document not found in document storage'))
metadata_dict = {'document': document}
metadata_dict.update(dict([(metadata.metadata_type.name, SLUGIFY_FUNCTION(metadata.value)) for metadata in document.documentmetadata_set.all()]))
for metadata_index in document.document_type.metadataindex_set.all():
if metadata_index.enabled:
try:
fabricated_directory = eval(metadata_index.expression, metadata_dict, AVAILABLE_INDEXING_FUNCTIONS)
target_directory = os.path.join(FILESERVING_PATH, fabricated_directory)
try:
os.makedirs(target_directory)
except OSError, exc:
if exc.errno == errno.EEXIST:
pass
else:
raise OSError(_(u'Unable to create metadata indexing directory: %s') % exc)
next_available_filename(document, metadata_index, target_directory, SLUGIFY_FUNCTION(document.file_filename), SLUGIFY_FUNCTION(document.file_extension))
except NameError, exc:
warnings.append(_(u'Error in metadata indexing expression: %s') % exc)
#raise NameError()
#This should be a warning not an error
#pass
except Exception, exc:
raise Exception(_(u'Unable to create metadata indexing directory: %s') % exc)
return warnings
def document_delete_fs_links(document):
if FILESERVING_ENABLE:
for document_metadata_index in document.documentmetadataindex_set.all():
try:
os.unlink(document_metadata_index.filename)
document_metadata_index.delete()
except OSError, exc:
if exc.errno == errno.ENOENT:
#No longer exits, so delete db entry anyway
document_metadata_index.delete()
else:
raise OSError(_(u'Unable to delete metadata indexing symbolic link: %s') % exc)
path, filename = os.path.split(document_metadata_index.filename)
#Cleanup directory of dead stuff
#Delete siblings that are dead links
try:
for f in os.listdir(path):
filepath = os.path.join(path, f)
if os.path.islink(filepath):
#Get link's source
source = os.readlink(filepath)
if os.path.isabs(source):
if not os.path.exists(source):
#link's source is absolute and doesn't exit
os.unlink(filepath)
else:
os.unlink(os.path.join(path, filepath))
elif os.path.isdir(filepath):
#is a directory, try to delete it
try:
os.removedirs(path)
except:
pass
except OSError, exc:
pass
#Remove the directory if it is empty
try:
os.removedirs(path)
except:
pass
def next_available_filename(document, metadata_index, path, filename, extension, suffix=0):
target = filename
if suffix:
target = '_'.join([filename, unicode(suffix)])
filepath = os.path.join(path, os.extsep.join([target, extension]))
matches = DocumentMetadataIndex.objects.filter(filename=filepath)
if matches.count() == 0:
document_metadata_index = DocumentMetadataIndex(
document=document, metadata_index=metadata_index,
filename=filepath)
try:
os.symlink(document.file.path, filepath)
document_metadata_index.save()
except OSError, exc:
if exc.errno == errno.EEXIST:
#This link should not exist, try to delete it
try:
os.unlink(filepath)
#Try again with same suffix
return next_available_filename(document, metadata_index, path, filename, extension, suffix)
except Exception, exc:
raise Exception(_(u'Unable to create symbolic link, filename clash: %(filepath)s; %(exc)s') % {'filepath': filepath, 'exc': exc})
else:
raise OSError(_(u'Unable to create symbolic link: %(filepath)s; %(exc)s') % {'filepath': filepath, 'exc': exc})
return filepath
else:
if suffix > MAX_RENAME_COUNT:
raise Exception(_(u'Maximum rename count reached, not creating symbolic link'))
return next_available_filename(document, metadata_index, path, filename, extension, suffix + 1)
#TODO: diferentiate between evaluation error and filesystem errors
def do_recreate_all_links(raise_exception=True):
errors = []
warnings = []
for document in Document.objects.all():
try:
document_delete_fs_links(document)
except NameError, e:
warnings.append('%s: %s' % (document, e))
except Exception, e:
if raise_exception:
raise Exception(e)
else:
errors.append('%s: %s' % (document, e))
for document in Document.objects.all():
try:
create_warnings = document_create_fs_links(document)
except Exception, e:
if raise_exception:
raise Exception(e)
else:
errors.append('%s: %s' % (document, e))
for warning in create_warnings:
warnings.append('%s: %s' % (document, warning))
return errors, warnings

View File

@@ -1,14 +0,0 @@
"""Configuration options for the filesystem_serving app"""
from smart_settings.api import register_settings
register_settings(
namespace=u'filesystem_serving',
module=u'filesystem_serving.conf.settings',
settings=[
{'name': u'SLUGIFY_PATHS', 'global_name': u'FILESYSTEM_SLUGIFY_PATHS', 'default': False},
{'name': u'MAX_RENAME_COUNT', 'global_name': u'FILESYSTEM_MAX_RENAME_COUNT', 'default': 200},
{'name': u'FILESERVING_PATH', 'global_name': u'FILESYSTEM_FILESERVING_PATH', 'default': u'/tmp/mayan/documents', 'exists': True},
{'name': u'FILESERVING_ENABLE', 'global_name': u'FILESYSTEM_FILESERVING_ENABLE', 'default': True}
]
)

View File

@@ -1,118 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-05-06 13:29-0400\n"
"PO-Revision-Date: 2011-05-06 13:30\n"
"Last-Translator: Roberto Rosario <rosario_r@jp.pr.gov>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Translated-Using: django-rosetta 0.6.0\n"
#: __init__.py:11
msgid "Recreate filesystem links."
msgstr "Recrear vínculos de sistema de archivos."
#: __init__.py:14
msgid "recreate index links"
msgstr "recrear enlaces índice"
#: __init__.py:14
msgid "Deletes and creates from scratch all the file system indexing links."
msgstr ""
"Borra y crea de la nada todos los enlaces de indexación del sistema de"
" archivos."
#: __init__.py:16
msgid "Filesystem"
msgstr "Sistema de archivos"
#: api.py:27
msgid "Not creating metadata indexing, document not found in document storage"
msgstr ""
"No de creara indexación de metadatos, el documento no se encuentran en"
" almacenamiento de documentos"
#: api.py:42 api.py:51
#, python-format
msgid "Unable to create metadata indexing directory: %s"
msgstr "No se puedo crear el directorio de indexación de metadatos: %s"
#: api.py:46
#, python-format
msgid "Error in metadata indexing expression: %s"
msgstr "Error en la expresión de indexación de metadatos: %s"
#: api.py:67
#, python-format
msgid "Unable to delete metadata indexing symbolic link: %s"
msgstr ""
"No se puede eliminar el enlace simbólico de indexación de metadatos: "
"%s"
#: api.py:122
#, python-format
msgid "Unable to create symbolic link, filename clash: %(filepath)s; %(exc)s"
msgstr ""
"No se puede crear el enlace simbólico, coque de nombre de archivo: "
"%(filepath)s; %(exc)s "
#: api.py:124
#, python-format
msgid "Unable to create symbolic link: %(filepath)s; %(exc)s"
msgstr "No se puedo crear enlace simbólico: %(filepath)s; %(exc)s "
#: api.py:129
msgid "Maximum rename count reached, not creating symbolic link"
msgstr ""
"Conteo máxima de cambio de nombre alcanzado, no se creará el enlaces "
"simbólico"
#: models.py:8
msgid "document"
msgstr "documento"
#: models.py:9
msgid "metadata index"
msgstr "índice de metadatos"
#: models.py:10
msgid "filename"
msgstr "nombre de archivo"
#: models.py:11
msgid "suffix"
msgstr "sufijo"
#: models.py:17
msgid "document metadata index"
msgstr "índice de metadatos de document"
#: models.py:18
msgid "document metadata indexes"
msgstr "índices de metadatos de documentos"
#: views.py:23
msgid "On large databases this operation may take some time to execute."
msgstr ""
"En bases de datos de gran tamaño esta operación puede tardar algún "
"tiempo en ejecutarse."
#: views.py:28
msgid "Filesystem links re-creation completed successfully."
msgstr "Re creación de enlaces de sistema de archivos completó correctamente."
#: views.py:33
#, python-format
msgid "Filesystem links re-creation error: %s"
msgstr "Error de re creación de enlaces de sistema de archivos: %s"

View File

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

View File

@@ -1,23 +0,0 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View File

@@ -1,5 +0,0 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('filesystem_serving.views',
url(r'^recreate_all_links/$', 'recreate_all_links', (), 'recreate_all_links'),
)

View File

@@ -1,35 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib import messages
from permissions.api import check_permissions
from filesystem_serving import FILESYSTEM_SERVING_RECREATE_LINKS
from filesystem_serving.api import do_recreate_all_links
def recreate_all_links(request):
check_permissions(request.user, 'filesystem_serving', [FILESYSTEM_SERVING_RECREATE_LINKS])
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', None)))
if request.method != 'POST':
return render_to_response('generic_confirm.html', {
'previous': previous,
'next': next,
'message': _(u'On large databases this operation may take some time to execute.'),
}, context_instance=RequestContext(request))
else:
try:
errors, warnings = do_recreate_all_links()
messages.success(request, _(u'Filesystem links re-creation completed successfully.'))
for warning in warnings:
messages.warning(request, warning)
except Exception, e:
messages.error(request, _(u'Filesystem links re-creation error: %s') % e)
return HttpResponseRedirect(next)