Bugfixes and implemented attachment forwarding

This commit is contained in:
Mike 2023-06-07 21:21:37 +02:00
parent 8dae830443
commit f61455bad0

65
main.py
View File

@ -1,4 +1,5 @@
import datetime, imaplib, email, time, utm, requests, json, os, smtplib, logging, sys import datetime, imaplib, email, time, utm, requests, json, os, smtplib, logging, sys
from urllib.parse import unquote
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
if os.environ.get("DEBUG", False): if os.environ.get("DEBUG", False):
@ -91,6 +92,7 @@ class FetchEmail():
logger.debug(f"Using search term '{searchTerm}'") logger.debug(f"Using search term '{searchTerm}'")
(result, messages) = self.connection.search(None, searchTerm) (result, messages) = self.connection.search(None, searchTerm)
body = None body = None
attachment = []
if result == "OK": if result == "OK":
mail_ids = messages[0] mail_ids = messages[0]
@ -99,7 +101,7 @@ class FetchEmail():
if mail_ids == b"": if mail_ids == b"":
logger.debug(f"No Email found") logger.debug(f"No Email found")
self.close_connection() self.close_connection()
return None return None, attachment
try: try:
#ret, data = self.connection.fetch(id_list[-1], '(UID BODY[TEXT])') #ret, data = self.connection.fetch(id_list[-1], '(UID BODY[TEXT])')
@ -115,19 +117,29 @@ class FetchEmail():
if email_msg.is_multipart(): if email_msg.is_multipart():
for part in email_msg.walk(): for part in email_msg.walk():
if part.get_content_type() == "text/html": if part.get_content_type() == "text/html":
logger.debug("Found HTML File in Email")
body = part.get_payload(decode=True)
body = body.decode()
elif part.get_content_type() == "text/plain":
logger.debug("Found Text in Email")
body = part.get_payload(decode=True) body = part.get_payload(decode=True)
body = body.decode() body = body.decode()
elif part.get_content_type() == "text/plain": if part.get_content_type() == "application/pdf":
body = part.get_payload(decode=True) logger.debug("Found PDF File in Email")
body = body.decode() attachment.append({
"filename": part.get_filename(),
"type": "application/pdf",
"content": part.get_payload(decode=True)
})
except Exception as err: except Exception as err:
logger.error(f"Could not retrieve email. Got: {err}", exc_info=True) logger.error(f"Could not retrieve email. Got: {err}", exc_info=True)
self.close_connection() self.close_connection()
return None return None, attachment
logger.debug(f"Found an email") logger.debug(f"Found an email")
return str(body) return str(body), attachment
def parse_email_address(self, email_address): def parse_email_address(self, email_address):
""" """
@ -193,25 +205,25 @@ class Alarmdepesche():
for td in tds: for td in tds:
key = str(str(td.string).strip()) key = str(str(td.string).strip())
if key == "Druckdatum:": if "Druckdatum:" in key:
self.timestamp = datetime.datetime.strptime(self.get_string(td), "%d.%m.%Y %H:%M:%S") self.timestamp = datetime.datetime.strptime(self.get_string(td), "%d.%m.%Y %H:%M:%S")
if key == "Einsatzstichwort:": if "Einsatzstichwort:" in key:
self.intervention_code = self.get_string(td) self.intervention_code = self.get_string(td)
if key == "Sachverhalt:": if "Sachverhalt:" in key:
self.intervention_message = self.get_string(td) self.intervention_message = self.get_string(td)
if key == "Alarmiertes Einsatzmittel:": if "Alarmiertes Einsatzmittel:" in key:
engine = self.get_string(td) engine = self.get_string(td)
if "," in engine: if "," in engine:
logger.warning(f"Unusual engine format, got {engine} only using last entry") logger.warning(f"Unusual engine format, got {engine} only using last entry")
engine = engine.split(",")[-1].strip() engine = engine.split(",")[-1].strip()
self.engine = engine self.engine = engine
if key == "Einsatznummer:": if "Einsatznummer:" in key:
self.intervention_number = self.get_string(td) self.intervention_number = self.get_string(td)
if key == "Stadt:": if "Stadt:" in key:
self.city = self.get_string(td) self.city = self.get_string(td)
if key == "Info:": if "Info:" in key:
self.info = self.get_string(td) self.info = self.get_string(td)
if key == "UTM - Koordinaten:": if "UTM - Koordinaten:" in key:
utm_string = self.get_string(td).split(" ") utm_string = self.get_string(td).split(" ")
self.geo_point = utm.to_latlon(int(utm_string[1]), int(utm_string[2]), int(utm_string[0][:2]), self.geo_point = utm.to_latlon(int(utm_string[1]), int(utm_string[2]), int(utm_string[0][:2]),
utm_string[0][2]) utm_string[0][2])
@ -281,13 +293,19 @@ class Email():
smtp_client : smtplib.SMTP smtp_client : smtplib.SMTP
def __init__(self, smtp_server, smtp_port, smtp_user, smtp_password): def __init__(self, smtp_server, smtp_port, smtp_user, smtp_password):
if os.environ.get("SMTP_SERVER", None):
smtp_server = os.environ.get("SMTP_SERVER")
if os.environ.get("SMTP_PORT", None):
smtp_port = os.environ.get("SMTP_PORT")
logger.debug(f"Connecting to SMTP Server {smtp_server}") logger.debug(f"Connecting to SMTP Server {smtp_server}")
try: try:
self.smtp_client = smtplib.SMTP(smtp_server, smtp_port) self.smtp_client = smtplib.SMTP(smtp_server, smtp_port)
self.smtp_client.ehlo() self.smtp_client.ehlo()
if os.environ.get("MAIL_SMTP_STARTTLS", True): if os.environ.get("MAIL_SMTP_STARTTLS", True):
self.smtp_client.starttls() self.smtp_client.starttls()
self.smtp_client.login(smtp_user, smtp_password) if os.environ.get("SMTP_AUTH", True):
self.smtp_client.login(smtp_user, smtp_password)
logger.debug("Connection to SMTP Sever was successfull") logger.debug("Connection to SMTP Sever was successfull")
except BaseException as err: except BaseException as err:
logger.error(f"Connection to SMTP Sevrer failed. Got {err}", exc_info=True) logger.error(f"Connection to SMTP Sevrer failed. Got {err}", exc_info=True)
@ -297,9 +315,10 @@ class Email():
self.smtp_client.close() self.smtp_client.close()
def sendmail(self, alarmdepesche, msg_from, msg_to): def sendmail(self, alarmdepesche, msg_from, msg_to, attachment=None):
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
logger.debug(f"Preparing email for {msg_to}") logger.debug(f"Preparing email for {msg_to}")
@ -321,6 +340,11 @@ class Email():
msg.attach(part1) msg.attach(part1)
msg.attach(part2) msg.attach(part2)
if attachment:
part3 = MIMEApplication(attachment[0]["content"], Name=unquote(attachment[0]["filename"]), _subtype="pdf")
part3['Content-Disposition'] = f'attachment; filename="{unquote(attachment[0]["filename"])}"'
msg.attach(part3)
logger.info(f"Sending email to {msg_to}") logger.info(f"Sending email to {msg_to}")
# sendmail function takes 3 arguments: sender's address, recipient's address # sendmail function takes 3 arguments: sender's address, recipient's address
@ -341,6 +365,7 @@ if __name__ == '__main__':
mail_user = os.environ.get('MAIL_USER', None) mail_user = os.environ.get('MAIL_USER', None)
mail_from = os.environ.get('MAIL_FROM', mail_user) mail_from = os.environ.get('MAIL_FROM', mail_user)
mail_pass = os.environ.get('MAIL_PASS', None) mail_pass = os.environ.get('MAIL_PASS', None)
mail_port = os.environ.get('MAIL_PORT', 587)
if not mail_server or not mail_user or not mail_pass: if not mail_server or not mail_user or not mail_pass:
logger.error("Environment variables not set!, exiting...") logger.error("Environment variables not set!, exiting...")
@ -363,18 +388,18 @@ if __name__ == '__main__':
fetchmail = FetchEmail(mail_server, mail_user, mail_pass) fetchmail = FetchEmail(mail_server, mail_user, mail_pass)
fetchmail.select_mailbox() fetchmail.select_mailbox()
html_message = fetchmail.fetch_messages_content("FROM els.112@cgdis.lu (UNSEEN)") html_message, attachment = fetchmail.fetch_messages_content("FROM els.112@cgdis.lu (UNSEEN)")
if html_message: if html_message:
current_alarmdepsche = Alarmdepesche() current_alarmdepsche = Alarmdepesche()
current_alarmdepsche.from_html(html_message) current_alarmdepsche.from_html(html_message)
current_alarmdepsche.saveToDisk() current_alarmdepsche.saveToDisk()
metric_api_up = current_alarmdepsche.metric_api_up metric_api_up = current_alarmdepsche.metric_api_up
members = current_alarmdepsche.get_members_emails() members = current_alarmdepsche.get_members_emails()
sendmail = Email(mail_server, 587, mail_user, mail_pass) sendmail = Email(mail_server, mail_port, mail_user, mail_pass)
for email_addr in members: for email_addr in members:
sendmail.sendmail(current_alarmdepsche, mail_from, email_addr) sendmail.sendmail(current_alarmdepsche, mail_from, email_addr, attachment)
else: else:
logger.info("Message could not be loaded, exiting...") logger.info("No message found, exiting...")
timer_global.end() timer_global.end()
prometheus.append_gauge_metric("permaalert_execution_time", timer_global.took, prometheus.append_gauge_metric("permaalert_execution_time", timer_global.took,