2011-10-27 56 views
5

請原諒我。當我試圖研究這個問題時,我最終看到了我根本無法理解的代碼。我有大約3個小時的Python經驗,可能嘗試的不止我能處理的。將單個文件附加到電子郵件

問題很簡單。我可以成功地從R(我的分析軟件)調用Python來發送電子郵件。添加消息,主題,以及我可以做的字段。我希望能夠發送附件。如果我只發送一份附件,生活將會很棒。

我的代碼迄今是

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() 

當運行該代碼,我得到預期消息 串有效負載:[式名單'](但是<不是[)

今天我正處於自我學習的極限。我希望這是對比我更有經驗的人的明顯修補。

我希望你們都有美好的一天。

+0

我不太瞭解Python,但是因爲yourr只使用「[」是以「msg [From],」msg [To和msg [Subject]用<>替換[]的地方。 –

+1

類似的代碼似乎適合我。你可以請發佈完整的追溯?此外,這似乎與r沒有任何關係,所以我將刪除該標記。 –

+0

你看起來是正確的。當我今天上午跑過來時,它工作得很好。我在下面的R函數中發佈了適配。感謝您查看它。 – Benjamin

回答

0

我知道這是不好的形式來回答我自己的問題,但它開始奇蹟般地工作,沒有任何變化。怎樣才能讓我的第一印象,對吧?

無論如何,我把它包裝成R函數。這將從Gmail發送,但我還沒有嘗試從其他帳戶發送它。我最感興趣的是從Outlook發送郵件,因爲我會使用它從我的腳本中發送分析報告。當我進入我的僱主的SMTP服務器時,它給出錯誤「服務器不支持SMTP AUTH擴展名」。我懷疑我將不得不與我的技術支持人員一起工作。

這可能只適用於Windows,這要歸功於winDialog()函數。但這是一個好的開始。

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

不錯的表單來回答你自己的問題 - 它甚至被鼓勵! http://meta.stackexchange.com/questions/9933/is-there-a-convention-for-accepting-my-own-answer-to-my-own-question – Chadwick

1

您可以嘗試使用'郵件程序'而不是直接嘗試使用SMTP。梅勒可以找到here

下面是一些簡單的代碼,顯示它是如何工作的。

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) 

我從本地的一些例子中拼湊出來的。上面鏈接的郵件頁面還顯示了其他示例。一旦我找到這個代碼,我轉換了所有其他的Python電子郵件代碼來使用這個包。

+0

我在嘗試之前嘗試了一下。不幸的是,沒有Python發行版並通過R運行我的代碼,它似乎沒有認識到這個軟件包,而且我也不知道如何開始工作。對不起,我不能成爲一個更有生產力的學生。 – Benjamin