From ce7e98f4433e91d0226d9c841d51e192f4e72642 Mon Sep 17 00:00:00 2001 From: Arjun Suresh Date: Mon, 24 Mar 2025 19:19:21 +0530 Subject: [PATCH 1/5] Added send-email script --- script/send-mail/customize.py | 49 ++++++++++++++++++++++++ script/send-mail/meta.yaml | 18 +++++++++ script/send-mail/run.bat | 23 ++++++++++++ script/send-mail/run.sh | 18 +++++++++ script/send-mail/send-email.py | 68 ++++++++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+) create mode 100644 script/send-mail/customize.py create mode 100644 script/send-mail/meta.yaml create mode 100644 script/send-mail/run.bat create mode 100644 script/send-mail/run.sh create mode 100644 script/send-mail/send-email.py diff --git a/script/send-mail/customize.py b/script/send-mail/customize.py new file mode 100644 index 000000000..73c908843 --- /dev/null +++ b/script/send-mail/customize.py @@ -0,0 +1,49 @@ +from mlc import utils +import os +import subprocess + + +def preprocess(i): + + env = i['env'] + state = i['state'] + + os_info = i['os_info'] + + + # Start constructing the argument string + args = f"--subject \"{env.get('MLC_EMAIL_SUBJECT', '')}\" " + + # Process other arguments + args += f"--to_addresses \"{','.join(env.get('MLC_TO_ADDRESS', []))}\" " + args += f"--cc_addresses \"{env.get('MLC_CC_ADDRESS', '')}\" " + args += f"--bcc_addresses \"{env.get('MLC_BCC_ADDRESS', '')}\" " + args += f"--content_file \"{env.get('MLC_CONTENT_FILE', '')}\" " + + # Process attachments + attachments = ' '.join(env.get('MLC_ATTACHMENTS', '').split()) + args += f"--attachments \"{attachments}\" " + + # Add flags for SMTP server, email and password if needed + if env.get('USE_SMTP_SERVER'): + args += "--use_smtp_server " + args += f"--email \"{env.get('EMAIL', '')}\" " + args += f"--password \"{env.get('PASSWORD', '')}\" " + args += f"--smtp_server \"{env.get('SMTP_SERVER', '')}\" " + + subject = env.get('MLC_EMAIL_SUBJECT', '') + to_address = ",".join(env.get('MLC_TO_ADDRESS', [])) + + env['MLC_RUN_CMD'] = f"""{env['MLC_PYTHON_BIN_WITH_PATH'] {os.path.join(env['MLC_TMP_CURRENT_SCRIPT_PATH'], 'send-email.py')} {args}""" + + return {'return': 0} + + +def postprocess(i): + + env = i['env'] + state = i['state'] + + os_info = i['os_info'] + + return {'return': 0} diff --git a/script/send-mail/meta.yaml b/script/send-mail/meta.yaml new file mode 100644 index 000000000..d19dcc15c --- /dev/null +++ b/script/send-mail/meta.yaml @@ -0,0 +1,18 @@ +alias: send-mail +automation_alias: script +automation_uid: 5b4e0237da074764 +category: Utils +deps: + - tags: get,generic-sys-util,_postfix + enable_if_env: + MLC_HOST_OS_FLAVOR: + - ubuntu +new_env_keys: [] +new_state_keys: [] +post_deps: [] +posthook_deps: [] +prehook_deps: [] +tags: +- generic +- template +uid: 5f9b9654ecbe4662 diff --git a/script/send-mail/run.bat b/script/send-mail/run.bat new file mode 100644 index 000000000..80625c80e --- /dev/null +++ b/script/send-mail/run.bat @@ -0,0 +1,23 @@ +@echo off +setlocal enabledelayedexpansion + +:: Function to exit if the last command failed +:exit_if_error +if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% +exit /b 0 + +:: Function to run a command +:run +echo Running: +echo %1 +echo. + +if /I "%MLC_FAKE_RUN%" NEQ "yes" ( + call %1 + call :exit_if_error +) +exit /b 0 + +:: Add your run commands here... +:: call :run "%MLC_RUN_CMD%" + diff --git a/script/send-mail/run.sh b/script/send-mail/run.sh new file mode 100644 index 000000000..d191bbd97 --- /dev/null +++ b/script/send-mail/run.sh @@ -0,0 +1,18 @@ +#!/bin/bash +function exit_if_error() { + test $? -eq 0 || exit $? +} + +function run() { + echo "Running: " + echo "$1" + echo "" + if [[ ${MLC_FAKE_RUN} != 'yes' ]]; then + eval "$1" + exit_if_error + fi +} + +#Add your run commands here... +MLC_RUN_CMD="${MLC_PYTHON_BIN_WITH_PATH} ${MLC_TMP_CURRENT_SCRIPT_PATH}/send-email.py" +run "$MLC_RUN_CMD" diff --git a/script/send-mail/send-email.py b/script/send-mail/send-email.py new file mode 100644 index 000000000..a1a814070 --- /dev/null +++ b/script/send-mail/send-email.py @@ -0,0 +1,68 @@ +import smtplib +import sys +import argparse +from email.mime.multipart import MIMEMultipart +from email.mime.base import MIMEBase +from email.mime.text import MIMEText +from email.utils import COMMASPACE +from email import encoders + +def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, attachments, use_smtp_server=False, smtp_server=None, email=None, password=None): + + to_list = to_addresses.split(',') + cc_list = cc_addresses.split(',') + bcc_list = bcc_addresses.split(',') + attachment_list = attachments.split(',') + + with open(content_file, 'r') as file: + email_content = file.read() + + msg = MIMEMultipart() + msg['From'] = email if use_smtp_server else 'localhost' + msg['To'] = COMMASPACE.join(to_list) + msg['Cc'] = COMMASPACE.join(cc_list) + msg['Subject'] = subject + + msg.attach(MIMEText(email_content, 'plain')) + + for attachment in attachment_list: + with open(attachment, 'rb') as file: + part = MIMEBase('application', 'octet-stream') + part.set_payload(file.read()) + encoders.encode_base64(part) + part.add_header('Content-Disposition', f'attachment; filename={attachment}') + msg.attach(part) + + recipients = to_list + cc_list + bcc_list + + if use_smtp_server: + with smtplib.SMTP_SSL(smtp_server) as server: + server.login(email, password) + server.sendmail(email, recipients, msg.as_string()) + print("Email sent successfully using SMTP server!") + else: + with smtplib.SMTP('localhost') as server: + server.sendmail('localhost@example.com', recipients, msg.as_string()) + print("Email sent successfully using localhost!") + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Send an email with specified attachments') + parser.add_argument('subject', type=str, help='Email subject') + parser.add_argument('to_addresses', type=str, help='To addresses, comma-separated') + parser.add_argument('cc_addresses', type=str, help='CC addresses, comma-separated') + parser.add_argument('bcc_addresses', type=str, help='BCC addresses, comma-separated') + parser.add_argument('content_file', type=str, help='File containing email content') + parser.add_argument('attachments', type=str, help='Attachments, comma-separated file paths') + + parser.add_argument('--use_smtp_server', action='store_true', help='Use an SMTP server instead of localhost') + parser.add_argument('--email', type=str, help='Email address for SMTP server') + parser.add_argument('--password', type=str, help='Password for SMTP server') + parser.add_argument('--smtp_server', type=str, help='SMTP server address') + + args = parser.parse_args() + + if args.use_smtp_server and not all([args.email, args.password, args.smtp_server]): + parser.error('--email, --password, and --smtp_server are required when --use_smtp_server is set') + + send_email(args.subject, args.to_addresses, args.cc_addresses, args.bcc_addresses, args.content_file, args.attachments, args.use_smtp_server, args.smtp_server, args.email, args.password) + From cdcbf8705c0ff6959c42418ac6b38ba9fc1efd24 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Mar 2025 13:49:39 +0000 Subject: [PATCH 2/5] [Automated Commit] Format Codebase [skip ci] --- script/send-mail/customize.py | 1 - script/send-mail/send-email.py | 76 +++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/script/send-mail/customize.py b/script/send-mail/customize.py index 73c908843..9a2089594 100644 --- a/script/send-mail/customize.py +++ b/script/send-mail/customize.py @@ -10,7 +10,6 @@ def preprocess(i): os_info = i['os_info'] - # Start constructing the argument string args = f"--subject \"{env.get('MLC_EMAIL_SUBJECT', '')}\" " diff --git a/script/send-mail/send-email.py b/script/send-mail/send-email.py index a1a814070..631b729b8 100644 --- a/script/send-mail/send-email.py +++ b/script/send-mail/send-email.py @@ -7,7 +7,9 @@ from email.utils import COMMASPACE from email import encoders -def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, attachments, use_smtp_server=False, smtp_server=None, email=None, password=None): + +def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, + attachments, use_smtp_server=False, smtp_server=None, email=None, password=None): to_list = to_addresses.split(',') cc_list = cc_addresses.split(',') @@ -30,7 +32,9 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, part = MIMEBase('application', 'octet-stream') part.set_payload(file.read()) encoders.encode_base64(part) - part.add_header('Content-Disposition', f'attachment; filename={attachment}') + part.add_header( + 'Content-Disposition', + f'attachment; filename={attachment}') msg.attach(part) recipients = to_list + cc_list + bcc_list @@ -42,27 +46,67 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, print("Email sent successfully using SMTP server!") else: with smtplib.SMTP('localhost') as server: - server.sendmail('localhost@example.com', recipients, msg.as_string()) + server.sendmail( + 'localhost@example.com', + recipients, + msg.as_string()) print("Email sent successfully using localhost!") + if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Send an email with specified attachments') + parser = argparse.ArgumentParser( + description='Send an email with specified attachments') parser.add_argument('subject', type=str, help='Email subject') - parser.add_argument('to_addresses', type=str, help='To addresses, comma-separated') - parser.add_argument('cc_addresses', type=str, help='CC addresses, comma-separated') - parser.add_argument('bcc_addresses', type=str, help='BCC addresses, comma-separated') - parser.add_argument('content_file', type=str, help='File containing email content') - parser.add_argument('attachments', type=str, help='Attachments, comma-separated file paths') + parser.add_argument( + 'to_addresses', + type=str, + help='To addresses, comma-separated') + parser.add_argument( + 'cc_addresses', + type=str, + help='CC addresses, comma-separated') + parser.add_argument( + 'bcc_addresses', + type=str, + help='BCC addresses, comma-separated') + parser.add_argument( + 'content_file', + type=str, + help='File containing email content') + parser.add_argument( + 'attachments', + type=str, + help='Attachments, comma-separated file paths') - parser.add_argument('--use_smtp_server', action='store_true', help='Use an SMTP server instead of localhost') - parser.add_argument('--email', type=str, help='Email address for SMTP server') - parser.add_argument('--password', type=str, help='Password for SMTP server') + parser.add_argument( + '--use_smtp_server', + action='store_true', + help='Use an SMTP server instead of localhost') + parser.add_argument( + '--email', + type=str, + help='Email address for SMTP server') + parser.add_argument( + '--password', + type=str, + help='Password for SMTP server') parser.add_argument('--smtp_server', type=str, help='SMTP server address') args = parser.parse_args() - if args.use_smtp_server and not all([args.email, args.password, args.smtp_server]): - parser.error('--email, --password, and --smtp_server are required when --use_smtp_server is set') - - send_email(args.subject, args.to_addresses, args.cc_addresses, args.bcc_addresses, args.content_file, args.attachments, args.use_smtp_server, args.smtp_server, args.email, args.password) + if args.use_smtp_server and not all( + [args.email, args.password, args.smtp_server]): + parser.error( + '--email, --password, and --smtp_server are required when --use_smtp_server is set') + send_email( + args.subject, + args.to_addresses, + args.cc_addresses, + args.bcc_addresses, + args.content_file, + args.attachments, + args.use_smtp_server, + args.smtp_server, + args.email, + args.password) From b689ae19aff96da40cbf9e474455c36ceb8589c0 Mon Sep 17 00:00:00 2001 From: Arjun Date: Mon, 24 Mar 2025 20:20:59 +0530 Subject: [PATCH 3/5] Fixes for send-email --- script/send-mail/customize.py | 28 +++++++++++++++------------- script/send-mail/meta.yaml | 15 +++++++++++++-- script/send-mail/run.sh | 1 - script/send-mail/send-email.py | 33 +++++++++++++++++++++++++-------- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/script/send-mail/customize.py b/script/send-mail/customize.py index 9a2089594..02aa4ff2d 100644 --- a/script/send-mail/customize.py +++ b/script/send-mail/customize.py @@ -11,30 +11,32 @@ def preprocess(i): os_info = i['os_info'] # Start constructing the argument string - args = f"--subject \"{env.get('MLC_EMAIL_SUBJECT', '')}\" " + args = f"--subject '{env.get('MLC_EMAIL_SUBJECT', '')}' " + # Process other arguments - args += f"--to_addresses \"{','.join(env.get('MLC_TO_ADDRESS', []))}\" " - args += f"--cc_addresses \"{env.get('MLC_CC_ADDRESS', '')}\" " - args += f"--bcc_addresses \"{env.get('MLC_BCC_ADDRESS', '')}\" " - args += f"--content_file \"{env.get('MLC_CONTENT_FILE', '')}\" " + args += f"--to_addresses '{env.get('MLC_EMAIL_TO_ADDRESSES', '')}' " + args += f"--cc_addresses '{env.get('MLC_EMAIL_CC_ADDRESSES', '')}' " + args += f"--bcc_addresses '{env.get('MLC_EMAIL_BCC_ADDRESSES', '')}' " + args += f"--content_file '{env.get('MLC_EMAIL_CONTENT_FILE', '')}' " + # Process attachments - attachments = ' '.join(env.get('MLC_ATTACHMENTS', '').split()) - args += f"--attachments \"{attachments}\" " + args += f"--attachments '{env.get('MLC_EMAIL_ATTACHMENTS', '')}'" # Add flags for SMTP server, email and password if needed - if env.get('USE_SMTP_SERVER'): + if env.get('MLC_EMAIL_USE_SMTP_SERVER'): args += "--use_smtp_server " - args += f"--email \"{env.get('EMAIL', '')}\" " - args += f"--password \"{env.get('PASSWORD', '')}\" " - args += f"--smtp_server \"{env.get('SMTP_SERVER', '')}\" " + args += f"--email '{env.get('MLC_EMAIL_SMPT_EMAIL', '')}' " + args += f"--password '{env.get('MLC_EMAIL_SMTP_PASSWORD', '')}' " + args += f"--smtp_server '{env.get('MLC_EMAIL_SMTP_SERVER', '')}' " subject = env.get('MLC_EMAIL_SUBJECT', '') - to_address = ",".join(env.get('MLC_TO_ADDRESS', [])) + to_address = ",".join(env.get('MLC_EMAIL_TO_ADDRESS', [])) - env['MLC_RUN_CMD'] = f"""{env['MLC_PYTHON_BIN_WITH_PATH'] {os.path.join(env['MLC_TMP_CURRENT_SCRIPT_PATH'], 'send-email.py')} {args}""" + env['MLC_RUN_CMD'] = f"""{env['MLC_PYTHON_BIN_WITH_PATH']} {os.path.join(env['MLC_TMP_CURRENT_SCRIPT_PATH'], 'send-email.py')} {args}""" + print(env) return {'return': 0} diff --git a/script/send-mail/meta.yaml b/script/send-mail/meta.yaml index d19dcc15c..72cf19fa3 100644 --- a/script/send-mail/meta.yaml +++ b/script/send-mail/meta.yaml @@ -3,6 +3,10 @@ automation_alias: script automation_uid: 5b4e0237da074764 category: Utils deps: + - tags: get,python + names: + - python + - python3 - tags: get,generic-sys-util,_postfix enable_if_env: MLC_HOST_OS_FLAVOR: @@ -12,7 +16,14 @@ new_state_keys: [] post_deps: [] posthook_deps: [] prehook_deps: [] +input_mapping: + subject: MLC_EMAIL_SUBJECT + to_addresses: MLC_EMAIL_TO_ADDRESSES + to_address: MLC_EMAIL_TO_ADDRESSES + attachments: MLC_EMAIL_ATTACHMENTS + attachment: MLC_EMAIL_ATTACHMENTS tags: -- generic -- template +- send +- mail +- email uid: 5f9b9654ecbe4662 diff --git a/script/send-mail/run.sh b/script/send-mail/run.sh index d191bbd97..c4542b8c2 100644 --- a/script/send-mail/run.sh +++ b/script/send-mail/run.sh @@ -14,5 +14,4 @@ function run() { } #Add your run commands here... -MLC_RUN_CMD="${MLC_PYTHON_BIN_WITH_PATH} ${MLC_TMP_CURRENT_SCRIPT_PATH}/send-email.py" run "$MLC_RUN_CMD" diff --git a/script/send-mail/send-email.py b/script/send-mail/send-email.py index 631b729b8..a0ff723a7 100644 --- a/script/send-mail/send-email.py +++ b/script/send-mail/send-email.py @@ -16,8 +16,11 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, bcc_list = bcc_addresses.split(',') attachment_list = attachments.split(',') - with open(content_file, 'r') as file: - email_content = file.read() + if content_file and os.path.exists(content_file): + with open(content_file, 'r') as file: + email_content = file.read() + else: + email_content='' msg = MIMEMultipart() msg['From'] = email if use_smtp_server else 'localhost' @@ -28,6 +31,8 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, msg.attach(MIMEText(email_content, 'plain')) for attachment in attachment_list: + if attachment.strip() == '': + continue with open(attachment, 'rb') as file: part = MIMEBase('application', 'octet-stream') part.set_payload(file.read()) @@ -56,26 +61,34 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, if __name__ == '__main__': parser = argparse.ArgumentParser( description='Send an email with specified attachments') - parser.add_argument('subject', type=str, help='Email subject') + parser.add_argument('--subject', type=str, help='Email subject') parser.add_argument( - 'to_addresses', + '--to_addresses', type=str, help='To addresses, comma-separated') parser.add_argument( - 'cc_addresses', + '--cc_addresses', type=str, + nargs='?', + default='', help='CC addresses, comma-separated') parser.add_argument( - 'bcc_addresses', + '--bcc_addresses', type=str, + nargs='?', + default='', help='BCC addresses, comma-separated') parser.add_argument( - 'content_file', + '--content_file', type=str, + nargs='?', + default='', help='File containing email content') parser.add_argument( - 'attachments', + '--attachments', type=str, + nargs='?', + default='', help='Attachments, comma-separated file paths') parser.add_argument( @@ -85,10 +98,14 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, parser.add_argument( '--email', type=str, + default='', + nargs='?', help='Email address for SMTP server') parser.add_argument( '--password', type=str, + default='', + nargs='?', help='Password for SMTP server') parser.add_argument('--smtp_server', type=str, help='SMTP server address') From 3a1bfb7e39a08d353af2bbca3d78d3ff78704fa0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Mar 2025 14:54:37 +0000 Subject: [PATCH 4/5] [Automated Commit] Format Codebase [skip ci] --- script/send-mail/customize.py | 2 -- script/send-mail/send-email.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/script/send-mail/customize.py b/script/send-mail/customize.py index 02aa4ff2d..ed1b40c41 100644 --- a/script/send-mail/customize.py +++ b/script/send-mail/customize.py @@ -13,14 +13,12 @@ def preprocess(i): # Start constructing the argument string args = f"--subject '{env.get('MLC_EMAIL_SUBJECT', '')}' " - # Process other arguments args += f"--to_addresses '{env.get('MLC_EMAIL_TO_ADDRESSES', '')}' " args += f"--cc_addresses '{env.get('MLC_EMAIL_CC_ADDRESSES', '')}' " args += f"--bcc_addresses '{env.get('MLC_EMAIL_BCC_ADDRESSES', '')}' " args += f"--content_file '{env.get('MLC_EMAIL_CONTENT_FILE', '')}' " - # Process attachments args += f"--attachments '{env.get('MLC_EMAIL_ATTACHMENTS', '')}'" diff --git a/script/send-mail/send-email.py b/script/send-mail/send-email.py index a0ff723a7..00b4571f0 100644 --- a/script/send-mail/send-email.py +++ b/script/send-mail/send-email.py @@ -20,7 +20,7 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, with open(content_file, 'r') as file: email_content = file.read() else: - email_content='' + email_content = '' msg = MIMEMultipart() msg['From'] = email if use_smtp_server else 'localhost' From d6684edd2a54f52db5d6c32be590ca777d9a7450 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Mar 2025 16:48:17 +0000 Subject: [PATCH 5/5] [Automated Commit] Format Codebase [skip ci] --- script/send-mail/send-email.py | 1 - 1 file changed, 1 deletion(-) diff --git a/script/send-mail/send-email.py b/script/send-mail/send-email.py index 79d120dc2..0bb25f7e2 100644 --- a/script/send-mail/send-email.py +++ b/script/send-mail/send-email.py @@ -22,7 +22,6 @@ def send_email(subject, to_addresses, cc_addresses, bcc_addresses, content_file, else: email_content = '' - msg = MIMEMultipart() msg['From'] = email if use_smtp_server else 'localhost' msg['To'] = COMMASPACE.join(to_list)