2

以下函数(在此处找到)适用于包含 ASCII 字符的消息。你能帮我修改多语言消息吗,因为我根本不懂python?

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" = "recip@somewhere.net") 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") 
}

我这样称呼它:

send.email(list("somebody@somecompany.com"),
list("rJythonMail@mycompany.com"),
"Δοκιμή αποστολής email με attachment",
"Με χρήση της rJython",
attachment="monthly_report.xls",
username="gd047",password="xxxxxx")
4

1 回答 1

3

问题是您所附的 Python 代码的结构。此博客条目更详细地介绍了如何正确发送 Unicode 电子邮件,您正在使用 Python 来管理底层 SMTP 连接。请注意,根据 R. David Murray 的说法,这将email在 Python 包的后续迭代中得到修复。

以下是您可以在 rJython 中改装到您的调用中的显着 Python 代码,直接从上述博客文章中借用:

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

移植后,这应该可以使您的代码正常工作。希望尽快添加对RFC2047RFC3490的更好支持。现在,很遗憾你不得不解决这个问题。

于 2012-04-08T23:59:13.683 回答