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 コードがどのように構成されているかです。このブログ エントリでは、基になる SMTP 接続を管理するために Python を使用しているUnicode メールを適切に送信する方法について詳しく説明しています。R. David Murray によると、これはPythonのパッケージの後の反復で修正されることemailに注意してください。

前述のブログ投稿から直接借用して、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 に答える