Code python notification de mail

Résolu
quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   Ambassadeur -  
jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour,

J'ai voulu tester un code python pour être averti de l'arrivée d'un mail dans ma messagerie SFR. Je ne sais s'il est correct :

# -*- coding: utf-8 -*-
import poplib
import time


class CompteEmail:
    """
    Je représente un compte email, chez un fournisseur.
    """
    def __init__(self):
        self.serveur = ''
        self.identifiant = ''
        self.motDePasse = ''
 
    def set(self, serveur, identifiant, motDePasse):
        self.serveur = serveur
        self.identifiant = identifiant
        self.motDePasse = motDePasse


class Notification:
    """
    Je notifie, à intervalle régulier, le nombre d'emails d'un
    compte donné.
    """
    def __init__(self):
        self.compte = None
        self.nombreDeMail = 0
 
    def set(self, compte):
        self.compte = compte


def verifieMail(self):
    """
    Je me connecte par pop3 au compte mail pour connaitre le nombre
    de mails présent sur le serveur. Quand le nombre de mails
    changent, j'écris un message sur le terminal.
    """
    connexion = poplib.POP3(self.compte.serveur)
    connexion.user(self.compte.identifiant)
    connexion.pass_(self.compte.motDePasse)
    numMessages = connexion.stat()[0]
 
    if numMessages != self.nombreDeMail:
        self.nombreDeMail = numMessages
        if self.nombreDeMail != 0:
            print '%d email(s) en attente.' % (numMessages)
    connexion.quit()


def commence(self):
    """
    Je demande la vérification du nombre de mail toutes les minutes.
    Comme je suis une boucle infinie, vous devrez tapez Ctrl+C pour
    mettre fin au programme.
    """
    while True:
        self.verifieMail()
        time.sleep(60)


if __name__ == "__main__":
    compte = CompteEmail()
    compte.set('pop.free.fr', 'votre.pseudo@free.fr', 'motdepasse')
    notif = Notification()
    notif.set(compte)
    notif.commence()

Je l'exécute ainsi dans la console pycharm :

python ./notification.py

“Impose ta chance, serre ton bonheur et va vers ton risque. A te regarder, ils s’habitueront.”  René Char 

11 réponses

Résumé de la discussion

