我正在尝试编写一个R包,该包具有使用python的smtplib模块发送电子邮件的功能。当我直接或通过devtools::load_all()
来获取函数时,该函数可以工作,但是在打包程序包并调用该函数时,R崩溃。
我正在使用mailR软件包,该软件包使用java发送电子邮件,但是升级Java版本后出现问题。我决定写一个快速的软件包,用python版本替换它。一切正常,直到我用devtools::install_local()
安装它,然后尝试调用该函数。我对python没有太多的经验,我觉得它可能与我导入python模块的方式有关,我尝试将导入内容移入函数中,但这没有帮助。
这是我与网状采购的python函数:
import smtplib
import re
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import COMMASPACE, formatdate
def py_sendmail(send_from, send_to, subject,
text_body = None, html_body = None,
inline = False, authenticate = False, ssl = False,
smtp_server = None, port = 587, username = None,
password = None, send = True, attach_files = None,
debug = False):
img_content = []
msg = MIMEMultipart('related')
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
if inline == True:
img_re = re.compile("<img(?:.+?)src\s*=\s*(?P<quote>['\"])(?P<imgurl>.*?)(?P=quote)")
imgs = img_re.findall(html_body)
img_cnt = 1
for(q, imgurl) in imgs:
fp = open(imgurl, 'rb')
msg_img = MIMEImage(fp.read())
fp.close()
img_id = "image" + str(img_cnt)
msg_img.add_header("Content-ID", "<"+img_id+">")
img_content.append(msg_img)
html_body = re.sub(imgurl, "cid:"+img_id, html_body)
img_cnt = img_cnt + 1
if text_body is not None and html_body is not None:
msgAlt = MIMEMultipart('alternative')
msg.attach(msgAlt)
msgAlt.attach(MIMEText(text_body, 'plain'))
msgAlt.attach(MIMEText(html_body, 'html'))
elif text_body is not None:
msg.attach(MIMEText(text_body, 'plain'))
elif html_body is not None:
msg.attach(MIMEText(html_body, 'html'))
if attach_files is not None:
for f in attach_files or []:
with open(f, 'rb') as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
if len(img_content) > 0:
for img in img_content:
msg.attach(img)
if send == True:
if ssl == True:
server = smtplib.SMTP_SSL(smtp_server, port)
else:
server = smtplib.SMTP(smtp_server, port)
if authenticate == True:
server.login(username, password)
x = server.sendmail(send_from, send_to, msg.as_string())
server.quit()
return x == {}
else:
return msg.as_string()
它应该发送电子邮件,并且在发送到全局环境或加载devtools::load_all()
时会发送。但是,如果我使用devtools::install_local()
安装它并对其进行库化,它将使R崩溃。当我在RStudio中运行它时,它崩溃了而没有任何解释,当我从命令行运行它时,我得到了:
> library(pymailr)
> pymailr:::py_sendmail("<from_address>", "<to_address>", "Test",
+ text_body = "Testing", html_body = "<h1>Testing</h1>",
+ inline = FALSE, authenticate = TRUE, ssl = TRUE,
+ smtp_server = "<smtp_server>", port = 465, username = "<user_name>",
+ password = "<password>", send = TRUE)
*** caught segfault ***
address (nil), cause 'memory not mapped'
Traceback:
1: py_call_impl(callable, dots$args, dots$keywords)
2: pymailr:::py_sendmail("<from_address>", "<to_address>", "Test", text_body = "Testing", html_body = "<h1>Testing</h1>", inline = FALSE, authenticate = TRUE, ssl = TRUE, smtp_server = "<smtp_server>", port = 465, username = "<username>", password = "<password>", send = TRUE)