diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 66736bdbf..652e5fe30 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -1,11 +1,13 @@ +import re + import magic from django.utils.text import slugify from rest_framework import serializers from rest_framework.fields import SerializerMethodField from . import bulk_edit -from .models import Correspondent, Tag, Document, Log, DocumentType, \ - SavedView, SavedViewFilterRule +from .models import Correspondent, Tag, Document, DocumentType, \ + SavedView, SavedViewFilterRule, MatchingModel from .parsers import is_mime_type_supported from django.utils.translation import gettext as _ @@ -33,16 +35,27 @@ class DynamicFieldsModelSerializer(serializers.ModelSerializer): self.fields.pop(field_name) -class CorrespondentSerializer(serializers.ModelSerializer): +class MatchingModelSerializer(serializers.ModelSerializer): document_count = serializers.IntegerField(read_only=True) - last_correspondence = serializers.DateTimeField(read_only=True) - def get_slug(self, obj): return slugify(obj.name) slug = SerializerMethodField() + def validate_match(self, match): + if 'matching_algorithm' in self.initial_data and self.initial_data['matching_algorithm'] == MatchingModel.MATCH_REGEX: # NOQA: E501 + try: + re.compile(match) + except Exception as e: + raise serializers.ValidationError(_("Invalid regular expresssion: ") + str(e)) + return match + + +class CorrespondentSerializer(MatchingModelSerializer): + + last_correspondence = serializers.DateTimeField(read_only=True) + class Meta: model = Correspondent fields = ( @@ -57,13 +70,7 @@ class CorrespondentSerializer(serializers.ModelSerializer): ) -class DocumentTypeSerializer(serializers.ModelSerializer): - - document_count = serializers.IntegerField(read_only=True) - - def get_slug(self, obj): - return slugify(obj.name) - slug = SerializerMethodField() +class DocumentTypeSerializer(MatchingModelSerializer): class Meta: model = DocumentType @@ -78,13 +85,7 @@ class DocumentTypeSerializer(serializers.ModelSerializer): ) -class TagSerializer(serializers.ModelSerializer): - - document_count = serializers.IntegerField(read_only=True) - - def get_slug(self, obj): - return slugify(obj.name) - slug = SerializerMethodField() +class TagSerializer(MatchingModelSerializer): class Meta: model = Tag diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py index 7486154e1..cbd10ac71 100644 --- a/src/documents/tests/test_api.py +++ b/src/documents/tests/test_api.py @@ -14,7 +14,7 @@ from rest_framework.test import APITestCase from whoosh.writing import AsyncWriter from documents import index, bulk_edit -from documents.models import Document, Correspondent, DocumentType, Tag, SavedView +from documents.models import Document, Correspondent, DocumentType, Tag, SavedView, MatchingModel from documents.tests.utils import DirectoriesMixin @@ -772,6 +772,41 @@ class TestDocumentApi(DirectoriesMixin, APITestCase): self.assertEqual(response.status_code, 200) self.assertListEqual(response.data, ["test", "test2"]) + def test_invalid_regex_other_algorithm(self): + for endpoint in ['correspondents', 'tags', 'document_types']: + response = self.client.post(f"/api/{endpoint}/", { + "name": "test", + "matching_algorithm": MatchingModel.MATCH_ANY, + "match": "[" + }, format='json') + self.assertEqual(response.status_code, 201, endpoint) + + def test_invalid_regex(self): + for endpoint in ['correspondents', 'tags', 'document_types']: + response = self.client.post(f"/api/{endpoint}/", { + "name": "test", + "matching_algorithm": MatchingModel.MATCH_REGEX, + "match": "[" + }, format='json') + self.assertEqual(response.status_code, 400, endpoint) + + def test_valid_regex(self): + for endpoint in ['correspondents', 'tags', 'document_types']: + response = self.client.post(f"/api/{endpoint}/", { + "name": "test", + "matching_algorithm": MatchingModel.MATCH_REGEX, + "match": "[0-9]" + }, format='json') + self.assertEqual(response.status_code, 201, endpoint) + + def test_regex_no_algorithm(self): + for endpoint in ['correspondents', 'tags', 'document_types']: + response = self.client.post(f"/api/{endpoint}/", { + "name": "test", + "match": "[0-9]" + }, format='json') + self.assertEqual(response.status_code, 201, endpoint) + class TestBulkEdit(DirectoriesMixin, APITestCase): diff --git a/src/locale/en_US/LC_MESSAGES/django.po b/src/locale/en_US/LC_MESSAGES/django.po index cb31bbc8c..c234d5c2a 100644 --- a/src/locale/en_US/LC_MESSAGES/django.po +++ b/src/locale/en_US/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-16 14:52+0100\n" +"POT-Creation-Date: 2021-02-23 12:30+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -346,7 +346,11 @@ msgstr "" msgid "filter rules" msgstr "" -#: documents/serialisers.py:370 +#: documents/serialisers.py:52 +msgid "Invalid regular expresssion: " +msgstr "" + +#: documents/serialisers.py:376 #, python-format msgid "File type %(type)s not supported" msgstr "" @@ -411,7 +415,7 @@ msgstr "" msgid "French" msgstr "" -#: paperless/urls.py:114 +#: paperless/urls.py:118 msgid "Paperless-ng administration" msgstr ""