Migration updates

Squash version page migrations.
Add manual OCR and parsing migrations.
Fix tests.
Page search updates.

Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-10-09 16:38:00 -04:00
parent d0ee8aba16
commit 7fbb94a8ae
36 changed files with 449 additions and 269 deletions

View File

@@ -3,13 +3,13 @@ from __future__ import unicode_literals
from django.contrib import admin
from .models import (
DocumentPageContent, DocumentVersionParseError
DocumentVersionPageContent, DocumentVersionParseError
)
@admin.register(DocumentPageContent)
class DocumentPageContentAdmin(admin.ModelAdmin):
list_display = ('document_page',)
@admin.register(DocumentVersionPageContent)
class DocumentVersionPageContentAdmin(admin.ModelAdmin):
list_display = ('document_version_page',)
@admin.register(DocumentVersionParseError)

View File

@@ -8,7 +8,7 @@ from rest_framework.response import Response
from mayan.apps.documents.models import Document
from mayan.apps.rest_api.permissions import MayanPermission
from .models import DocumentPageContent
from .models import DocumentVersionPageContent
from .permissions import permission_content_view
from .serializers import DocumentPageContentSerializer
@@ -41,8 +41,8 @@ class APIDocumentPageContentView(generics.RetrieveAPIView):
try:
content = instance.content
except DocumentPageContent.DoesNotExist:
content = DocumentPageContent.objects.none()
except DocumentVersionPageContent.DoesNotExist:
content = DocumentVersionPageContent.objects.none()
serializer = self.get_serializer(content)
return Response(serializer.data)

View File

@@ -133,7 +133,7 @@ class DocumentParsingApp(MayanAppConfig):
)
document_search.add_model_field(
field='versions__pages__content__content', label=_('Content')
field='pages__content__content', label=_('Content')
)
document_page_search.add_model_field(

View File

@@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext
from mayan.apps.common.widgets import TextAreaDiv
from .models import DocumentPageContent
from .models import DocumentVersionPageContent
class DocumentContentForm(forms.Form):
@@ -29,7 +29,7 @@ class DocumentContentForm(forms.Form):
for page in document_pages:
try:
page_content = page.content.content
except DocumentPageContent.DoesNotExist:
except DocumentVersionPageContent.DoesNotExist:
pass
else:
content.append(conditional_escape(force_text(page_content)))
@@ -73,7 +73,7 @@ class DocumentPageContentForm(forms.Form):
try:
page_content = document_page.content.content
except DocumentPageContent.DoesNotExist:
except DocumentVersionPageContent.DoesNotExist:
pass
else:
content = conditional_escape(force_text(page_content))

View File

@@ -0,0 +1,28 @@
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('document_parsing', '0004_auto_20180917_0645'),
('documents', '0052_rename_document_page'),
]
operations = [
migrations.RenameModel(
'DocumentPageContent', 'DocumentVersionPageContent'
),
migrations.AlterField(
model_name='documentversionpagecontent',
name='document_page',
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
name='document_version_page',
related_name='content',
to='documents.DocumentVersionPage',
verbose_name='Document version page'
),
),
]

View File

