[Users] How to use python to send mail from sylpheed

Ranjan Maitra maitra at gmx.com
Sun May 19 21:25:54 CEST 2019


Hello,

I am a long time (15-year) sylpheed/sylpheed-claws/claws-mail user and am very comfortable with using it for my needs.

Recently, my workplace moved to an exchange server which requires two-factor authentication with the 2FA done using a third-party. Rather than give up on my mailer of choice, I have decided to adapt my e-mail sending to accommodate the change. I have written a python script which does the two-factor authentication and is able to send mail (with attachments) from the commandline. I want to integrate this script with claws-mail.

Because it is not possible to create a reproducible example including the 2FA OTP framework for someone more knowledgeable to help me here, I think that it will be enough for me to figure out how to make python's sendmail facility work with claws-mail.

Here is python code that sort of does what the in-built sendmail in claws-mail does, in sending e-mail, but that works from the command line or reading from a config file.

#### start python script: call it mailsend.py

#!/usr/bin/env python

"""
Send an email. With Python.
"""

import smtplib
import mimetypes
from email import encoders
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.charset import add_charset, QP
import os
import argparse
try:
    import configparser
except ImportError:
    import ConfigParser as configparser

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--subject', required=True)
    parser.add_argument('--from', required=True)
    parser.add_argument('--to', required=True)
    parser.add_argument('--configfile', type=argparse.FileType('r'), required=True, help='The .ini file with the mailserver credentials')
    parser.add_argument('--configsection', default='DEFAULT', help='The mail server section to choose in the configfile.')
    parser.add_argument('mailbody', metavar='MAILBODY', type=argparse.FileType('r'), help='A text file containing the mail body itself')
    parser.add_argument('attachments', metavar='ATTACHMENT', type=argparse.FileType('rb'), nargs='*', help='Optional files to attach')
    args = parser.parse_args()

    config = configparser.ConfigParser()
    config.sections()
    config.read_file(args.configfile)
    try:
        args.configsection
        config.items(args.configsection)
    except configparser.NoSectionError:
        print("Section {} not found in configfile {}.".format(args.configsection, args.configfile.name))

    add_charset('utf-8', QP, QP, 'utf-8')
    if len(args.attachments):
        msg = MIMEMultipart()
        msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
        mime_parts = []
        msg.attach(MIMEText(args.mailbody.read(), _charset='utf-8'))
        args.mailbody.close()
        for attachment in args.attachments:
            ctype, encoding = mimetypes.guess_type(attachment.name)
            if ctype is None or encoding is not None:
                ctype = 'application/octet-stream'
            maintype, subtype = ctype.split('/', 1)
            if maintype == 'image':
                mime_part = MIMEImage(attachment.read(), _subtype=subtype)
            else:
                mime_part = MIMEBase(maintype, subtype)
                mime_part.set_payload(attachment.read())
                encoders.encode_base64(mime_part)
            attachment.close()
            mime_part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachment.name))
            msg.attach(mime_part)
    else:
        msg = MIMEText(args.mailbody.read(), _charset='utf-8')
        args.mailbody.close()

    msg['Subject'] = args.subject
    msg['From'] = getattr(args, 'from')
    msg['To'] = args.to

    server = smtplib.SMTP(config.get(args.configsection, 'server'), config.get(args.configsection, 'port'))
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login(config.get(args.configsection, 'username'), config.get(args.configsection, 'password'))

    server.send_message(msg)
    server.quit()

if __name__ == "__main__":
    main()

##### end python script.

The usage for this script is:

./mailsend.py [-h] --subject SUBJECT --from FROM --to TO --configfile CONFIGFILE [--configsection CONFIGSECTION]
                   MAILBODY [ATTACHMENT [ATTACHMENT ...]]


I can get this to send e-mail from the command line or from reading the configuration file.

My question is: how do I modify claws-mail and/or my code to use this python script. I understand that there is an option for an external program to send mail but I can not figure out how to use it, in the sense that how do I write and pass the external command (in this case my python script) to do the actual sending with claws-mail.

Any advice, pointers to reading material/examples and/or suggestions would be very much appreciated.

Of course, please feel free to ask for more information and clarifications.

Thanks very much again!

Best wishes,
Ranjan





















--
Ranjan Maitra <maitra at gmx.com>


More information about the Users mailing list