Don't ever send GMail related keywords if the server doesn't report support for the extensions

This commit is contained in:
Trenton H 2023-04-28 14:22:06 -07:00
parent 646db73061
commit 26cd470d31
2 changed files with 20 additions and 11 deletions

View File

@ -2,7 +2,6 @@ import datetime
import itertools import itertools
import logging import logging
import os import os
import re
import tempfile import tempfile
import traceback import traceback
from datetime import date from datetime import date
@ -145,7 +144,7 @@ class TagMailAction(BaseMailAction):
A mail action that tags mails after processing. A mail action that tags mails after processing.
""" """
def __init__(self, parameter): def __init__(self, parameter: str, supports_gmail_labels: bool):
# The custom tag should look like "apple:<color>" # The custom tag should look like "apple:<color>"
if "apple:" in parameter.lower(): if "apple:" in parameter.lower():
_, self.color = parameter.split(":") _, self.color = parameter.split(":")
@ -159,18 +158,22 @@ class TagMailAction(BaseMailAction):
else: else:
self.keyword = parameter self.keyword = parameter
self.color = None self.color = None
self.supports_gmail_labels = supports_gmail_labels
def get_criteria(self): def get_criteria(self):
# AppleMail: We only need to check if mails are \Flagged # AppleMail: We only need to check if mails are \Flagged
if self.color: if self.color:
return {"flagged": False} return {"flagged": False}
elif self.keyword: elif self.keyword:
return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword) if self.supports_gmail_labels:
return AND(NOT(gmail_label=self.keyword), no_keyword=self.keyword)
else:
return NOT(no_keyword=self.keyword)
else: # pragma: nocover else: # pragma: nocover
raise ValueError("This should never happen.") raise ValueError("This should never happen.")
def post_consume(self, M: MailBox, message_uid: str, parameter: str): def post_consume(self, M: MailBox, message_uid: str, parameter: str):
if re.search(r"gmail\.com$|googlemail\.com$", M._host): if self.supports_gmail_labels:
M.client.uid("STORE", message_uid, "+X-GM-LABELS", self.keyword) M.client.uid("STORE", message_uid, "+X-GM-LABELS", self.keyword)
# AppleMail # AppleMail
@ -248,15 +251,18 @@ def apply_mail_action(
message_date = make_aware(message_date) message_date = make_aware(message_date)
try: try:
action = get_rule_action(rule)
with get_mailbox( with get_mailbox(
server=account.imap_server, server=account.imap_server,
port=account.imap_port, port=account.imap_port,
security=account.imap_security, security=account.imap_security,
) as M: ) as M:
# Need to know the support for the possible tagging
supports_gmail_labels = "X-GM-EXT-1" in M.client.capabilities
mailbox_login(M, account) mailbox_login(M, account)
M.folder.set(rule.folder) M.folder.set(rule.folder)
action = get_rule_action(rule, supports_gmail_labels)
action.post_consume(M, message_uid, rule.action_parameter) action.post_consume(M, message_uid, rule.action_parameter)
ProcessedMail.objects.create( ProcessedMail.objects.create(
@ -337,7 +343,7 @@ def queue_consumption_tasks(
).delay() ).delay()
def get_rule_action(rule) -> BaseMailAction: def get_rule_action(rule: MailRule, supports_gmail_labels: bool) -> BaseMailAction:
""" """
Returns a BaseMailAction instance for the given rule. Returns a BaseMailAction instance for the given rule.
""" """
@ -351,12 +357,12 @@ def get_rule_action(rule) -> BaseMailAction:
elif rule.action == MailRule.MailAction.MARK_READ: elif rule.action == MailRule.MailAction.MARK_READ:
return MarkReadMailAction() return MarkReadMailAction()
elif rule.action == MailRule.MailAction.TAG: elif rule.action == MailRule.MailAction.TAG:
return TagMailAction(rule.action_parameter) return TagMailAction(rule.action_parameter, supports_gmail_labels)
else: else:
raise NotImplementedError("Unknown action.") # pragma: nocover raise NotImplementedError("Unknown action.") # pragma: nocover
def make_criterias(rule): def make_criterias(rule: MailRule, supports_gmail_labels: bool):
""" """
Returns criteria to be applied to MailBox.fetch for the given rule. Returns criteria to be applied to MailBox.fetch for the given rule.
""" """
@ -374,7 +380,7 @@ def make_criterias(rule):
if rule.filter_body: if rule.filter_body:
criterias["body"] = rule.filter_body criterias["body"] = rule.filter_body
rule_query = get_rule_action(rule).get_criteria() rule_query = get_rule_action(rule, supports_gmail_labels).get_criteria()
if isinstance(rule_query, dict): if isinstance(rule_query, dict):
if len(rule_query) or len(criterias): if len(rule_query) or len(criterias):
return AND(**rule_query, **criterias) return AND(**rule_query, **criterias)
@ -490,6 +496,7 @@ class MailAccountHandler(LoggingMixin):
total_processed_files += self._handle_mail_rule( total_processed_files += self._handle_mail_rule(
M, M,
rule, rule,
supports_gmail_labels,
) )
except Exception as e: except Exception as e:
self.log( self.log(
@ -512,6 +519,7 @@ class MailAccountHandler(LoggingMixin):
self, self,
M: MailBox, M: MailBox,
rule: MailRule, rule: MailRule,
supports_gmail_labels: bool,
): ):
self.log("debug", f"Rule {rule}: Selecting folder {rule.folder}") self.log("debug", f"Rule {rule}: Selecting folder {rule.folder}")
@ -537,7 +545,7 @@ class MailAccountHandler(LoggingMixin):
f"does not exist in account {rule.account}", f"does not exist in account {rule.account}",
) from err ) from err
criterias = make_criterias(rule) criterias = make_criterias(rule, supports_gmail_labels)
self.log( self.log(
"debug", "debug",

View File

@ -737,6 +737,7 @@ class TestMail(
MailError, MailError,
TagMailAction, TagMailAction,
"apple:black", "apple:black",
False,
) )
def test_handle_mail_account_tag_applemail(self): def test_handle_mail_account_tag_applemail(self):