Compare commits

..

1 Commits

Author SHA1 Message Date
Roberto Rosario
d29fb86c55 Initial commit to support filename generators
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-09-25 00:08:32 -04:00
16 changed files with 69 additions and 95 deletions

View File

@@ -233,12 +233,6 @@ and will exhaust the available Postgres connections available if a number
other than 0 is used. Reference: https://serverfault.com/questions/635100/django-conn-max-age-persists-connections-but-doesnt-reuse-them-with-postgresq
and https://github.com/benoitc/gunicorn/issues/996
``MAYAN_GUNICORN_TIMEOUT``
Optional. Changes the amount of time the frontend worker will wait for a
request to finish before raising a timeout error. The default is 120
seconds.
``MAYAN_GUNICORN_WORKERS``
Optional. This environment variable controls the number of frontend workers

View File

@@ -1,31 +0,0 @@
'use strict';
QUnit.test('partialNavigation.filterLocation', function (assert) {
var testPartialNavigation = new PartialNavigation({
initialURL: '/testInitialURL',
});
/*
* For an empty newLocation we expect the fragment of the URL minus the
* query
*/
var expected = new URI(new URI(location).fragment()).path().toString();
assert.strictEqual(
testPartialNavigation.filterLocation(''), expected, 'newLocation === ""');
/*
* For an empty root value we expect initialURL passed to the
* partialNavigation instance when initialized.
*/
assert.strictEqual(
testPartialNavigation.filterLocation('/'), testPartialNavigation.initialURL, 'newLocation === "/"'
);
/*
* For an empty root value we expect initialURL passed to the
* partialNavigation instance when initialized.
*/
assert.strictEqual(
testPartialNavigation.filterLocation('random'), 'random', 'newLocation === "random"'
);
});

View File

@@ -38,7 +38,6 @@
<script src="{% static 'appearance/node_modules/jquery/dist/jquery.min.js' %}" type="text/javascript"></script>
<script src="{% static 'appearance/node_modules/bootstrap/dist/js/bootstrap.min.js' %}" type="text/javascript"></script>
<script src="{% static 'appearance/node_modules/@fortawesome/fontawesome-free/js/all.min.js' %}" data-auto-replace-svg="nest" type="text/javascript"></script>
{% block javascript %}{% endblock %}
</body>
</html>
{% endspaceless %}

View File

