mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Adds owner and original name to the possible naming schemes
This commit is contained in:
parent
ef6c4e6789
commit
97ff2e126c
@ -309,6 +309,8 @@ Paperless provides the following placeholders within filenames:
|
||||
- `{added_month_name_short}`: Month added abbreviated name, as per
|
||||
locale
|
||||
- `{added_day}`: Day added only (number 01-31).
|
||||
- `{owner_username}`: Username of document owner, if any, or "none"
|
||||
- `{original_name}`: Document original filename, minus the extension, if any, or "none"
|
||||
|
||||
Paperless will try to conserve the information from your database as
|
||||
much as possible. However, some characters that you can use in document
|
||||
|
@ -1,12 +1,13 @@
|
||||
import logging
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from pathlib import PurePath
|
||||
|
||||
import pathvalidate
|
||||
from django.conf import settings
|
||||
from django.template.defaultfilters import slugify
|
||||
from django.utils import timezone
|
||||
|
||||
from documents.models import Document
|
||||
|
||||
logger = logging.getLogger("paperless.filehandling")
|
||||
|
||||
@ -125,7 +126,12 @@ def generate_unique_filename(doc, archive_filename=False):
|
||||
return new_filename
|
||||
|
||||
|
||||
def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False):
|
||||
def generate_filename(
|
||||
doc: Document,
|
||||
counter=0,
|
||||
append_gpg=True,
|
||||
archive_filename=False,
|
||||
):
|
||||
path = ""
|
||||
filename_format = settings.FILENAME_FORMAT
|
||||
|
||||
@ -150,13 +156,15 @@ def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False):
|
||||
replacement_text="-",
|
||||
)
|
||||
|
||||
no_value_default = "-none-"
|
||||
|
||||
if doc.correspondent:
|
||||
correspondent = pathvalidate.sanitize_filename(
|
||||
doc.correspondent.name,
|
||||
replacement_text="-",
|
||||
)
|
||||
else:
|
||||
correspondent = "-none-"
|
||||
correspondent = no_value_default
|
||||
|
||||
if doc.document_type:
|
||||
document_type = pathvalidate.sanitize_filename(
|
||||
@ -164,12 +172,23 @@ def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False):
|
||||
replacement_text="-",
|
||||
)
|
||||
else:
|
||||
document_type = "-none-"
|
||||
document_type = no_value_default
|
||||
|
||||
if doc.archive_serial_number:
|
||||
asn = str(doc.archive_serial_number)
|
||||
else:
|
||||
asn = "-none-"
|
||||
asn = no_value_default
|
||||
|
||||
if doc.owner is not None:
|
||||
owner_username_str = str(doc.owner.username)
|
||||
else:
|
||||
owner_username_str = no_value_default
|
||||
|
||||
if doc.original_filename is not None:
|
||||
# No extension
|
||||
original_name = PurePath(doc.original_filename).with_suffix("").name
|
||||
else:
|
||||
original_name = no_value_default
|
||||
|
||||
# Convert UTC database datetime to localized date
|
||||
local_added = timezone.localdate(doc.added)
|
||||
@ -196,6 +215,8 @@ def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False):
|
||||
asn=asn,
|
||||
tags=tags,
|
||||
tag_list=tag_list,
|
||||
owner_username=owner_username_str,
|
||||
original_name=original_name,
|
||||
).strip()
|
||||
|
||||
if settings.FILENAME_FORMAT_REMOVE_NONE:
|
||||
|
@ -818,6 +818,8 @@ class StoragePathSerializer(MatchingModelSerializer, OwnedObjectSerializer):
|
||||
asn="asn",
|
||||
tags="tags",
|
||||
tag_list="tag_list",
|
||||
owner_username="someone",
|
||||
original_name="testfile",
|
||||
)
|
||||
|
||||
except (KeyError):
|
||||
|
@ -20,8 +20,6 @@ except ImportError:
|
||||
import backports.zoneinfo as zoneinfo
|
||||
|
||||
import pytest
|
||||
from django.db import transaction
|
||||
from django.db.utils import IntegrityError
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import Permission
|
||||
|
@ -5,6 +5,7 @@ from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import DatabaseError
|
||||
from django.test import override_settings
|
||||
from django.test import TestCase
|
||||
@ -1059,3 +1060,93 @@ class TestFilenameGeneration(DirectoriesMixin, TestCase):
|
||||
checksum="2",
|
||||
)
|
||||
self.assertEqual(generate_filename(doc), "84/August/Aug/The Title.pdf")
|
||||
|
||||
@override_settings(
|
||||
FILENAME_FORMAT="{owner_username}/{title}",
|
||||
)
|
||||
def test_document_owner_string(self):
|
||||
"""
|
||||
GIVEN:
|
||||
- Document with an other
|
||||
- Document without an owner
|
||||
- Filename format string includes owner
|
||||
WHEN:
|
||||
- Filename is generated for each document
|
||||
THEN:
|
||||
- Owned document includes username
|
||||
- Document without owner returns "none"
|
||||
"""
|
||||
|
||||
u1 = User.objects.create_user("user1")
|
||||
|
||||
owned_doc = Document.objects.create(
|
||||
title="The Title",
|
||||
mime_type="application/pdf",
|
||||
checksum="2",
|
||||
owner=u1,
|
||||
)
|
||||
|
||||
no_owner_doc = Document.objects.create(
|
||||
title="does matter",
|
||||
mime_type="application/pdf",
|
||||
checksum="3",
|
||||
)
|
||||
|
||||
self.assertEqual(generate_filename(owned_doc), "user1/The Title.pdf")
|
||||
self.assertEqual(generate_filename(no_owner_doc), "none/does matter.pdf")
|
||||
|
||||
@override_settings(
|
||||
FILENAME_FORMAT="{original_name}",
|
||||
)
|
||||
def test_document_original_filename(self):
|
||||
"""
|
||||
GIVEN:
|
||||
- Document with an original filename
|
||||
- Document without an original filename
|
||||
- Document which was plain text document
|
||||
- Filename format string includes original filename
|
||||
WHEN:
|
||||
- Filename is generated for each document
|
||||
THEN:
|
||||
- Document with original name uses it, dropping suffix
|
||||
- Document without original name returns "none"
|
||||
- Text document returns extension of .txt
|
||||
- Text document archive returns extension of .pdf
|
||||
- No extensions are doubled
|
||||
"""
|
||||
doc_with_original = Document.objects.create(
|
||||
title="does matter",
|
||||
mime_type="application/pdf",
|
||||
checksum="3",
|
||||
original_filename="someepdf.pdf",
|
||||
)
|
||||
tricky_with_original = Document.objects.create(
|
||||
title="does matter",
|
||||
mime_type="application/pdf",
|
||||
checksum="1",
|
||||
original_filename="some pdf with spaces and stuff.pdf",
|
||||
)
|
||||
no_original = Document.objects.create(
|
||||
title="does matter",
|
||||
mime_type="application/pdf",
|
||||
checksum="2",
|
||||
)
|
||||
|
||||
text_doc = Document.objects.create(
|
||||
title="does matter",
|
||||
mime_type="text/plain",
|
||||
checksum="4",
|
||||
original_filename="logs.txt",
|
||||
)
|
||||
|
||||
self.assertEqual(generate_filename(doc_with_original), "someepdf.pdf")
|
||||
|
||||
self.assertEqual(
|
||||
generate_filename(tricky_with_original),
|
||||
"some pdf with spaces and stuff.pdf",
|
||||
)
|
||||
|
||||
self.assertEqual(generate_filename(no_original), "none.pdf")
|
||||
|
||||
self.assertEqual(generate_filename(text_doc), "logs.txt")
|
||||
self.assertEqual(generate_filename(text_doc, archive_filename=True), "logs.pdf")
|
||||
|
Loading…
x
Reference in New Issue
Block a user