Merge branch 'dev' into feature-remote-ocr-2

This commit is contained in:
shamoon 2025-10-27 21:22:42 -07:00 committed by GitHub
commit f5525bbdff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 158 additions and 32 deletions

View File

@ -51,5 +51,5 @@ body:
id: logs
attributes:
label: Relevant logs or output
description: If you have logs, errors that might help, paste it here.
description: If you have logs, errors that might help, paste it here. For example other containers or services (database, redis, etc).
render: bash

View File

@ -6,8 +6,8 @@ body:
- type: markdown
attributes:
value: |
### ⚠️ Please remember: issues are for *bugs*
That is, something you believe affects every single user of Paperless-ngx, not just you. If you're not sure, start with one of the other options below.
### ⚠️ Please remember: issues are for *bugs* only! ⚠️
That is, something you believe affects every single user of Paperless-ngx (and the demo, for example), not just you. If you are not sure, start with one of the other options below.
Also, note that **Paperless-ngx does not perform OCR or archive file creation itself**, those are handled by other tools. Problems with OCR or archive versions of specific files should likely be raised 'upstream', see https://github.com/ocrmypdf/OCRmyPDF/issues or https://github.com/tesseract-ocr/tesseract/issues
- type: markdown
@ -59,6 +59,12 @@ body:
label: Browser logs
description: Logs from the web browser related to your issue, if needed
render: bash
- type: textarea
id: logs_services
attributes:
label: Services logs
description: Logs from other services (or containers) related to your issue, if needed. For example, the database or redis logs.
render: bash
- type: input
id: version
attributes:

View File

@ -7,6 +7,8 @@ from django.conf import settings
from django.core.mail import EmailMessage
from filelock import FileLock
from documents.data_models import ConsumableDocument
if TYPE_CHECKING:
from documents.models import Document
@ -15,7 +17,7 @@ def send_email(
subject: str,
body: str,
to: list[str],
attachments: list[Document],
attachments: list[Document | ConsumableDocument],
*,
use_archive: bool,
) -> int:
@ -45,12 +47,15 @@ def send_email(
# Something could be renaming the file concurrently so it can't be attached
with FileLock(settings.MEDIA_LOCK):
for document in attachments:
if isinstance(document, ConsumableDocument):
attachment_path = document.original_file
friendly_filename = document.original_file.name
else:
attachment_path = (
document.archive_path
if use_archive and document.has_archive_version
else document.source_path
)
friendly_filename = _get_unique_filename(
document,
used_filenames,

View File

@ -3,7 +3,6 @@ import logging
from django.db import migrations
from django.db import models
from django.db import transaction
from documents.templating.utils import convert_format_str_to_template_format
@ -11,21 +10,34 @@ logger = logging.getLogger("paperless.migrations")
def convert_from_format_to_template(apps, schema_editor):
WorkflowActions = apps.get_model("documents", "WorkflowAction")
WorkflowAction = apps.get_model("documents", "WorkflowAction")
with transaction.atomic():
for WorkflowAction in WorkflowActions.objects.all():
if not WorkflowAction.assign_title:
continue
WorkflowAction.assign_title = convert_format_str_to_template_format(
WorkflowAction.assign_title,
batch_size = 500
actions_to_update = []
queryset = (
WorkflowAction.objects.filter(assign_title__isnull=False)
.exclude(assign_title="")
.only("id", "assign_title")
)
for action in queryset:
action.assign_title = convert_format_str_to_template_format(
action.assign_title,
)
logger.debug(
"Converted WorkflowAction id %d title to template format: %s",
WorkflowAction.id,
WorkflowAction.assign_title,
action.id,
action.assign_title,
)
actions_to_update.append(action)
if actions_to_update:
WorkflowAction.objects.bulk_update(
actions_to_update,
["assign_title"],
batch_size=batch_size,
)
WorkflowAction.save()
class Migration(migrations.Migration):

View File

@ -0,0 +1,28 @@
# Generated by Django 5.2.6 on 2025-10-27 15:11
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1073_migrate_workflow_title_jinja"),
]
operations = [
migrations.AddField(
model_name="workflowrun",
name="deleted_at",
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name="workflowrun",
name="restored_at",
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name="workflowrun",
name="transaction_id",
field=models.UUIDField(blank=True, null=True),
),
]

View File

@ -1547,7 +1547,7 @@ class Workflow(models.Model):
return f"Workflow: {self.name}"
class WorkflowRun(models.Model):
class WorkflowRun(SoftDeleteModel):
workflow = models.ForeignKey(
Workflow,
on_delete=models.CASCADE,

View File

@ -80,7 +80,7 @@ def parse_w_workflow_placeholders(
if doc_url is not None:
formatting.update({"doc_url": doc_url})
logger.debug(f"Jinja Template is : {text}")
logger.debug(f"Parsing Workflow Jinja template: {text}")
try:
template = _template_environment.from_string(
text,

View File

@ -30,6 +30,7 @@ from pytest_django.fixtures import SettingsWrapper
from documents import tasks
from documents.data_models import ConsumableDocument
from documents.data_models import DocumentMetadataOverrides
from documents.data_models import DocumentSource
from documents.matching import document_matches_workflow
from documents.matching import existing_document_matches_workflow
@ -2788,6 +2789,80 @@ class TestWorkflows(
self.assertEqual(doc.tags.all().count(), 1)
self.assertIn(self.t2, doc.tags.all())
@override_settings(
PAPERLESS_EMAIL_HOST="localhost",
EMAIL_ENABLED=True,
PAPERLESS_URL="http://localhost:8000",
)
@mock.patch("django.core.mail.message.EmailMessage.send")
def test_workflow_assignment_then_email_includes_attachment(self, mock_email_send):
"""
GIVEN:
- Workflow with assignment and email actions
- Email action configured to include the document
WHEN:
- Workflow is run on a newly created document
THEN:
- Email action sends the document as an attachment
"""
storage_path = StoragePath.objects.create(
name="sp2",
path="workflow/{{ document.pk }}",
)
trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
)
assignment_action = WorkflowAction.objects.create(
type=WorkflowAction.WorkflowActionType.ASSIGNMENT,
assign_storage_path=storage_path,
assign_owner=self.user2,
)
assignment_action.assign_tags.add(self.t1)
email_action_config = WorkflowActionEmail.objects.create(
subject="Doc ready {doc_title}",
body="Document URL: {doc_url}",
to="owner@example.com",
include_document=True,
)
email_action = WorkflowAction.objects.create(
type=WorkflowAction.WorkflowActionType.EMAIL,
email=email_action_config,
)
workflow = Workflow.objects.create(name="Assignment then email", order=0)
workflow.triggers.add(trigger)
workflow.actions.set([assignment_action, email_action])
temp_working_copy = shutil.copy(
self.SAMPLE_DIR / "simple.pdf",
self.dirs.scratch_dir / "working-copy.pdf",
)
Document.objects.create(
title="workflow doc",
correspondent=self.c,
checksum="wf-assignment-email",
mime_type="application/pdf",
)
consumable_document = ConsumableDocument(
source=DocumentSource.ConsumeFolder,
original_file=temp_working_copy,
)
mock_email_send.return_value = 1
with self.assertNoLogs("paperless.handlers", level="ERROR"):
run_workflows(
WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
consumable_document,
overrides=DocumentMetadataOverrides(),
)
mock_email_send.assert_called_once()
@override_settings(
PAPERLESS_EMAIL_HOST="localhost",
EMAIL_ENABLED=True,