mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-09 09:58:20 -05:00
Enhancement: check for mail destination directory, log post-consume errors (#7808)
--------- Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
parent
f8d79b012f
commit
b3487f1843
@ -28,6 +28,7 @@ from imap_tools import MailboxFolderSelectError
|
|||||||
from imap_tools import MailBoxUnencrypted
|
from imap_tools import MailBoxUnencrypted
|
||||||
from imap_tools import MailMessage
|
from imap_tools import MailMessage
|
||||||
from imap_tools import MailMessageFlags
|
from imap_tools import MailMessageFlags
|
||||||
|
from imap_tools import errors
|
||||||
from imap_tools.mailbox import MailBoxTls
|
from imap_tools.mailbox import MailBoxTls
|
||||||
from imap_tools.query import LogicOperator
|
from imap_tools.query import LogicOperator
|
||||||
|
|
||||||
@ -266,7 +267,14 @@ def apply_mail_action(
|
|||||||
M.folder.set(rule.folder)
|
M.folder.set(rule.folder)
|
||||||
|
|
||||||
action = get_rule_action(rule, supports_gmail_labels)
|
action = get_rule_action(rule, supports_gmail_labels)
|
||||||
action.post_consume(M, message_uid, rule.action_parameter)
|
try:
|
||||||
|
action.post_consume(M, message_uid, rule.action_parameter)
|
||||||
|
except errors.ImapToolsError:
|
||||||
|
logger = logging.getLogger("paperless_mail")
|
||||||
|
logger.exception(
|
||||||
|
"Error while processing mail action during post_consume",
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
ProcessedMail.objects.create(
|
ProcessedMail.objects.create(
|
||||||
owner=rule.owner,
|
owner=rule.owner,
|
||||||
@ -570,13 +578,17 @@ class MailAccountHandler(LoggingMixin):
|
|||||||
rule: MailRule,
|
rule: MailRule,
|
||||||
supports_gmail_labels: bool,
|
supports_gmail_labels: bool,
|
||||||
):
|
):
|
||||||
self.log.debug(f"Rule {rule}: Selecting folder {rule.folder}")
|
folders = [rule.folder]
|
||||||
|
# In case of MOVE, make sure also the destination exists
|
||||||
|
if rule.action == MailRule.MailAction.MOVE:
|
||||||
|
folders.insert(0, rule.action_parameter)
|
||||||
try:
|
try:
|
||||||
M.folder.set(rule.folder)
|
for folder in folders:
|
||||||
|
self.log.debug(f"Rule {rule}: Selecting folder {folder}")
|
||||||
|
M.folder.set(folder)
|
||||||
except MailboxFolderSelectError as err:
|
except MailboxFolderSelectError as err:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
f"Unable to access folder {rule.folder}, attempting folder listing",
|
f"Unable to access folder {folder}, attempting folder listing",
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
for folder_info in M.folder.list():
|
for folder_info in M.folder.list():
|
||||||
@ -588,7 +600,7 @@ class MailAccountHandler(LoggingMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
raise MailError(
|
raise MailError(
|
||||||
f"Rule {rule}: Folder {rule.folder} "
|
f"Rule {rule}: Folder {folder} "
|
||||||
f"does not exist in account {rule.account}",
|
f"does not exist in account {rule.account}",
|
||||||
) from err
|
) from err
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import pytest
|
|||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.db import DatabaseError
|
from django.db import DatabaseError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.utils import timezone
|
||||||
from imap_tools import NOT
|
from imap_tools import NOT
|
||||||
from imap_tools import EmailAddress
|
from imap_tools import EmailAddress
|
||||||
from imap_tools import FolderInfo
|
from imap_tools import FolderInfo
|
||||||
@ -17,6 +18,7 @@ from imap_tools import MailboxFolderSelectError
|
|||||||
from imap_tools import MailboxLoginError
|
from imap_tools import MailboxLoginError
|
||||||
from imap_tools import MailMessage
|
from imap_tools import MailMessage
|
||||||
from imap_tools import MailMessageFlags
|
from imap_tools import MailMessageFlags
|
||||||
|
from imap_tools import errors
|
||||||
|
|
||||||
from documents.models import Correspondent
|
from documents.models import Correspondent
|
||||||
from documents.tests.utils import DirectoriesMixin
|
from documents.tests.utils import DirectoriesMixin
|
||||||
@ -28,6 +30,7 @@ from paperless_mail.mail import TagMailAction
|
|||||||
from paperless_mail.mail import apply_mail_action
|
from paperless_mail.mail import apply_mail_action
|
||||||
from paperless_mail.models import MailAccount
|
from paperless_mail.models import MailAccount
|
||||||
from paperless_mail.models import MailRule
|
from paperless_mail.models import MailRule
|
||||||
|
from paperless_mail.models import ProcessedMail
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
@ -1424,6 +1427,95 @@ class TestMail(
|
|||||||
) # still 2
|
) # still 2
|
||||||
|
|
||||||
|
|
||||||
|
class TestPostConsumeAction(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.account = MailAccount.objects.create(
|
||||||
|
name="test",
|
||||||
|
imap_server="imap.test.com",
|
||||||
|
imap_port=993,
|
||||||
|
imap_security=MailAccount.ImapSecurity.SSL,
|
||||||
|
username="testuser",
|
||||||
|
password="password",
|
||||||
|
)
|
||||||
|
self.rule = MailRule.objects.create(
|
||||||
|
name="testrule",
|
||||||
|
account=self.account,
|
||||||
|
action=MailRule.MailAction.MARK_READ,
|
||||||
|
action_parameter="",
|
||||||
|
folder="INBOX",
|
||||||
|
)
|
||||||
|
self.message_uid = "12345"
|
||||||
|
self.message_subject = "Test Subject"
|
||||||
|
self.message_date = timezone.make_aware(timezone.datetime(2023, 1, 1, 12, 0, 0))
|
||||||
|
|
||||||
|
@mock.patch("paperless_mail.mail.get_mailbox")
|
||||||
|
@mock.patch("paperless_mail.mail.mailbox_login")
|
||||||
|
@mock.patch("paperless_mail.mail.get_rule_action")
|
||||||
|
def test_post_consume_success(
|
||||||
|
self,
|
||||||
|
mock_get_rule_action,
|
||||||
|
mock_mailbox_login,
|
||||||
|
mock_get_mailbox,
|
||||||
|
):
|
||||||
|
mock_mailbox = mock.MagicMock()
|
||||||
|
mock_get_mailbox.return_value.__enter__.return_value = mock_mailbox
|
||||||
|
mock_action = mock.MagicMock()
|
||||||
|
mock_get_rule_action.return_value = mock_action
|
||||||
|
|
||||||
|
apply_mail_action(
|
||||||
|
result=[],
|
||||||
|
rule_id=self.rule.pk,
|
||||||
|
message_uid=self.message_uid,
|
||||||
|
message_subject=self.message_subject,
|
||||||
|
message_date=self.message_date,
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_mailbox_login.assert_called_once_with(mock_mailbox, self.account)
|
||||||
|
mock_mailbox.folder.set.assert_called_once_with(self.rule.folder)
|
||||||
|
mock_action.post_consume.assert_called_once_with(
|
||||||
|
mock_mailbox,
|
||||||
|
self.message_uid,
|
||||||
|
self.rule.action_parameter,
|
||||||
|
)
|
||||||
|
|
||||||
|
processed_mail = ProcessedMail.objects.get(uid=self.message_uid)
|
||||||
|
self.assertEqual(processed_mail.status, "SUCCESS")
|
||||||
|
|
||||||
|
@mock.patch("paperless_mail.mail.get_mailbox")
|
||||||
|
@mock.patch("paperless_mail.mail.mailbox_login")
|
||||||
|
@mock.patch("paperless_mail.mail.get_rule_action")
|
||||||
|
def test_post_consume_failure(
|
||||||
|
self,
|
||||||
|
mock_get_rule_action,
|
||||||
|
mock_mailbox_login,
|
||||||
|
mock_get_mailbox,
|
||||||
|
):
|
||||||
|
mock_mailbox = mock.MagicMock()
|
||||||
|
mock_get_mailbox.return_value.__enter__.return_value = mock_mailbox
|
||||||
|
mock_action = mock.MagicMock()
|
||||||
|
mock_get_rule_action.return_value = mock_action
|
||||||
|
mock_action.post_consume.side_effect = errors.ImapToolsError("Test Exception")
|
||||||
|
|
||||||
|
with (
|
||||||
|
self.assertRaises(errors.ImapToolsError),
|
||||||
|
self.assertLogs("paperless.mail", level="ERROR") as cm,
|
||||||
|
):
|
||||||
|
apply_mail_action(
|
||||||
|
result=[],
|
||||||
|
rule_id=self.rule.pk,
|
||||||
|
message_uid=self.message_uid,
|
||||||
|
message_subject=self.message_subject,
|
||||||
|
message_date=self.message_date,
|
||||||
|
)
|
||||||
|
error_str = cm.output[0]
|
||||||
|
expected_str = "Error while processing mail action during post_consume"
|
||||||
|
self.assertIn(expected_str, error_str)
|
||||||
|
|
||||||
|
processed_mail = ProcessedMail.objects.get(uid=self.message_uid)
|
||||||
|
self.assertEqual(processed_mail.status, "FAILED")
|
||||||
|
self.assertIn("Test Exception", processed_mail.error)
|
||||||
|
|
||||||
|
|
||||||
class TestManagementCommand(TestCase):
|
class TestManagementCommand(TestCase):
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
"paperless_mail.management.commands.mail_fetcher.tasks.process_mail_accounts",
|
"paperless_mail.management.commands.mail_fetcher.tasks.process_mail_accounts",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user