@@ -5,20 +5,20 @@ from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from mayan.apps.documents.models import (
DocumentPage, DocumentType, DocumentVersion
DocumentPage, DocumentType, DocumentVersion, DocumentVersionPage
)
from .managers import DocumentPageContentManager, DocumentTypeSettingsManager
@python_2_unicode_compatible
class DocumentPageContent(models.Model):
class DocumentVersionPageContent(models.Model):
"""
This model store's the parsed content of a document page.
"""
document_page = models.OneToOneField(
document_version_page = models.OneToOneField(
on_delete=models.CASCADE, related_name='content',
to=DocumentPage, verbose_name=_('Document page')
to=DocumentVersionPage, verbose_name=_('Document version page')
)
content = models.TextField(
blank=True, help_text=_(
@@ -30,8 +30,8 @@ class DocumentPageContent(models.Model):
objects = DocumentPageContentManager()
class Meta:
verbose_name = _('Document page content')
verbose_name_plural = _('Document pages contents')
verbose_name = _('Document version page content')
verbose_name_plural = _('Document version pages contents')
def __str__(self):
return force_text(self.document_page)

View File

@@ -2,10 +2,10 @@ from __future__ import unicode_literals
from rest_framework import serializers
from .models import DocumentPageContent
from .models import DocumentVersionPageContent
class DocumentPageContentSerializer(serializers.ModelSerializer):
class Meta:
fields = ('content',)
model = DocumentPageContent
model = DocumentVersionPageContent

View File

@@ -7,7 +7,9 @@ from .views import (
DocumentContentView, DocumentContentDeleteView,
DocumentContentDownloadView, DocumentPageContentView,
DocumentParsingErrorsListView, DocumentSubmitView,
DocumentTypeSettingsEditView, DocumentTypeSubmitView, ParseErrorListView
DocumentTypeSettingsEditView, DocumentTypeSubmitView,
DocumentVersionPageContentView,
ParseErrorListView
)
urlpatterns = [
@@ -34,6 +36,11 @@ urlpatterns = [
regex=r'^documents/pages/(?P<pk>\d+)/content/$',
view=DocumentPageContentView.as_view(), name='document_page_content'
),
url(
regex=r'^documents/versions/pages/(?P<pk>\d+)/content/$',
view=DocumentVersionPageContentView.as_view(),
name='document_version_page_content'
),
url(
regex=r'^documents/(?P<pk>\d+)/submit/$',
view=DocumentSubmitView.as_view(), name='document_submit'

View File

@@ -13,11 +13,11 @@ from mayan.apps.common.generics import (
from mayan.apps.common.mixins import ExternalObjectMixin
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
from mayan.apps.documents.models import (
Document, DocumentType, DocumentVersionPage
Document, DocumentPage, DocumentType, DocumentVersionPage
)
from .forms import DocumentContentForm, DocumentPageContentForm
from .models import DocumentPageContent, DocumentVersionParseError
from .models import DocumentVersionPageContent, DocumentVersionParseError
from .permissions import (
permission_content_view, permission_document_type_parsing_setup,
permission_parse_document
@@ -48,7 +48,7 @@ class DocumentContentDeleteView(MultipleObjectConfirmActionView):
return result
def object_action(self, form, instance):
DocumentPageContent.objects.delete_content_for(
DocumentVersionPageContent.objects.delete_content_for(
document=instance, user=self.request.user
)
@@ -89,7 +89,7 @@ class DocumentContentDownloadView(SingleObjectDownloadView):
class DocumentPageContentView(SingleObjectDetailView):
form_class = DocumentPageContentForm
model = DocumentVersionPage
model = DocumentPage
object_permission = permission_content_view
def dispatch(self, request, *args, **kwargs):
@@ -109,6 +109,30 @@ class DocumentPageContentView(SingleObjectDetailView):
}
class DocumentVersionPageContentView(SingleObjectDetailView):
form_class = DocumentPageContentForm
model = DocumentVersionPage
object_permission = permission_content_view
def dispatch(self, request, *args, **kwargs):
result = super(DocumentPageContentView, self).dispatch(
request, *args, **kwargs
)
self.get_object().document.add_as_recent_document_for_user(
request.user
)
return result
def get_extra_context(self):
return {
'hide_labels': True,
'object': self.get_object(),
'title': _(
'Content for document version page: %s'
) % self.get_object(),
}
class DocumentParsingErrorsListView(SingleObjectListView):
view_permission = permission_content_view

View File

@@ -127,6 +127,7 @@ class DocumentsApp(MayanAppConfig):
DocumentType = self.get_model(model_name='DocumentType')
DocumentTypeFilename = self.get_model(model_name='DocumentTypeFilename')
DocumentVersion = self.get_model(model_name='DocumentVersion')
DocumentVersionPage = self.get_model(model_name='DocumentVersionPage')
DuplicatedDocument = self.get_model(model_name='DuplicatedDocument')
DynamicSerializerField.add_serializer(
@@ -228,7 +229,7 @@ class DocumentsApp(MayanAppConfig):
model=Document, manager_name='passthrough'
)
ModelPermission.register_inheritance(
model=DocumentPage, related='document_version__document',
model=DocumentPage, related='document',
)
ModelPermission.register_manager(
model=DocumentPage, manager_name='passthrough'
@@ -245,6 +246,9 @@ class DocumentsApp(MayanAppConfig):
ModelPermission.register_inheritance(
model=DocumentVersion, related='document',
)
ModelPermission.register_inheritance(
model=DocumentVersionPage, related='document_version',
)
# Document and document page thumbnail widget
document_page_thumbnail_widget = DocumentPageThumbnailWidget()

View File

@@ -5,7 +5,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('documents', '0051_documentpage_enabled'),
]
@@ -20,8 +19,20 @@ class Migration(migrations.Migration):
name='document_version',
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name='version_pages', to='documents.DocumentVersion',
related_name='pages', to='documents.DocumentVersion',
verbose_name='Document version'
),
),
migrations.RemoveField(
model_name='documentversionpage',
name='enabled',
),
migrations.AlterModelOptions(
name='documentversionpage',
options={
'ordering': ('page_number',),
'verbose_name': 'Document version page',
'verbose_name_plural': 'Document version pages'
},
),
]

View File

@@ -1,27 +0,0 @@
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('documents', '0052_auto_20191007_1921'),
('ocr', '0008_auto_20180917_0646'),
('document_parsing', '0004_auto_20180917_0645'),
]
operations = [
migrations.CreateModel(
name='DocumentPageResult',
fields=[
],
options={
'verbose_name': 'Document version page',
'verbose_name_plural': 'Document version pages',
'ordering': ('document_version__document', 'page_number'),
'proxy': True,
'indexes': [],
},
bases=('documents.documentversionpage',),
),
]

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.22 on 2019-10-08 21:16
from __future__ import unicode_literals
from django.db import migrations, models
@@ -7,10 +5,9 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('documents', '0054_auto_20191008_1522'),
('documents', '0052_rename_document_page'),
]
operations = [
@@ -25,22 +22,36 @@ class Migration(migrations.Migration):
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pages', to='documents.Document', verbose_name='Document')),
],
options={
'unique_together': set([('document', 'page_number')]),
'verbose_name': 'Document page',
'verbose_name_plural': 'Document pages',
'ordering': ('page_number',),
},
),
migrations.AlterModelOptions(
name='documentversionpage',
options={'ordering': ('page_number',), 'verbose_name': 'Document version page', 'verbose_name_plural': 'Document version pages'},
migrations.CreateModel(
name='DocumentPageResult',
fields=[
],
options={
'verbose_name': 'Document page result',
'verbose_name_plural': 'Document pages result',
'ordering': ('document', 'page_number'),
'proxy': True,
'indexes': [],
},
bases=('documents.documentpage',),
),
migrations.AlterField(
model_name='documentversionpage',
name='document_version',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pages', to='documents.DocumentVersion', verbose_name='Document version'),
),
migrations.AlterUniqueTogether(
name='documentpage',
unique_together=set([('document', 'page_number')]),
migrations.CreateModel(
name='DocumentVersionPageResult',
fields=[
],
options={
'verbose_name': 'Document version page',
'verbose_name_plural': 'Document version pages',
'ordering': ('document_version__document', 'page_number'),
'proxy': True,
'indexes': [],
},
bases=('documents.documentversionpage',),
),
]

View File

@@ -1,31 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.22 on 2019-10-08 15:22
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('documents', '0053_auto_20191007_1922'),
]
operations = [
migrations.DeleteModel(
name='DocumentPageResult',
),
migrations.CreateModel(
name='DocumentVersionPageResult',
fields=[
],
options={
'verbose_name': 'Document version page',
'verbose_name_plural': 'Document version pages',
'ordering': ('document_version__document', 'page_number'),
'proxy': True,
'indexes': [],
},
bases=('documents.documentversionpage',),
),
]

View File

@@ -0,0 +1,62 @@
from __future__ import unicode_literals
from django.db import migrations
def get_latest_version(document):
return document.versions.order_by('timestamp').last()
def operation_reset_document_pages(apps, schema_editor):
Document = apps.get_model(app_label='documents', model_name='Document')
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
# Define inside the function to use the migration's apps instance
def pages_reset(document):
ContentType = apps.get_model('contenttypes', 'ContentType')
DocumentVersionPage = apps.get_model(
app_label='documents', model_name='DocumentVersionPage'
)
content_type = ContentType.objects.get_for_model(
model=DocumentVersionPage
)
for document_page in document.pages.all():
document_page.delete()
for version_page in get_latest_version(document=document).pages.all():
document_page = document.pages.create(
content_type=content_type,
page_number=version_page.page_number,
object_id=version_page.pk,
)
for document in Document.objects.using(schema_editor.connection.alias).all():
pages_reset(document=document)
def operation_reset_document_pages_reverse(apps, schema_editor):
Document = apps.get_model(app_label='documents', model_name='Document')
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
for document in Document.objects.using(schema_editor.connection.alias).all():
for document_page in document.pages.all():
document_page.delete()
class Migration(migrations.Migration):
dependencies = [
('documents', '0053_create_document_page_and_result_models'),
]
operations = [
migrations.RunPython(
code=operation_reset_document_pages,
reverse_code=operation_reset_document_pages_reverse
),
]

View File

@@ -116,6 +116,14 @@ class Document(models.Model):
)
return partition
@property
def checksum(self):
return self.latest_version.checksum
@property
def date_updated(self):
return self.latest_version.timestamp
def delete(self, *args, **kwargs):
to_trash = kwargs.pop('to_trash', True)
@@ -140,6 +148,14 @@ class Document(models.Model):
else:
return False
@property
def file_mime_encoding(self):
return self.latest_version.encoding
@property
def file_mimetype(self):
return self.latest_version.mimetype
def get_absolute_url(self):
return reverse(
viewname='documents:document_preview', kwargs={'pk': self.pk}
@@ -154,6 +170,10 @@ class Document(models.Model):
def is_in_trash(self):
return self.in_trash
@property
def latest_version(self):
return self.versions.order_by('timestamp').last()
def natural_key(self):
return (self.uuid,)
natural_key.dependencies = ['documents.DocumentType']
@@ -171,8 +191,6 @@ class Document(models.Model):
logger.info('New document version queued for document: %s', self)
self.reset_pages(update_page_count=False)
return document_version
def open(self, *args, **kwargs):
@@ -197,7 +215,7 @@ class Document(models.Model):
)
return DocumentPage.passthrough.filter(document=self)
def reset_pages(self, update_page_count=True):
def pages_reset(self, update_page_count=True):
with transaction.atomic():
for page in self.pages.all():
page.delete()
@@ -254,25 +272,3 @@ class Document(models.Model):
@property
def size(self):
return self.latest_version.size
# Compatibility methods
@property
def checksum(self):
return self.latest_version.checksum
@property
def date_updated(self):
return self.latest_version.timestamp
@property
def file_mime_encoding(self):
return self.latest_version.encoding
@property
def file_mimetype(self):
return self.latest_version.mimetype
@property
def latest_version(self):
return self.versions.order_by('timestamp').last()

