1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
def send(self, address, subject, message, attachment=None, signature=None):
"""
envoi un mail a l'adresse 'address'
ce couriel a pour sujet 'subject', pour contenu 'message'
et possiblement pour piece jointe 'attachment'
"""
def generator_attachment(attachment):
"""
cede au fur a meusure le binaire de chaque piece jointe
lier a son nom
"""
if attachment:
if type(attachment) is bytes:
yield "attachement", attachment
elif type(attachment) is str:
if os.path.isfile(attachment):
with open(attachment, "rb") as f:
yield os.path.basename(attachment), f.read()
elif type(attachment) in (tuple, list, set):
for att in set(attachment):
for name, data in generator_attachment(att):
yield name, data
else:
raise TypeError("la piece jointe n'est pas prise en charge")
assert re.fullmatch(r"[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}\.[a-z]{2,4}", address), "l'adresse %s n'est pas une adresse valide" % address
outgoing_serv= self.get_outgoing_server(self.address) # adresse sortante probable
with raisin.Printer("sending a mail to '%s' from '%s'..." % (address, self.address), signature=signature) as p:
#mise en forme du message
msg = email.mime.multipart.MIMEMultipart()
msg["From"] = self.address
msg["To"] = address
msg["Subject"] = subject
msg.attach(email.mime.text.MIMEText(message.encode("utf-8"), "plain", "utf-8"))
for name, data in generator_attachment(attachment):
part = email.mime.base.MIMEBase("application", "octet-stream")
part.set_payload(data)
email.encoders.encode_base64(part)
part.add_header("Content-Disposition", "piece; filename= %s" % name)
msg.attach(part)
for i, (port, SmtplibClass) in enumerate(zip((587, 465), (smtplib.SMTP, smtplib.SMTP_SSL))):
p.show("connection a '%s' sur le port %d..." % (outgoing_serv, port))
try:
with SmtplibClass(outgoing_serv, port, timeout=10) as mailserver:# connexion au serveur sortant (en precisant son nom et son port)
# mailserver.set_debuglevel(True) # permet d'afficher tout ce qui se passe en arriere plan
mailserver.ehlo() # on s'assure que la connection soit faite
if SmtplibClass == smtplib.SMTP:
p.show("etablissement du tls...")
mailserver.starttls() # connection TLS
mailserver.ehlo()
p.show("autentification a '%s' avec le mdp: '%s'..." % (self.address, self.psw))
mailserver.login(self.address, self.psw) # autentification
p.show("envoi du message...")
mailserver.sendmail(self.address, address, msg.as_string().encode("utf-8"))
return None
except smtplib.SMTPException as e:
if i == 0:
p.show("echec! deuxieme tentative:")
else:
raise e from e |
Partager