@@ -4,12 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.dependencies.classes import (
environment_build, environment_development, environment_testing,
JavaScriptDependency, PythonDependency
)
JavaScriptDependency(
environment=environment_testing, label=_('QUnit'), module=__name__,
name='qunit', version_string='=2.9.2'
PythonDependency
)
PythonDependency(

View File

@@ -1,22 +0,0 @@
{% extends 'appearance/base.html' %}
{% load i18n %}
{% load static %}
{% block base_title %}{% trans 'Qunit' %}{% endblock %}
{% block project_name %}{% endblock %}
{% block stylesheets %}
<link href="{% static 'common/node_modules/qunit/qunit/qunit.css' %}" media="screen" rel="stylesheet" type="text/css" />
{% endblock %}
{% block content %}
<div id="qunit"></div>
<div id="qunit-fixture"></div>
{% endblock %}
{% block javascript %}
<script src="{% static 'common/node_modules/qunit/qunit/qunit.js' %}" type="text/javascript"></script>
<script src="{% static 'appearance/js/test/unit/partial_navigation.js' %}" type="text/javascript"></script>
{% endblock %}

View File

@@ -1 +0,0 @@
TEST FILE SPECIAL CHARACTERS FILENAME

View File

@@ -11,7 +11,6 @@ TEST_VIEW_NAME = 'test view name'
TEST_VIEW_URL = 'test-view-url'
# Filenames
TEST_ARCHIVE_ZIP_SPECIAL_CHARACTERS_FILENAME_MEMBER = 'test_archvive_with_special_characters_filename_member.zip'
TEST_FILENAME1 = 'test_file1.txt'
TEST_FILENAME2 = 'test_file2.txt'
TEST_FILENAME3 = 'test_file3.txt'
@@ -24,10 +23,6 @@ TEST_ZIP_FILE = 'test_file.zip'
TEST_COMPRESSED_FILE_CONTENTS = [TEST_FILENAME1, TEST_FILENAME2]
# File paths
TEST_ARCHIVE_ZIP_SPECIAL_CHARACTERS_FILENAME_MEMBER_PATH = os.path.join(
settings.BASE_DIR, 'apps', 'common', 'tests', 'contrib',
TEST_ARCHIVE_ZIP_SPECIAL_CHARACTERS_FILENAME_MEMBER
)
TEST_FILE3_PATH = os.path.join(
settings.BASE_DIR, 'apps', 'common', 'tests', 'contrib', TEST_FILENAME3
)

View File

@@ -5,7 +5,6 @@ from mayan.apps.common.tests import BaseTestCase
from ..compressed_files import Archive, TarArchive, ZipArchive
from .literals import (
TEST_ARCHIVE_ZIP_SPECIAL_CHARACTERS_FILENAME_MEMBER_PATH,
TEST_COMPRESSED_FILE_CONTENTS, TEST_FILE_CONTENTS_1, TEST_FILE3_PATH,
TEST_FILENAME1, TEST_FILENAME3, TEST_TAR_BZ2_FILE_PATH,
TEST_TAR_FILE_PATH, TEST_TAR_GZ_FILE_PATH, TEST_ZIP_FILE_PATH
@@ -59,11 +58,6 @@ class ZipArchiveClassTestCase(TarArchiveClassTestCase):
archive_path = TEST_ZIP_FILE_PATH
cls = ZipArchive
def test_open_member_with_special_characters_filename(self):
with open(TEST_ARCHIVE_ZIP_SPECIAL_CHARACTERS_FILENAME_MEMBER_PATH, mode='rb') as file_object:
archive = Archive.open(file_object=file_object)
list(archive.get_members())
class TarGzArchiveClassTestCase(TarArchiveClassTestCase):
archive_path = TEST_TAR_GZ_FILE_PATH
@@ -73,5 +67,3 @@ class TarGzArchiveClassTestCase(TarArchiveClassTestCase):
class TarBz2ArchiveClassTestCase(TarArchiveClassTestCase):
archive_path = TEST_TAR_BZ2_FILE_PATH
cls = TarArchive

View File

@@ -10,8 +10,7 @@ from .views import (
AboutView, CurrentUserLocaleProfileDetailsView,
CurrentUserLocaleProfileEditView, FaviconRedirectView, HomeView,
LicenseView, ObjectErrorLogEntryListClearView, ObjectErrorLogEntryListView,
RootView, SetupListView, ToolsListView, QUnitView,
multi_object_action_view
RootView, SetupListView, ToolsListView, multi_object_action_view
)
urlpatterns = [
@@ -44,9 +43,6 @@ urlpatterns = [
view=ObjectErrorLogEntryListClearView.as_view(),
name='object_error_list_clear'
),
url(
regex=r'^qunit/', view=QUnitView.as_view(), name='qunit'
)
]
urlpatterns += [

View File

@@ -276,8 +276,3 @@ def multi_object_action_view(request):
action, urlencode({'id_list': id_list, 'next': next})
)
)
class QUnitView(SimpleView):
extra_context = {'title': _('QUnit tests')}
template_name = 'common/qunit.html'

View File

@@ -0,0 +1,39 @@
from __future__ import absolute_import, unicode_literals
import uuid
from django.utils.translation import ugettext_lazy as _
class BaseDocumentFilenameGenerator(object):
_registry = {}
@classmethod
def get(cls, name):
return cls._registry[name]
@classmethod
def get_choices(cls):
return sorted(
[
(name, klass.label) for name, klass in cls._registry.items()
]
)
@classmethod
def register(cls, klass):
cls._registry[klass.name] = klass
def upload_to(self, instance, filename):
raise NotImplementedError
class UUIDDocumentFilenameGenerator(BaseDocumentFilenameGenerator):
name = 'uuid'
label = _('UUID')
def upload_to(self, instance, filename):
return force_text(uuid.uuid4())
BaseDocumentFilenameGenerator.register(klass=UUIDDocumentFilenameGenerator)

View File

@@ -5,11 +5,20 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls.models import AccessControlList
from ..classes import BaseDocumentFilenameGenerator
from ..models import DocumentType, DocumentTypeFilename
__all__ = ('DocumentTypeFilteredSelectForm', 'DocumentTypeFilenameForm_create')
class DocumentTypeForm(forms.ModelForm):
#filename_generator = forms.
class Meta:
fields = ('label', 'filename_generator')
model = DocumentType
class DocumentTypeFilteredSelectForm(forms.Form):
"""
Form to select the document type of a document to be created. This form

View File

@@ -11,6 +11,7 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls.models import AccessControlList
from mayan.apps.common.literals import TIME_DELTA_UNIT_CHOICES
from ..classes import BaseDocumentFilenameGenerator
from ..events import event_document_type_created, event_document_type_edited
from ..literals import DEFAULT_DELETE_PERIOD, DEFAULT_DELETE_TIME_UNIT
from ..managers import DocumentTypeManager
@@ -52,6 +53,12 @@ class DocumentType(models.Model):
default=DEFAULT_DELETE_TIME_UNIT, max_length=8, null=True,
verbose_name=_('Delete time unit')
)
filename_generator = models.CharField(
help_text=_(
'The class responsible for producing the actual filename used '
'to store the uploaded documents.'
), max_length=128, verbose_name=_('Filename generator')
)
objects = DocumentTypeManager()
@@ -94,6 +101,10 @@ class DocumentType(models.Model):
return queryset.count()
def get_upload_filename(self, instance, filename):
klass = BaseDocumentFilenameGenerator.get(name=self.filename_generator)
return klass.upload_to(instance=instance, filename=filename)
def natural_key(self):
return (self.label,)

View File

@@ -4,7 +4,6 @@ import hashlib
import logging
import os
import shutil
import uuid
from django.apps import apps
from django.core.files.base import ContentFile
@@ -37,8 +36,10 @@ def hash_function():
return hashlib.sha256()
def UUID_FUNCTION(*args, **kwargs):
return force_text(uuid.uuid4())
def upload_to(instance, filename):
return instance.document.document_type.get_upload_filename(
instance=instance, filename=filename
)
@python_2_unicode_compatible
@@ -86,7 +87,7 @@ class DocumentVersion(models.Model):
# File related fields
file = models.FileField(
storage=storage_documentversion, upload_to=UUID_FUNCTION,
storage=storage_documentversion, upload_to=upload_to,
verbose_name=_('File')
)
mimetype = models.CharField(

View File

@@ -82,7 +82,9 @@ class DocumentTypeListView(SingleObjectListView):
class DocumentTypeCreateView(SingleObjectCreateView):
fields = ('label',)
model = DocumentType
post_action_redirect = reverse_lazy(viewname='documents:document_type_list')
post_action_redirect = reverse_lazy(
viewname='documents:document_type_list'
)
view_permission = permission_document_type_create
def get_extra_context(self):