nutools/lib/pyulib/src/uapps/umail.py
2014-07-07 20:58:50 +04:00

167 lines
5.7 KiB
Python
Executable File

#!/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] <SUBJECT> 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()