Add support for deleting the OCR content

Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-09-23 16:31:04 -04:00
parent 907e2213e9
commit c9567d0c6d
9 changed files with 152 additions and 47 deletions

View File

@@ -5,6 +5,8 @@
long labels.
* Update Django to version 1.11.24
* Update jQuery to version 3.4.1
* Add support for deleting the OCR content of a document
or selection of documents.
3.2.7 (2019-08-28)
==================

View File

@@ -21,7 +21,8 @@ Other changes
- Add cabinet add and remove workflow actions.
- Update Django to version 1.11.24.
- Update jQuery to version 3.4.1
- Add support for deleting the OCR content of a document
or selection of documents.
Removals
--------

View File

@@ -23,10 +23,11 @@ from .handlers import (
)
from .links import (
link_document_page_ocr_content, link_document_ocr_content,
link_document_ocr_download, link_document_ocr_errors_list,
link_document_submit, link_document_submit_multiple,
link_document_type_ocr_settings, link_document_type_submit,
link_entry_list
link_document_ocr_content_delete,
link_document_ocr_content_delete_multiple, link_document_ocr_download,
link_document_ocr_errors_list, link_document_submit,
link_document_submit_multiple, link_document_type_ocr_settings,
link_document_type_submit, link_entry_list
)
from .methods import (
method_document_ocr_submit, method_document_version_ocr_submit
@@ -131,10 +132,14 @@ class OCRApp(MayanAppConfig):
links=(link_document_type_ocr_settings,), sources=(DocumentType,)
)
menu_multi_item.bind_links(
links=(link_document_submit_multiple,), sources=(Document,)
links=(
link_document_ocr_content_delete_multiple,
link_document_submit_multiple,
), sources=(Document,)
)
menu_secondary.bind_links(
links=(
link_document_ocr_content_delete,
link_document_ocr_errors_list,
link_document_ocr_download, link_document_submit
),

View File

@@ -3,6 +3,11 @@ from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon
icon_document_ocr_content = Icon(driver_name='fontawesome', symbol='font')
icon_document_ocr_content_delete = Icon(
driver_name='fontawesome-dual',
primary_symbol='font',
secondary_symbol='minus'
)
icon_document_page_ocr_content = Icon(driver_name='fontawesome', symbol='font')
icon_document_multiple_submit = Icon(driver_name='fontawesome', symbol='font')
icon_document_ocr_download = Icon(

View File

@@ -21,6 +21,17 @@ link_document_ocr_content = Link(
permissions=(permission_ocr_content_view,), text=_('OCR'),
view='ocr:document_ocr_content',
)
link_document_ocr_content_delete = Link(
args='resolved_object.id',
icon_class_path='mayan.apps.ocr.icons.icon_document_ocr_content_delete',
permissions=(permission_ocr_content_view,), text=_('Delete OCR content'),
view='ocr:document_ocr_content_delete',
)
link_document_ocr_content_delete_multiple = Link(
icon_class_path='mayan.apps.ocr.icons.icon_document_ocr_content_delete',
text=_('Delete OCR content'),
view='ocr:document_ocr_content_delete_multiple',
)
link_document_submit = Link(
args='resolved_object.id',
icon_class_path='mayan.apps.ocr.icons.icon_document_submit',

View File

@@ -6,7 +6,7 @@ import traceback
from django.apps import apps
from django.conf import settings
from django.db import models
from django.db import models, transaction
from mayan.apps.documents.storages import storage_documentimagecache
from mayan.apps.documents.literals import DOCUMENT_IMAGE_TASK_TIMEOUT
@@ -20,6 +20,11 @@ logger = logging.getLogger(__name__)
class DocumentPageOCRContentManager(models.Manager):
def delete_ocr_content_for(self, document):
with transaction.atomic():
for document_page in document.pages.all():
self.filter(document_page=document_page).delete()
def process_document_page(self, document_page):
logger.info(
'Processing page: %d of document version: %s',

View File

@@ -2,6 +2,7 @@ from __future__ import unicode_literals
from mayan.apps.documents.tests import GenericDocumentViewTestCase
from ..models import DocumentPageOCRContent
from ..permissions import (
permission_ocr_content_view, permission_ocr_document,
permission_document_type_ocr_setup
@@ -11,11 +12,7 @@ from ..utils import get_document_ocr_content
from .literals import TEST_DOCUMENT_CONTENT
class OCRViewsTestCase(GenericDocumentViewTestCase):
# PyOCR's leak descriptor in get_available_languages and image_to_string
# Disable descriptor leak test until fixed in upstream
_skip_file_descriptor_test = True
class OCRViewTestMixin(object):
def _request_document_content_view(self):
return self.get(
viewname='ocr:document_ocr_content', kwargs={
@@ -23,6 +20,54 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
}
)
def _request_document_content_delete_view(self):
return self.post(
viewname='ocr:document_ocr_content_delete', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_page_content_view(self):
return self.get(
viewname='ocr:document_page_ocr_content', kwargs={
'pk': self.test_document.pages.first().pk
}
)
def _request_document_submit_view(self):
return self.post(
viewname='ocr:document_submit', kwargs={
'pk': self.test_document.pk
}
)
def _request_multiple_document_submit_view(self):
return self.post(
viewname='ocr:document_submit_multiple',
data={
'id_list': self.test_document.pk,
}
)
def _request_document_ocr_download_view(self):
return self.get(
viewname='ocr:document_ocr_download', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_type_ocr_settings_view(self):
return self.get(
viewname='ocr:document_type_ocr_settings',
kwargs={'pk': self.test_document.document_type.pk}
)
class OCRViewsTestCase(OCRViewTestMixin, GenericDocumentViewTestCase):
# PyOCR's leak descriptor in get_available_languages and image_to_string
# Disable descriptor leak test until fixed in upstream
_skip_file_descriptor_test = True
def test_document_content_view_no_permissions(self):
self.test_document.submit_for_ocr()
@@ -40,11 +85,31 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
response=response, text=TEST_DOCUMENT_CONTENT, status_code=200
)
def _request_document_page_content_view(self):
return self.get(
viewname='ocr:document_page_ocr_content', kwargs={
'pk': self.test_document.pages.first().pk
}
def test_document_content_delete_view_no_permissions(self):
self.test_document.submit_for_ocr()
response = self._request_document_content_delete_view()
self.assertEqual(response.status_code, 404)
self.assertTrue(
DocumentPageOCRContent.objects.filter(
document_page=self.test_document.pages.first()
).exists()
)
def test_document_content_delete_view_with_access(self):
self.test_document.submit_for_ocr()
self.grant_access(
obj=self.test_document, permission=permission_ocr_document
)
response = self._request_document_content_delete_view()
self.assertEqual(response.status_code, 302)
self.assertFalse(
DocumentPageOCRContent.objects.filter(
document_page=self.test_document.pages.first()
).exists()
)
def test_document_page_content_view_no_permissions(self):
@@ -64,13 +129,6 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
response=response, text=TEST_DOCUMENT_CONTENT, status_code=200
)
def _request_document_submit_view(self):
return self.post(
viewname='ocr:document_submit', kwargs={
'pk': self.test_document.pk
}
)
def test_document_submit_view_no_permission(self):
response = self._request_document_submit_view()
self.assertEqual(response.status_code, 404)
@@ -92,14 +150,6 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
)
)
def _request_multiple_document_submit_view(self):
return self.post(
viewname='ocr:document_submit_multiple',
data={
'id_list': self.test_document.pk,
}
)
def test_multiple_document_submit_view_no_permission(self):
response = self._request_multiple_document_submit_view()
self.assertEqual(response.status_code, 404)
@@ -121,13 +171,6 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
)
)
def _request_document_ocr_download_view(self):
return self.get(
viewname='ocr:document_ocr_download', kwargs={
'pk': self.test_document.pk
}
)
def test_document_ocr_download_view_no_permission(self):
self.test_document.submit_for_ocr()
@@ -151,12 +194,6 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
),
)
def _request_document_type_ocr_settings_view(self):
return self.get(
viewname='ocr:document_type_ocr_settings',
kwargs={'pk': self.test_document.document_type.pk}
)
def test_document_type_ocr_settings_view_no_permission(self):
response = self._request_document_type_ocr_settings_view()
self.assertEqual(response.status_code, 404)

