2012-04-05 6 views
2

Die folgende Funktion (gefunden here) funktioniert gut für Nachrichten, die ASCII-Zeichen enthalten. Kannst du mir helfen, es für mehrsprachige Nachrichten zu ändern, weil ich Python überhaupt nicht kenne?Wie schicke ich eine E-Mail mit griechischen Buchstaben mit rJython?

send.email <- function(to, from, subject, 
    message, attachment=NULL, 
    username, password, 
    server="xxx.xxx.xxx.xxx", 
    confirmBeforeSend=FALSE){ 
    # 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") 
} 

Ich nenne es wie folgt aus:

send.email(list("[email protected]"), 
list("[email protected]"), 
"Δοκιμή αποστολής email με attachment", 
"Με χρήση της rJython", 
attachment="monthly_report.xls", 
username="gd047",password="xxxxxx") 
+0

Ich würde vermuten, dass es ein einfaches [Unicode-Mail-Codierungsproblem] (http://en.wikipedia.org/wiki/Unicode_and_email) ist. Ich suche jetzt eine gute Lösung. – MrGomez

+1

Es scheint etwas komisch zu sein, Python über rJava aus R zu benutzen. Habt ihr überlegt, [Python] (http://userpage.fu-berlin.de/~kweinert/projekte/easymail.py) über 'system()' aufzurufen oder verwenden Sie eine [Java-Bibliothek] (http://java.sun.com/developer/onlineTraining/JavaMail/contents.html)? –

+0

Ich bin nur auf der Suche nach einer Möglichkeit zum Senden einer Unicode (und vorzugsweise HTML-formatiert) Nachricht mit Anhängen, mit R –

Antwort

3

Die Frage ist, wie Sie Ihren geschlossenen Python-Code strukturiert ist. This blog entry geht ausführlicher auf, wie man richtig send Unicode email, mit dem Sie Python verwenden, um die unterlagernde SMTP-Verbindung zu verwalten. Beachten Sie, dass nach R. David Murray, this will be fixed in later iterations of the email package in Python.

Hier ist der ausgeprägte Python Code, den Sie in Ihre Anrufe in rJython nachrüsten können, direkt von the aforementioned blog post borgen:

from smtplib import SMTP 
from email.MIMEText import MIMEText 
from email.Header import Header 
from email.Utils import parseaddr, formataddr 

def send_email(sender, recipient, subject, body): 
    """Send an email. 

    All arguments should be Unicode strings (plain ASCII works as well). 

    Only the real name part of sender and recipient addresses may contain 
    non-ASCII characters. 

    The email will be properly MIME encoded and delivered though SMTP to 
    localhost port 25. This is easy to change if you want something different. 

    The charset of the email will be the first one out of US-ASCII, ISO-8859-1 
    and UTF-8 that can represent all the characters occurring in the email. 
    """ 

    # Header class is smart enough to try US-ASCII, then the charset we 
    # provide, then fall back to UTF-8. 
    header_charset = 'ISO-8859-1' 

    # We must choose the body charset manually 
    for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': 
     try: 
      body.encode(body_charset) 
     except UnicodeError: 
      pass 
     else: 
      break 

    # Split real name (which is optional) and email address parts 
    sender_name, sender_addr = parseaddr(sender) 
    recipient_name, recipient_addr = parseaddr(recipient) 

    # We must always pass Unicode strings to Header, otherwise it will 
    # use RFC 2047 encoding even on plain ASCII strings. 
    sender_name = str(Header(unicode(sender_name), header_charset)) 
    recipient_name = str(Header(unicode(recipient_name), header_charset)) 

    # Make sure email addresses do not contain non-ASCII characters 
    sender_addr = sender_addr.encode('ascii') 
    recipient_addr = recipient_addr.encode('ascii') 

    # Create the message ('plain' stands for Content-Type: text/plain) 
    msg = MIMEText(body.encode(body_charset), 'plain', body_charset) 
    msg['From'] = formataddr((sender_name, sender_addr)) 
    msg['To'] = formataddr((recipient_name, recipient_addr)) 
    msg['Subject'] = Header(unicode(subject), header_charset) 

    # Send the message via SMTP to localhost:25 
    smtp = SMTP("localhost") 
    smtp.sendmail(sender, recipient, msg.as_string()) 
    smtp.quit() 

Sobald portiert, sollte dies Ihr Code bekommen arbeiten. Hoffentlich wird bald eine bessere Unterstützung für RFC2047 und RFC3490 hinzugefügt werden. Fürs Erste müssen Sie leider das Problem hacken.

+0

Vielen Dank, aber ich war nicht erfolgreich in Nachrüstung ... –

+0

@ gd047 Keine Sorge. Ich werde mir das ansehen und schauen, ob ich es später durcheinander bringen kann. Wenn ich das tue, werde ich meine Antwort aktualisieren. – MrGomez

+3

@ gd047 Eigentlich ist das viel einfacher. Umschließen Sie für Ihre _From: _ und _To: _ -Adressen die Sender-/Empfängerzeichenfolgen in der Funktion "unicode()". Verwenden Sie für den Nachrichtentext die Methode '.encode ('UTF-8')', wie in dem Beispiel gezeigt, das ich oben in meine Antwort eingefügt habe. Dies sollte alles sein, was Sie tun müssen, um Ihren Code zum Laufen zu bringen. Ich würde gerne mit Beispielen illustrieren, sollten Sie sie benötigen. – MrGomez

Verwandte Themen