pagina
precedente
Script python
sendMailAttach.py - v. 1.0
Scritto da: Demaldè Gastone
Data: domenica 16 settembre 2007
Lo script permette di spedire una o più mail con uno o più attachment.
Sintassi: sendMailAttach.py nomeFileMessaggi.xml
Il file contenente le informazioni relative ai messaggi da spedire è scritto in xml.
La sintassi del file è la seguente:
--- inizio file messaggi
<?xml version='1.0' encoding='iso-8859-15'?>
<msgs>
<message>
<from> ... </from>
<!-- gli indirizzi multipli vanno separati con una virgola -->
<to> ... </to>
<cc> ... </cc>
<bcc> ... </bcc>
<subject> ... </subject>
<body>
...
...
</body>
<!-- singolo nome di file per ogni tag <file> -->
<file> ...</file>
...
<file> ... </file>
</message>
<!-- eventuali altri messaggi da spedire -->
<message>
...
</message>
...
</msgs>
--- fine file messaggi-------
I
tag del file xml devono essere scritti in minuscolo.
Per
poter spedire i messaggi occorre cambiare la linea smtpHost = 'out.alice.it'
inserendo l'indirizzo IP o il nome del server SMTP che si util
izza normalmente per spedire la posta.
Lo script
fa del suo meglio per individuare dove si trovano il file dei messaggi e
d i file da spedire in attach.
In particolare:
&nb
sp; - se non trova il file dei messaggi, prova a cercarlo nella
directory dello script
- se non trova i file da spedire, prova a cercarli nella directory
del file dei messaggi e poi nella directory dello script.
Lo script può essere memorizzato in una posizione diversa rispetto al file xml dei messaggi.
Ad esempio:
/usr/local/bin/sendMailAttach.py /home/user/sendMailAttach/mail-1234.xml
Durante l'esecuzione viene generato un file di log contenente le operazioni eseguite e gli errori incontrati.
Il file di log si trova nella stessa cartella del file xml dei messaggi
ed ha lo stesso nome del file dei messaggi seguito da una estensione
.log
All'inizio dell'eleborazione, il file xml dei messaggi viene rinominato aggiungendo un .begin
Alla fine viene aggiunto un .end
In questo modo non è possibile lanciare per due volte lo stesso script,
inoltre la presenza di un file senza .end indica una fine non prevista
dell'esecuzione dello script.
Nel caso esistano già i file .begin e .begin.end, questi vengono sovrascritti.
Se si vuole utilizzare lo script in contemporanea da più applicazioni,
bisogna assicurarsi di generare file xml con nomi diversi,
ad esempio inserendo nel nome del file xml:
- data e ora di generazione,
- nome utente,
- numero casuale,
- ecc.
I tag <file> sono opzionali e possono essere omessi.
Il loro numero non è limitato, quindi si possono spedire zero, uno o più attachment in ogni messaggio.
I vari tag possono essere omessi.
E' consigliato mettere sempre i tag
<from>,<to>,<subject>,<body> per evitare rischi
di filtraggio del messaggio da parte dei server.
E' consigliato anche mettere un indirizzo email valido nel campo
<from>, in modo da ricevere le segnalazioni di errore dei server
nel caso gli indirizzi di destinazione non fossero validi.
Nel caso di tag multipli, viene letto solo il primo. Sono gestite le ripetizioni solo del tag <file>.
Eventuali indirizzi multipli devono essere inseriti nei tag <to>, <cc>, <bcc> separandoli con le virgole.
Nel file xml è possibile inserire commenti:
<!-- inizio commento
fine commento -->
Nel file xml i caratteri speciali < e > possono essere utilizzati
solo nei tag. Al di fuori dei tag, < e > devono essere sostituiti
rispettivamente
con < e >
SCRIPT PYTHON - send.py
#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
# name : ...path-sendmail/send.py
import email.MIMEMultipart
import email.MIMEText
import email.MIMEBase
import email.Encoders
import email.Utils
import smtplib
import time
import shutil
import sys
import os.path
import xml.dom.minidom
smtpHost = 'out.alice.it'
class Messaggio:
def __init__(self):
self.From=''
self.To=''
self.Cc=''
self.Bcc=''
self.Subject=''
self.Body=''
self.Files=[]
def __str__(self):
s = '--- inizio messaggio ---\n'
s += 'From: %s\n' % self.From
s += 'To: %s\n' % self.To
s += 'Cc: %s\n' % self.Cc
s += 'Bcc: %s\n' % self.Bcc
s += 'Subject: %s\n' % self.Subject
s += 'Body: %s\n' % self.Body
s += 'Files: %s\n' % self.Files
s += '--- fine messaggio ---'
return s.encode(charset)
def fromTo(self):
s = 'From: %s, To: %s' % (self.From,self.To)
return s.encode(charset)
def stampa(s):
print s
fLog.write(s + '\n')
def leggiTestoNodoXML(nodoXML):
t = ""
try:
for n in nodoXML.childNodes:
if n.nodeType == n.TEXT_NODE:
t = t + n.data
except: pass
return t
def leggiTags(nodo,tag):
testi = []
for n in nodo.getElementsByTagName(tag):
t = leggiTestoNodoXML(n)
testi.append(t)
if len(testi)==0 and tag!='file':
testi.append('')
return testi
def leggiMessaggi(nomeFile):
msgs = []
s = file(nomeFile).read()
s = unicode(s,charset)
doc = xml.dom.minidom.parseString(s.encode(charset))
nodiMess = doc.getElementsByTagName('message')
for m in nodiMess:
message = Messaggio()
message.From = leggiTags(m,'from')[0]
message.To = leggiTags(m,'to')[0]
message.Cc = leggiTags(m,'cc')[0]
message.Bcc = leggiTags(m,'bcc')[0]
message.Subject = leggiTags(m,'subject')[0]
message.Body = leggiTags(m,'body')[0]
message.Files = leggiTags(m,'file')
msgs.append(message)
return msgs
def controllaFile(f):
if os.path.exists(f): return f
n = os.path.join(dirConf,f)
if os.path.exists(n): return n
n = os.path.join(dirScript,f)
if os.path.exists(n): return n
s = 'Errore: non trovo il file %s' % f
stampa(s)
raise Exception(s)
def sendMailAttach(m):
Date = email.Utils.formatdate(time.time(),True)
outer = email.MIMEMultipart.MIMEMultipart()
outer['Subject'] = m.Subject.strip()
if m.To: outer['To'] = m.To.strip()
outer['From'] = m.From.strip()
outer['Date'] = Date
if m.Cc: outer['Cc'] = m.Cc.strip()
outer['X-mailer'] = 'ADS Python script'
outer.preamble = 'ADS Python script\n'
outer.epilogue = ''
msg = email.MIMEText.MIMEText(m.Body,_charset=charset)
outer.attach(msg)
for f in m.Files:
maintype = 'application'
subtype = 'octet-stream'
nomeFile = controllaFile(f)
buff = file(nomeFile).read()
msg = email.MIMEBase.MIMEBase(maintype, subtype)
msg.set_payload(buff)
email.Encoders.encode_base64(msg)
nomeFile = os.path.basename(nomeFile)
msg.add_header('Content-Disposition','attachment',filename=nomeFile)
outer.attach(msg)
s = smtplib.SMTP()
# s.set_debuglevel(1)
s.connect(smtpHost)
destinatari = m.To.split(',') + m.Cc.split(',') + m.Bcc.split(',')
for i in range(len(destinatari)):
destinatari[i] = destinatari[i].strip()
s.sendmail(m.From, destinatari, outer.as_string())
s.close()
if len(sys.argv)!=2:
print 'Numero argomenti errato.'
print 'Esempio: %s messaggi.xml' % sys.argv[0]
print
sys.exit(1)
dirScript = os.path.dirname(sys.argv[0])
nomeFileMessaggi = sys.argv[1]
if not os.path.exists(nomeFileMessaggi):
nomeFileMessaggi = os.path.join(dirScript,nomeFileMessaggi)
if not os.path.exists(nomeFileMessaggi):
print 'File di configurazione mancante: %s' % sys.argv[1]
sys.exit(2)
dirConf = os.path.dirname(nomeFileMessaggi)
charset = 'iso-8859-15'
nomeFileLog = nomeFileMessaggi + '.log'
shutil.move(nomeFileMessaggi,nomeFileMessaggi+'.begin')
nomeFileMessaggi += '.begin'
fLog = file(nomeFileLog,'at')
fLog.write('''---
--- %s
---
''' % time.asctime())
messaggi = leggiMessaggi(nomeFileMessaggi)
stampa ('Letto %d messaggi' % len(messaggi))
for m in messaggi:
# stampa(str(m))
stampa(m.fromTo())
try:
sendMailAttach(m)
stampa('messaggio spedito')
except:
stampa('Errore: non riesco a spedire il messaggio')
stampa('-')
fLog.close()
shutil.move(nomeFileMessaggi,nomeFileMessaggi+'.end')