mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-24 20:36:25 +00:00
Compare commits
1 Commits
dev
...
mail-dedup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7118f61a0 |
@@ -536,6 +536,7 @@ class MailAccountHandler(LoggingMixin):
|
||||
self.log.debug(f"Processing mail account {account}")
|
||||
|
||||
total_processed_files = 0
|
||||
consumed_messages: set[tuple[str, str]] = set()
|
||||
try:
|
||||
with get_mailbox(
|
||||
account.imap_server,
|
||||
@@ -574,6 +575,7 @@ class MailAccountHandler(LoggingMixin):
|
||||
M,
|
||||
rule,
|
||||
supports_gmail_labels=supports_gmail_labels,
|
||||
consumed_messages=consumed_messages,
|
||||
)
|
||||
if total_processed_files > 0 and rule.stop_processing:
|
||||
self.log.debug(
|
||||
@@ -605,6 +607,7 @@ class MailAccountHandler(LoggingMixin):
|
||||
rule: MailRule,
|
||||
*,
|
||||
supports_gmail_labels: bool,
|
||||
consumed_messages: set[tuple[str, str]],
|
||||
):
|
||||
folders = [rule.folder]
|
||||
# In case of MOVE, make sure also the destination exists
|
||||
@@ -652,11 +655,26 @@ class MailAccountHandler(LoggingMixin):
|
||||
|
||||
mails_processed = 0
|
||||
total_processed_files = 0
|
||||
rule_seen_messages: set[tuple[str, str]] = set()
|
||||
|
||||
for message in messages:
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(message, MailMessage)
|
||||
|
||||
message_key = (rule.folder, message.uid)
|
||||
if message_key in rule_seen_messages:
|
||||
self.log.debug(
|
||||
f"Skipping duplicate fetched mail '{message.uid}' subject '{message.subject}' from '{message.from_}'.",
|
||||
)
|
||||
continue
|
||||
rule_seen_messages.add(message_key)
|
||||
|
||||
if message_key in consumed_messages:
|
||||
self.log.debug(
|
||||
f"Skipping mail '{message.uid}' subject '{message.subject}' from '{message.from_}', already queued by a previous rule in this run.",
|
||||
)
|
||||
continue
|
||||
|
||||
if ProcessedMail.objects.filter(
|
||||
rule=rule,
|
||||
uid=message.uid,
|
||||
@@ -669,6 +687,8 @@ class MailAccountHandler(LoggingMixin):
|
||||
|
||||
try:
|
||||
processed_files = self._handle_message(message, rule)
|
||||
if processed_files > 0:
|
||||
consumed_messages.add(message_key)
|
||||
|
||||
total_processed_files += processed_files
|
||||
mails_processed += 1
|
||||
|
||||
@@ -863,6 +863,66 @@ class TestMail(
|
||||
|
||||
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 0)
|
||||
|
||||
def test_handle_mail_account_overlapping_rules_only_first_consumes(self):
|
||||
account = MailAccount.objects.create(
|
||||
name="test",
|
||||
imap_server="",
|
||||
username="admin",
|
||||
password="secret",
|
||||
)
|
||||
|
||||
first_rule = MailRule.objects.create(
|
||||
name="testrule-first",
|
||||
account=account,
|
||||
action=MailRule.MailAction.DELETE,
|
||||
filter_subject="Claim",
|
||||
order=1,
|
||||
)
|
||||
_ = MailRule.objects.create(
|
||||
name="testrule-second",
|
||||
account=account,
|
||||
action=MailRule.MailAction.DELETE,
|
||||
filter_subject="Claim",
|
||||
order=2,
|
||||
)
|
||||
|
||||
self.mail_account_handler.handle_mail_account(account)
|
||||
self.mailMocker.apply_mail_actions()
|
||||
|
||||
self.assertEqual(self.mailMocker._queue_consumption_tasks_mock.call_count, 1)
|
||||
queued_rule = self.mailMocker._queue_consumption_tasks_mock.call_args.kwargs[
|
||||
"rule"
|
||||
]
|
||||
self.assertEqual(queued_rule.id, first_rule.id)
|
||||
|
||||
def test_handle_mail_account_skip_duplicate_uids_from_fetch(self):
|
||||
account = MailAccount.objects.create(
|
||||
name="test",
|
||||
imap_server="",
|
||||
username="admin",
|
||||
password="secret",
|
||||
)
|
||||
_ = MailRule.objects.create(
|
||||
name="testrule",
|
||||
account=account,
|
||||
action=MailRule.MailAction.DELETE,
|
||||
filter_subject="Duplicated mail",
|
||||
)
|
||||
|
||||
duplicated_message = self.mailMocker.messageBuilder.create_message(
|
||||
subject="Duplicated mail",
|
||||
)
|
||||
self.mailMocker.bogus_mailbox.messages = [
|
||||
duplicated_message,
|
||||
duplicated_message,
|
||||
]
|
||||
self.mailMocker.bogus_mailbox.updateClient()
|
||||
|
||||
self.mail_account_handler.handle_mail_account(account)
|
||||
self.mailMocker.apply_mail_actions()
|
||||
|
||||
self.assertEqual(self.mailMocker._queue_consumption_tasks_mock.call_count, 1)
|
||||
|
||||
@pytest.mark.flaky(reruns=4)
|
||||
def test_handle_mail_account_flag(self) -> None:
|
||||
account = MailAccount.objects.create(
|
||||
|
||||
Reference in New Issue
Block a user