--- /dev/null
+config.yaml
--- /dev/null
+# email tools
+
+This directory holds a few trivial email testing tools. They work on emails
+that are in the `mailqueue` app, so they first have to be generated (with pgweb
+that's typically done by approving news or using the `news_send_email` command),
+and then referenced by their id number. They are used to test formats and markups.
+
+## parse_email.py
+
+This tool will simply parse and print the MIME structure of the email in question.
+
+## send_email.py
+
+This tools will take the email and send it out using SMTP/AUTH (hardcoded to always
+have STARTTLS) according to the settings in `config.yaml` for end-to-end testing.
+
+Note that emails are *not* removed from the queue when sent this way! This way they
+can be sent to multiple addresses for testing.
+
+## config.yaml
+
+Used for both tools to find their database, and for `send_email.py` to know how to
+connect to the server. See the `config.yaml.sample` file for example/docs.
--- /dev/null
+---
+mail:
+ server: smtp.example.com # your server
+ port: 587
+ user: someone@example.com # to log in with
+ sender: someone@example.com # Email to use as envelope sender. Usually, but not always, matches user.
+ password: # Can be either a string here
+ smtp: someone@example.com # Or a lookup of a key/value pair in the secrets store
+db: # List of databases that we can connect to
+ pgweb: dbname=pgweb # Each in psyocpg2 dsn format
+ pgeu: dbname=postgresqleu
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import email
+import email.policy
+import psycopg2
+import sys
+import yaml
+
+
+def print_message(msg, level=0):
+ def _out(t):
+ print("{}{}".format(' ' * level, t))
+
+ _out(msg.get_content_type())
+ if msg.is_multipart():
+ for p in msg.iter_parts():
+ print_message(p, level + 1)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Print email MIME structure")
+ parser.add_argument('db', help='Name of database (looked up in config.yaml) t connect to')
+ parser.add_argument('id', type=int, help='ID of email entry to send')
+
+ args = parser.parse_args()
+
+ with open('config.yaml') as f:
+ config = yaml.load(f, Loader=yaml.SafeLoader)
+
+ if args.db not in config['db']:
+ print("Non-existing db specified")
+ sys.exit(1)
+
+ # Connect to db and get message
+ dbconn = psycopg2.connect(config['db'][args.db])
+ curs = dbconn.cursor()
+ curs.execute("SELECT fullmsg FROM mailqueue_queuedmail WHERE id=%(id)s", {
+ 'id': args.id,
+ })
+ r = curs.fetchall()
+ dbconn.close()
+
+ if len(r) == 0:
+ print("Email not found")
+ sys.exit(1)
+
+ msg = email.message_from_string(r[0][0], policy=email.policy.default)
+
+ print_message(msg)
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import psycopg2
+import smtplib
+import sys
+import yaml
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("Email tester")
+ parser.add_argument('db', help='Name of database (looked up in config.yaml) t connect to')
+ parser.add_argument('id', type=int, help='ID of email entry to send')
+ parser.add_argument('recipient', help='Email address of recipient to send to')
+
+ args = parser.parse_args()
+
+ with open('config.yaml') as f:
+ config = yaml.load(f, Loader=yaml.SafeLoader)
+
+ if args.db not in config['db']:
+ print("Non-existing db specified")
+ sys.exit(1)
+
+ if isinstance(config['mail']['password'], str):
+ password = config['mail']['password']
+ elif isinstance(config['mail']['password'], dict):
+ import secretstorage
+ coll = secretstorage.get_default_collection(secretstorage.dbus_init())
+ if coll.is_locked():
+ coll.unlock()
+ r = list(coll.search_items(config['mail']['password']))
+ if len(r) == 0:
+ print("Could not find password in secret storage.")
+ sys.exit(1)
+ elif len(r) > 1:
+ print("Found more than one password, try again.")
+ sys.exit(1)
+ password = r[0].get_secret().decode()
+ else:
+ print("Invalid type for password in configuration")
+ sys.exit(1)
+
+ # Connect to db and get message
+ dbconn = psycopg2.connect(config['db'][args.db])
+ curs = dbconn.cursor()
+ curs.execute("SELECT fullmsg FROM mailqueue_queuedmail WHERE id=%(id)s", {
+ 'id': args.id,
+ })
+ r = curs.fetchall()
+ dbconn.close()
+
+ if len(r) == 0:
+ print("Email not found")
+ sys.exit(1)
+
+ msg = r[0][0]
+
+ # Now do it!
+ smtp = smtplib.SMTP(host=config['mail']['server'], port=config['mail']['port'])
+ smtp.starttls()
+ smtp.login(user=config['mail']['user'], password=password)
+
+ smtp.sendmail(config['mail']['sender'], args.recipient, msg)
+
+ smtp.quit()
+
+ print("Sent.")