View File

@@ -29,9 +29,8 @@ from ..settings import (
)
from .document_models import Document
#from .document_version_page_models import DocumentVersionPage
__all__ = ('DocumentPage',)# 'DocumentPageResult')
__all__ = ('DocumentPage', 'DocumentPageResult')
logger = logging.getLogger(__name__)
@@ -301,9 +300,9 @@ class DocumentPage(models.Model):
return '{}-{}'.format(self.document.uuid, self.pk)
#class DocumentVersionPageResult(DocumentVersionPage):
# class Meta:
# ordering = ('document_version__document', 'page_number')
# proxy = True
# verbose_name = _('Document version page')
# verbose_name_plural = _('Document version pages')
class DocumentPageResult(DocumentPage):
class Meta:
ordering = ('document', 'page_number')
proxy = True
verbose_name = _('Document page result')
verbose_name_plural = _('Document pages result')

View File

@@ -246,12 +246,12 @@ class DocumentVersion(models.Model):
return result
@property
def page_count(self):
"""
The number of pages that the document posses.
"""
return self.pages.count()
#@property
#def page_count(self):
# """
# The number of pages that the document posses.
# """
# return self.pages.count()
def revert(self, _user=None):
"""
@@ -326,6 +326,8 @@ class DocumentVersion(models.Model):
sender=Document, instance=self.document
)
self.document.pages_reset(update_page_count=False)
def save_to_file(self, file_object):
"""
Save a copy of the document from the document storage backend

