Refactored delete_empty_directory into try_delete_empty_directories and

implemented feature to ensure, that all created and now empty
directories are really deleted
This commit is contained in:
Wolf-Bastian Poettner 2020-02-01 20:03:20 +00:00
parent a45e6c1b48
commit 86a51c6fa5
2 changed files with 52 additions and 16 deletions

View File

@ -294,7 +294,7 @@ class Document(models.Model):
key = t.name[:delimeter] key = t.name[:delimeter]
value = t.name[delimeter+1:] value = t.name[delimeter+1:]
mydictionary[key] = value mydictionary[key] = slugify(value)
return mydictionary return mydictionary
@ -302,10 +302,10 @@ class Document(models.Model):
# Create directory name based on configured format # Create directory name based on configured format
if settings.PAPERLESS_DIRECTORY_FORMAT is not None: if settings.PAPERLESS_DIRECTORY_FORMAT is not None:
directory = settings.PAPERLESS_DIRECTORY_FORMAT.format( directory = settings.PAPERLESS_DIRECTORY_FORMAT.format(
correspondent=self.correspondent, correspondent=slugify(self.correspondent),
title=self.title, title=slugify(self.title),
created=self.created, created=slugify(self.created),
added=self.added, added=slugify(self.added),
tags=defaultdict(str, tags=defaultdict(str,
self.many_to_dictionary(self.tags))) self.many_to_dictionary(self.tags)))
else: else:
@ -314,16 +314,16 @@ class Document(models.Model):
# Create filename based on configured format # Create filename based on configured format
if settings.PAPERLESS_FILENAME_FORMAT is not None: if settings.PAPERLESS_FILENAME_FORMAT is not None:
filename = settings.PAPERLESS_FILENAME_FORMAT.format( filename = settings.PAPERLESS_FILENAME_FORMAT.format(
correspondent=self.correspondent, correspondent=slugify(self.correspondent),
title=self.title, title=slugify(self.title),
created=self.created, created=slugify(self.created),
added=self.added, added=slugify(self.added),
tags=defaultdict(str, tags=defaultdict(str,
self.many_to_dictionary(self.tags))) self.many_to_dictionary(self.tags)))
else: else:
filename = "" filename = ""
path = os.path.join(slugify(directory), slugify(filename)) path = os.path.join(directory, filename)
# Always append the primary key to guarantee uniqueness of filename # Always append the primary key to guarantee uniqueness of filename
if len(path) > 0: if len(path) > 0:
@ -398,13 +398,18 @@ class Document(models.Model):
self.filename = filename self.filename = filename
def delete_empty_directory(directory): def try_delete_empty_directories(directory):
if len(os.listdir(directory)) == 0: # Go up in the directory hierarchy and try to delete all directories
while directory != Document.filename_to_path(""):
# Try to delete the current directory
try: try:
os.rmdir(directory) os.rmdir(directory)
except os.error: except os.error:
# Directory not empty # Directory not empty, no need to go further up
pass return
# Cut off actual directory and go one level up
directory, tmp = os.path.split(directory)
@receiver(models.signals.m2m_changed, sender=Document.tags.through) @receiver(models.signals.m2m_changed, sender=Document.tags.through)
@ -441,7 +446,7 @@ def update_filename(sender, instance, **kwargs):
# Delete empty directory # Delete empty directory
old_dir = os.path.dirname(instance.filename) old_dir = os.path.dirname(instance.filename)
old_path = instance.filename_to_path(old_dir) old_path = instance.filename_to_path(old_dir)
delete_empty_directory(old_path) try_delete_empty_directories(old_path)
instance.filename = new_filename instance.filename = new_filename
@ -469,7 +474,7 @@ def delete_files(sender, instance, **kwargs):
# And remove the directory (if applicable) # And remove the directory (if applicable)
old_dir = os.path.dirname(instance.filename) old_dir = os.path.dirname(instance.filename)
old_path = instance.filename_to_path(old_dir) old_path = instance.filename_to_path(old_dir)
delete_empty_directory(old_path) try_delete_empty_directories(old_path)
class Log(models.Model): class Log(models.Model):

View File

@ -145,6 +145,37 @@ class TestDate(TestCase):
"/documents/originals/none/none-0000001.pdftest") "/documents/originals/none/none-0000001.pdftest")
os.rmdir(settings.MEDIA_ROOT + "/documents/originals/none") os.rmdir(settings.MEDIA_ROOT + "/documents/originals/none")
@override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}".
format(str(uuid4())[:8]))
@override_settings(PAPERLESS_DIRECTORY_FORMAT="{correspondent}/{correspondent}")
@override_settings(PAPERLESS_FILENAME_FORMAT="{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)
@override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}". @override_settings(MEDIA_ROOT="/tmp/paperless-tests-{}".
format(str(uuid4())[:8])) format(str(uuid4())[:8]))
@override_settings(PAPERLESS_DIRECTORY_FORMAT=None) @override_settings(PAPERLESS_DIRECTORY_FORMAT=None)