La classe centrale nel package email è la classe Message; è la classe base per il modello dell'oggetto email. Message fornisce le funzionalità basilari per impostare ed interrogare i campi delle intestazioni e per accedere al corpo del messaggio.
Concettualmente, un oggetto Message è composto da headers (NdT: intestazioni) e payloads (NdT: carico utile). Le intestazioni hanno nomi dei campi e valori in stile RFC 2822 dove i nomi dei campi ed i valori sono separati da un due punti. Il due punti non è né parte del nome del campo né del suo valore.
Le intestazioni vengono immagazzinate e restituite in una forma che ne
mantiene la sensibilità a maiuscole e minuscole, ma sono fatte
corrispondere in modo non sensibile a queste differenze. Può anche
esserci una singola intestazione della busta, anche nota come
l'intestazione Unix-From o l'intestazione From_
. Il carico
utile può essere sia una stringa, in caso di semplici oggetti
messaggio, sia una lista di oggetti Message per documenti che
contengono MIME (per esempio multipart/* e
messaggi/rfc822).
Gli oggetti Message forniscono un'interfaccia in stile mappa per accedere alle intestazioni dei messaggi ed una specifica interfaccia per accedere sia alle intestazioni che al carico utile. Fornisce metodi utili per generare una rappresentazione dell'albero degli oggetti di messaggio, per accedere ai parametri delle intestazioni acceduti comunemente e per navigare ricorsivamente nell'albero degli oggetti.
Questi sono i metodi della classe Message:
) |
[unixfrom]) |
True
, l'intestazione della busta
viene inclusa nella stringa restituita. Il valore predefinito di
unixfrom è False
.
Notare che questo metodo viene fornito per comodità ma non può sempre formattare il messaggio nel modo voluto. Per avere maggiore flessibilità, istanziare un'istanza di Generator ed utilizzare direttamente il suo metodo flatten(). Per esempio:
from cStringIO import StringIO from email.Generator import Generator fp = StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(msg) text = fp.getvalue()
) |
) |
True
se il carico utile del messaggio è una lista
di oggetti sotto Message, altrimenti restituisce False
.
Quando is_multipart() restituisce False
, il carico
utile deve essere un oggetto di tipo stringa.
unixfrom) |
) |
None
se nessuna intestazione della busta è mai
stata impostata.
payload) |
None
o una lista di oggetti
Message prima della chiamata. Dopo la chiamata, il carico
utile sarà sempre una lista di oggetti di tipo Message. Se
si vuole impostare il carico utile a un oggetto scalare (tipo una
stringa), utilizzare invece set_payload().
[i[, decode]]) |
True
o una stringa quando is_multipart() è
False
. Se il carico utile è una lista e viene modificato l'oggetto
lista si modifica anche il carico utile dell'oggetto.
Con l'argomento facoltativo i, get_payload()
restituisce l'i-esimo elemento del carico utile, contando da
zero, se is_multipart() è True
. Viene sollevata
l'eccezione IndexError se i è minore di 0 o maggiore
o uguale al numero di oggetti nel carico utile. Se il carico utile è
una stringa (is_multipart() è False
) e i viene
fornito, viene sollevata l'eccezione TypeError.
L'opzione facoltativa decode indica se il carico utile deve
essere decodificato o no, in accordo con l'intestazione
Content-Transfer-Encoding:. Quando il valore è True
ed il
messaggio non è multipart, il carico utile viene decodificato se il
valore dell'intestazione è "quoted-printable" o "base64". Se
altre codifiche vengono utilizzate o l'intestazione
Content-Transfer-Encoding: manca o il carico utile ha dati
base64 falsi, il carico utile viene restituito così com'è (non
decodificato). Se il messaggio è multipart ed l'opzione decode
è impostata a True
, viene restituito None
. Il valore
predefinito per decode è False
.
payload[, charset]) |
Modificato nella versione 2.2.2: Aggiunto l'argomento charset.
charset) |
None
. Se è una stringa,
verrà convertita ad un'istanza di Charset. Se charset è
None
, il parametro charset viene rimosso dall'intestazione
Content-Type:. Qualunque altra cosa solleva l'eccezione
TypeError.
Il messaggio si assume essere di tipo text/* codificato con
charset.input_charset
. Verrà convertito in
charset.output_charset
e codificato opportunamente, se
necessario, quando verrà generata la rappresentazione in testo del
messaggio. Le intestazioni MIME (MIME-Version:,
Content-Type:, Content-Transfer-Encoding:)
verranno aggiunte quando necessario.
Nuovo nella versione 2.2.2.
) |
I seguenti metodi implementano un'interfaccia in stile mappa per accedere alle intestazioni RFC 2822 del messaggio. Si noti che ci sono alcune differenze semantiche tra questi metodi e l'interfaccia delle normali mappe (dizionari). Per esempio, in un dizionario non ci sono chiavi duplicate, ma qui ci possono essere intestazioni duplicate. Inoltre, nei dizionari non c'è garanzia di ordinamento per le chiavi restituite da keys(), ma in un oggetto Message, le intestazioni vengono sempre restituite nell'ordine in cui appaiono nel messaggio originale, o aggiunte al messaggio in seguito. Ogni intestazione cancellata e poi reinserita viene sempre aggiunta alla fine della lista delle intestazioni.
Queste differenze semantiche sono intenzionali e sono polarizzate verso la massima convenienza.
Notare che in tutti i casi, ogni intestazione della busta presente nel messaggio non viene inclusa nella mappa di interfaccia.
) |
name) |
in
, per esempio:
if 'message-id' in myMessage: print 'Message-ID:', myMessage['message-id']
name) |
None
; l'eccezione
KeyError non viene mai sollevata.
Notare che se il campo nominato appare più di una volta nelle intestazioni del messaggio, non è definito quale di questi verrà restituito. Utilizzare il metodo get_all() per ottenere i valori di tutte le intestazioni nominate.
name, val) |
Notare che questo non sovrascrive o cancella nessuna intestazione esistente con lo stesso nome. Se si vuole l'assicurazione che la nuova intestazione sia l'unica presente nel messaggio con quel nome di campo, cancellare il campo prima dell'inserimento, per esempio:
del msg['subject'] msg['subject'] = 'Python roolz!'
name) |
name) |
) |
) |
) |
name[, failobj]) |
None
).
Qui di seguito altri metodi utili:
name[, failobj]) |
None
).
_name, _value, **_params) |
Per ogni oggetto nel dizionario degli argomenti di tipo keyword
_params, la chiave viene presa come il nome del parametro, con i
caratteri di trattino basso convertiti in punti (poiché i punti sono
illegali come identificatori Python). Normalmente, il parametro viene
aggiunto come chiave="valore"
a meno che value non sia
None
, in tal caso solo la chiave verrà aggiunta.
Ecco un esempio:
msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')
Questo aggiunge un'intestazione che avrà questa forma:
Content-Disposition: attachment; filename="bud.gif"
_name, _value) |
Nuovo nella versione 2.2.2.
) |
La RFC 2045 definisce il tipo predefinito del messaggio come text/plain (NdT: puro testo), a meno che non appaia all'interno di un contenitore multipart/digest, in tal caso sarà message/rfc822. Se l'intestazione Content-Type: ha una specifica errata per il tipo, la RFC 2045 stabilisce che il tipo predefinito sia text/plain.
Nuovo nella versione 2.2.2.
) |
Nuovo nella versione 2.2.2.
) |
Nuovo nella versione 2.2.2.
) |
Nuovo nella versione 2.2.2.
ctype) |
Nuovo nella versione 2.2.2.
[failobj[, header[, unquote]]]) |
True
(il valore
predefinito).
L'argomento facoltativo failobj è l'oggetto restituito se non c'è l'intestazione Content-Type:. L'argomento facoltativo header è l'intestazione da ricercare al posto di Content-Type:.
Modificato nella versione 2.2.2: aggiunto l'argomento unquote.
param[, failobj[, header[, unquote]]]) |
None
).
Se viene fornito l'argomento facoltativo header, specifica l'intestazione del messaggio da utilizzare al posto di Content-Type:.
Le chiavi dei parametri sono sempre confrontate in modo non sensibile
alle differenze tra maiuscole e minuscole. Il valore restituito può
essere una stringa o una tupla di 3 elementi se il parametro è
codificato secondo la RFC 2231. Quando è una tupla di 3 elementi,
gli elementi del valore sono nella forma (CHARSET, LANGUAGE,
VALUE)
. Notare che siaCHARSET
che LANGUAGE
possono
essere None
, in qual caso doveva considerare VALUE
come
codificato nel charset us-ascii
. Si può generalmente ignorare
LANGUAGE
.
Un'applicazione deve essere pronta a gestire i valori restituiti come tuple di 3 elementi, e deve poter convertire il parametro in una stringa Unicode, tipo:
param = msg.get_param('foo') if isinstance(param, tuple): param = unicode(param[2], param[0] or 'us-ascii')
In ogni caso, il parametro value (sia restituito come stringa o
l'oggetto VALUE
nella tupla di 3 elementi) è sempre non
quotato, a meno che unquote non sia impostato a False
.
Modificato nella versione 2.2.2: aggiunto l'argomento unquote e la tupla di 3 elementi restituisce i valori possibili.
param, value[, header[, requote[, charset[, language]]]]) |
Imposta un parametro nell'intestazione Content-Type:. Se il parametro esiste nell'intestazione, il valore viene sostituito con value. Se l'intestazione Content-Type: non è ancora stata definita per questo messaggio, viene impostata a text/plain, ed il nuovo parametro viene aggiunto in coda come per l'RFC 2045.
L'header facoltativo specifica un'intestazione alternativa a
Content-Type: e tutti i parametri verranno quotati come
necessario a meno che il facoltativo requote sia False
(il valore predefinito è True
).
Se il facoltativo charset viene specificato, il parametro verrà codificato secondo l'RFC 2231. Il facoltativo language specifica la lingua secondo la RFC 2231, il valore predefinito è la stringa vuota. Sia charset che language devono essere stringhe.
Nuovo nella versione 2.2.2.
param[, header[, requote]]) |
False
(il valore
predefinito è True
). Il facoltativo header specifica
un'alternativa a Content-Type:.
Nuovo nella versione 2.2.2.
type[, header][, requote]) |
Questo metodo sostituisce l'intestazione Content-Type:,
mantenendo tutti i parametri in linea. Se requote è
False
, questo lascia la quotatura esistente delle intestazioni
invariata, altrimenti il parametro verrà quotato (il comportamento
predefinito).
Un'intestazione alternativa può essere specificata nell'argomento header. Quando l'intestazione Content-Type: viene impostata, viene anche aggiunta un'intestazione MIME-Version:.
Nuovo nella versione 2.2.2.
[failobj]) |
filename
dell'intestazione
Content-Disposition: del messaggio o failobj se
l'intestazione è assente o non ha un parametro filename
. Alla
stringa restituita viene sempre rimossa la quotatura come da
Utils.unquote().
[failobj]) |
boundary
(NdT: limite)
dell'intestazione Content-Type: del messaggio o
failobj se l'intestazione è assente o non ha un parametro
boundary
. Alla stringa restituita viene sempre rimossa la
quotatura come da Utils.unquote().
boundary) |
boundary
dell'intestazione
Content-Type: a boundary
. set_boundary()
quoterà sempre boundary
se necessario. Viene sollevata
l'eccezione HeaderParseError se l'oggetto del messaggio
non contiene l'intestazione Content-Type:.
Notare che usare questo metodo è sottilmente differente che non
cancellare la vecchia intestazione Content-Type: ed
aggiungerne una nuova con il nuovo boundary
tramite
add_header(), poiché set_boundary() mantiene
l'ordine dell'intestazione Content-Type: nella lista delle
intestazioni. Comunque, non mantiene alcuna soluzione di
continuità che poteva essere presente nell'intestazione
Content-Type: originale.
[failobj]) |
charset
dell'intestazione
Content-Type: convertito in minuscolo. Se non c'è
un'intestazione Content-Type: o se questa intestazione non
ha un parametro charset
viene restituito failobj.
Notare che questo metodo differisce da get_charset() che restituisce l'istanza di Charset per la codifica predefinita per il corpo del messaggio.
Nuovo nella versione 2.2.2.
[failobj]) |
Ogni elemento nella lista sarà una stringa corrispondente al valore
del parametro charset
dell'intestazione
Content-Type: per la sotto parte rappresentata. Comunque,
se la sotto parte non ha un header Content-Type:, non ha un
parametro charset
o non è il text del tipo MIME
principale, l'elemento nella lista restituita sarà failobj.
) |
for
; ogni iterazione restituisce la prossima
sotto parte.
Ecco un esempio che stampa il tipo di MIME di tutte le parti di una struttura di messaggio multipart:
>>> for part in msg.walk(): >>> print part.get_content_type() multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822
Gli oggetti Message possono, facoltativamente, contenere due attributi delle istanze, che possono essere utilizzate quando si genera la versione testuale di un messaggio MIME.
L'attributo preamble contiene questo testo iniziale, fuori dagli standard, per il documento MIME. Quando l'analizzatore (Parser) scopre del testo dopo le intestazioni ma prima della prima stringa di limite, assegna questo testo all'attributo preamble. Quando il generatore Generator sta scrivendo la rappresentazione in testo del messaggio MIME, e vede che il messaggio ha un attributo preamble, scriverà questo testo nell'area tra le intestazioni ed il primo limite. Vedere email.Parser ed email.Generator per i dettagli.
Notare che se l'oggetto messaggio non ha un preambolo, l'attributo
preamble varrà None
.
Una nota: quando si genera la versione testuale di un messaggio multipart che non ha epilogue (utilizzando la classe standard Generator), nessun fine riga viene aggiunto dopo la riga del limite di chiusura. Se nell'oggetto del messaggio è presente epilogue e questo valore non inizia con un fine riga, un fine riga viene stampato dopo il limite di chiusura. Questo parrebbe un po' malcostruito, ma è la cosa più logica. Il risultato è che se si vuole assicurare che un fine riga sia stampato dopo il limite di chiusura del multipart, si deve impostare epilogue ad una stringa vuota.