scripts/gestion/email_tools.py
Daniel STAN 7426578b0d gestion: retrait des shabang inutiles
Puisque les fichiers ne sont pas executables
2014-10-24 23:07:37 +02:00

134 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (C) Stéphane Glondu + ???
# Licence : ???
"""
Envoi de mails textes encodés et bien formatés (encodages spécifiés là il faut).
Autres outils relatifs aux mails.
format_sender et send_email adaptés depuis /usr/scripts/impression/crans_backend.py.
"""
import re
def format_sender(sender, header_charset='utf-8'):
"""
Check and format sender for header.
"""
from email.Header import Header
from email.Utils import parseaddr, formataddr
# Split real name (which is optional) and email address parts
sender_name, sender_addr = parseaddr(sender)
# We must always pass Unicode strings to Header, otherwise it will
# use RFC 2047 encoding even on plain ASCII strings.
sender_name = str(Header(unicode(sender_name), header_charset))
# Make sure email addresses do not contain non-ASCII characters
sender_addr = sender_addr.encode('ascii')
return formataddr((sender_name, sender_addr))
def send_email(sender, recipient, subject, body, server='localhost', cc=None, debug=False, actual_sender=None):
"""
Send an email.
All arguments should be Unicode strings (plain ASCII works as well).
Only the real name part of sender and recipient addresses may contain
non-ASCII characters. The email will be properly MIME encoded.
The charset of the email will be the first one out of US-ASCII or UTF-8
that can represent all the characters occurring in the email.
Argument server maybe a string, indicating the name of the SMTP server, or
directly an instance of smtplib.SMTP.
The resulting mail will be sent to debug if not False.
Otherwise, it will be sent to recipient and cc.
"""
from smtplib import SMTP
from email.MIMEText import MIMEText
from email.Header import Header
# Header class is smart enough to try US-ASCII, then the charset we
# provide, then fall back to UTF-8.
header_charset = 'UTF-8'
# We must choose the body charset manually
for body_charset in 'US-ASCII', 'UTF-8':
try:
body.encode(body_charset)
except UnicodeError:
pass
else:
break
sender = format_sender(sender)
recipient = format_sender(recipient)
if cc: cc = format_sender(cc)
# Create the message ('plain' stands for Content-Type: text/plain)
msg = MIMEText(body.encode(body_charset), 'plain', body_charset)
msg['From'] = sender
msg['To'] = recipient
msg['Subject'] = Header(unicode(subject), header_charset)
if cc: msg['Cc'] = cc
if debug:
actual_recipient = [debug]
else:
actual_recipient = [recipient]
if cc: actual_recipient.append(cc)
if actual_sender:
actual_sender = format_sender(actual_sender)
else:
actual_sender = sender
# Send the message
if isinstance(server, SMTP):
server.sendmail(actual_sender, actual_recipient, msg.as_string())
else:
smtp = SMTP()
smtp.connect(server)
smtp.sendmail(actual_sender, actual_recipient, msg.as_string())
smtp.quit()
def parse_mail_template(fichier):
"""
Lit fichier et renvoie le couple sujet, corps en unicode.
Les trois premières lignes de fichier doivent être :
Encoding: <encodage du fichier>
Subject: <sujet du mail>
<ligne vide>
Le reste forme le corps du mail.
L'argument fichier peut être un nom de fichier, ou directement une
instance de file.
"""
if not isinstance(fichier, file):
fichier = file(fichier)
encoding = fichier.readline()
matched = re.search(r'^Encoding:\s*([^\r\n]*)', encoding)
if matched:
encoding = matched.group(1)
else:
raise SyntaxError("Encoding manquant dans template")
subject = fichier.readline()
matched = re.search(r'^Subject:\s*([^\r\n]*)', subject)
if matched:
subject = matched.group(1).decode(encoding)
else:
raise SyntaxError("Subject manquant dans template")
if fichier.readline() not in ['\r\n', '\n']:
raise SyntaxError("le fichier n'a pas le bon format")
body = fichier.read().decode(encoding)
return subject, body