1つのファイルを電子メールに添付する

私を前に許してください。私がこの質問を研究しようとしたとき、私は理解できないコードを見てしまいます。私はPythonで約3時間の経験があり、おそらく私が扱える以上の試みをしています。

問題は簡単です。 PythonをR(私の解析ソフトウェア)から呼び出して、電子メールを送ることができます。メッセージ、件名、場所、および私ができるフィールドからのメッセージを追加します。私は添付ファイルを送信できるようにしたいと思います。私が添付ファイルを1つだけ送ることができれば、人生は素晴らしいものになるでしょう。

私がこれまでに持っていたコードは

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

When I run this code, I get the message string payload expected: [type 'list'] (but with < not [)

今日私は自己学習の限界に達しています。私はこれが自分よりも経験豊かな人には明らかな修正だと思っています。

あなたは皆素晴らしい一日を過ごしてくれることを願っています。

5
同様のコードが私のために働くようです。完全なトレースバックを投稿できますか?また、これはrとは関係がないように思われるので、そのタグを削除します。
追加された 著者 Michael Hoffman,
私は多くのPythonを知らないが、 "["は "msg" [From "、" msg [To "と" msg [Subject " <>で。
追加された 著者 Carl Witthoft,
あなたは正しいようです。私が今朝来て走ったとき、うまくいった。以下のR関数に適応を投稿しました。それを見ていただきありがとうございます。
追加された 著者 Benjamin,

2 答え

SMTPを直接使用するのではなく、「メーラー」を使用してみてください。メーラーは、こちらにあります。

これはどのように動作するかを示す簡単なコードです。

messages=[]
message = mailer.Message()
message.attach('filename.txt')
message.From = 'Cool guy '
message.To = 'Random Dude '
message.Cc = 'Cards Fan '
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電子メールコードをこのパッケージを使用するように変換しました。

1
追加された
私は何かが働く前にこれを試しました。残念ながら、Pythonディストリビューションがなく、Rを通してコードを実行していると、パッケージを認識していないように見えて、どうやって作業するのか分かりませんでした。申し訳ありませんが、私はより生産的な学生ではありませんでした。
追加された 著者 Benjamin,

私は自分の質問に答えるのが悪いことを知っていますが、それは変化なしで奇跡的に働き始めました。私の最初の印象を作るにはどうしたらいいですか?

とにかく、私はそれをR関数にラップしました。これはgmailから送信されますが、まだ他のアカウントから送信しようとしていません。私はOutlookからの送信に最も関心があります。なぜなら、これをスクリプト内から分析レポートを送信するために使用するからです。雇用者のSMTPサーバーに入ったときに、「サーバーによってサポートされていないSMTP AUTH拡張」エラーが発生しました。私は私の技術サポートの人とこれを動作させなければならないと思う。

これはwinDialog()関数のおかげで、おそらくWindows上でのみ動作します。しかしそれは良いスタートです。

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")
}
0
追加された
あなた自身の質問にまったく答えられない悪い形ではなく、それは奨励されています!
追加された 著者 Chadwick,