View File

@@ -41,14 +41,12 @@ class DocumentVersionPage(models.Model):
on_delete=models.CASCADE, related_name='pages', to=DocumentVersion,
verbose_name=_('Document version')
)
enabled = models.BooleanField(default=True, verbose_name=_('Enabled'))
page_number = models.PositiveIntegerField(
db_index=True, default=1, editable=False,
verbose_name=_('Page number')
)
objects = DocumentVersionPageManager()
#passthrough = models.Manager()
class Meta:
ordering = ('page_number',)
@@ -261,11 +259,11 @@ class DocumentVersionPage(models.Model):
return (self.page_number, self.document_version.natural_key())
natural_key.dependencies = ['documents.DocumentVersion']
#@property
#def siblings(self):
# return DocumentVersionPage.objects.filter(
# document_version=self.document_version
# )
@property
def siblings(self):
return DocumentVersionPage.objects.filter(
document_version=self.document_version
)
@property
def uuid(self):

View File

@@ -71,7 +71,7 @@ queue_tools.add_task_type(
)
queue_uploads.add_task_type(
dotted_path='mayan.apps.documents.tasks.task_document_reset_pages',
dotted_path='mayan.apps.documents.tasks.task_document_pages_reset',
label=_('Reset document pages')
)
queue_uploads.add_task_type(

View File

@@ -17,12 +17,20 @@ def transformation_format_uuid(term_string):
return term_string
def get_queryset_page_search_queryset():
def get_queryset_document_page_search_queryset():
# Ignore documents in trash can
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
return DocumentPage.objects.filter(document__in_trash=False)
def get_queryset_document_version_page_search_queryset():
# Ignore documents in trash can
DocumentVersionPage = apps.get_model(
app_label='documents', model_name='DocumentVersionPage'
)
return DocumentPage.objects.filter(document_version__document__in_trash=False)
return DocumentVersionPage.objects.filter(document_version__document__in_trash=False)
document_search = SearchModel(
@@ -49,25 +57,50 @@ document_search.add_model_field(
document_page_search = SearchModel(
app_label='documents', list_mode=LIST_MODE_CHOICE_ITEM,
model_name='DocumentVersionPage', permission=permission_document_view,
queryset=get_queryset_page_search_queryset,
model_name='DocumentPage', permission=permission_document_view,
queryset=get_queryset_document_page_search_queryset,
serializer_path='mayan.apps.documents.serializers.DocumentPageSerializer'
)
document_version_page_search = SearchModel(
app_label='documents', list_mode=LIST_MODE_CHOICE_ITEM,
model_name='DocumentVersionPage', permission=permission_document_view,
queryset=get_queryset_document_version_page_search_queryset,
serializer_path='mayan.apps.documents.serializers.DocumentPageVersionSerializer'
)
document_page_search.add_model_field(
field='document_version__document__document_type__label',
field='document__document_type__label',
label=_('Document type')
)
document_page_search.add_model_field(
field='document_version__document__versions__mimetype',
field='document__versions__mimetype',
label=_('MIME type')
)
document_page_search.add_model_field(
field='document__label', label=_('Label')
)
document_page_search.add_model_field(
field='document__description', label=_('Description')
)
document_page_search.add_model_field(
field='document__document_version__checksum', label=_('Checksum')
)
document_version_page_search.add_model_field(
field='document_version__document__document_type__label',
label=_('Document type')
)
document_version_page_search.add_model_field(
field='document_version__document__versions__mimetype',
label=_('MIME type')
)
document_version_page_search.add_model_field(
field='document_version__document__label', label=_('Label')
)
document_page_search.add_model_field(
document_version_page_search.add_model_field(
field='document_version__document__description', label=_('Description')
)
document_page_search.add_model_field(
document_version_page_search.add_model_field(
field='document_version__checksum', label=_('Checksum')
)

View File

@@ -66,7 +66,7 @@ def task_delete_stubs():
@app.task(bind=True, default_retry_delay=RETRY_DELAY_DOCUMENT_RESET_PAGES, ignore_result=True)
def task_document_reset_pages(self, document_id):
def task_document_pages_reset(self, document_id):
Document = apps.get_model(
app_label='documents', model_name='Document'
)
@@ -74,7 +74,7 @@ def task_document_reset_pages(self, document_id):
document = Document.objects.get(pk=document_id)
try:
document.reset_pages()
document.pages_reset()
except OperationalError as exception:
logger.warning(
'Operational error during attempt to reset pages for '

View File

@@ -70,6 +70,7 @@ class DocumentTestMixin(object):
self.test_document = document
self.test_documents.append(document)
self.test_document_version = document.latest_version
self.test_document_page = document.pages_all.first()
class DocumentTypeViewTestMixin(object):
@@ -264,4 +265,3 @@ class DocumentViewTestMixin(object):
def _request_empty_trash_view(self):
return self.post(viewname='documents:trash_can_empty')

View File

@@ -530,8 +530,7 @@ class DocumentPageAPIViewTestMixin(object):
page = self.test_document.pages.first()
return self.get(
viewname='rest_api:documentpage-image', kwargs={
'pk': page.document.pk, 'version_pk': page.document_version.pk,
'page_pk': page.pk
'pk': page.document.pk, 'page_pk': page.pk
}
)
@@ -552,6 +551,33 @@ class DocumentPageAPIViewTestCase(
self.assertEqual(response.status_code, status.HTTP_200_OK)
class DocumentVersionPageAPIViewTestMixin(object):
def _request_document_version_page_image(self):
page = self.test_document_version.pages.first()
return self.get(
viewname='rest_api:documentversionpage-image', kwargs={
'pk': page.document.pk, 'version_pk': page.document_version.pk,
'page_pk': page.pk
}
)
class DocumentVersionPageAPIViewTestCase(
DocumentVersionPageAPIViewTestMixin, DocumentTestMixin, BaseAPITestCase
):
def test_document_version_page_api_image_view_no_access(self):
response = self._request_document_version_page_image()
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_document_version_page_api_image_view_with_access(self):
self.grant_access(
obj=self.test_document, permission=permission_document_view
)
response = self._request_document_version_page_image()
self.assertEqual(response.status_code, status.HTTP_200_OK)
class TrashedDocumentAPIViewTestMixin(object):
def _request_test_document_api_trash_view(self):
return self.delete(
@@ -580,7 +606,6 @@ class TrashedDocumentAPIViewTestMixin(object):
return self.get(
viewname='rest_api:documentpage-image', kwargs={
'pk': latest_version.document.pk,
'version_pk': latest_version.pk,
'page_pk': latest_version.pages.first().pk
}
)

View File

@@ -9,10 +9,10 @@ from ..permissions import (
from .base import GenericDocumentViewTestCase
class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DocumentPageDisableViewTestCase, self).setUp()
self.test_document_page = self.test_document.pages_all.first()
class DocumentPageDisableViewTestMixin(object):
def _disable_test_document_page(self):
self.test_document_page.enabled = False
self.test_document_page.save()
def _request_test_document_page_disable_view(self):
return self.post(
@@ -21,6 +21,31 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
}
)
def _request_test_document_page_enable_view(self):
return self.post(
viewname='documents:document_page_enable', kwargs={
'pk': self.test_document_page.pk
}
)
def _request_test_document_page_multiple_disable_view(self):
return self.post(
viewname='documents:document_page_multiple_disable', data={
'id_list': self.test_document_page.pk
}
)
def _request_test_document_page_multiple_enable_view(self):
return self.post(
viewname='documents:document_page_multiple_enable', data={
'id_list': self.test_document_page.pk
}
)
class DocumentPageDisableViewTestCase(
DocumentPageDisableViewTestMixin, GenericDocumentViewTestCase
):
def test_document_page_disable_view_no_permission(self):
test_document_page_count = self.test_document.pages.count()
@@ -45,13 +70,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count()
)
def _request_test_document_page_multiple_disable_view(self):
return self.post(
viewname='documents:document_page_multiple_disable', data={
'id_list': self.test_document_page.pk
}
)
def test_document_page_multiple_disable_view_no_permission(self):
test_document_page_count = self.test_document.pages.count()
@@ -76,17 +94,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count()
)
def _disable_test_document_page(self):
self.test_document_page.enabled = False
self.test_document_page.save()
def _request_test_document_page_enable_view(self):
return self.post(
viewname='documents:document_page_enable', kwargs={
'pk': self.test_document_page.pk
}
)
def test_document_page_enable_view_no_permission(self):
self._disable_test_document_page()
@@ -114,13 +121,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count()
)
def _request_test_document_page_multiple_enable_view(self):
return self.post(
viewname='documents:document_page_multiple_enable', data={
'id_list': self.test_document_page.pk
}
)
def test_document_page_multiple_enable_view_no_permission(self):
self._disable_test_document_page()
test_document_page_count = self.test_document.pages.count()
@@ -148,7 +148,7 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
)
class DocumentPageViewTestCase(GenericDocumentViewTestCase):
class DocumentPageViewTestMixin(object):
def _request_test_document_page_list_view(self):
return self.get(
viewname='documents:document_pages', kwargs={
@@ -156,6 +156,18 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
}
)
def _request_test_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'pk': document_page.pk,
}
)
class DocumentPageViewTestCase(
DocumentPageViewTestMixin, GenericDocumentViewTestCase
):
def test_document_page_list_view_no_permission(self):
response = self._request_test_document_page_list_view()
self.assertEqual(response.status_code, 404)
@@ -170,13 +182,6 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
response=response, text=self.test_document.label, status_code=200
)
def _request_test_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'pk': document_page.pk,
}
)
def test_document_page_view_no_permissions(self):
response = self._request_test_document_page_view(
document_page=self.test_document.pages.first()

View File

@@ -1,9 +1,11 @@
from __future__ import unicode_literals
from mayan.apps.common.tests.base import BaseTestCase
from mayan.apps.documents.permissions import permission_document_view
from mayan.apps.documents.search import document_search, document_page_search
from mayan.apps.documents.tests.mixins import DocumentTestMixin
from ..permissions import permission_document_view
from ..search import document_search, document_page_search
from .mixins import DocumentTestMixin
class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase):

