Warning: Undefined array key "DOKU_PREFS" in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/common.php on line 2082
expedition_mail [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


expedition_mail

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
Prochaine révision Les deux révisions suivantes
expedition_mail [2008/12/10 20:17]
tyrtamos
expedition_mail [2015/02/23 21:10]
tyrtamos
Ligne 1: Ligne 1:
 ====== Expédition de mail texte ou html (avec et sans pièces jointes) ====== ====== Expédition de mail texte ou html (avec et sans pièces jointes) ======
 +
 +[en cours de modification]
  
 ===== Objectif ===== ===== Objectif =====
  
-J'avais un problème très concret à résoudre. J'ai en charge l'informatique du concours photo d'un photo-club, et je suis amené à envoyer des mails à une liste d'adresses extraite d'une base de données. Pour donner une idée du sujetnous recevons environ 3000 photos issues de 30 pays... Certains de ces mails sont avec pièces jointes (par exemple la notification personnelle du résultat en pdf) et d'autres non. Bref, je ne sais pas faire avec mon outlook, et j'ai donc cherché une solution de programmation avec Python.+J'avais un problème très concret à résoudre. J'ai en charge l'informatique d'un concours photo international, et je suis amené à envoyer des emails à une liste d'adresses extraite d'une base de données. La quantité d'emails à envoyer est d'au moins 400et ceci dans plus de 35 pays situés dans le monde entier. Certains de ces emails sont avec pièces jointes et d'autres non. Certaines de ces pièces jointes sont spécifiques au destinataire (par exemple le résultat au concours)et d'autre sont des documents généraux. 
 + 
 +Bref, je ne me voyais pas envoyer autant d'email avec mon Outlook, et j'ai donc cherché une solution de programmation avec Python.
  
 Je dois dire que j'ai eu du mal. Même avec google, j'ai trouvé peu d'exemples, et souvent des exemples partiels et/ou dépassés. Et la doc officielle Python est assez "rustique" sur le sujet. Quand à la norme officielle sur le protocole SMTP, elle est comme toutes les normes ... Je dois dire que j'ai eu du mal. Même avec google, j'ai trouvé peu d'exemples, et souvent des exemples partiels et/ou dépassés. Et la doc officielle Python est assez "rustique" sur le sujet. Quand à la norme officielle sur le protocole SMTP, elle est comme toutes les normes ...
  
-Bref, voilà mon code qui me permet de faire à peu près ce que je veux!+Bref, voilà mon code qui me permet de faire à peu près ce que je veux! J'ai même fait ensuite un programme complet pour tous les e-mailings de mon association, mais je ne le diffuse pas, parce qu'il est trop facile d'envoyer des spams avec...
  
 ===== Présentation du code ===== ===== Présentation du code =====
Ligne 37: Ligne 41:
 Après le code, on trouvera ces 4 utilisations détaillées à titre d'exemple Après le code, on trouvera ces 4 utilisations détaillées à titre d'exemple
  
-\\+D'abord le code sous Python 2.7: 
 <code python> <code python>
 #!/usr/bin/python #!/usr/bin/python
 # -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
 +# Python 2.7
  
 import sys import sys
Ligne 147: Ligne 153:
     return rep     return rep
 </code> </code>
 +
 +\\
 +Et voici le même code converti en Python 3, et un peu retouché:
 +
 +<code python>
 +#!/usr/bin/python3
 +# -*- coding: utf-8 -*-
 +# Python 3
 +
 +import sys
 +import os
 +
 +from smtplib import SMTP
 +
 +from email import encoders
 +from email.mime.text import MIMEText
 +from email.mime.multipart import MIMEMultipart
 +from email.mime.base import MIMEBase
 +from email.utils import formatdate
 +
 +##############################################################################
 +class ServeurSMTP(object):
 +
 +    def __init__(self, adresse="", port=25, login="", mdpasse=""):
 +        """conserve les paramètres d'un compte mail sur un serveur SMTP"""
 +        self.adresse = adresse
 +        self.port = port
 +        self.login = login
 +        self.mdpasse = mdpasse
 +
 +##############################################################################
 +class MessageSMTP(object):
 +
 +    def __init__(self, exped="", to=(), cc=(), bcc=(), sujet="", corps="", pjointes=(), codage='UTF-8', typetexte='plain'):
 +        """fabrique un mail empaqueté correctement à partir des données détaillées"""
 +
 +        #---------------------------------------------------------------------
 +        # correction des arguments selon leur type
 +
 +        self.expediteur = exped
 +
 +        if isinstance(to, str):
 +            to = to.split(';')
 +
 +        if to == [] or to == ['']:
 +            raise ValueError("échec: pas de destinataire!")
 +
 +        if isinstance(cc, str):
 +            cc = cc.split(';')
 +
 +        if isinstance(bcc, str):
 +            bcc = bcc.split(';')
 +
 +        if isinstance(pjointes, str):
 +            pjointes = pjointes.split(';')
 +
 +        if codage == None or codage == "":
 +            codage = 'UTF-8'
 +
 +        #---------------------------------------------------------------------
 +        # construction du mail à envoyer (en-tête + corps)
 +
 +        if pjointes == []:
 +            # message sans pièce jointe
 +            msg = MIMEText(corps, typetexte, _charset=codage)
 +        else:
 +            # message "multipart" avec une ou plusieurs pièce(s) jointe(s)
 +            msg = MIMEMultipart('alternatives')
 +
 +        msg['From'] = exped
 +        msg['To'] = ', '.join(to)
 +        msg['Cc'] = ', '.join(cc)
 +        msg['Bcc'] = ', '.join(bcc)
 +        msg['Date'] = formatdate(localtime=True)
 +        msg['Subject'] = sujet
 +        msg['Charset'] = codage
 +        msg['Content-Type'] = 'text/' + typetexte + '; charset=' + codage
 +
 +        if pjointes != []:
 +            msg.attach(MIMEText(corps, typetexte, _charset=codage))
 +
 +            # ajout des pièces jointes
 +            for fichier in pjointes:
 +                part = MIMEBase('application', "octet-stream")
 +                try:
 +                    with open(fichier, "rb") as f:
 +                        part.set_payload(f.read())
 +                except Exception as msgerr:
 +                    raise ValueError ("échec à la lecture d'un fichier joint (" + msgerr + ")")
 +                encoders.encode_base64(part)
 +                part.add_header('Content-Disposition', 'attachment', filename="%s" % (os.path.basename(fichier),))
 +                msg.attach(part)
 +
 +        # compactage final du message dans les 2 cas (avec ou sans pièce(s) jointe(s))
 +        self.mail = msg.as_string()
 +
 +        # construction de la liste complète de tous les destinataires (to + cc + bcc)
 +        self.destinataires = to
 +        self.destinataires.extend(cc)
 +        self.destinataires.extend(bcc)
 +
 +##############################################################################
 +def envoieSMTP(message, serveur):
 +    """envoie le message correctement compacté au serveur SMTP donné"""
 +
 +    #=========================================================================
 +    # connexion au serveur SMTP
 +    smtp = None
 +    try:
 +        smtp = SMTP(serveur.adresse, serveur.port)
 +    except Exception as msgerr:
 +        if smtp != None:
 +            smtp.quit()
 +        return "échec: serveur non reconnu: (" + msgerr + ")"
 +
 +    #=========================================================================
 +    # à décommenter pour avoir tous les échanges du protocole dans la console
 +    # smtp.set_debuglevel(1)
 +
 +    #=========================================================================
 +    # ouverture de session
 +    if serveur.login != "":
 +        try:
 +            rep = smtp.login(serveur.login, serveur.mdpasse)
 +        except Exception as msgerr:
 +            if smtp != None:
 +                smtp.quit()
 +            return "échec: login ou mdp non reconnu (" + msgerr + ")"
 +
 +    #=========================================================================
 +    # envoi du mail
 +    try:
 +        rep = smtp.sendmail(message.expediteur, message.destinataires, message.mail)
 +    except Exception as msgerr:
 +        if smtp != None:
 +            smtp.quit()
 +        return "échec à l'envoi de mail (" + msgerr + ")"
 +
 +    #=========================================================================
 +    # ici, l'envoi a été réussi
 +    smtp.quit()
 +    return ""  # retourner une chaine vide est la signature d'un envoi réussi
 +
 +</code>
 +
  
 ===== Envoi d'un mail "texte" sans pièce jointe ===== ===== Envoi d'un mail "texte" sans pièce jointe =====
expedition_mail.txt · Dernière modification: 2015/02/23 21:12 de tyrtamos