This commit is contained in:
Daniel Langbein 2023-06-14 22:10:04 +02:00
parent 21f07daba6
commit 2376296b86
4 changed files with 50 additions and 50 deletions

View File

@ -5,7 +5,7 @@
_name=exec-notify _name=exec-notify
pkgname="python-$_name-git" pkgname="python-$_name-git"
pkgver=r49.b96b44a pkgver=r50.21f07da
pkgrel=1 pkgrel=1
pkgdesc='execute command and notify about failure via email' pkgdesc='execute command and notify about failure via email'
arch=(any) arch=(any)

View File

@ -41,7 +41,7 @@ def main():
print(SUBJECT) print(SUBJECT)
print(BODY) print(BODY)
mail.sendMailOrWriteToFile(SUBJECT=SUBJECT, BODY=BODY) mail.send_mail_or_write_to_file(subject=SUBJECT, body=BODY)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -9,34 +9,34 @@ from email.mime.multipart import MIMEMultipart
from exec_notify.lib import config, util from exec_notify.lib import config, util
def sendMailOrWriteToFile(SUBJECT: str, BODY: str, informAboutLocalMail: bool = True): def send_mail_or_write_to_file(subject: str, body: str, inform_about_local_mail: bool = True):
if informAboutLocalMail and _localMailExists(): if inform_about_local_mail and _local_mail_exists():
mailDir = config.getMailDir() mail_dir = config.getMailDir()
SUBJECT = f'{SUBJECT} | UNREAD LOCAL MAIL' subject = f'{subject} | UNREAD LOCAL MAIL'
BODY = f'[!] Note [!]\n' \ body = f'[!] Note [!]\n' \
f'There is local mail inside {mailDir} that was not delivered previously! ' \ f'There is local mail inside {mail_dir} that was not delivered previously! ' \
f'Please read and then delete it to get rid of this warning.\n\n\n' \ f'Please read and then delete it to get rid of this warning.\n\n\n' \
f'{BODY}' f'{body}'
try: try:
sendMail(SUBJECT=SUBJECT, BODY=BODY) send_mail(subject=subject, body=body)
except Exception as e: except Exception as e:
print(f'exec-notify>> Could not send mail: {e}', file=sys.stderr) print(f'exec-notify>> Could not send mail: {e}', file=sys.stderr)
print(f'exec-notify>> Writing to file instead ...', file=sys.stderr) print(f'exec-notify>> Writing to file instead ...', file=sys.stderr)
# Instead, try to save the mail so that the user can read # Instead, try to save the mail so that the user can read
# it later when connected to this computer # it later when connected to this computer
saveMail(SUBJECT=SUBJECT, BODY=BODY) save_mail(subject=subject, body=body)
def sendMail(SUBJECT: str, BODY: str): def send_mail(subject: str, body: str):
""" """
:raises Exception: If mail could not be sent :raises Exception: If mail could not be sent
""" """
FROM = config.getFrom() from_ = config.getFrom()
TO = config.getTo() to = config.getTo()
password = config.getPassword() password = config.getPassword()
# Create a secure SSL context # Create a secure SSL context
@ -44,58 +44,58 @@ def sendMail(SUBJECT: str, BODY: str):
host, port = config.getHostAndPort() host, port = config.getHostAndPort()
with smtplib.SMTP_SSL(host=host, port=port, context=context) as server: with smtplib.SMTP_SSL(host=host, port=port, context=context) as server:
server.login(FROM, password) server.login(from_, password)
message = MIMEMultipart() message = MIMEMultipart()
message["Subject"] = SUBJECT message["Subject"] = subject
message["From"] = FROM message["From"] = from_
message["To"] = TO message["To"] = to
message["Bcc"] = TO # Recommended for mass emails message["Bcc"] = to # Recommended for mass emails
# Turn plain/html message_body into plain/html MIMEText objects # Turn plain/html message_body into plain/html MIMEText objects
message.attach(MIMEText(BODY, "plain")) message.attach(MIMEText(body, "plain"))
server.sendmail(FROM, TO, message.as_string()) server.sendmail(from_, to, message.as_string())
def saveMail(SUBJECT: str, BODY: str): def save_mail(subject: str, body: str):
""" """
This method does NOT throw exceptions This method does NOT throw exceptions
""" """
time = datetime.datetime.now() time = datetime.datetime.now()
timeStr = time.strftime('%Y%m%d_%H%M%S') time_str = time.strftime('%Y%m%d_%H%M%S')
mailDir = config.getMailDir() mail_dir = config.getMailDir()
mailFile = mailDir.joinpath(timeStr) mail_file = mail_dir.joinpath(time_str)
prefix = '' prefix = ''
mailStr = f'{""*19}\n' \ mail_str = f'{"" * 19}\n' \
f'┣╸Date:\n' \ f'┣╸Date:\n' \
f'{util.appendLinePrefix(prefix, timeStr)}\n' \ f'{util.appendLinePrefix(prefix, time_str)}\n' \
f'┣╸Subject:\n' \ f'┣╸Subject:\n' \
f'{util.appendLinePrefix(prefix, SUBJECT)}\n' \ f'{util.appendLinePrefix(prefix, subject)}\n' \
f'┣╸Body:\n' \ f'┣╸Body:\n' \
f'{util.appendLinePrefix(prefix, BODY)}\n' \ f'{util.appendLinePrefix(prefix, body)}\n' \
f'{"" * 19}' f'{"" * 19}'
try: try:
# create parent directory if not existent # create parent directory if not existent
mailDir.mkdir(parents=True, exist_ok=True) mail_dir.mkdir(parents=True, exist_ok=True)
# append to file; create file if not existent # append to file; create file if not existent
with open(mailFile, "a") as f: with open(mail_file, "a") as f:
f.write(mailStr) f.write(mail_str)
except Exception as e: except Exception as e:
print(f'exec-notify>> Could not write to file: {e}', file=sys.stderr) print(f'exec-notify>> Could not write to file: {e}', file=sys.stderr)
def _localMailExists(): def _local_mail_exists():
""" """
:return: True if local mail exists in maildir folder. Once the mail is read the user shall delete (or move) it. :return: True if local mail exists in maildir folder. Once the mail is read the user shall delete (or move) it.
""" """
mailDir = config.getMailDir() mail_dir = config.getMailDir()
if not mailDir.exists(): if not mail_dir.exists():
return False return False
else: else:
# mailDir has at least one child (file/folder) # mail_dir has at least one child (file/folder)
return len(list(mailDir.iterdir())) > 0 return len(list(mail_dir.iterdir())) > 0

