mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	unified data folders
This commit is contained in:
		| @@ -20,9 +20,6 @@ class Command(BaseCommand): | ||||
|     consumption directory, and fetch any mail available. | ||||
|     """ | ||||
|  | ||||
|     ORIGINAL_DOCS = os.path.join(settings.MEDIA_ROOT, "documents", "originals") | ||||
|     THUMB_DOCS = os.path.join(settings.MEDIA_ROOT, "documents", "thumbnails") | ||||
|  | ||||
|     def __init__(self, *args, **kwargs): | ||||
|  | ||||
|         self.verbosity = 0 | ||||
| @@ -79,7 +76,7 @@ class Command(BaseCommand): | ||||
|         except (ConsumerError, MailFetcherError) as e: | ||||
|             raise CommandError(e) | ||||
|  | ||||
|         for d in (self.ORIGINAL_DOCS, self.THUMB_DOCS): | ||||
|         for d in (settings.ORIGINALS_DIR, settings.THUMBNAIL_DIR): | ||||
|             os.makedirs(d, exist_ok=True) | ||||
|  | ||||
|         logging.getLogger(__name__).info( | ||||
|   | ||||
| @@ -196,9 +196,7 @@ class Document(models.Model): | ||||
|             file_name += ".gpg" | ||||
|  | ||||
|         return os.path.join( | ||||
|             settings.MEDIA_ROOT, | ||||
|             "documents", | ||||
|             "originals", | ||||
|             settings.ORIGINALS_DIR, | ||||
|             file_name | ||||
|         ) | ||||
|  | ||||
| @@ -222,9 +220,7 @@ class Document(models.Model): | ||||
|             file_name += ".gpg" | ||||
|  | ||||
|         return os.path.join( | ||||
|             settings.MEDIA_ROOT, | ||||
|             "documents", | ||||
|             "thumbnails", | ||||
|             settings.THUMBNAIL_DIR, | ||||
|             file_name | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -1,559 +0,0 @@ | ||||
| import datetime | ||||
| import os | ||||
| import shutil | ||||
| from unittest import mock | ||||
| from uuid import uuid4 | ||||
| from pathlib import Path | ||||
| from shutil import rmtree | ||||
|  | ||||
| from dateutil import tz | ||||
| from django.test import TestCase, override_settings | ||||
|  | ||||
| from django.utils.text import slugify | ||||
| from ..models import Tag, Document, Correspondent | ||||
| from django.conf import settings | ||||
|  | ||||
|  | ||||
| class TestDate(TestCase): | ||||
|     deletion_list = [] | ||||
|  | ||||
|     def add_to_deletion_list(self, dirname): | ||||
|         self.deletion_list.append(dirname) | ||||
|  | ||||
|     def setUp(self): | ||||
|         folder = "/tmp/paperless-tests-{}".format(str(uuid4())[:8]) | ||||
|         os.makedirs(folder + "/documents/originals") | ||||
|         storage_override = override_settings(MEDIA_ROOT=folder) | ||||
|         storage_override.enable() | ||||
|         self.add_to_deletion_list(folder) | ||||
|  | ||||
|     def tearDown(self): | ||||
|         for dirname in self.deletion_list: | ||||
|             shutil.rmtree(dirname, ignore_errors=True) | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="") | ||||
|     def test_source_filename(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         self.assertEqual(document.source_filename, "0000001.pdf") | ||||
|  | ||||
|         document.filename = "test.pdf" | ||||
|         self.assertEqual(document.source_filename, "test.pdf") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="") | ||||
|     def test_generate_source_filename(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         self.assertEqual(document.generate_source_filename(), "0000001.pdf") | ||||
|  | ||||
|         document.storage_type = Document.STORAGE_TYPE_GPG | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "0000001.pdf.gpg") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_file_renaming(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Test source_path | ||||
|         self.assertEqual(document.source_path, settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf") | ||||
|  | ||||
|         # Enable encryption and check again | ||||
|         document.storage_type = Document.STORAGE_TYPE_GPG | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf.gpg") | ||||
|         document.save() | ||||
|  | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), True) | ||||
|  | ||||
|         # Set a correspondent and save the document | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="test")[0] | ||||
|         document.save() | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/test"), True) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), False) | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/test/test-0000001.pdf.gpg"), True) | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "test/test-0000001.pdf.gpg") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_file_renaming_missing_permissions(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Test source_path | ||||
|         self.assertEqual(document.source_path, settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf") | ||||
|  | ||||
|         # Make the folder read- and execute-only (no writing and no renaming) | ||||
|         os.chmod(settings.MEDIA_ROOT + "/documents/originals/none", 0o555) | ||||
|  | ||||
|         # Set a correspondent and save the document | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="test")[0] | ||||
|         document.save() | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/none/none-0000001.pdf"), True) | ||||
|         self.assertEqual(document.source_filename, | ||||
|                          "none/none-0000001.pdf") | ||||
|  | ||||
|         os.chmod(settings.MEDIA_ROOT + "/documents/originals/none", 0o777) | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_document_delete(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Ensure file deletion after delete | ||||
|         document.delete() | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf"), False) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), False) | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_document_delete_nofile(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_directory_not_empty(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|         Path(document.source_path + "test").touch() | ||||
|  | ||||
|         # Set a correspondent and save the document | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="test")[0] | ||||
|         document.save() | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/test"), True) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), True) | ||||
|  | ||||
|         # Cleanup | ||||
|         os.remove(settings.MEDIA_ROOT + | ||||
|                   "/documents/originals/none/none-0000001.pdftest") | ||||
|         os.rmdir(settings.MEDIA_ROOT + "/documents/originals/none") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{tags[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(PAPERLESS_FILENAME_FORMAT="{tags[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(PAPERLESS_FILENAME_FORMAT="{tags[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(), | ||||
|                          "none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|     @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(PAPERLESS_FILENAME_FORMAT="{tags[0]}") | ||||
|     def test_tags_out_of_bounds_0(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{tags[10000000]}") | ||||
|     def test_tags_out_of_bounds_10000000(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{tags[99]}") | ||||
|     def test_tags_out_of_bounds_99(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}/{correspondent}") | ||||
|     def test_nested_directory_cleanup(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none"), True) | ||||
|  | ||||
|         document.delete() | ||||
|  | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + | ||||
|                          "/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 + | ||||
|                          "/documents/originals/none"), False) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals"), True) | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT=None) | ||||
|     def test_format_none(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         self.assertEqual(document.generate_source_filename(), "0000001.pdf") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_document_renamed(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Test source_path | ||||
|         self.assertEqual(document.source_path, settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf") | ||||
|  | ||||
|         # Rename the document "illegaly" | ||||
|         os.makedirs(settings.MEDIA_ROOT + "/documents/originals/test") | ||||
|         os.rename(settings.MEDIA_ROOT + "/documents/originals/" + | ||||
|                                         "none/none-0000001.pdf", | ||||
|                   settings.MEDIA_ROOT + "/documents/originals/" + | ||||
|                                         "test/test-0000001.pdf") | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/test/test-0000001.pdf"), True) | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/none/none-0000001.pdf"), False) | ||||
|  | ||||
|         # Set new correspondent and expect document to be saved properly | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="foo")[0] | ||||
|         document.save() | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/foo/foo-0000001.pdf"), True) | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/foo"), True) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), False) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/test"), False) | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "foo/foo-0000001.pdf") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_document_renamed_encrypted(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_GPG | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf.gpg") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Test source_path | ||||
|         self.assertEqual(document.source_path, settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf.gpg") | ||||
|  | ||||
|         # Rename the document "illegaly" | ||||
|         os.makedirs(settings.MEDIA_ROOT + "/documents/originals/test") | ||||
|         os.rename(settings.MEDIA_ROOT + "/documents/originals/" + | ||||
|                                         "none/none-0000001.pdf.gpg", | ||||
|                   settings.MEDIA_ROOT + "/documents/originals/" + | ||||
|                                         "test/test-0000001.pdf.gpg") | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/test/test-0000001.pdf.gpg"), True) | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/none/none-0000001.pdf"), False) | ||||
|  | ||||
|         # Set new correspondent and expect document to be saved properly | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="foo")[0] | ||||
|         document.save() | ||||
|         self.assertEqual(os.path.isfile(settings.MEDIA_ROOT + "/documents/" + | ||||
|                          "originals/foo/foo-0000001.pdf.gpg"), True) | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/foo"), True) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), False) | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/test"), False) | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "foo/foo-0000001.pdf.gpg") | ||||
|  | ||||
|     def test_delete_all_empty_subdirectories(self): | ||||
|         # Create our working directory | ||||
|         tmp = "/tmp/paperless-tests-{}".format(str(uuid4())[:8]) | ||||
|         os.makedirs(tmp) | ||||
|         self.add_to_deletion_list(tmp) | ||||
|  | ||||
|         os.makedirs(os.path.join(tmp, "empty")) | ||||
|         os.makedirs(os.path.join(tmp, "empty", "subdirectory")) | ||||
|  | ||||
|         os.makedirs(os.path.join(tmp, "notempty")) | ||||
|         Path(os.path.join(tmp, "notempty", "file")).touch() | ||||
|  | ||||
|         Document.delete_all_empty_subdirectories(tmp) | ||||
|  | ||||
|         self.assertEqual(os.path.isdir(os.path.join(tmp, "notempty")), True) | ||||
|         self.assertEqual(os.path.isdir(os.path.join(tmp, "empty")), False) | ||||
|         self.assertEqual(os.path.isfile( | ||||
|             os.path.join(tmp, "notempty", "file")), True) | ||||
|  | ||||
|     def test_try_delete_empty_directories(self): | ||||
|         # Create our working directory | ||||
|         tmp = "/tmp/paperless-tests-{}".format(str(uuid4())[:8]) | ||||
|         os.makedirs(tmp) | ||||
|         self.add_to_deletion_list(tmp) | ||||
|  | ||||
|         os.makedirs(os.path.join(tmp, "notempty")) | ||||
|         Path(os.path.join(tmp, "notempty", "file")).touch() | ||||
|         os.makedirs(os.path.join(tmp, "notempty", "empty")) | ||||
|  | ||||
|         Document.try_delete_empty_directories( | ||||
|                 os.path.join(tmp, "notempty", "empty")) | ||||
|         self.assertEqual(os.path.isdir(os.path.join(tmp, "notempty")), True) | ||||
|         self.assertEqual(os.path.isfile( | ||||
|             os.path.join(tmp, "notempty", "file")), True) | ||||
|         self.assertEqual(os.path.isdir( | ||||
|             os.path.join(tmp, "notempty", "empty")), False) | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_document_accidentally_deleted(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Test source_path | ||||
|         self.assertEqual(document.source_path, settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none/none-0000001.pdf") | ||||
|  | ||||
|         # Delete the document "illegaly" | ||||
|         os.remove(settings.MEDIA_ROOT + "/documents/originals/" + | ||||
|                                         "none/none-0000001.pdf") | ||||
|  | ||||
|         # Set new correspondent and expect document to be saved properly | ||||
|         document.correspondent = Correspondent.objects.get_or_create( | ||||
|                 name="foo")[0] | ||||
|         document.save() | ||||
|  | ||||
|         # Check proper handling of files | ||||
|         self.assertEqual(os.path.isdir(settings.MEDIA_ROOT + | ||||
|                          "/documents/originals/none"), True) | ||||
|         self.assertEqual(document.source_filename, | ||||
|                          "none/none-0000001.pdf") | ||||
|  | ||||
|     @override_settings(PAPERLESS_FILENAME_FORMAT="{correspondent}/" + | ||||
|                        "{correspondent}") | ||||
|     def test_set_filename(self): | ||||
|         document = Document() | ||||
|         document.file_type = "pdf" | ||||
|         document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||
|         document.save() | ||||
|  | ||||
|         # Ensure that filename is properly generated | ||||
|         tmp = document.source_filename | ||||
|         self.assertEqual(document.generate_source_filename(), | ||||
|                          "none/none-0000001.pdf") | ||||
|         document.create_source_directory() | ||||
|         Path(document.source_path).touch() | ||||
|  | ||||
|         # Set existing filename | ||||
|         document.set_filename(tmp) | ||||
|         self.assertEqual(document.source_filename, "none/none-0000001.pdf") | ||||
|  | ||||
|         # Set non-existing filename | ||||
|         document.set_filename("doesnotexist") | ||||
|         self.assertEqual(document.source_filename, "none/none-0000001.pdf") | ||||
| @@ -4,6 +4,28 @@ import shutil | ||||
| from django.conf import settings | ||||
| from django.core.checks import Error, Warning, register | ||||
|  | ||||
| exists_message = "{} is set but doesn't exist." | ||||
| exists_hint = "Create a directory at {}" | ||||
| writeable_message = "{} is not writeable" | ||||
| writeable_hint = ( | ||||
|     "Set the permissions of {} to be writeable by the user running the " | ||||
|     "Paperless services" | ||||
| ) | ||||
| def path_check(env_var): | ||||
|     messages = [] | ||||
|     directory = os.getenv(env_var) | ||||
|     if directory: | ||||
|         if not os.path.exists(directory): | ||||
|             messages.append(Error( | ||||
|                 exists_message.format(env_var), | ||||
|                 exists_hint.format(directory) | ||||
|             )) | ||||
|         elif not os.access(directory, os.W_OK | os.X_OK): | ||||
|             messages.append(Error( | ||||
|                 writeable_message.format(env_var), | ||||
|                 writeable_hint.format(directory) | ||||
|             )) | ||||
|     return messages | ||||
|  | ||||
| @register() | ||||
| def paths_check(app_configs, **kwargs): | ||||
| @@ -11,57 +33,8 @@ def paths_check(app_configs, **kwargs): | ||||
|     Check the various paths for existence, readability and writeability | ||||
|     """ | ||||
|  | ||||
|     check_messages = [] | ||||
|  | ||||
|     exists_message = "{} is set but doesn't exist." | ||||
|     exists_hint = "Create a directory at {}" | ||||
|     writeable_message = "{} is not writeable" | ||||
|     writeable_hint = ( | ||||
|         "Set the permissions of {} to be writeable by the user running the " | ||||
|         "Paperless services" | ||||
|     ) | ||||
|  | ||||
|     directory = os.getenv("PAPERLESS_DBDIR") | ||||
|     if directory: | ||||
|         if not os.path.exists(directory): | ||||
|             check_messages.append(Error( | ||||
|                 exists_message.format("PAPERLESS_DBDIR"), | ||||
|                 exists_hint.format(directory) | ||||
|             )) | ||||
|         if not check_messages: | ||||
|             if not os.access(directory, os.W_OK | os.X_OK): | ||||
|                 check_messages.append(Error( | ||||
|                     writeable_message.format("PAPERLESS_DBDIR"), | ||||
|                     writeable_hint.format(directory) | ||||
|                 )) | ||||
|  | ||||
|     directory = os.getenv("PAPERLESS_MEDIADIR") | ||||
|     if directory: | ||||
|         if not os.path.exists(directory): | ||||
|             check_messages.append(Error( | ||||
|                 exists_message.format("PAPERLESS_MEDIADIR"), | ||||
|                 exists_hint.format(directory) | ||||
|             )) | ||||
|         if not check_messages: | ||||
|             if not os.access(directory, os.W_OK | os.X_OK): | ||||
|                 check_messages.append(Error( | ||||
|                     writeable_message.format("PAPERLESS_MEDIADIR"), | ||||
|                     writeable_hint.format(directory) | ||||
|                 )) | ||||
|  | ||||
|     directory = os.getenv("PAPERLESS_STATICDIR") | ||||
|     if directory: | ||||
|         if not os.path.exists(directory): | ||||
|             check_messages.append(Error( | ||||
|                 exists_message.format("PAPERLESS_STATICDIR"), | ||||
|                 exists_hint.format(directory) | ||||
|             )) | ||||
|         if not check_messages: | ||||
|             if not os.access(directory, os.W_OK | os.X_OK): | ||||
|                 check_messages.append(Error( | ||||
|                     writeable_message.format("PAPERLESS_STATICDIR"), | ||||
|                     writeable_hint.format(directory) | ||||
|                 )) | ||||
|     check_messages = path_check("PAPERLESS_DATA_DIR") +\ | ||||
|                      path_check("PAPERLESS_STATICDIR") | ||||
|  | ||||
|     return check_messages | ||||
|  | ||||
|   | ||||
| @@ -37,6 +37,12 @@ def __get_boolean(key, default="NO"): | ||||
| # Build paths inside the project like this: os.path.join(BASE_DIR, ...) | ||||
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||||
|  | ||||
| DATA_DIR = os.getenv('PAPERLESS_DATA_DIR', os.path.join(BASE_DIR, "..", "data")) | ||||
|  | ||||
| INDEX_DIR = os.path.join(DATA_DIR, "index") | ||||
| ORIGINALS_DIR = os.path.join(DATA_DIR, "documents") | ||||
| THUMBNAIL_DIR = os.path.join(DATA_DIR, "thumbnails") | ||||
| MODEL_FILE = os.path.join(DATA_DIR, "classification_model.pickle") | ||||
|  | ||||
| # Quick-start development settings - unsuitable for production | ||||
| # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ | ||||
| @@ -145,10 +151,7 @@ DATABASES = { | ||||
|     "default": { | ||||
|         "ENGINE": "django.db.backends.sqlite3", | ||||
|         "NAME": os.path.join( | ||||
|             os.getenv( | ||||
|                 "PAPERLESS_DBDIR", | ||||
|                 os.path.join(BASE_DIR, "..", "data") | ||||
|             ), | ||||
|             DATA_DIR, | ||||
|             "db.sqlite3" | ||||
|         ) | ||||
|     } | ||||
| @@ -206,11 +209,8 @@ USE_TZ = True | ||||
|  | ||||
| STATIC_ROOT = os.getenv( | ||||
|     "PAPERLESS_STATICDIR", os.path.join(BASE_DIR, "..", "static")) | ||||
| MEDIA_ROOT = os.getenv( | ||||
|     "PAPERLESS_MEDIADIR", os.path.join(BASE_DIR, "..", "media")) | ||||
|  | ||||
| STATIC_URL = os.getenv("PAPERLESS_STATIC_URL", "/static/") | ||||
| MEDIA_URL = os.getenv("PAPERLESS_MEDIA_URL", "/media/") | ||||
|  | ||||
|  | ||||
| # Other | ||||
| @@ -223,14 +223,6 @@ MEDIA_URL = os.getenv("PAPERLESS_MEDIA_URL", "/media/") | ||||
| DATA_UPLOAD_MAX_NUMBER_FIELDS = None | ||||
|  | ||||
|  | ||||
| # Document classification models location | ||||
| MODEL_FILE = os.getenv( | ||||
|     "PAPERLESS_MODEL_FILE", os.path.join( | ||||
|         BASE_DIR, "..", "models", "model.pickle" | ||||
|     ) | ||||
| ) | ||||
|  | ||||
|  | ||||
| # Paperless-specific stuff | ||||
| # You shouldn't have to edit any of these values.  Rather, you can set these | ||||
| # values in /etc/paperless.conf instead. | ||||
| @@ -294,7 +286,6 @@ SCRATCH_DIR = os.getenv("PAPERLESS_SCRATCH_DIR", "/tmp/paperless") | ||||
| # This is where Paperless will look for PDFs to index | ||||
| CONSUMPTION_DIR = os.getenv("PAPERLESS_CONSUMPTION_DIR") | ||||
|  | ||||
| INDEX_DIR = os.getenv('PAPERLESS_INDEX_DIR', os.path.join(BASE_DIR, "..", "index")) | ||||
|  | ||||
| # (This setting is ignored on Linux where inotify is used instead of a | ||||
| # polling loop.) | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| from django.conf import settings | ||||
| from django.conf.urls import include, static, url | ||||
| from django.conf.urls import include, url | ||||
| from django.contrib import admin | ||||
| from rest_framework.authtoken import views | ||||
| from rest_framework.routers import DefaultRouter | ||||
| @@ -39,7 +38,7 @@ urlpatterns = [ | ||||
|     # Root of the Frontent | ||||
|     url(r".*", IndexView.as_view()), | ||||
|  | ||||
| ] + static.static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | ||||
| ] | ||||
|  | ||||
| # Text in each page's <h1> (and above login form). | ||||
| admin.site.site_header = 'Paperless' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler