2011-10-27 4 views
5

Per favore perdonami in anticipo. Quando ho provato a cercare questa domanda, finisco per guardare un codice che semplicemente non riesco a comprendere. Ho circa 3 ore di esperienza con Python e sto probabilmente tentando più di quanto io possa gestire.Allegare un singolo file ad una e-mail

Il problema è semplice. Posso chiamare con successo Python da R (il mio software di analisi) per inviare una e-mail. Aggiungere il messaggio, l'oggetto, a e dai campi che posso fare. Mi piacerebbe essere in grado di inviare un allegato. La vita sarebbe grandiosa se potessi inviare solo un allegato.

Il codice che ho finora è

import smtplib 
import os 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEBase import MIMEBase 
from email.MIMEText import MIMEText 
from email.Utils import COMMASPACE, formatdate 
from email import Encoders 
import email.utils 

fromaddr = '[email protected]' 
toaddrs = '[email protected]' 
msg = MIMEMultipart(MIMEText('This is the body of the e-mail')) 
msg['From'] = email.utils.formataddr(('Benjamin Nutter', fromaddr)) 
msg['To'] = email.utils.formataddr(('Benjamin Nutter', toaddrs)) 
msg['Subject'] = 'Simple test message' 
f = 'filename.pdf' 
part=MIMEBase('application', 'octet-stream') 
part.set_payload(open(f, 'rb').read()) 
Encoders.encode_base64(part) 
part.add_header('Content-Disposition', 'attachment; filename=\"%s\"' % os.path.basename(f)) 
msg.attach(part) 

"username = 'user' 
"password = 'pw' 

server = smtplib.SMTP('smtp.gmail.com:587') 
server.ehlo() 
server.starttls() 
server.ehlo() 
server.login(username,password) 
server.sendmail(fromaddr, toaddrs, msg.as_string()) 
server.quit() 

Quando ho eseguito questo codice, ottengo il messaggio stringa di payload atteso: [type 'list'] (ma con < non [)

Oggi sono al limite per l'autoapprendimento. Spero che questa sia una soluzione ovvia per qualcuno più esperto di me stesso.

Spero che stiate tutti passando una bella giornata.

+0

Io non ne so molto di Python, ma dal momento che yourr solo uso di "[" è nelle linee che iniziano con "msg [Da", "msg [A" e "msg [Soggetto" che suona certo come il posto da sostituire [] con <>. –

+1

Il codice simile sembra funzionare per me. Puoi postare per favore il traceback completo? Inoltre, questo non sembra avere nulla a che fare con r, quindi ho intenzione di rimuovere quel tag. –

+0

Sembra che tu abbia ragione. Quando sono arrivato stamattina e l'ho eseguito, ha funzionato bene. Ho postato l'adattamento in una funzione R sotto. Grazie per averlo controllato. – Benjamin

risposta

0

So che è una cattiva forma rispondere alla mia domanda, ma ha iniziato a funzionare miracolosamente senza modifiche. Che modo di fare la mia prima impressione, vero?

In ogni caso, l'ho avvolto in una funzione R. Questo verrà inviato da Gmail, ma non ho ancora provato a inviarlo da altri account. Sono più interessato all'invio da Outlook, poiché utilizzerei questo per inviare report di analisi dai miei script. Quando ho inserito il server SMTP del mio datore di lavoro, ha dato l'errore "Estensione SMTP AUTH non supportata dal server". Sospetto che dovrò risolvere questo problema con i miei ragazzi del supporto tecnico.

Questo probabilmente funzionerà solo su Windows, grazie alle funzioni winDialog(). Ma è un buon inizio.

send.email <- function(to, from, subject, 
    message, attachment=NULL, 
    username, password, 
    server="smtp.gmail.com:587", 
    confirmBeforeSend=TRUE){ 
    # to: a list object of length 1. Using list("Recipient" = "[email protected]") will send the message to the address but 
    #  the name will appear instead of the address. 
    # from: a list object of length 1. Same behavior as 'to' 
    # subject: Character(1) giving the subject line. 
    # message: Character(1) giving the body of the message 
    # attachment: Character(1) giving the location of the attachment 
    # username: character(1) giving the username. If missing and you are using Windows, R will prompt you for the username. 
    # password: character(1) giving the password. If missing and you are using Windows, R will prompt you for the password. 
    # server: character(1) giving the smtp server. 
    # confirmBeforeSend: Logical. If True, a dialog box appears seeking confirmation before sending the e-mail. This is to 
    #     prevent me to send multiple updates to a collaborator while I am working interactively. 

    if (!is.list(to) | !is.list(from)) stop("'to' and 'from' must be lists") 
    if (length(from) > 1) stop("'from' must have length 1") 
    if (length(to) > 1) stop("'send.email' currently only supports one recipient e-mail address") 
    if (length(attachment) > 1) stop("'send.email' can currently send only one attachment") 
    if (length(message) > 1){ 
    stop("'message' must be of length 1") 
    message <- paste(message, collapse="\\n\\n") 
    } 

    if (is.null(names(to))) names(to) <- to 
    if (is.null(names(from))) names(from) <- from 
    if (!is.null(attachment)) if (!file.exists(attachment)) stop(paste("'", attachment, "' does not exist!", sep="")) 

    if (missing(username)) username <- winDialogString("Please enter your e-mail username", "") 
    if (missing(password)) password <- winDialogString("Please enter your e-mail password", "") 

    require(rJython) 
    rJython <- rJython() 

    rJython$exec("import smtplib") 
    rJython$exec("import os") 
    rJython$exec("from email.MIMEMultipart import MIMEMultipart") 
    rJython$exec("from email.MIMEBase import MIMEBase") 
    rJython$exec("from email.MIMEText import MIMEText") 
    rJython$exec("from email.Utils import COMMASPACE, formatdate") 
    rJython$exec("from email import Encoders") 
    rJython$exec("import email.utils") 

    mail<-c(
    #Email settings 
    paste("fromaddr = '", from, "'", sep=""), 
    paste("toaddrs = '", to, "'", sep=""), 
    "msg = MIMEMultipart()", 
    paste("msg.attach(MIMEText('", message, "'))", sep=""), 
    paste("msg['From'] = email.utils.formataddr(('", names(from), "', fromaddr))", sep=""), 
    paste("msg['To'] = email.utils.formataddr(('", names(to), "', toaddrs))", sep=""), 
    paste("msg['Subject'] = '", subject, "'", sep="")) 

    if (!is.null(attachment)){ 
    mail <- c(mail, 
     paste("f = '", attachment, "'", sep=""), 
    "part=MIMEBase('application', 'octet-stream')", 
    "part.set_payload(open(f, 'rb').read())", 
    "Encoders.encode_base64(part)", 
    "part.add_header('Content-Disposition', 'attachment; filename=\"%s\"' % os.path.basename(f))", 
    "msg.attach(part)") 
    } 

#SMTP server credentials 
    mail <- c(mail, 
    paste("username = '", username, "'", sep=""), 
    paste("password = '", password, "'", sep=""), 

#Set SMTP server and send email, e.g., google mail SMTP server 
    paste("server = smtplib.SMTP('", server, "')", sep=""), 
    "server.ehlo()", 
    "server.starttls()", 
    "server.ehlo()", 
    "server.login(username,password)", 
    "server.sendmail(fromaddr, toaddrs, msg.as_string())", 
    "server.quit()") 

    message.details <- 
    paste("To:    ", names(to), " (", unlist(to), ")", "\n", 
      "From:    ", names(from), " (", unlist(from), ")", "\n", 
      "Using server:  ", server, "\n", 
      "Subject:   ", subject, "\n", 
      "With Attachments: ", attachment, "\n", 
      "And the message:\n", message, "\n", sep="") 

    if (confirmBeforeSend) 
    SEND <- winDialog("yesnocancel", paste("Are you sure you want to send this e-mail to ", unlist(to), "?", sep="")) 
    else SEND <- "YES" 

    if (SEND %in% "YES"){ 
    jython.exec(rJython,mail) 
    cat(message.details) 
    } 
    else cat("E-mail Delivery was Canceled by the User") 
} 
+1

Non è una cattiva forma per rispondere alla tua stessa domanda - è addirittura incoraggiata! http://meta.stackexchange.com/questions/9933/is-there-a-convention-for-accepting-my-own-answer-to-my-own-question – Chadwick

1

Si potrebbe provare a utilizzare "mailer" invece di provare a utilizzare direttamente SMTP. Mailer può essere trovato here.

Ecco un semplice codice che mostra come funziona.

messages=[] 
message = mailer.Message() 
message.attach('filename.txt') 
message.From = 'Cool guy <[email protected]>' 
message.To = 'Random Dude <[email protected]>' 
message.Cc = 'Cards Fan <[email protected]>' 
message.Subject = 'Test Email' 
message.body = 'Here is the body of the email.' 
messages.append(message) 

emailer = mailer.Mailer(smtphost.example.com) 
emailer.send(messages) 

ho acciottolata questo insieme da alcuni esempi che ho avuto a livello locale. La pagina di mailer collegata sopra mostra anche altri esempi. Una volta trovato questo codice, ho convertito tutto il mio altro codice email Python per utilizzare questo pacchetto.

+0

Ho provato questo prima di far funzionare qualcosa. Sfortunatamente, senza una distribuzione Python ed eseguendo il mio codice attraverso R, non sembrava riconoscere il pacchetto e non sapevo come mettermi al lavoro. Mi dispiace, non potrei essere uno studente più produttivo. – Benjamin