Un script Python vise à avertir l'arrivée d'un email sur une messagerie SFR en utilisant le protocole POP3 et à afficher le nombre de messages lorsque celui-ci change. Des échanges soulignent que le code souffre d'indentations incorrectes et que des ajustements d'authentification et de paramètres serveur sont nécessaires, certains décelant aussi des différences entre POP3 et IMAP selon les fournisseurs. Des cas pratiques évoquent des tests sur Outlook et Yahoo, montrant que Gmail demande une authentification particulière et que IMAP peut être plus fiable que POP3 selon le compte. D'autres remarquent des détails d'environnement, tels que la gestion des variables PATH et les chemins Python, et commente que l'adaptation du code dépend largement du protocole et du client.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    Je ne sais pas pour ton environnement, je n'utilise pas le même, juste le python de base. Pour le répertoire en trop c'est peut être qu'il faut le retirer des variables d'environnement, la variable PATH de Windows

    Voilà un exemple de code simple IMAP

    import imaplib
    
    # Configuration
    server = "outlook.office365.com"
    user = "xxxx@outlook.fr"
    password = "yyyy"
    
    # Connexion au serveur
    try:
        mail = imaplib.IMAP4_SSL(server)
        mail.login(user, password)
        mail.select("Inbox")
    except:
        print('Anomalie de connexion',server)
    else:
      (retcode, messages) = mail.search(None, '(UNSEEN)')
      if retcode == 'OK':
        nonlus = len(messages[0].split())
      else:
        nonlus = "?"
    
      (retcode, messages) = mail.search(None, '(SEEN)')
      if retcode == 'OK':
        lus = len(messages[0].split())
      else:
        lus = "?"
    
      print(user, "messages (non lus/lus) :",nonlus,"/",lus)
    
    

    J'avais essayé le code POP il fonctionnait pour free, laposte, et certains comptes microsoft mais pas tous, et pas pour Gmail. Le code en IMAP fonctionne sur free, laposte, tous les comptes microsoft. Mais pas pour les comptes Gmail qui nécessitent une authentification particulière avec une ouverture de session.


    1
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      Merci, je le testerai et je te redis. 

      0
  2. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    Bonjour,

    Ce programme, légèrement remis en forme, et passage instruction print en python 3 fonctionne, en donnant un compte mail free et son mot de passe. Pour sfr il te faut en plus changer le pop.free.fr peut être, mais pas sur, par pop.sfr.fr

    # -*- coding: utf-8 -*-
    import poplib
    import time
    
    
    class CompteEmail:
        """
        Je représente un compte email, chez un fournisseur.
        """
        def __init__(self):
            self.serveur = ''
            self.identifiant = ''
            self.motDePasse = ''
     
        def set(self, serveur, identifiant, motDePasse):
            self.serveur = serveur
            self.identifiant = identifiant
            self.motDePasse = motDePasse
    
    
    class Notification:
        """
        Je notifie, à intervalle régulier, le nombre d'emails d'un
        compte donné.
        """
        def __init__(self):
            self.compte = None
            self.nombreDeMail = 0
     
        def set(self, compte):
            self.compte = compte
    
        def verifieMail(self):
            """
            Je me connecte par pop3 au compte mail pour connaitre le nombre
            de mails présent sur le serveur. Quand le nombre de mails
            changent, j'écris un message sur le terminal.
            """
            connexion = poplib.POP3(self.compte.serveur)
            connexion.user(self.compte.identifiant)
            connexion.pass_(self.compte.motDePasse)
            numMessages = connexion.stat()[0]
     
            if numMessages != self.nombreDeMail:
                self.nombreDeMail = numMessages
                if self.nombreDeMail != 0:
                    print('%d email(s) en attente.' % (numMessages))
            connexion.quit()
    
        def commence(self):
            """
            Je demande la vérification du nombre de mail toutes les minutes.
            Comme je suis une boucle infinie, vous devrez tapez Ctrl+C pour
            mettre fin au programme.
            """
            while True:
                self.verifieMail()
                time.sleep(60)
    
    
    if __name__ == "__main__":
        compte = CompteEmail()
        compte.set('pop.free.fr', 'xxxxx@free.fr', 'xxxxxxx')
        notif = Notification()
        notif.set(compte)
        notif.commence()
    
    

    0
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      Salut !

      Avec mon  code, je ne sais pas si le tien est différent ? Donc avec le mien, en l'exéxutant j'ai cette erreur :

      0
      1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
         

        bien sur que le mien est différent puisque je l'ai corrigé, comme tu dois le savoir en Python, la forme et l'indentation est primordiale

        0
      2. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention  
         

        Ok excuse ma confusion. J'ai corrigé des indentations, à la fin je l'exécute dans la console Pycharm, rien ne se passe ? Je te joins mon fichier .py :

        https://www.cjoint.com/c/***********

        0
  3. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    tes indentations ne sont toujours pas bonnes, utilise

    # -*- coding: utf-8 -*-
    import poplib
    import time
    
    
    class CompteEmail:
        """
        je représente un compte mail, chez un fournisseur.
        """
        def __init__(self):
            self.serveur = ''
            self.identifiant =  ''
            self.motDePasse = ''
    
        def set(self, serveur, identifiant, motDePasse):
            self.serveur = serveur
            self.identifiant = identifiant
            self.motDePasse = motDePasse
    
    class Notification:
                """
                Je notifie, à intervalle régulier, le nombre d'emails d'un
                compte donné.
                """
    
                def __init__(self):
                    self.compte = None
                    self.nombreDeMail = 0
    
                def set(self, compte):
                    self.compte = compte
    
                def verifieMail(self):
                        """
                        Je me connecte par pop3 au compte mail pour connaitre le nombre
                        de mails présent sur le serveur. Quand le nombre de mails
                        changent, j'écris un message sur le terminal.
                        """
                        connexion = poplib.POP3(self.compte.serveur)
                        connexion.user(self.compte.identifiant)
                        connexion.pass_(self.compte.motDePasse)
                        numMessages = connexion.stat()[0]
    
                        if numMessages != self.nombreDeMail:
                            self.nombreDeMail = numMessages
                            if self.nombreDeMail != 0:
                                print ('%d email(s) en attente.' % (numMessages))
                        connexion.quit()
    
                def commence(self):
                     """
                    Je demande la vérification du nombre de mail toutes les minutes.
                     Comme je suis une boucle infinie, vous devrez tapez Ctrl+C pour
                    mettre fin au programme.
                    """
                     while True:
                         self.verifieMail()
                         time.sleep(60)
    
    
    if __name__ == "__main__":
        compte = CompteEmail()
        compte.set('pop.sfr.fr', '@club-internet.fr', '')
        notif = Notification()
        notif.set(compte)
        notif.commence()
    
    
    

    le code fonctionne, réponse 6001 emails

    je supprime ton lien vers le fichier déposé puisque tu donnes compte et mot de passe :-/


    0
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      Ok, merci bien jee pee, mon compte et mdp c'était pour que tu vois bien mes erreurs. Je te fais confiance !

      Corrigé les indentations, cela fonctionne :)

      J'ai du mal avec elles, ces blocs de code, faut souvent décaler et je n'ai pas le sens de savoir quand le faire ! C'est tout un monde à apprendre la programmation, déjà à partir d'une idée, il faut savoir comment débuter le code, avec def ou if ou autre. Je n'ai que les bases, mes notes papiers, après les cours de l'école française. Il faut faire plein d'excercices pour capter le sens de tout cela.

      ps : je pense qu'avec des adresses outlook et yahoo ce serait différent, car ce n'est pas un protocole pop ?

      1
  4. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    Si on n'est pas déjà un programmeur expérimenté, pour se lancer dans un nouveau langage, il ne faut pas bruler les étapes. Il faut attaquer par une formation, et suivre toutes les étapes qu'elle propose, pas juste picorer ce qui semble intéressant, on rate des bases indispensables. Comme là dans Python le formalisme des lignes source. C'est une notion pas habituelle, dans d'autres langages on va faire de la mise en forme pour rendre le source plus lisible, mais l'interpréteur ou le compilateur du langage s'en moque, pas Python.

    Des instructions comme class, def, for, if, while ..., constituent des débuts de blocs de lignes source. Cette ligne d'entête de bloc se termine par :

    Les lignes qui suivent constituent le corps du bloc, le corps du bloc est indenté par rapport au titre du bloc, et les lignes du bloc sont alignées. Un bloc peut contenir un autre bloc, le second sera donc indenté par rapport au bloc père.

    La plupart des messageries ont un service pop : https://www.commentcamarche.net/applis-sites/mail/981-pop-imap-smtp-adresses-serveurs-mail/ Mais certaines demandent un paramétrage particulier, comme un port ou une connexion SSL, options qui ne sont peut être pas présentes soit dans ton source, soit dans la bibliothèque utilisée.


    0
    1. Diablo76 Messages postés 344 Date d'inscription   Statut Membre Dernière intervention   140
       

      'Dans d'autres langages on va faire de la mise en forme pour rendre le source plus lisible'

      Quand c'est respecté, j'ai vu des codes sources pro qui étaient une véritable cata :-)

      0
    2. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      "Après une instruction, la ligne d'entête de bloc se termine par :

          le corps du bloc est indenté par rapport au titre du bloc"

      le repère d'intentation est une touche tab ou 4 touches espaces ?

      0
      1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
         

        c'est ce que tu veux, tab, 4 blancs, ou même juste un blanc. Moi je trouve que 4 blancs cela fait beaucoup, j'ai plutôt tendance à en mettre 3 ;-)


        C'est juste qu'il faut être cohérent. C'est conventionnellement tab ou 4 blancs, mais déjà dans un même code mixer les 2 est vite mauvais, puis il existe des éditeurs qui vont remplacer le tab par 4 blancs, d'autres pas, et si tu copies le code, par exemple pour le publier sur le forum, les tab et les 4 blancs pourraient se présenter différemment.

        0
    3. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      J'ai essayé avec messagerie outlook, en changeant le serveur et tout, j'ai ça :

      1
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    SI tu regardes l'article sur les serveurs POP des différents fournisseurs de mails, on voit qu'Outlook est en SSL. Pour un serveur POP en SSL, la bibliothèque Python utilisée comporte une classe différente : https://docs.python.org/3/library/poplib.html

    Il faut alors changer le source, et remplacer

            connexion = poplib.POP3(self.compte.serveur)

    par

            connexion = poplib.POP3_SSL(self.compte.serveur)

    0
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      Toujours un message d'erreur à la ligne 58 :

      time.sleep (60)

      C'est une messagerie 9online, donc sfr en serveur, comme club internet, ça fonctionne avec club et pas 9 online !

      Je suppose qu'avec outlook et yahoo faut ajouter en POP3_SSL, comme tu dis en msg 12 ?

      0
    2. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
       

      C'est à la ligne 62 :

      modération : image supprimée contient compte/mdp
      0
    3. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
       

      le message d'erreur est toujours important à lire, là cela indique indentation error

      0
    4. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention  
       

      ok, maintenant c'est :

      notif.commence()

      AttributeError: 'Notification' object has no attribute 'commence'

      0
    5. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
       

      tu reviens sur les anomalies de départ, il doit toujours y avoir des soucis de mise en forme. Repars d'une version qui fonctionne.

      même si au final sfr pourrait ne pas fonctionner, car l'authentification est de type TLS pas SSL

      0
  7. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    Et comment veux tu que l'on fasse sans le code source correspondant ? Sauf si comme la première fois tu as une erreur d'indentation.


    0
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      C'est le même code source que celui ici du départ de ce post :

      notif.commence() c'est à cette ligne l'erreur de mon message 22. Tout le reste est bon.

      0
    2. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
       

      ton source de départ est développé autour d'une bibliothèque POP, pour de l'IMAP, il doit falloir une autre bibliothèque, et un autre source adapté

      0
    3. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention  
       

      Pour l'Imap, j'ai modifié POP3, par POP3_SSL. Tu connaîtrais un autre code Python pour ce faire ?

      0
    4. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973 > quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention  
       

      IMAP n'est pas POP3, fait une recherche IMAP Python

      0
    5. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention  
       

      J'ai trouvé cela :

      erreur ligne 2 "no module named 'gi'

      #!/usr/bin/python
      import gi
      gi.require_version('Notify', '0.7')
      from gi.repository import Notify
      from imapclient import IMAPClient
      import time
      
      
      HOSTNAME = 'ServeurImap' # sans http:// !
      USERNAME = 'Identiant'
      PASSWORD = 'MotDePasse'
      MAILBOX = 'Inbox'
      
      
      NEWMAIL_OFFSET = 0   # my unread messages never goes to zero, yours might
      MAIL_CHECK_FREQ = 60 # check mail every 60 seconds
      
      
      while True:
          server = IMAPClient(HOSTNAME, use_uid=True, ssl=True)
          server.login(USERNAME, PASSWORD)
      
      
          folder_status = server.folder_status(MAILBOX, 'UNSEEN')
          newmails = str(folder_status['UNSEEN'])
      
      
          if newmails > NEWMAIL_OFFSET:
                       Notify.init("Courrier")
                       Notify.uninit()
      
      
          time.sleep(MAIL_CHECK_FREQ)
      0
  8. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   Ambassadeur 1 312
     

    Re jee pee,

    Ton code fonctionne parfaitement, un grand merci !

    Tu l'as crée toi même? Ou tu t'es inspiré d'un modèle !

    Pour la variable d'environnement, python version 312 qui à été désinstallée, s'il reste des fichiers dans le répertoire, il faut les supprimer, c'est ça que tu veux me dire ?


    0
    1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
       

      j'ai effectué une recherche python + imap, et à partir de 3 exemples j'ai créé un source a minima.
       

      peut être supprimer les sources dans le répertoire, mais ce que j'indiquais c'est supprimer le répertoire 3.12 de la variable d'environnement PATH :

      0
      1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312 > jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention  
         

        Ok j'ai fait pour les variables d'enveironnement et le chemin de python311.

        Le code fonctionne pour outlook, mais pas pour yahoo.

        0
  9. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   Ambassadeur 1 312
     

    Bonjour,

    Voici un code pour notification de mail sur messagerie yahoo :

    Erreur d'indentification, est-il correct ce code ?

    import imaplib
    box = imaplib.IMAP4_SSL('imap.mail.yahoo.com', 993)
    box.login("xxxx","xxxx")
    
    # Connexion au serveur
    try:
        mail = imaplib.IMAP4_SSL(server)
        mail.login(user, password)
        mail.select("Inbox")
    except:
        print('Anomalie de connexion',server)
    else:
      (retcode, messages) = mail.search(None, '(UNSEEN)')
      if retcode == 'OK':
         nonlus = len(messages[0].split())
      else:
        nonlus = "?"
    
       (retcode, messages) = mail.search(None, '(SEEN)')
         if retcode == 'OK':
            lus = len(messages[0].split())
       else:
         lus = "?"
    
       print(user, "messages (non lus/lus) :", nonlus, "/", lus)
    input()
    
    
    
    
    
    
    
    
        
    
    
    
    
    

    0
  10. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
     

    Il faut que tu travailles en essayant de comprendre ce que fait le code. Tu recherches des bouts de codes que tu mixes entre eux, sans logique. Là si la connexion lignes 2 et 3 fonctionnaient, tu aurais tout de même une erreur en ligne 7 avec une variable non définie.

    Pour tester la connexion, il suffit de

    import imaplib
    box = imaplib.IMAP4_SSL('imap.mail.yahoo.com', 993)
    box.login("xxxx","xxxx")
    input()

    Ce qui est insatisfaisant puisque si cela fonctionne, le programme ne le dit pas ;-)

    Je n'ai pas de compte yahoo. Mais il est probable que comme les comptes gmail, la procédure de connexion soit particulière. En consultant :

    je pense que le mot de passe à donner n'est pas le mot de passe du compte mail mais un "mot de passe d'application" qu'il faudrait générer depuis son compte yahoo.


    0
    1. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   1 312
       

      Merci des conseils. J'ai repris le meme code que pour outlook, modifié le serveur, identifiant et mdp de l'application, ça fonctionne !

      0
  11. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   Ambassadeur 1 312
     

    J'ai essayé de faire le code de yahoo mail à partir de l'IDLE de python :

    J'ai l'erreur "unexpected indentation", que pense tu de mon identation !

    import imaplib
    
    # Configuration
    server = "mail.yahoo.com"
    user = "xxx"
    password = "xxx "
    
    # Connexion au serveur
    try:
        mail = imaplib.IMAP4_SSL(server)
        mail.login(user, password)
        mail.select("Inbox")
    except:
        print('Anomalie de connexion',server)
    else:
       (retcode, messages) = mail.search(None, '(UNSEEN)')
       if retcode == 'OK':
          nonlus = len(messages[0].split())
       else:
         nonlus = "?"
    
       (retcode, messages) = mail.search(None, '(SEEN)')
         if retcode == 'OK':
            lus = len(messages[0].split())
       else:
         lus = "?"
    
       print(user, "messages (non lus/lus) :", nonlus, "/", lus)
    input()
    
    
    
    
    
    
    
    
        
    
    
    
    
    

    Le souci serait ligne "if retcode" en ligne 17.


    0
    1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
       

      oui en ligne 23 2 blancs en trop.

      0
  12. quentin2121 Messages postés 9063 Date d'inscription   Statut Membre Dernière intervention   Ambassadeur 1 312
     

    Ok merci. Je trouve perso que le code répond plus vite à l'exécution sur pycharm que par IDLE. Mais c'est plus clair dans l'éditeur, pour taper le code.


    0
    1. jee pee Messages postés 9437 Date d'inscription   Statut Modérateur Dernière intervention   9 973
       

      IDLE est l'outil de base livré avec Python. Pycharm est un environnement de développement que j'imagine beaucoup plus complet, qu'il faut, comme tout, apprendre à utiliser, pour en tirer des avantages.

      Pycharm doit répondre plus rapidement, car au démarrage il doit charger l'interpréteur Python, alors qu'IDLE sur run va devoir lancer l'interpréteur Python.

      0