View File

@@ -9,7 +9,7 @@ from ..permissions import (
from .base import GenericDocumentViewTestCase
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
class TrashedDocumentTestMixin(object):
def _request_document_restore_get_view(self):
return self.get(
viewname='documents:document_restore', kwargs={
@@ -17,6 +17,46 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
}
)
def _request_document_restore_post_view(self):
return self.post(
viewname='documents:document_restore', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_trash_get_view(self):
return self.get(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_trash_post_view(self):
return self.post(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def _request_trashed_document_delete_get_view(self):
return self.get(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def _request_trashed_document_delete_post_view(self):
return self.post(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def _request_trashed_document_list_view(self):
return self.get(viewname='documents:document_list_deleted')
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
def test_document_restore_get_view_no_permission(self):
self.test_document.delete()
self.assertEqual(Document.objects.count(), 0)
@@ -43,13 +83,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(Document.objects.count(), document_count)
def _request_document_restore_post_view(self):
return self.post(
viewname='documents:document_restore', kwargs={
'pk': self.test_document.pk
}
)
def test_document_restore_post_view_no_permission(self):
self.test_document.delete()
self.assertEqual(Document.objects.count(), 0)
@@ -74,13 +107,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 1)
def _request_document_trash_get_view(self):
return self.get(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def test_document_trash_get_view_no_permissions(self):
document_count = Document.objects.count()
@@ -101,13 +127,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(Document.objects.count(), document_count)
def _request_document_trash_post_view(self):
return self.post(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def test_document_trash_post_view_no_permissions(self):
response = self._request_document_trash_post_view()
self.assertEqual(response.status_code, 404)
@@ -126,13 +145,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(DeletedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0)
def _request_document_delete_get_view(self):
return self.get(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def test_document_delete_get_view_no_permissions(self):
self.test_document.delete()
self.assertEqual(Document.objects.count(), 0)
@@ -140,7 +152,7 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
trashed_document_count = DeletedDocument.objects.count()
response = self._request_document_delete_get_view()
response = self._request_trashed_document_delete_get_view()
self.assertEqual(response.status_code, 404)
self.assertEqual(
@@ -158,26 +170,19 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
trashed_document_count = DeletedDocument.objects.count()
response = self._request_document_delete_get_view()
response = self._request_trashed_document_delete_get_view()
self.assertEqual(response.status_code, 200)
self.assertEqual(
DeletedDocument.objects.count(), trashed_document_count
)
def _request_document_delete_post_view(self):
return self.post(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def test_document_delete_post_view_no_permissions(self):
self.test_document.delete()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
response = self._request_document_delete_post_view()
response = self._request_trashed_document_delete_post_view()
self.assertEqual(response.status_code, 404)
self.assertEqual(Document.objects.count(), 0)
@@ -192,19 +197,16 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
obj=self.test_document, permission=permission_document_delete
)
response = self._request_document_delete_post_view()
response = self._request_trashed_document_delete_post_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0)
def _request_document_list_deleted_view(self):
return self.get(viewname='documents:document_list_deleted')
def test_deleted_document_list_view_no_permissions(self):
self.test_document.delete()
response = self._request_document_list_deleted_view()
response = self._request_trashed_document_list_view()
self.assertNotContains(
response=response, text=self.test_document.label, status_code=200
)
@@ -216,7 +218,7 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
obj=self.test_document, permission=permission_document_view
)
response = self._request_document_list_deleted_view()
response = self._request_trashed_document_list_view()
self.assertContains(
response=response, text=self.test_document.label, status_code=200
)

View File

@@ -44,7 +44,7 @@ from ..permissions import (
from ..settings import (
setting_print_width, setting_print_height, setting_recent_added_count
)
from ..tasks import task_document_reset_pages
from ..tasks import task_document_pages_reset
from ..utils import parse_range
__all__ = (
@@ -450,7 +450,7 @@ class DocumentPagesResetView(MultipleObjectConfirmActionView):
def object_action(self, form, instance):
latest_version = instance.latest_version
if latest_version:
task_document_reset_pages.apply_async(
task_document_pages_reset.apply_async(
kwargs={'document_id': instance.pk}
)
else:

View File

@@ -3,13 +3,14 @@ from __future__ import unicode_literals
from django.contrib import admin
from .models import (
DocumentPageOCRContent, DocumentTypeSettings, DocumentVersionOCRError
DocumentTypeSettings, DocumentVersionPageOCRContent,
DocumentVersionOCRError
)
@admin.register(DocumentPageOCRContent)
class DocumentPageOCRContentAdmin(admin.ModelAdmin):
list_display = ('document_page',)
@admin.register(DocumentVersionPageOCRContent)
class DocumentVersionPageOCRContentAdmin(admin.ModelAdmin):
list_display = ('document_version_page',)
@admin.register(DocumentTypeSettings)

View File

@@ -8,7 +8,7 @@ from rest_framework.response import Response
from mayan.apps.documents.models import Document, DocumentVersion
from mayan.apps.rest_api.permissions import MayanPermission
from .models import DocumentPageOCRContent
from .models import DocumentVersionPageOCRContent
from .permissions import permission_ocr_content_view, permission_ocr_document
from .serializers import DocumentPageOCRContentSerializer
@@ -90,8 +90,8 @@ class APIDocumentPageOCRContentView(generics.RetrieveAPIView):
try:
ocr_content = instance.ocr_content
except DocumentPageOCRContent.DoesNotExist:
ocr_content = DocumentPageOCRContent.objects.none()
except DocumentVersionPageOCRContent.DoesNotExist:
ocr_content = DocumentVersionPageOCRContent.objects.none()
serializer = self.get_serializer(ocr_content)
return Response(serializer.data)

View File

@@ -128,7 +128,7 @@ class OCRApp(MayanAppConfig):
)
document_search.add_model_field(
field='versions__version_pages__ocr_content__content', label=_('OCR')
field='pages__ocr_content__content', label=_('OCR')
)
document_page_search.add_model_field(

View File

@@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext
from mayan.apps.common.widgets import TextAreaDiv
from .models import DocumentPageOCRContent
from .models import DocumentVersionPageOCRContent
class DocumentPageOCRContentForm(forms.Form):
@@ -30,7 +30,7 @@ class DocumentPageOCRContentForm(forms.Form):
try:
page_content = page.ocr_content.content
except DocumentPageOCRContent.DoesNotExist:
except DocumentVersionPageOCRContent.DoesNotExist:
pass
else:
content = conditional_escape(force_text(page_content))
@@ -66,7 +66,7 @@ class DocumentOCRContentForm(forms.Form):
for page in document_pages:
try:
page_content = page.ocr_content.content
except DocumentPageOCRContent.DoesNotExist:
except DocumentVersionPageOCRContent.DoesNotExist:
pass
else:
content.append(conditional_escape(force_text(page_content)))

View File

@@ -0,0 +1,28 @@
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('ocr', '0008_auto_20180917_0646'),
('documents', '0052_rename_document_page'),
]
operations = [
migrations.RenameModel(
'DocumentPageOCRContent', 'DocumentVersionPageOCRContent'
),
migrations.AlterField(
model_name='documentversionpageocrcontent',
name='document_page',
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
name='document_version_page',
related_name='ocr_content',
to='documents.DocumentVersionPage',
verbose_name='Document version page'
),
),
]

View File

@@ -5,7 +5,7 @@ from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from mayan.apps.documents.models import (
DocumentPage, DocumentType, DocumentVersion
DocumentPage, DocumentType, DocumentVersion, DocumentVersionPage
)
from .managers import (
@@ -38,13 +38,13 @@ class DocumentTypeSettings(models.Model):
@python_2_unicode_compatible
class DocumentPageOCRContent(models.Model):
class DocumentVersionPageOCRContent(models.Model):
"""
This model stores the OCR results for a document page.
"""
document_page = models.OneToOneField(
document_version_page = models.OneToOneField(
on_delete=models.CASCADE, related_name='ocr_content',
to=DocumentPage, verbose_name=_('Document page')
to=DocumentVersionPage, verbose_name=_('Document version page')
)
content = models.TextField(
blank=True, help_text=_(
@@ -55,8 +55,8 @@ class DocumentPageOCRContent(models.Model):
objects = DocumentPageOCRContentManager()
class Meta:
verbose_name = _('Document page OCR content')
verbose_name_plural = _('Document pages OCR contents')
verbose_name = _('Document version page OCR content')
verbose_name_plural = _('Document version pages OCR contents')
def __str__(self):
return force_text(self.document_page)

View File

@@ -2,10 +2,10 @@ from __future__ import unicode_literals
from rest_framework import serializers
from .models import DocumentPageOCRContent
from .models import DocumentVersionPageOCRContent
class DocumentPageOCRContentSerializer(serializers.ModelSerializer):
class Meta:
fields = ('content',)
model = DocumentPageOCRContent
model = DocumentVersionPageOCRContent

View File

@@ -17,7 +17,7 @@ from mayan.apps.documents.models import (
)
from .forms import DocumentPageOCRContentForm, DocumentOCRContentForm
from .models import DocumentPageOCRContent, DocumentVersionOCRError
from .models import DocumentVersionPageOCRContent, DocumentVersionOCRError
from .permissions import (
permission_ocr_content_view, permission_ocr_document,
permission_document_type_ocr_setup
@@ -48,7 +48,7 @@ class DocumentOCRContentDeleteView(MultipleObjectConfirmActionView):
return result
def object_action(self, form, instance):
DocumentPageOCRContent.objects.delete_content_for(
DocumentVersionPageOCRContent.objects.delete_content_for(
document=instance, user=self.request.user
)