Merge pull request #25816 from barredterra/refactor-receive
refactor: receive email
This commit is contained in:
commit
245fbb6459
1 changed files with 41 additions and 47 deletions
|
|
@ -190,7 +190,7 @@ class EmailServer:
|
|||
if cint(self.settings.use_imap):
|
||||
self.check_imap_uidvalidity(folder)
|
||||
|
||||
readonly = False if self.settings.email_sync_rule == "UNSEEN" else True
|
||||
readonly = self.settings.email_sync_rule != "UNSEEN"
|
||||
|
||||
self.imap.select(folder, readonly=readonly)
|
||||
response, message = self.imap.uid("search", None, self.settings.email_sync_rule)
|
||||
|
|
@ -213,27 +213,32 @@ class EmailServer:
|
|||
|
||||
if not uid_validity or uid_validity != current_uid_validity:
|
||||
# uidvalidity changed & all email uids are reindexed by server
|
||||
Communication = frappe.qb.DocType("Communication")
|
||||
frappe.qb.update(Communication).set(Communication.uid, -1).where(
|
||||
Communication.communication_medium == "Email"
|
||||
).where(Communication.email_account == self.settings.email_account).run()
|
||||
frappe.db.set_value(
|
||||
"Communication",
|
||||
{"communication_medium": "Email", "email_account": self.settings.email_account},
|
||||
"uid",
|
||||
-1,
|
||||
update_modified=False,
|
||||
)
|
||||
|
||||
if self.settings.use_imap:
|
||||
# Remove {"} quotes that are added to handle spaces in IMAP Folder names
|
||||
if folder[0] == folder[-1] == '"':
|
||||
folder = folder[1:-1]
|
||||
# new update for the IMAP Folder DocType
|
||||
IMAPFolder = frappe.qb.DocType("IMAP Folder")
|
||||
frappe.qb.update(IMAPFolder).set(IMAPFolder.uidvalidity, current_uid_validity).set(
|
||||
IMAPFolder.uidnext, uidnext
|
||||
).where(IMAPFolder.parent == self.settings.email_account_name).where(
|
||||
IMAPFolder.folder_name == folder
|
||||
).run()
|
||||
|
||||
frappe.db.set_value(
|
||||
"IMAP Folder",
|
||||
{"parent": self.settings.email_account_name, "folder_name": folder},
|
||||
{"uidvalidity": current_uid_validity, "uidnext": uidnext},
|
||||
update_modified=False,
|
||||
)
|
||||
else:
|
||||
EmailAccount = frappe.qb.DocType("Email Account")
|
||||
frappe.qb.update(EmailAccount).set(EmailAccount.uidvalidity, current_uid_validity).set(
|
||||
EmailAccount.uidnext, uidnext
|
||||
).where(EmailAccount.name == self.settings.email_account_name).run()
|
||||
frappe.db.set_value(
|
||||
"Email Account",
|
||||
self.settings.email_account_name,
|
||||
{"uidvalidity": current_uid_validity, "uidnext": uidnext},
|
||||
update_modified=False,
|
||||
)
|
||||
|
||||
sync_count = 100 if uid_validity else int(self.settings.initial_sync_count)
|
||||
from_uid = 1 if uidnext < (sync_count + 1) or (uidnext - sync_count) < 1 else uidnext - sync_count
|
||||
|
|
@ -245,10 +250,7 @@ class EmailServer:
|
|||
pattern = rf"(?<={cmd} )[0-9]*"
|
||||
match = re.search(pattern, response.decode("utf-8"), re.U | re.I)
|
||||
|
||||
if match:
|
||||
return match.group(0)
|
||||
else:
|
||||
return None
|
||||
return match[0] if match else None
|
||||
|
||||
def retrieve_message(self, uid, msg_num):
|
||||
try:
|
||||
|
|
@ -267,7 +269,7 @@ class EmailServer:
|
|||
|
||||
except Exception as e:
|
||||
if self.has_login_limit_exceeded(e):
|
||||
raise LoginLimitExceeded(e)
|
||||
raise LoginLimitExceeded(e) from e
|
||||
|
||||
frappe.log_error("Unable to fetch email", self.make_error_msg(uid, msg_num))
|
||||
|
||||
|
|
@ -295,20 +297,18 @@ class EmailServer:
|
|||
with suppress(Exception):
|
||||
if not cint(self.settings.use_imap):
|
||||
self.pop.dele(msg_num)
|
||||
else:
|
||||
# mark as seen if email sync rule is UNSEEN (syncing only unseen mails)
|
||||
if self.settings.email_sync_rule == "UNSEEN":
|
||||
self.imap.uid("STORE", uid, "+FLAGS", "(\\SEEN)")
|
||||
elif self.settings.email_sync_rule == "UNSEEN":
|
||||
self.imap.uid("STORE", uid, "+FLAGS", "(\\SEEN)")
|
||||
|
||||
def is_temporary_system_problem(self, e):
|
||||
messages = (
|
||||
"-ERR [SYS/TEMP] Temporary system problem. Please try again later.",
|
||||
"Connection timed out",
|
||||
)
|
||||
for message in messages:
|
||||
if message in strip(cstr(e)) or message in strip(cstr(getattr(e, "strerror", ""))):
|
||||
return True
|
||||
return False
|
||||
return any(
|
||||
message in strip(cstr(e)) or message in strip(cstr(getattr(e, "strerror", "")))
|
||||
for message in messages
|
||||
)
|
||||
|
||||
def make_error_msg(self, uid, msg_num):
|
||||
traceback = frappe.get_traceback(with_context=True)
|
||||
|
|
@ -322,14 +322,16 @@ class EmailServer:
|
|||
partial_mail = Email(headers)
|
||||
|
||||
if partial_mail:
|
||||
return (
|
||||
"\nDate: {date}\nFrom: {from_email}\nSubject: {subject}\n\n\nTraceback: \n{traceback}".format(
|
||||
date=partial_mail.date,
|
||||
from_email=partial_mail.from_email,
|
||||
subject=partial_mail.subject,
|
||||
traceback=traceback,
|
||||
)
|
||||
)
|
||||
return f"""
|
||||
Date: {partial_mail.date}
|
||||
From: {partial_mail.from_email}
|
||||
Subject: {partial_mail.subject}
|
||||
|
||||
|
||||
Traceback:
|
||||
{traceback}
|
||||
"""
|
||||
|
||||
return traceback
|
||||
|
||||
def update_flag(self, folder, uid_list=None):
|
||||
|
|
@ -415,10 +417,7 @@ class Email:
|
|||
|
||||
# Convert non-string (e.g. None)
|
||||
# Truncate to 140 chars (can be used as a document name)
|
||||
self.subject = str(self.subject).strip()[:140]
|
||||
|
||||
if not self.subject:
|
||||
self.subject = "No Subject"
|
||||
self.subject = str(self.subject).strip()[:140] or "No Subject"
|
||||
|
||||
def set_from(self):
|
||||
# gmail mailing-list compatibility
|
||||
|
|
@ -499,12 +498,7 @@ class Email:
|
|||
self.html_content += markdown(text_content)
|
||||
|
||||
def get_charset(self, part):
|
||||
"""Detect charset."""
|
||||
charset = part.get_content_charset()
|
||||
if not charset:
|
||||
charset = chardet.detect(safe_encode(cstr(part)))["encoding"]
|
||||
|
||||
return charset
|
||||
return part.get_content_charset() or chardet.detect(safe_encode(cstr(part)))["encoding"]
|
||||
|
||||
def get_payload(self, part):
|
||||
charset = self.get_charset(part)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue