Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace email functions with apprise notification functions. #29

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
*.yml
*.yaml
*.log
snapraid-runner.conf
3 changes: 3 additions & 0 deletions apprise.yml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
urls:
- pbul://MY-KEY

27 changes: 11 additions & 16 deletions snapraid-runner.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,22 @@ file = snapraid.log
; maximum logfile size in KiB, leave empty for infinite
maxsize = 5000

[email]
; when to send an email, comma-separated list of [success, error]
[notification]
enabled = true

; when to send a notificariton on, comma-separated list of [success, error]
sendon = success,error
; set to false to get full programm output via email

; set to false to get full programm output
short = true
subject = [SnapRAID] Status Report:
from =
to =

; Python Apprise config.
; https://github.com/caronc/apprise/wiki/config_yaml
config = apprise.yml

; maximum email size in KiB
maxsize = 500

[smtp]
host =
; leave empty for default port
port =
; set to "true" to activate
ssl = false
tls = false
user =
password =

[scrub]
; set to true to run scrub after sync
enabled = false
Expand Down
105 changes: 41 additions & 64 deletions snapraid-runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Global variables
config = None
email_log = None
notification_log = None


def tee_log(infile, out_lines, log_level):
Expand Down Expand Up @@ -71,64 +71,42 @@ def snapraid_command(command, args={}, *, allow_statuscodes=[]):
else:
raise subprocess.CalledProcessError(ret, "snapraid " + command)

def send_notification(success):
import apprise
logging.info("sending msg")
# Create an Apprise instance
apobj = apprise.Apprise()

def send_email(success):
import smtplib
from email.mime.text import MIMEText
from email import charset
# Create an Config instance
apprise_config = apprise.AppriseConfig()

if len(config["smtp"]["host"]) == 0:
logging.error("Failed to send email because smtp host is not set")
return
apprise_config_file = config["notification"]["config"]
# Add a configuration source:
apprise_config.add(apprise_config_file)
# Make sure to add our config into our apprise object
apobj.add(apprise_config)

# use quoted-printable instead of the default base64
charset.add_charset("utf-8", charset.SHORTEST, charset.QP)
if success:
body = "SnapRAID job completed successfully:\n\n\n"
message_title = "SnapRAID job completed successfully:\n\n\n"
else:
body = "Error during SnapRAID job:\n\n\n"

log = email_log.getvalue()
maxsize = config['email'].get('maxsize', 500) * 1024
if maxsize and len(log) > maxsize:
cut_lines = log.count("\n", maxsize // 2, -maxsize // 2)
log = (
"NOTE: Log was too big for email and was shortened\n\n" +
log[:maxsize // 2] +
"[...]\n\n\n --- LOG WAS TOO BIG - {} LINES REMOVED --\n\n\n[...]".format(
cut_lines) +
log[-maxsize // 2:])
body += log

msg = MIMEText(body, "plain", "utf-8")
msg["Subject"] = config["email"]["subject"] + \
(" SUCCESS" if success else " ERROR")
msg["From"] = config["email"]["from"]
msg["To"] = config["email"]["to"]
smtp = {"host": config["smtp"]["host"]}
if config["smtp"]["port"]:
smtp["port"] = config["smtp"]["port"]
if config["smtp"]["ssl"]:
server = smtplib.SMTP_SSL(**smtp)
else:
server = smtplib.SMTP(**smtp)
if config["smtp"]["tls"]:
server.starttls()
if config["smtp"]["user"]:
server.login(config["smtp"]["user"], config["smtp"]["password"])
server.sendmail(
config["email"]["from"],
[config["email"]["to"]],
msg.as_string())
server.quit()

message_title = "Error during SnapRAID job:\n\n\n"

message_body = notification_log.getvalue()

# Then notify these services any time you desire. The below would
# notify all of the services that have not been bound to any specific
# tag.
apobj.notify(
body=message_body,
title=message_title,
)

def finish(is_success):
if ("error", "success")[is_success] in config["email"]["sendon"]:
if ("error", "success")[is_success] in config["notification"]["sendon"]:
try:
send_email(is_success)
send_notification(is_success)
except Exception:
logging.exception("Failed to send email")
logging.exception("Failed to send notification")
if is_success:
logging.info("Run finished successfully")
else:
Expand All @@ -140,27 +118,25 @@ def load_config(args):
global config
parser = configparser.RawConfigParser()
parser.read(args.conf)
sections = ["snapraid", "logging", "email", "smtp", "scrub"]
sections = ["snapraid", "logging", "scrub", "notification"]
config = dict((x, defaultdict(lambda: "")) for x in sections)
for section in parser.sections():
for (k, v) in parser.items(section):
config[section][k] = v.strip()

int_options = [
("snapraid", "deletethreshold"), ("logging", "maxsize"),
("scrub", "percentage"), ("scrub", "older-than"), ("email", "maxsize"),
("scrub", "percentage"), ("scrub", "older-than"),
]
for section, option in int_options:
try:
config[section][option] = int(config[section][option])
except ValueError:
config[section][option] = 0

config["smtp"]["ssl"] = (config["smtp"]["ssl"].lower() == "true")
config["smtp"]["tls"] = (config["smtp"]["tls"].lower() == "true")
config["scrub"]["enabled"] = (config["scrub"]["enabled"].lower() == "true")
config["email"]["short"] = (config["email"]["short"].lower() == "true")
config["snapraid"]["touch"] = (config["snapraid"]["touch"].lower() == "true")
config["snapraid"]["touch"] = (
config["snapraid"]["touch"].lower() == "true")

if args.scrub is not None:
config["scrub"]["enabled"] = args.scrub
Expand Down Expand Up @@ -188,15 +164,15 @@ def setup_logger():
file_logger.setFormatter(log_format)
root_logger.addHandler(file_logger)

if config["email"]["sendon"]:
global email_log
email_log = StringIO()
email_logger = logging.StreamHandler(email_log)
email_logger.setFormatter(log_format)
if config["email"]["short"]:
if config["notification"]["sendon"]:
global notification_log
notification_log = StringIO()
notification_logger = logging.StreamHandler(notification_log)
notification_logger.setFormatter(log_format)
if config["notification"]["short"]:
# Don't send programm stdout in email
email_logger.setLevel(logging.INFO)
root_logger.addHandler(email_logger)
notification_logger.setLevel(logging.INFO)
root_logger.addHandler(notification_logger)


def main():
Expand Down Expand Up @@ -302,3 +278,4 @@ def run():


main()