mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-31 10:37:12 -04:00 
			
		
		
		
	unified data folders
This commit is contained in:
		
							parent
							
								
									d324e4383a
								
							
						
					
					
						commit
						c596fe6782
					
				| @ -20,9 +20,6 @@ class Command(BaseCommand): | |||||||
|     consumption directory, and fetch any mail available. |     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): |     def __init__(self, *args, **kwargs): | ||||||
| 
 | 
 | ||||||
|         self.verbosity = 0 |         self.verbosity = 0 | ||||||
| @ -79,7 +76,7 @@ class Command(BaseCommand): | |||||||
|         except (ConsumerError, MailFetcherError) as e: |         except (ConsumerError, MailFetcherError) as e: | ||||||
|             raise CommandError(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) |             os.makedirs(d, exist_ok=True) | ||||||
| 
 | 
 | ||||||
|         logging.getLogger(__name__).info( |         logging.getLogger(__name__).info( | ||||||
|  | |||||||
| @ -196,9 +196,7 @@ class Document(models.Model): | |||||||
|             file_name += ".gpg" |             file_name += ".gpg" | ||||||
| 
 | 
 | ||||||
|         return os.path.join( |         return os.path.join( | ||||||
|             settings.MEDIA_ROOT, |             settings.ORIGINALS_DIR, | ||||||
|             "documents", |  | ||||||
|             "originals", |  | ||||||
|             file_name |             file_name | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
| @ -222,9 +220,7 @@ class Document(models.Model): | |||||||
|             file_name += ".gpg" |             file_name += ".gpg" | ||||||
| 
 | 
 | ||||||
|         return os.path.join( |         return os.path.join( | ||||||
|             settings.MEDIA_ROOT, |             settings.THUMBNAIL_DIR, | ||||||
|             "documents", |  | ||||||
|             "thumbnails", |  | ||||||
|             file_name |             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.conf import settings | ||||||
| from django.core.checks import Error, Warning, register | 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() | @register() | ||||||
| def paths_check(app_configs, **kwargs): | 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 the various paths for existence, readability and writeability | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     check_messages = [] |     check_messages = path_check("PAPERLESS_DATA_DIR") +\ | ||||||
| 
 |                      path_check("PAPERLESS_STATICDIR") | ||||||
|     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) |  | ||||||
|                 )) |  | ||||||
| 
 | 
 | ||||||
|     return check_messages |     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, ...) | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) | ||||||
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 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 | # Quick-start development settings - unsuitable for production | ||||||
| # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ | ||||||
| @ -145,10 +151,7 @@ DATABASES = { | |||||||
|     "default": { |     "default": { | ||||||
|         "ENGINE": "django.db.backends.sqlite3", |         "ENGINE": "django.db.backends.sqlite3", | ||||||
|         "NAME": os.path.join( |         "NAME": os.path.join( | ||||||
|             os.getenv( |             DATA_DIR, | ||||||
|                 "PAPERLESS_DBDIR", |  | ||||||
|                 os.path.join(BASE_DIR, "..", "data") |  | ||||||
|             ), |  | ||||||
|             "db.sqlite3" |             "db.sqlite3" | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| @ -206,11 +209,8 @@ USE_TZ = True | |||||||
| 
 | 
 | ||||||
| STATIC_ROOT = os.getenv( | STATIC_ROOT = os.getenv( | ||||||
|     "PAPERLESS_STATICDIR", os.path.join(BASE_DIR, "..", "static")) |     "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/") | STATIC_URL = os.getenv("PAPERLESS_STATIC_URL", "/static/") | ||||||
| MEDIA_URL = os.getenv("PAPERLESS_MEDIA_URL", "/media/") |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Other | # Other | ||||||
| @ -223,14 +223,6 @@ MEDIA_URL = os.getenv("PAPERLESS_MEDIA_URL", "/media/") | |||||||
| DATA_UPLOAD_MAX_NUMBER_FIELDS = None | 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 | # Paperless-specific stuff | ||||||
| # You shouldn't have to edit any of these values.  Rather, you can set these | # You shouldn't have to edit any of these values.  Rather, you can set these | ||||||
| # values in /etc/paperless.conf instead. | # 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 | # This is where Paperless will look for PDFs to index | ||||||
| CONSUMPTION_DIR = os.getenv("PAPERLESS_CONSUMPTION_DIR") | 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 | # (This setting is ignored on Linux where inotify is used instead of a | ||||||
| # polling loop.) | # polling loop.) | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| from django.conf import settings | from django.conf.urls import include, url | ||||||
| from django.conf.urls import include, static, url |  | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from rest_framework.authtoken import views | from rest_framework.authtoken import views | ||||||
| from rest_framework.routers import DefaultRouter | from rest_framework.routers import DefaultRouter | ||||||
| @ -39,7 +38,7 @@ urlpatterns = [ | |||||||
|     # Root of the Frontent |     # Root of the Frontent | ||||||
|     url(r".*", IndexView.as_view()), |     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). | # Text in each page's <h1> (and above login form). | ||||||
| admin.site.site_header = 'Paperless' | admin.site.site_header = 'Paperless' | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user