mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-12-24 02:05:48 -06:00
Merge branch 'dev' into feature-ai
This commit is contained in:
@@ -61,6 +61,7 @@ from django_filters.rest_framework import DjangoFilterBackend
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiParameter
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from drf_spectacular.utils import extend_schema_serializer
|
||||
from drf_spectacular.utils import extend_schema_view
|
||||
from drf_spectacular.utils import inline_serializer
|
||||
from guardian.utils import get_group_obj_perms_model
|
||||
@@ -159,6 +160,7 @@ from documents.serialisers import CustomFieldSerializer
|
||||
from documents.serialisers import DocumentListSerializer
|
||||
from documents.serialisers import DocumentSerializer
|
||||
from documents.serialisers import DocumentTypeSerializer
|
||||
from documents.serialisers import EmailSerializer
|
||||
from documents.serialisers import NotesSerializer
|
||||
from documents.serialisers import PostDocumentSerializer
|
||||
from documents.serialisers import RunTaskViewSerializer
|
||||
@@ -486,6 +488,14 @@ class DocumentTypeViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
|
||||
ordering_fields = ("name", "matching_algorithm", "match", "document_count")
|
||||
|
||||
|
||||
@extend_schema_serializer(
|
||||
component_name="EmailDocumentRequest",
|
||||
exclude_fields=("documents",),
|
||||
)
|
||||
class EmailDocumentDetailSchema(EmailSerializer):
|
||||
pass
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
retrieve=extend_schema(
|
||||
description="Retrieve a single document",
|
||||
@@ -653,20 +663,28 @@ class DocumentTypeViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
|
||||
404: None,
|
||||
},
|
||||
),
|
||||
email=extend_schema(
|
||||
email_document=extend_schema(
|
||||
description="Email the document to one or more recipients as an attachment.",
|
||||
request=inline_serializer(
|
||||
name="EmailRequest",
|
||||
fields={
|
||||
"addresses": serializers.CharField(),
|
||||
"subject": serializers.CharField(),
|
||||
"message": serializers.CharField(),
|
||||
"use_archive_version": serializers.BooleanField(default=True),
|
||||
},
|
||||
),
|
||||
request=EmailDocumentDetailSchema,
|
||||
responses={
|
||||
200: inline_serializer(
|
||||
name="EmailResponse",
|
||||
name="EmailDocumentResponse",
|
||||
fields={"message": serializers.CharField()},
|
||||
),
|
||||
400: None,
|
||||
403: None,
|
||||
404: None,
|
||||
500: None,
|
||||
},
|
||||
deprecated=True,
|
||||
),
|
||||
email_documents=extend_schema(
|
||||
operation_id="email_documents",
|
||||
description="Email one or more documents as attachments to one or more recipients.",
|
||||
request=EmailSerializer,
|
||||
responses={
|
||||
200: inline_serializer(
|
||||
name="EmailDocumentsResponse",
|
||||
fields={"message": serializers.CharField()},
|
||||
),
|
||||
400: None,
|
||||
@@ -1236,55 +1254,57 @@ class DocumentViewSet(
|
||||
|
||||
return Response(sorted(entries, key=lambda x: x["timestamp"], reverse=True))
|
||||
|
||||
@action(methods=["post"], detail=True)
|
||||
def email(self, request, pk=None):
|
||||
try:
|
||||
doc = Document.objects.select_related("owner").get(pk=pk)
|
||||
@action(methods=["post"], detail=True, url_path="email")
|
||||
# TODO: deprecated as of 2.19, remove in future release
|
||||
def email_document(self, request, pk=None):
|
||||
request_data = request.data.copy()
|
||||
request_data.setlist("documents", [pk])
|
||||
return self.email_documents(request, data=request_data)
|
||||
|
||||
@action(
|
||||
methods=["post"],
|
||||
detail=False,
|
||||
url_path="email",
|
||||
serializer_class=EmailSerializer,
|
||||
)
|
||||
def email_documents(self, request, data=None):
|
||||
serializer = EmailSerializer(data=data or request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
validated_data = serializer.validated_data
|
||||
document_ids = validated_data.get("documents")
|
||||
addresses = validated_data.get("addresses").split(",")
|
||||
addresses = [addr.strip() for addr in addresses]
|
||||
subject = validated_data.get("subject")
|
||||
message = validated_data.get("message")
|
||||
use_archive_version = validated_data.get("use_archive_version", True)
|
||||
|
||||
documents = Document.objects.select_related("owner").filter(pk__in=document_ids)
|
||||
for document in documents:
|
||||
if request.user is not None and not has_perms_owner_aware(
|
||||
request.user,
|
||||
"view_document",
|
||||
doc,
|
||||
document,
|
||||
):
|
||||
return HttpResponseForbidden("Insufficient permissions")
|
||||
except Document.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
try:
|
||||
if (
|
||||
"addresses" not in request.data
|
||||
or "subject" not in request.data
|
||||
or "message" not in request.data
|
||||
):
|
||||
return HttpResponseBadRequest("Missing required fields")
|
||||
|
||||
use_archive_version = request.data.get("use_archive_version", True)
|
||||
|
||||
addresses = request.data.get("addresses").split(",")
|
||||
if not all(
|
||||
re.match(r"[^@]+@[^@]+\.[^@]+", address.strip())
|
||||
for address in addresses
|
||||
):
|
||||
return HttpResponseBadRequest("Invalid email address found")
|
||||
|
||||
send_email(
|
||||
subject=request.data.get("subject"),
|
||||
body=request.data.get("message"),
|
||||
subject=subject,
|
||||
body=message,
|
||||
to=addresses,
|
||||
attachment=(
|
||||
doc.archive_path
|
||||
if use_archive_version and doc.has_archive_version
|
||||
else doc.source_path
|
||||
),
|
||||
attachment_mime_type=doc.mime_type,
|
||||
attachments=documents,
|
||||
use_archive=use_archive_version,
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f"Sent document {doc.id} via email to {addresses}",
|
||||
f"Sent documents {[doc.id for doc in documents]} via email to {addresses}",
|
||||
)
|
||||
return Response({"message": "Email sent"})
|
||||
except Exception as e:
|
||||
logger.warning(f"An error occurred emailing document: {e!s}")
|
||||
logger.warning(f"An error occurred emailing documents: {e!s}")
|
||||
return HttpResponseServerError(
|
||||
"Error emailing document, check logs for more detail.",
|
||||
"Error emailing documents, check logs for more detail.",
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user