Refactor code to combine email and XMPP alerting into single class
- Create a new module `alert_processor.py` for handling both email and XMPP alerts. - Remove the email_alert.py and xmpp_alert.py files.
This commit is contained in:
parent
ea34a0ef32
commit
2c8151870c
|
@ -0,0 +1,118 @@
|
|||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
import ssl
|
||||
import humanfriendly
|
||||
import slixmpp
|
||||
|
||||
class AlertProcessor:
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
def _create_email(self, event, next_alert, next_event):
|
||||
# Set up the SMTP server details
|
||||
smtp_server = self.config["email"]["smtp_server"]
|
||||
port = self.config["email"]["port"]
|
||||
sender_email = self.config["email"]["username"]
|
||||
receiver_email = self.config["email"]["recipient"]
|
||||
password = self.config["email"]["password"]
|
||||
|
||||
# Event details
|
||||
event_name, event_description, event_location, event_date, human_readable_time = self._get_event_details(event, next_alert, next_event)
|
||||
|
||||
# Create a multipart message and set headers
|
||||
message = MIMEMultipart()
|
||||
message["From"] = sender_email
|
||||
message["To"] = receiver_email
|
||||
message["Subject"] = "Event Alert: '{}' @ {}".format(event_name, event_date)
|
||||
|
||||
# Add body to email
|
||||
body = self._create_email_body(event_name, event_date, event_description, event_location, human_readable_time)
|
||||
message.attach(MIMEText(body, "plain"))
|
||||
text = message.as_string()
|
||||
|
||||
return smtp_server, port, sender_email, receiver_email, password, text
|
||||
|
||||
def _get_event_details(self, event, next_alert, next_event):
|
||||
# Event details
|
||||
event_name = event["summary"]
|
||||
event_description = event["description"]
|
||||
event_location = event["location"]
|
||||
event_date = next_event
|
||||
event_delta = next_event - next_alert
|
||||
total_seconds = event_delta.total_seconds()
|
||||
human_readable_time = humanfriendly.format_timespan(total_seconds)
|
||||
|
||||
return event_name, event_description, event_location, event_date, human_readable_time
|
||||
|
||||
def _create_email_body(self, event_name, event_date, event_description, event_location, human_readable_time):
|
||||
body = """\
|
||||
Hi,
|
||||
This is an event alert from remindme_caldav.
|
||||
|
||||
Event details:
|
||||
---------------------------------
|
||||
|
||||
Event name: {}
|
||||
Date/time: {}
|
||||
Description: {}
|
||||
Location: {}
|
||||
Time until event: {}
|
||||
|
||||
---------------------------------
|
||||
""".format(event_name, event_date, event_description, event_location, human_readable_time)
|
||||
return body
|
||||
|
||||
def send_email(self, event, next_alert, next_event):
|
||||
try:
|
||||
smtp_server, port, sender_email, receiver_email, password, text = self._create_email(event, next_alert, next_event)
|
||||
|
||||
# Create a secure SSL context and connect to the server
|
||||
context = ssl.create_default_context()
|
||||
with smtplib.SMTP(smtp_server, port) as server: # Use 'with' statement for automatic cleanup
|
||||
server.ehlo() # Can be omitted
|
||||
server.starttls(context=context) # Secure the connection
|
||||
server.login(sender_email, password)
|
||||
|
||||
# Send email here
|
||||
server.sendmail(sender_email, receiver_email, text)
|
||||
return print("Message sent via email")
|
||||
except Exception as e:
|
||||
# Print any error messages to stdout
|
||||
print("An error occured when sending alert via email, please check your config. Message: {}".format(e))
|
||||
|
||||
def _create_xmpp_bot(self, event, next_alert, next_event):
|
||||
class SendMsgBot(slixmpp.ClientXMPP):
|
||||
def __init__(self, jid, password, recipient, message):
|
||||
super().__init__(jid, password)
|
||||
self.recipient = recipient
|
||||
self.msg = message
|
||||
self.add_event_handler("session_start", self.start)
|
||||
|
||||
def start(self, event):
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
self.send_message(mto=self.recipient, mbody=self.msg, mtype='chat')
|
||||
self.disconnect()
|
||||
|
||||
jid = self.config["xmpp"]["jid"]
|
||||
password = self.config["xmpp"]["password"] # replace with your password
|
||||
recipient = self.config["xmpp"]["recipient"]
|
||||
|
||||
event_name, event_description, event_location, event_date, human_readable_time = self._get_event_details(event, next_alert, next_event)
|
||||
|
||||
message = self._create_email_body(event_name, event_date, event_description, event_location, human_readable_time)
|
||||
|
||||
return SendMsgBot(jid, password, recipient, message)
|
||||
|
||||
def send_xmpp(self, event, next_alert, next_event):
|
||||
try:
|
||||
bot = self._create_xmpp_bot(event, next_alert, next_event)
|
||||
|
||||
bot.register_plugin('xep_0030') # Service Discovery
|
||||
bot.register_plugin('xep_0199') # XMPP Ping
|
||||
bot.connect()
|
||||
bot.process(forever=False)
|
||||
return print("Message sent via XMPP")
|
||||
except Exception as e:
|
||||
print("An error occured when sending alert via XMPP, please check your config. Message: {}".format(e))
|
|
@ -1,62 +0,0 @@
|
|||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
import ssl
|
||||
import humanfriendly
|
||||
|
||||
def send_email(event, next_alert, next_event, config):
|
||||
# Set up the SMTP server details
|
||||
smtp_server = config["email"]["smtp_server"]
|
||||
port = config["email"]["port"]
|
||||
sender_email = config["email"]["username"]
|
||||
receiver_email = config["email"]["recipient"]
|
||||
password = config["email"]["password"]
|
||||
|
||||
# Event details
|
||||
event_name = event["summary"]
|
||||
event_description = event["description"]
|
||||
event_location = event["location"]
|
||||
event_date = next_event
|
||||
event_delta = next_event - next_alert
|
||||
total_seconds = event_delta.total_seconds()
|
||||
human_readable_time = humanfriendly.format_timespan(total_seconds)
|
||||
|
||||
# Create a multipart message and set headers
|
||||
message = MIMEMultipart()
|
||||
message["From"] = sender_email
|
||||
message["To"] = receiver_email
|
||||
message["Subject"] = "Event Alert: '{}' @ {}".format(event_name, event_date)
|
||||
|
||||
# Add body to email
|
||||
body = """\
|
||||
Hi,
|
||||
This is an event alert from remindme_caldav.
|
||||
|
||||
Event details:
|
||||
---------------------------------
|
||||
|
||||
Event name: {}
|
||||
Date/time: {}
|
||||
Description: {}
|
||||
Location: {}
|
||||
Time until event: {}
|
||||
|
||||
---------------------------------
|
||||
""".format(event_name, event_date, event_description, event_location, human_readable_time)
|
||||
message.attach(MIMEText(body, "plain"))
|
||||
text = message.as_string()
|
||||
|
||||
try:
|
||||
# Create a secure SSL context and connect to the server
|
||||
context = ssl.create_default_context()
|
||||
with smtplib.SMTP(smtp_server, port) as server: # Use 'with' statement for automatic cleanup
|
||||
server.ehlo() # Can be omitted
|
||||
server.starttls(context=context) # Secure the connection
|
||||
server.login(sender_email, password)
|
||||
|
||||
# Send email here
|
||||
server.sendmail(sender_email, receiver_email, text)
|
||||
return print("Message sent via email")
|
||||
except Exception as e:
|
||||
# Print any error messages to stdout
|
||||
print("An error occured when sending alert via email, please check your config. Message: {}".format(e))
|
|
@ -7,13 +7,10 @@ import datetime as dt
|
|||
import time
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
import email_alert, xmpp_alert
|
||||
from pprint import pprint
|
||||
import humanfriendly
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import textwrap
|
||||
import logging
|
||||
import argparse, textwrap, logging
|
||||
from alert_processor import AlertProcessor
|
||||
|
||||
def setup_logger(loglevel):
|
||||
"""Setup basic logging."""
|
||||
|
@ -148,7 +145,7 @@ class RecurringEventGenerator:
|
|||
"infinite_recur": False,
|
||||
"recur_freq": None,
|
||||
"recur_interval": None,
|
||||
"n_recur_dates_left": None
|
||||
"n_recur_dates_left": 1
|
||||
}
|
||||
|
||||
def generate(self):
|
||||
|
@ -161,9 +158,10 @@ class RecurringEventGenerator:
|
|||
freq = self.rrule.get('FREQ')[0]
|
||||
count = self.rrule.get("COUNT")
|
||||
interval = self.rrule.get('INTERVAL')[0]
|
||||
until = self.rrule.get('UNTIL')
|
||||
current_date = dt.datetime.now().replace(tzinfo=pytz.UTC)
|
||||
|
||||
if count is None:
|
||||
if count is None or until is not None:
|
||||
delta = None
|
||||
|
||||
if freq == "DAILY":
|
||||
|
@ -211,7 +209,6 @@ class CalendarParser:
|
|||
generator = RecurringEventGenerator(dtstart, event_dict["rrule"])
|
||||
recur_info = generator.generate()
|
||||
event_dates = self.remove_exdates(event_dict["exdate"], recur_info["recur_dates"])
|
||||
|
||||
valarms = self.process_valarm(event)
|
||||
|
||||
event_dict = {
|
||||
|
@ -290,15 +287,21 @@ def get_next_alert(event, current_time):
|
|||
if event_dates == [] or event_dates is None or current_time > event_dates[-1]:
|
||||
return None, None
|
||||
next_event = [i for i in event_dates if i >= current_time][0]
|
||||
next_alert_list = [next_event + i for i in valarm_deltas]
|
||||
next_alert = min(next_alert_list)
|
||||
next_alert_list = [next_event + i for i in valarm_deltas if next_event + i >= current_time]
|
||||
if len(next_alert_list) == 0:
|
||||
next_alert = next_event
|
||||
else:
|
||||
next_alert = min(next_alert_list)
|
||||
return next_alert - dt.timedelta(seconds=5), next_event
|
||||
|
||||
def process_alert(current_time, next_alert, next_event, event, config):
|
||||
"""
|
||||
This function processes a given alert and passes it to a messaging client.
|
||||
"""
|
||||
if current_time >= next_alert and next_alert < next_alert + dt.timedelta(seconds=15):
|
||||
if current_time >= next_alert and current_time < next_alert + dt.timedelta(seconds=15):
|
||||
print(current_time, next_alert, next_alert + dt.timedelta(seconds=15))
|
||||
print(True if current_time >= next_alert else False)
|
||||
print(True if next_alert < next_alert + dt.timedelta(seconds=15) else False)
|
||||
if len(event["alert_history"]) == 0:
|
||||
print("First alert for '{}' detected".format(event["summary"]))
|
||||
event["alert_history"] = [{"timestamp_alert_triggered": current_time, "alert_defintition_time": next_alert}]
|
||||
|
@ -308,8 +311,9 @@ def process_alert(current_time, next_alert, next_event, event, config):
|
|||
print("Posting alert for {}!".format(event["summary"]))
|
||||
event["alert_history"].append({"timestamp_alert_triggered": current_time, "alert_defintition_time": next_alert})
|
||||
#xmpp_alert.send_xmpp(event["summary"], next_alert, next_event, args.config)
|
||||
email_alert.send_email(event, next_alert, next_event, config)
|
||||
xmpp_alert.send_xmpp(event, next_alert, next_event, config)
|
||||
processor = AlertProcessor(config)
|
||||
processor.send_email(event, next_alert, next_event)
|
||||
#processor.send_xmpp(event, next_alert, next_event)
|
||||
with open("alert_history", 'a') as f:
|
||||
f.write(str(event)) # write expects a str not dict
|
||||
return
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
import slixmpp
|
||||
import humanfriendly
|
||||
|
||||
class SendMsgBot(slixmpp.ClientXMPP):
|
||||
def __init__(self, jid, password, recipient, message):
|
||||
super().__init__(jid, password)
|
||||
self.recipient = recipient
|
||||
self.msg = message
|
||||
self.add_event_handler("session_start", self.start)
|
||||
|
||||
def start(self, event):
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
self.send_message(mto=self.recipient, mbody=self.msg, mtype='chat')
|
||||
self.disconnect()
|
||||
|
||||
def send_xmpp(event, next_alert, next_event, config):
|
||||
event_name = event["summary"]
|
||||
event_description = event["description"]
|
||||
event_location = event["location"]
|
||||
event_date = next_event
|
||||
event_delta = next_event - next_alert
|
||||
total_seconds = event_delta.total_seconds()
|
||||
human_readable_time = humanfriendly.format_timespan(total_seconds)
|
||||
|
||||
jid = config["xmpp"]["jid"]
|
||||
password = config["xmpp"]["password"] # replace with your password
|
||||
recipient = config["xmpp"]["recipient"]
|
||||
|
||||
message = """\
|
||||
Hi,
|
||||
This is an event alert from remindme_caldav.
|
||||
|
||||
Event details:
|
||||
---------------------------------
|
||||
|
||||
Event name: {}
|
||||
Date/time: {}
|
||||
Description: {}
|
||||
Location: {}
|
||||
Time until event: {}
|
||||
|
||||
---------------------------------
|
||||
""".format(event_name, event_date, event_description, event_location, human_readable_time)
|
||||
try:
|
||||
bot = SendMsgBot(jid, password, recipient, message)
|
||||
bot.register_plugin('xep_0030') # Service Discovery
|
||||
bot.register_plugin('xep_0199') # XMPP Ping
|
||||
bot.connect()
|
||||
bot.process(forever=False)
|
||||
return print("Message sent via XMPP")
|
||||
except Exception as e:
|
||||
print("An error occured when sending alert via XMPP, please check your config. Message: {}".format(e))
|
Loading…
Reference in New Issue