diff --git a/aprsd/email.py b/aprsd/email.py index 68481b3..921b14f 100644 --- a/aprsd/email.py +++ b/aprsd/email.py @@ -184,7 +184,12 @@ def parse_email(msgid, data, server): else: from_addr = "noaddr" LOG.debug("Got a message from '{}'".format(from_addr)) - m = server.fetch([msgid], ["RFC822"]) + try: + m = server.fetch([msgid], ["RFC822"]) + except Exception as e: + LOG.exception("Couldn't fetch email from server in parse_email", e) + return + msg = email.message_from_string(m[msgid][b"RFC822"].decode(errors="ignore")) if msg.is_multipart(): text = "" @@ -324,7 +329,12 @@ def resend_email(count, fromcall): LOG.exception("Failed to Connect to IMAP. Cannot resend email ", e) return - messages = server.search(["SINCE", today]) + try: + messages = server.search(["SINCE", today]) + except Exception as e: + LOG.exception("Couldn't search for emails in resend_email ", e) + return + # LOG.debug("%d messages received today" % len(messages)) msgexists = False @@ -332,11 +342,21 @@ def resend_email(count, fromcall): messages.sort(reverse=True) del messages[int(count) :] # only the latest "count" messages for message in messages: - for msgid, data in list(server.fetch(message, ["ENVELOPE"]).items()): + try: + parts = server.fetch(message, ["ENVELOPE"]).items() + except Exception as e: + LOG.exception("Couldn't fetch email parts in resend_email", e) + continue + + for msgid, data in list(parts): # one at a time, otherwise order is random (body, from_addr) = parse_email(msgid, data, server) # unset seen flag, will stay bold in email client - server.remove_flags(msgid, [imapclient.SEEN]) + try: + server.remove_flags(msgid, [imapclient.SEEN]) + except Exception as e: + LOG.exception("Failed to remove SEEN flag in resend_email", e) + if from_addr in shortcuts_inverted: # reverse lookup of a shortcut from_addr = shortcuts_inverted[from_addr] @@ -436,60 +456,81 @@ class APRSDEmailThread(threads.APRSDThread): continue LOG.debug("{} messages received today".format(len(messages))) - LOG.debug("Try Server.fetch.") try: - for msgid, data in server.fetch(messages, ["ENVELOPE"]).items(): - envelope = data[b"ENVELOPE"] - LOG.debug( - 'ID:%d "%s" (%s)' - % (msgid, envelope.subject.decode(), envelope.date), - ) - f = re.search( - r"'([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)", - str(envelope.from_[0]), - ) - if f is not None: - from_addr = f.group(1) - else: - from_addr = "noaddr" + _msgs = server.fetch(messages, ["ENVELOPE"]) + except Exception as e: + LOG.exception("IMAP failed to fetch/flag messages: ", e) + continue - # LOG.debug("Message flags/tags: " + str(server.get_flags(msgid)[msgid])) - # if "APRS" not in server.get_flags(msgid)[msgid]: - # in python3, imap tags are unicode. in py2 they're strings. so .decode them to handle both - taglist = [ - x.decode(errors="ignore") - for x in server.get_flags(msgid)[msgid] - ] - if "APRS" not in taglist: - # if msg not flagged as sent via aprs - LOG.debug("Try single fetch.") + for msgid, data in _msgs.items(): + envelope = data[b"ENVELOPE"] + LOG.debug( + 'ID:%d "%s" (%s)' + % (msgid, envelope.subject.decode(), envelope.date), + ) + f = re.search( + r"'([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)", + str(envelope.from_[0]), + ) + if f is not None: + from_addr = f.group(1) + else: + from_addr = "noaddr" + + # LOG.debug("Message flags/tags: " + str(server.get_flags(msgid)[msgid])) + # if "APRS" not in server.get_flags(msgid)[msgid]: + # in python3, imap tags are unicode. in py2 they're strings. so .decode them to handle both + taglist = [ + x.decode(errors="ignore") + for x in server.get_flags(msgid)[msgid] + ] + if "APRS" not in taglist: + # if msg not flagged as sent via aprs + LOG.debug("Try single fetch.") + try: server.fetch([msgid], ["RFC822"]) - LOG.debug("Did single fetch.") - (body, from_addr) = parse_email(msgid, data, server) - # unset seen flag, will stay bold in email client + except Exception as e: + LOG.exception("Failed single server fetch for RFC822", e) + break + + LOG.debug("Did single fetch.") + (body, from_addr) = parse_email(msgid, data, server) + # unset seen flag, will stay bold in email client + try: LOG.debug("Try remove flags.") server.remove_flags(msgid, [imapclient.SEEN]) LOG.debug("Did remove flags.") + except Exception as e: + LOG.exception("Failed to remove flags SEEN", e) + # Not much we can do here, so lets try and + # send the aprs message anyway - if from_addr in shortcuts_inverted: - # reverse lookup of a shortcut - from_addr = shortcuts_inverted[from_addr] + if from_addr in shortcuts_inverted: + # reverse lookup of a shortcut + from_addr = shortcuts_inverted[from_addr] - reply = "-" + from_addr + " " + body.decode(errors="ignore") - msg = messaging.TextMessage( - self.config["aprs"]["login"], - self.config["ham"]["callsign"], - reply, - ) - self.msg_queues["tx"].put(msg) - # flag message as sent via aprs + reply = "-" + from_addr + " " + body.decode(errors="ignore") + msg = messaging.TextMessage( + self.config["aprs"]["login"], + self.config["ham"]["callsign"], + reply, + ) + self.msg_queues["tx"].put(msg) + # flag message as sent via aprs + try: server.add_flags(msgid, ["APRS"]) # unset seen flag, will stay bold in email client + except Exception as e: + LOG.exception("Couldn't add APRS flag to email", e) + + try: server.remove_flags(msgid, [imapclient.SEEN]) - # check email more often since we just received an email - check_email_delay = 60 - except Exception as e: - LOG.exception("IMAP failed to fetch/flag messages: ", e) + except Exception as e: + LOG.exception("Couldn't remove seen flag from email", e) + + # check email more often since we just received an email + check_email_delay = 60 + # reset clock LOG.debug("Done looping over Server.fetch, logging out.") past = datetime.datetime.now()