Support title assignment in consumption templates
This commit is contained in:
parent
c12e1f8732
commit
1aa0792b88
@ -15,6 +15,7 @@
|
||||
<pngx-input-text i18n-title title="Filter path" formControlName="filter_path" i18n-hint hint="Apply template to documents that match this path. Wildcards specified as * are allowed. Case insensitive." [error]="error?.filter_path"></pngx-input-text>
|
||||
</div>
|
||||
<div class="col">
|
||||
<pngx-input-text i18n-title title="Assign title" formControlName="assign_title" i18n-hint hint="Assign a document title, can include some placeholders, see documentation." [error]="error?.assign_title"></pngx-input-text>
|
||||
<pngx-input-tags [allowCreate]="false" i18n-title title="Assign tags" formControlName="assign_tags"></pngx-input-tags>
|
||||
<pngx-input-select i18n-title title="Assign document type" [items]="documentTypes" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
<pngx-input-select i18n-title title="Assign correspondent" [items]="correspondents" [allowNull]="true" formControlName="assign_correspondent"></pngx-input-select>
|
||||
|
@ -86,15 +86,16 @@ export class ConsumptionTemplateEditDialogComponent extends EditDialogComponent<
|
||||
filter_path: new FormControl(null),
|
||||
order: new FormControl(null),
|
||||
sources: new FormControl([]),
|
||||
assign_title: new FormControl(null),
|
||||
assign_tags: new FormControl([]),
|
||||
assign_owner: new FormControl(null),
|
||||
assign_document_type: new FormControl(null),
|
||||
assign_correspondent: new FormControl(null),
|
||||
assign_storage_path: new FormControl(null),
|
||||
assign_view_users: new FormControl(null),
|
||||
assign_view_groups: new FormControl(null),
|
||||
assign_change_users: new FormControl(null),
|
||||
assign_change_groups: new FormControl(null),
|
||||
assign_view_users: new FormControl([]),
|
||||
assign_view_groups: new FormControl([]),
|
||||
assign_change_users: new FormControl([]),
|
||||
assign_change_groups: new FormControl([]),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ export interface PaperlessConsumptionTemplate extends ObjectWithPermissions {
|
||||
|
||||
filter_path: string
|
||||
|
||||
assign_title?: string
|
||||
|
||||
assign_tags?: number[] // PaperlessTag.id
|
||||
|
||||
assign_document_type?: number // PaperlessDocumentType.id
|
||||
|
@ -602,7 +602,7 @@ class Consumer(LoggingMixin):
|
||||
for template in ConsumptionTemplate.objects.all().order_by("order"):
|
||||
template_overrides = DocumentMetadataOverrides()
|
||||
|
||||
if int(input_doc.source) in list(template.sources) and (
|
||||
if int(input_doc.source) in [int(x) for x in list(template.sources)] and (
|
||||
(
|
||||
template.filter_filename is not None
|
||||
and fnmatch(
|
||||
@ -616,6 +616,8 @@ class Consumer(LoggingMixin):
|
||||
)
|
||||
):
|
||||
self.log.info(f"Document matched consumption template {template.name}")
|
||||
if template.assign_title is not None:
|
||||
template_overrides.title = template.assign_title
|
||||
if template.assign_tags is not None:
|
||||
template_overrides.tag_ids = [
|
||||
tag.pk for tag in template.assign_tags.all()
|
||||
@ -654,6 +656,38 @@ class Consumer(LoggingMixin):
|
||||
)
|
||||
return overrides
|
||||
|
||||
def _parse_title_placeholders(self, title: str) -> str:
|
||||
local_added = timezone.now()
|
||||
|
||||
correspondent_name = (
|
||||
Correspondent.objects.get(pk=self.override_correspondent_id).name
|
||||
if self.override_correspondent_id is not None
|
||||
else None
|
||||
)
|
||||
doc_type_name = (
|
||||
DocumentType.objects.get(pk=self.override_document_type_id).name
|
||||
if self.override_correspondent_id is not None
|
||||
else None
|
||||
)
|
||||
owner_username = (
|
||||
User.objects.get(pk=self.override_owner_id).username
|
||||
if self.override_owner_id is not None
|
||||
else None
|
||||
)
|
||||
|
||||
return title.format(
|
||||
correspondent=correspondent_name or None,
|
||||
document_type=doc_type_name or None,
|
||||
added=local_added.isoformat(),
|
||||
added_year=local_added.strftime("%Y"),
|
||||
added_year_short=local_added.strftime("%y"),
|
||||
added_month=local_added.strftime("%m"),
|
||||
added_month_name=local_added.strftime("%B"),
|
||||
added_month_name_short=local_added.strftime("%b"),
|
||||
added_day=local_added.strftime("%d"),
|
||||
owner_username=owner_username or None,
|
||||
).strip()
|
||||
|
||||
def _store(
|
||||
self,
|
||||
text: str,
|
||||
@ -686,9 +720,15 @@ class Consumer(LoggingMixin):
|
||||
|
||||
storage_type = Document.STORAGE_TYPE_UNENCRYPTED
|
||||
|
||||
print("override_title", self.override_title)
|
||||
|
||||
with open(self.path, "rb") as f:
|
||||
document = Document.objects.create(
|
||||
title=(self.override_title or file_info.title)[:127],
|
||||
title=(
|
||||
self._parse_title_placeholders(self.override_title)
|
||||
if self.override_title is not None
|
||||
else file_info.title
|
||||
)[:127],
|
||||
content=text,
|
||||
mime_type=mime_type,
|
||||
checksum=hashlib.md5(f.read()).hexdigest(),
|
||||
@ -800,6 +840,8 @@ def merge_overrides(
|
||||
overridesA: DocumentMetadataOverrides,
|
||||
overridesB: DocumentMetadataOverrides,
|
||||
) -> DocumentMetadataOverrides:
|
||||
if overridesA.title is None:
|
||||
overridesA.title = overridesB.title
|
||||
if overridesA.tag_ids is None:
|
||||
overridesA.tag_ids = overridesB.tag_ids
|
||||
if overridesA.correspondent_id is None:
|
||||
|
@ -167,6 +167,16 @@ class Migration(migrations.Migration):
|
||||
verbose_name="assign this tag",
|
||||
),
|
||||
),
|
||||
(
|
||||
"assign_title",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
help_text="Assign a document title, can include some placeholders, see documentation.",
|
||||
max_length=256,
|
||||
null=True,
|
||||
verbose_name="assign title",
|
||||
),
|
||||
),
|
||||
(
|
||||
"assign_view_groups",
|
||||
models.ManyToManyField(
|
||||
|
@ -786,6 +786,17 @@ class ConsumptionTemplate(ModelWithOwner):
|
||||
),
|
||||
)
|
||||
|
||||
assign_title = models.CharField(
|
||||
_("assign title"),
|
||||
max_length=256,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"Assign a document title, can include some placeholders,"
|
||||
"see documentation.",
|
||||
),
|
||||
)
|
||||
|
||||
assign_tags = models.ManyToManyField(
|
||||
Tag,
|
||||
blank=True,
|
||||
|
@ -1066,6 +1066,7 @@ class ConsumptionTemplateSerializer(OwnedObjectSerializer):
|
||||
"sources",
|
||||
"filter_path",
|
||||
"filter_filename",
|
||||
"assign_title",
|
||||
"assign_tags",
|
||||
"assign_correspondent",
|
||||
"assign_document_type",
|
||||
@ -1085,20 +1086,8 @@ class ConsumptionTemplateSerializer(OwnedObjectSerializer):
|
||||
super().update(instance, validated_data)
|
||||
return instance
|
||||
|
||||
# def create(self, validated_data):
|
||||
# if "assign_tags" in validated_data:
|
||||
# assign_tags = validated_data.pop("assign_tags")
|
||||
# mail_rule = super().create(validated_data)
|
||||
# if assign_tags:
|
||||
# mail_rule.assign_tags.set(assign_tags)
|
||||
# return mail_rule
|
||||
def validate(self, attrs):
|
||||
if len(attrs["filter_filename"]) == 0 and len(attrs["filter_path"]) == 0:
|
||||
raise serializers.ValidationError("File name or path filter are required")
|
||||
|
||||
# def validate(self, attrs):
|
||||
# TODO: require path or filename filter
|
||||
# if (
|
||||
# attrs["action"] == ConsumptionTemplate.MailAction.TAG
|
||||
# or attrs["action"] == ConsumptionTemplate.MailAction.MOVE
|
||||
# ) and attrs["action_parameter"] is None:
|
||||
# raise serializers.ValidationError("An action parameter is required.")
|
||||
|
||||
# return attrs
|
||||
return attrs
|
||||
|
Loading…
x
Reference in New Issue
Block a user