Add support for deleting the OCR content
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -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)
|
||||
==================
|
||||
|
||||
@@ -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
|
||||
--------
|
||||
|
||||
@@ -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
|
||||
),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user