Domanda

mi piacerebbe andare a prendere l'intero messaggio dal server IMAP4. In docs python se pensa che questa porzione di codice che funziona:

>>> t, data = M.fetch('1', '(RFC822)')
>>> body = data[0][1]

Mi chiedo se posso sempre fiducia che i dati [0] [1] restituisce il corpo del messaggio. Quando ho fatto funzionare 'RFC822.SIZE' Ho solo una stringa al posto di una tupla.

Ho sfogliato rfc1730, ma non ero in grado di capire la struttura di risposta adeguata per il 'RFC822'. E 'anche difficile dire la struttura risultato di richiamo da documentazione imaplib.

Ecco cosa voglio dire quando va a prendere RFC822:

('OK', [('1 (RFC822 {858569}', 'body of the message', ')')])

Ma quando vado a prendere RFC822.SIZE sto ottenendo:

('OK', ['1 (RFC822.SIZE 847403)'])

Come faccio a gestire correttamente i dati [0] lista? Mi posso fidare che quando si tratta di una lista di tuple del tuple ha esattamente 3 parti e la seconda parte è il carico utile?

Forse sapete qualsiasi libreria di meglio per IMAP4?

È stato utile?

Soluzione

No ... imaplib è un buon biblioteca, è imap che è così incomprensibile.

Si potrebbe desiderare di controllare che t == 'OK', ma data[0][1] funziona come previsto per quanto ho usato.

Ecco un rapido esempio che uso per estrarre i certificati firmati che ho ricevuto per e-mail, non è a prova di bomba-, ma si adatta al mio scopo:

import getpass, os, imaplib, email
from OpenSSL.crypto import load_certificate, FILETYPE_PEM

def getMsgs(servername="myimapserverfqdn"):
  usernm = getpass.getuser()
  passwd = getpass.getpass()
  subject = 'Your SSL Certificate'
  conn = imaplib.IMAP4_SSL(servername)
  conn.login(usernm,passwd)
  conn.select('Inbox')
  typ, data = conn.search(None,'(UNSEEN SUBJECT "%s")' % subject)
  for num in data[0].split():
    typ, data = conn.fetch(num,'(RFC822)')
    msg = email.message_from_string(data[0][1])
    typ, data = conn.store(num,'-FLAGS','\\Seen')
    yield msg

def getAttachment(msg,check):
  for part in msg.walk():
    if part.get_content_type() == 'application/octet-stream':
      if check(part.get_filename()):
        return part.get_payload(decode=1)

if __name__ == '__main__':
  for msg in getMsgs():
    payload = getAttachment(msg,lambda x: x.endswith('.pem'))
    if not payload:
      continue
    try:
      cert = load_certificate(FILETYPE_PEM,payload)
    except:
      cert = None
    if cert:
      cn = cert.get_subject().commonName
      filename = "%s.pem" % cn
      if not os.path.exists(filename):
        open(filename,'w').write(payload)
        print "Writing to %s" % filename
      else:
        print "%s already exists" % filename

Altri suggerimenti

Il IMAPClient pacchetto è un bel po 'più facile da lavorare. Dalla descrizione:

  

Facile da usare, Pythonic e completo   libreria client IMAP.

Questa è stata la mia soluzione per estrarre i bit di informazioni utili. E 'stato affidabile fino ad ora:

import datetime
import email
import imaplib
import mailbox


EMAIL_ACCOUNT = "your@gmail.com"
PASSWORD = "your password"

mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login(EMAIL_ACCOUNT, PASSWORD)
mail.list()
mail.select('inbox')
result, data = mail.uid('search', None, "UNSEEN") # (ALL/UNSEEN)
i = len(data[0].split())

for x in range(i):
    latest_email_uid = data[0].split()[x]
    result, email_data = mail.uid('fetch', latest_email_uid, '(RFC822)')
    # result, email_data = conn.store(num,'-FLAGS','\\Seen') 
    # this might work to set flag to seen, if it doesn't already
    raw_email = email_data[0][1]
    raw_email_string = raw_email.decode('utf-8')
    email_message = email.message_from_string(raw_email_string)

    # Header Details
    date_tuple = email.utils.parsedate_tz(email_message['Date'])
    if date_tuple:
        local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
        local_message_date = "%s" %(str(local_date.strftime("%a, %d %b %Y %H:%M:%S")))
    email_from = str(email.header.make_header(email.header.decode_header(email_message['From'])))
    email_to = str(email.header.make_header(email.header.decode_header(email_message['To'])))
    subject = str(email.header.make_header(email.header.decode_header(email_message['Subject'])))

    # Body details
    for part in email_message.walk():
        if part.get_content_type() == "text/plain":
            body = part.get_payload(decode=True)
            file_name = "email_" + str(x) + ".txt"
            output_file = open(file_name, 'w')
            output_file.write("From: %s\nTo: %s\nDate: %s\nSubject: %s\n\nBody: \n\n%s" %(email_from, email_to,local_message_date, subject, body.decode('utf-8')))
            output_file.close()
        else:
            continue

IMAP-tools libreria per efficace lavorare con i messaggi di posta elettronica utilizzando il protocollo IMAP.

  • lavoro trasparente con attributi lettera (compresi UID)
  • lavoro con le lettere nelle directory (copiare, cancellare, la bandiera, spostare, visto)
  • lavoro con le directory (elenco, insieme, ottenere, creare, esiste, rinominare, eliminare, stato)
  • dipendenze esterne
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top