View File

@ -22,10 +22,10 @@ def main():
print('No command given to execute!', file=sys.stderr) print('No command given to execute!', file=sys.stderr)
exit(1) exit(1)
exit(executeCommand(argv[1:])) exit(execute_command(argv[1:]))
def executeCommand(command: List[str]) -> int: def execute_command(command: List[str]) -> int:
""" """
Executes the given command and sends an email on failure. Executes the given command and sends an email on failure.
@ -33,16 +33,16 @@ def executeCommand(command: List[str]) -> int:
""" """
try: try:
exitCode, stdout, stderr = exec.execute(command) exit_code, stdout, stderr = exec.execute(command)
except Exception as e: except Exception as e:
exitCode, stdout, stderr = 1, '', 'Caught subprocess exception: ' + str(e) exit_code, stdout, stderr = 1, '', 'Caught subprocess exception: ' + str(e)
prefix = '' prefix = ''
BODY = f'{"" * 19}\n' \ BODY = f'{"" * 19}\n' \
f'┣╸Command:\n' \ f'┣╸Command:\n' \
f'{util.appendLinePrefix(prefix, str(command))}\n' \ f'{util.appendLinePrefix(prefix, str(command))}\n' \
f'┣╸Exit Code:\n' \ f'┣╸Exit Code:\n' \
f'{util.appendLinePrefix(prefix, str(exitCode))}\n' \ f'{util.appendLinePrefix(prefix, str(exit_code))}\n' \
f'┣╸stderr:\n' \ f'┣╸stderr:\n' \
f'{util.appendLinePrefix(prefix, stderr)}\n' \ f'{util.appendLinePrefix(prefix, stderr)}\n' \
f'┣╸stdout:\n' \ f'┣╸stdout:\n' \
@ -50,11 +50,11 @@ def executeCommand(command: List[str]) -> int:
f'{"" * 19}' f'{"" * 19}'
print(BODY) print(BODY)
if exitCode != 0: if exit_code != 0:
SUBJECT = f'{socket.gethostname()} | {str(command)}' subject = f'{socket.gethostname()} | {str(command)}'
mail.sendMailOrWriteToFile(SUBJECT=SUBJECT, BODY=BODY) mail.send_mail_or_write_to_file(subject=subject, body=BODY)
return exitCode return exit_code
if __name__ == '__main__': if __name__ == '__main__':