From d8fda64cd074e9d954b35310b71292d3f313be0d Mon Sep 17 00:00:00 2001 From: Wolf-Bastian Poettner Date: Sat, 1 Feb 2020 20:58:44 +0000 Subject: [PATCH] Tags in filenames can now either be found by key (in case - or _ are used as delimeter) or by index. Added some more tests. --- paperless.conf.example | 3 +- src/documents/models.py | 26 +++++- src/documents/tests/test_file_handling.py | 107 ++++++++++++++++++++-- 3 files changed, 125 insertions(+), 11 deletions(-) diff --git a/paperless.conf.example b/paperless.conf.example index ff96bfe20..a375ae8ba 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -60,7 +60,8 @@ PAPERLESS_EMAIL_SECRET="" # * {title} # * {created} # * {added} -# * {tags[FILTER]} +# * {tag[KEY]} If your tags conform to key_value or key-value +# * {tags[INDEX]} If your tags are strings, select the tag by index # Uniqueness of filenames is ensured, as an incrementing counter is attached # to each filename. #PAPERLESS_FILENAME_FORMAT="" diff --git a/src/documents/models.py b/src/documents/models.py index c52b6ba0a..ae49c1518 100644 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -283,21 +283,39 @@ class Document(models.Model): return self.filename - def many_to_dictionary(self, field): + @staticmethod + def many_to_dictionary(field): + # Converts ManyToManyField to dictionary by assuming, that field + # entries contain an _ or - which will be used as a delimeter mydictionary = dict() + for t in field.all(): + # Find delimeter delimeter = t.name.find('_') + if delimeter is -1: + delimeter = t.name.find('-') + if delimeter is -1: continue key = t.name[:delimeter] value = t.name[delimeter+1:] - mydictionary[key] = slugify(value) + mydictionary[slugify(key)] = slugify(value) return mydictionary + @staticmethod + def many_to_list(field): + # Converts ManyToManyField to list + mylist = list() + + for t in field.all(): + mylist.append(slugify(t)) + + return mylist + def generate_source_filename(self): # Create filename based on configured format if settings.PAPERLESS_FILENAME_FORMAT is not None: @@ -306,8 +324,8 @@ class Document(models.Model): title=slugify(self.title), created=slugify(self.created), added=slugify(self.added), - tags=defaultdict(str, - self.many_to_dictionary(self.tags))) + tag=defaultdict(str, self.many_to_dictionary(self.tags)), + tags=self.many_to_list(self.tags)) else: path = "" diff --git a/src/documents/tests/test_file_handling.py b/src/documents/tests/test_file_handling.py index 30dc8fd81..912d02573 100644 --- a/src/documents/tests/test_file_handling.py +++ b/src/documents/tests/test_file_handling.py @@ -9,7 +9,7 @@ from dateutil import tz from django.test import TestCase, override_settings from django.utils.text import slugify -from ..models import Document, Correspondent +from ..models import Tag, Document, Correspondent from django.conf import settings @@ -41,7 +41,8 @@ class TestDate(TestCase): @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". format(str(uuid4())[:8])) - @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/{correspondent}") + @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + + "{correspondent}") def test_file_renaming(self): document = Document() document.file_type = "pdf" @@ -86,7 +87,8 @@ class TestDate(TestCase): @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". format(str(uuid4())[:8])) - @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/{correspondent}") + @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + + "{correspondent}") def test_document_delete(self): document = Document() document.file_type = "pdf" @@ -109,7 +111,8 @@ class TestDate(TestCase): @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". format(str(uuid4())[:8])) - @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/{correspondent}") + @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + + "{correspondent}") def test_directory_not_empty(self): document = Document() document.file_type = "pdf" @@ -140,10 +143,101 @@ class TestDate(TestCase): "/documents/originals/none/none-0000001.pdftest") os.rmdir(settings.MEDIA_ROOT + "/documents/originals/none") + @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". + format(str(uuid4())[:8])) + @override_settings(PAPERLESS_FILENAME_FORMAT="{tag[type]}") + def test_tags_with_underscore(self): + document = Document() + document.file_type = "pdf" + document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED + document.save() + + # Add tag to document + document.tags.create(name="type_demo") + document.tags.create(name="foo_bar") + document.save() + + # Ensure that filename is properly generated + tmp = document.source_filename + self.assertEqual(document.generate_source_filename(), + "demo-0000001.pdf") + document.create_source_directory() + Path(document.source_path).touch() + + document.delete() @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". format(str(uuid4())[:8])) - @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/{correspondent}/{correspondent}") + @override_settings(PAPERLESS_FILENAME_FORMAT="{tag[type]}") + def test_tags_with_dash(self): + document = Document() + document.file_type = "pdf" + document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED + document.save() + + # Add tag to document + document.tags.create(name="type-demo") + document.tags.create(name="foo-bar") + document.save() + + # Ensure that filename is properly generated + tmp = document.source_filename + self.assertEqual(document.generate_source_filename(), + "demo-0000001.pdf") + document.create_source_directory() + Path(document.source_path).touch() + + document.delete() + + @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". + format(str(uuid4())[:8])) + @override_settings(PAPERLESS_FILENAME_FORMAT="{tag[type]}") + def test_tags_malformed(self): + document = Document() + document.file_type = "pdf" + document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED + document.save() + + # Add tag to document + document.tags.create(name="type:demo") + document.tags.create(name="foo:bar") + document.save() + + # Ensure that filename is properly generated + tmp = document.source_filename + self.assertEqual(document.generate_source_filename(), + "0000001.pdf") + document.create_source_directory() + Path(document.source_path).touch() + + document.delete() + + @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". + format(str(uuid4())[:8])) + @override_settings(PAPERLESS_FILENAME_FORMAT="{tags[0]}") + def test_tags_all(self): + document = Document() + document.file_type = "pdf" + document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED + document.save() + + # Add tag to document + document.tags.create(name="demo") + document.save() + + # Ensure that filename is properly generated + tmp = document.source_filename + self.assertEqual(document.generate_source_filename(), + "demo-0000001.pdf") + document.create_source_directory() + Path(document.source_path).touch() + + document.delete() + + @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". + format(str(uuid4())[:8])) + @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + + "{correspondent}/{correspondent}") def test_nested_directory_cleanup(self): document = Document() document.file_type = "pdf" @@ -164,7 +258,8 @@ class TestDate(TestCase): document.delete() self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + - "/documents/originals/none/none/none-0000001.pdf"), False) + "/documents/originals/none/none/none-0000001.pdf"), + False) self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + "/documents/originals/none/none"), False) self.assertEqual(os.path.isdir(settings.MEDIA_ROOT +