#!/usr/bin/env python # -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 u"""%(scriptname)s: Afficher un mail correctement encodé pour son envoi USAGE echo "BODY" | %(scriptname)s [options] RECIPIENTS... | /usr/sbin/sendmail -t -i OPTIONS -F, --from FROM Spécifier l'adresse de l'expéditeur. Par défaut, utiliser l'adresse %(DEFAULT_FROM)s -c, --cc CCRECIPIENTS Destinataires en copie du message, séparés par une virgule. Cette option peut être spécifiée autant de fois que nécessaire. -b, --bcc BCCRECIPIENTS Destinataires en copie cachée du message, séparés par une virgule. Cette option peut être spécifiée autant de fois que nécessaire. -a, --attach FILE Attacher un fichier au mail. Cette option peut être spécifiée autant de fois que nécessaire pour attacher plusieurs fichiers. SUBJECT Sujet du mail. Cette valeur est requise. RECIPIENTS Destinataires du mail. Il faut au moins un destinataire. BODY Corps du mail. Il est spécifié sur l'entrée standard. -f, --body FILE Spécifier un fichier qui contient le corps du message, au lieu de lire sur l'entrée standard.""" DEFAULT_FROM = 'no-reply@univ-reunion.fr' import i_need_py25 # nécessite module email version 4.0 import os, sys, mimetypes from os import path from email import encoders from email.header import Header from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.audio import MIMEAudio from email.mime.multipart import MIMEMultipart from email.generator import Generator from ulib.all import * def display_help(): uprint(__doc__ % globals()) def run_umail(): options, longoptions = build_options([ ('h', 'help', "Afficher l'aide"), ('F:', 'from=', "Spécifier l'expéditeur"), ('c:', 'cc=', "Destinataires en copie"), ('b:', 'bcc=', "Destinataires en copie cachée"), ('a:', 'attach=', "Attacher un fichier"), ('f:', 'body=', "Spécifier un fichier contenant le corps du message"), ]) options, args = get_args(None, options, longoptions) mfrom = DEFAULT_FROM subject = None mtos = [] mccs = [] mbccs = [] body = None bodyfile = None afiles = [] for option, value in options: if option in ('-h', '--help'): display_help() sys.exit(0) elif option in ('-F', '--from'): mfrom = value elif option in ('-c', '--cc'): mccs.extend(value.split(',')) elif option in ('-b', '--bcc'): mbccs.extend(value.split(',')) elif option in ('-a', '--attach'): afiles.append(value) elif option in ('-f', '--body'): bodyfile = value if bodyfile == "-": bodyfile = None elif not path.exists(bodyfile): die("%s: fichier introuvable" % bodyfile) if not args[0:1]: die("Vous devez spécifier le sujet") subject = args[0] if not args[1:]: die("Vous devez spécifier les destinataires") mtos = args[1:] lines = BLines() close = False if bodyfile is None: inf = sys.stdin close = False else: inf = open(bodyfile, 'rb') close = True try: lines.readlines(inf) finally: if close: inf.close() if not afiles: # Sans attachement, faire un message simple msg = MIMEText('\n'.join(lines), 'plain') msg.set_charset('utf-8') else: # Il y a des attachement, faire un multipart msg = MIMEMultipart() #msg.set_charset('utf-8') if lines: body = MIMEText('\n'.join(lines), 'plain') body.set_charset('utf-8') msg.attach(body) for afile in afiles: if not path.isfile(afile): die("%s: Fichier introuvable" % afile) mimetype, encoding = mimetypes.guess_type(afile) if mimetype is None or encoding is not None: mimetype = 'application/octet-stream' maintype, subtype = mimetype.split('/', 1) if maintype == 'text': inf = open(afile, 'rb') try: #XXX on considère que tous les fichiers texte sont encodés en # utf-8. Ce n'est pas forcément vrai, mais cette approximation # devrait être suffisante pour le moment part = MIMEText(inf.read(), _subtype=subtype, _charset='utf-8') finally: inf.close() elif maintype == 'image': inf = open(afile, 'rb') try: part = MIMEImage(inf.read(), _subtype=subtype) finally: inf.close() elif maintype == 'audio': inf = open(afile, 'rb') try: part = MIMEAudio(inf.read(), _subtype=subtype) finally: inf.close() else: part = MIMEBase(maintype, subtype) inf = open(afile, 'rb') try: part.set_payload(inf.read()) finally: inf.close() encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=path.basename(afile)) msg.attach(part) msg['From'] = mfrom msg['To'] = ', '.join(mtos) if mccs: msg['Cc'] = ', '.join(mccs) if mbccs: msg['Bcc'] = ', '.join(mbccs) msg['Subject'] = Header(subject, 'utf-8') Generator(sys.stdout).flatten(msg) if __name__ == '__main__': run_umail()