aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilvio Rhatto <rhatto@riseup.net>2022-02-10 13:39:03 -0300
committerSilvio Rhatto <rhatto@riseup.net>2022-02-10 13:39:03 -0300
commit994f9b294a8b834b69bb6af8121c0104103e58c9 (patch)
tree8130982155d4db10cb7f2271e6d340b777c9349f
parent703079974f0245015c585533ee551d9117324397 (diff)
downloadutils-mail-994f9b294a8b834b69bb6af8121c0104103e58c9.tar.gz
utils-mail-994f9b294a8b834b69bb6af8121c0104103e58c9.tar.bz2
Feat: minimailer-csv
-rwxr-xr-xminimailer1
-rwxr-xr-xminimailer-csv130
2 files changed, 131 insertions, 0 deletions
diff --git a/minimailer b/minimailer
index 8eadd8a..29e30d2 100755
--- a/minimailer
+++ b/minimailer
@@ -41,6 +41,7 @@ MSMTP_ACCOUNT="$3"
# Checks
if [ -z "$MSMTP_ACCOUNT" ]; then
echo "usage: $BASENAME <template-file> <recipients-filelist> <msmtp-account-name>"
+ echo ""
echo "example: $BASENAME message.tmpl recipients.lst my-provider"
echo "check the source code for template and recipient filelist formats"
exit 1
diff --git a/minimailer-csv b/minimailer-csv
new file mode 100755
index 0000000..802766d
--- /dev/null
+++ b/minimailer-csv
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Send emails according to a CSV input with fields and templating support.
+#
+# Copyright (C) 2022 Silvio Rhatto <rhatto@riseup.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License,
+# or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Dependencies
+import argparse
+import csv
+import sys, os, subprocess
+
+class MinimailerCSV:
+ """Send emails according to a CSV input with fields and templating support"""
+
+ def __init__(self, args):
+ self.args = args
+ self.data = []
+
+ if os.path.exists(args.template_file[0]):
+ with open(args.template_file[0], 'r') as template_file:
+ self.template = template_file.read()
+ else:
+ raise FileNotFoundError('No such file ' + template_file)
+
+ if os.path.exists(args.csv_file[0]):
+ with open(args.csv_file[0], newline='') as csv_file:
+ self.csv = csv.DictReader(csv_file,
+ delimiter=args.delimiter,
+ quotechar=args.quotechar,
+ )
+
+ for row in self.csv:
+ self.data.append(row)
+
+ else:
+ raise FileNotFoundError('No such file ' + csv_file)
+
+ def send(self):
+ for item in self.data:
+ print('sending message to {}'.format(item[self.args.recipient_field_address]))
+
+ message = self.template.format(**item)
+
+ with subprocess.Popen('{sendmail} {recipient}'.format(
+ message=message,
+ sendmail=self.args.sendmail_command,
+ recipient=item[self.args.recipient_field_address],
+ ), text=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) as proc:
+
+ proc.stdin.write(message)
+ proc.stdin.close()
+
+if __name__ == "__main__":
+ """Process from CLI"""
+
+ epilog = """Examples:
+
+ minimailer-csv message.tmpl data.csv --sendmail-command 'msmtp -a default'
+ minimailer-csv message.tmpl data.csv --recipient-field-address 'contact'
+ """
+
+ description = 'Send emails according to a CSV input with fields and templating support'
+ parser = argparse.ArgumentParser(
+ description=description,
+ epilog=epilog,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+
+ parser.add_argument('template_file', nargs=1, help='Message template filename')
+ parser.add_argument('csv_file', nargs=1, help='CSV filename. It\'s required that the first line in the CSV contain the field names.')
+ #parser.add_argument('mstmp_account_name', nargs='?', help='MSTMP account name')
+
+ # Defaults
+ sendmail_command_default = '/usr/bin/msmtp -a default'
+ recipiend_field_address_default = 'email'
+ delimiter_default = ','
+ quotechar_default = '"'
+
+ parser.add_argument(
+ '--sendmail-command',
+ help='Sendmail command invocation. Defaults to ' + sendmail_command_default
+ )
+
+ parser.add_argument(
+ '--recipient-field-address',
+ help='Email address field in the CSV file. Defaults to ' + recipiend_field_address_default
+ )
+
+ parser.add_argument(
+ '--delimiter',
+ help='CSV field delimiter. Defaults to' + delimiter_default,
+ )
+
+ parser.add_argument(
+ '--quotechar',
+ help='CSV quotechar. Defaults to' + quotechar_default,
+ )
+
+ # Set defaults
+ #parser.set_defaults(msmtp_account_name='default')
+ parser.set_defaults(sendmail_command=sendmail_command_default)
+ parser.set_defaults(recipiend_field_address=recipiend_field_address_default)
+ parser.set_defaults(delimiter=delimiter_default)
+ parser.set_defaults(quotechar=quotechar_default)
+
+ args = parser.parse_args()
+
+ # Dispatch
+ try:
+ mailer = MinimailerCSV(args)
+
+ mailer.send()
+
+ except (FileNotFoundError, KeyboardInterrupt, subprocess.SubprocessError) as e:
+ print(e)
+ exit(1)