2011-10-27 38 views
5

Hãy tha thứ cho tôi trước. Khi tôi đã cố gắng nghiên cứu câu hỏi này, tôi sẽ chỉ nhìn vào mã mà tôi không thể hiểu được. Tôi có khoảng 3 giờ kinh nghiệm với Python và có lẽ tôi đang cố gắng nhiều hơn tôi có thể xử lý.Đính kèm một tệp vào một e-mail

Vấn đề rất đơn giản. Tôi có thể gọi thành công Python từ R (phần mềm phân tích của tôi) để gửi một e-mail. Thêm thông điệp, chủ đề, đến và từ các trường tôi có thể làm. Tôi muốn có thể gửi tệp đính kèm. Cuộc sống sẽ tuyệt vời nếu tôi chỉ có thể gửi một tập tin đính kèm.

Mã Tôi có vậy, đến nay là

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

Khi tôi chạy mã này, tôi nhận được thông báo chuỗi tải trọng dự kiến: [type 'danh sách'] (nhưng với < không [)

Tôi đang ở giới hạn của mình để tự học ngày hôm nay. Tôi hy vọng đây là một sửa chữa rõ ràng cho một người nào đó có kinh nghiệm hơn bản thân tôi.

Tôi hy vọng tất cả các bạn đều có một ngày tuyệt vời.

+0

Tôi không biết nhiều Python, nhưng vì bạn chỉ sử dụng "[" trong các dòng bắt đầu bằng "msg [From", "msg [To" và "msg [Subject". nơi thay thế [] bằng <>. –

+1

Mã tương tự có vẻ phù hợp với tôi. Bạn có thể xin vui lòng đăng bài trở lại đầy đủ? Ngoài ra, điều này dường như không liên quan gì đến r, vì vậy tôi sẽ xóa thẻ đó. –

+0

Bạn có vẻ đúng. Khi tôi đến vào sáng nay và chạy nó, nó hoạt động tốt. Tôi đã đăng sự thích ứng vào một hàm R bên dưới. Cảm ơn bạn đã tìm kiếm nó. – Benjamin

Trả lời

0

Tôi biết đó là hình thức xấu để trả lời câu hỏi của riêng tôi, nhưng nó bắt đầu hoạt động một cách kỳ diệu mà không có thay đổi. Thật là một cách để tạo ấn tượng đầu tiên của tôi, đúng không?

Dù sao, tôi đã bọc nó vào một hàm R. Điều này sẽ gửi từ gmail, nhưng tôi chưa thử gửi nó từ các tài khoản khác. Tôi quan tâm nhất đến việc gửi từ Outlook, vì tôi sẽ sử dụng điều này để gửi báo cáo phân tích từ bên trong tập lệnh của mình. Khi tôi nhập máy chủ SMTP của chủ nhân của tôi, nó đã đưa ra lỗi "phần mở rộng SMTP AUTH không được máy chủ hỗ trợ". Tôi nghi ngờ tôi sẽ phải làm việc này với những người hỗ trợ kỹ thuật của tôi.

Điều này có thể chỉ hoạt động trên Windows, nhờ vào các hàm winDialog(). Nhưng đó là một khởi đầu tốt.

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

Không phải là hình thức xấu để trả lời câu hỏi của riêng bạn - thậm chí nó còn được khuyến khích! http://meta.stackexchange.com/questions/9933/is-there-a-convention-for-accepting-my-own-answer-to-my-own-question – Chadwick

1

Bạn có thể thử sử dụng 'bưu phẩm' thay vì cố gắng sử dụng SMTP trực tiếp. Mailer có thể được tìm thấy here.

Dưới đây là một số mã đơn giản cho biết cách hoạt động của nó.

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) 

Tôi đã kết hợp điều này với nhau từ một số ví dụ tôi đã có tại địa phương. Trang gửi thư được liên kết ở trên cũng hiển thị các ví dụ khác. Khi tôi tìm thấy mã này, tôi đã chuyển đổi tất cả mã email python khác của mình để sử dụng gói này.

+0

Tôi đã thử điều này trước khi làm việc gì đó. Thật không may, nếu không có một phân phối Python và chạy mã của tôi thông qua R, nó dường như không nhận ra các gói phần mềm và tôi không biết làm thế nào để có được để làm việc. Xin lỗi tôi không thể là một sinh viên hiệu quả hơn. – Benjamin

Các vấn đề liên quan