View File

@@ -7,7 +7,8 @@ from .api_views import (
APIDocumentVersionOCRView
)
from .views import (
DocumentOCRContentView, DocumentOCRDownloadView,
DocumentOCRContentDeleteView, DocumentOCRContentView,
DocumentOCRDownloadView,
DocumentOCRErrorsListView, DocumentPageOCRContentView, DocumentSubmitView,
DocumentTypeSettingsEditView, DocumentTypeSubmitView, EntryListView
)
@@ -22,6 +23,16 @@ urlpatterns = [
regex=r'^documents/(?P<pk>\d+)/content/$',
view=DocumentOCRContentView.as_view(), name='document_ocr_content'
),
url(
regex=r'^documents/(?P<pk>\d+)/content/delete/$',
view=DocumentOCRContentDeleteView.as_view(),
name='document_ocr_content_delete'
),
url(
regex=r'^documents/multiple/content/delete/$',
view=DocumentOCRContentDeleteView.as_view(),
name='document_ocr_content_delete_multiple'
),
url(
regex=r'^documents/(?P<pk>\d+)/submit/$',
view=DocumentSubmitView.as_view(), name='document_submit'

View File

@@ -15,7 +15,7 @@ from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
from .forms import DocumentPageOCRContentForm, DocumentOCRContentForm
from .models import DocumentVersionOCRError
from .models import DocumentPageOCRContent, DocumentVersionOCRError
from .permissions import (
permission_ocr_content_view, permission_ocr_document,
permission_document_type_ocr_setup
@@ -23,6 +23,34 @@ from .permissions import (
from .utils import get_document_ocr_content
class DocumentOCRContentDeleteView(MultipleObjectConfirmActionView):
model = Document
object_permission = permission_ocr_document
success_message = 'Deleted OCR content of %(count)d document.'
success_message_plural = 'Deleted OCR content of %(count)d documents.'
def get_extra_context(self):
queryset = self.object_list
result = {
'title': ungettext(
singular='Delete the OCR content of the selected document?',
plural='Delete the OCR content of the selected documents?',
number=queryset.count()
)
}
if queryset.count() == 1:
result['object'] = queryset.first()
return result
def object_action(self, form, instance):
DocumentPageOCRContent.objects.delete_ocr_content_for(
document=instance
)
class DocumentOCRContentView(SingleObjectDetailView):
form_class = DocumentOCRContentForm
model = Document