我已经实现了通过smtplib在 sendmail.py 中发送电子邮件的功能。
在 main.py 中,我导入了sendmail并使用它。然后我运行main.py,它在s = smtplib.SMTP(SMTP_SERVER)
上崩溃了:
Traceback (most recent call last):
File "./main.py", line 30, in <module>
main()
File "./main.py", line 26, in main
sendmail.send_email("alarm", images)
File "/home/pi/src/alarm-system/new_meta/sendmail.py", line 76, in send_email
s = smtplib.SMTP(SMTP_SERVER)
File "/home/pi/.pyenv/versions/3.6.1/lib/python3.6/smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "/home/pi/.pyenv/versions/3.6.1/lib/python3.6/smtplib.py", line 335, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/home/pi/.pyenv/versions/3.6.1/lib/python3.6/smtplib.py", line 306, in _get_socket
self.source_address)
File "/home/pi/.pyenv/versions/3.6.1/lib/python3.6/socket.py", line 704, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/home/pi/.pyenv/versions/3.6.1/lib/python3.6/socket.py", line 743, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
首先,我在交互式python3和ipython中检查我的sendmail模块(在部署代码的同一系统上)。 在交互式python / ipython中,它的工作方式就像魅力,电子邮件成功发送,没有错误的追溯:
pi at raspberrypi in ~/src/alarm-system/new_meta (master)
$ /usr/bin/env python3
Python 3.6.1 (default, Jun 22 2017, 22:14:56)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sendmail
>>> sendmail.send_email("alarm",[])
True
>>>
此外,我已检查系统如何解析smtp.gmail.com并使用telnet smtp.gmail.com 587
,因此它不是连接/网络问题。
注意:我已经通过pyenv安装了最新的python,所以/ usr / bin / env python3运行它。 Python / iPython运行相同版本的python。
也许有人反击同样的问题?什么建议下一步调试?
#!/usr/bin/env python3
import smtplib
import mimetypes
from email import encoders
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
import logging
logger = logging.getLogger(__name__)
SMTP_SERVER = "smtp.gmail.com:587"
# Function to send email with attachments or not.
# NOTE: attachments (files variable) must be a list of paths to files
def send_email(subj=None,files=None):
msg = MIMEMultipart()
if subj == "log":
subject = LOG_SUBJ
else:
subject = ALARM_SUBJ
msg["Subject"] = subject
msg["From"] = FROM_EMAIL
msg["To"] = TO_EMAIL
if files is not None and type(files) == list:
for filename in files:
content_type, encoding = mimetypes.guess_type(filename)
if content_type is None or encoding is not None:
content_type = "application/octet-stream"
maintype, subtype = content_type.split("/", 1)
if maintype == "text":
with open(filename) as fp:
file_attach = MIMEText(fp.read(), _subtype=subtype)
attach_name = filename.split("/")[-1]
file_attach.add_header('Content-Disposition', 'attachment',
filename=attach_name)
msg.attach(file_attach)
logger.info("Text file detected and attached. File: %s",
filename)
elif maintype == "image":
with open(filename, "rb") as fp:
file_attach = MIMEImage(fp.read(), _subtype=subtype)
attach_name = filename.split("/")[-1]
file_attach.add_header('Content-Disposition', 'attachment',
filename=attach_name)
msg.attach(file_attach)
logger.info("Image file detected and attached. File: %s",
filename)
else:
with open(filename,"rb") as fp:
file_attach = MIMEBase(maintype, subtype)
file_attach.set_payload(fp.read())
encoders.encode_base64(file_attach)
msg.attach(file_attach)
logger.info("Base64 file detected and attached. File: %s",
filename)
elif files is None:
msg += MIMEText("Alarm raised, no attachments files")
composed = msg.as_string()
s = smtplib.SMTP(SMTP_SERVER)
s.starttls()
try:
s.login(USERNAME, PASSWORD)
s.sendmail(FROM_EMAIL, TO_EMAIL, composed)
logger.info("Email sended successfully.")
logger.info("Email attachments: %s", files)
s.close()
return True
except Exception as err:
logger.error("Email not send! Error message: %s", err)
s.close()
return False
#!/usr/bin/env python3
import logging
from time import sleep
from gpiozero import MotionSensor
from datetime import datetime
import camera
import sendmail
logging.basicConfig(filename="/var/log/alarm/alarm.txt", level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(funcName)s - %(message)s")
logger = logging.getLogger(__name__)
def main():
pir = MotionSensor(7)
#pir.when_motion() = alarmLogging()
while True:
if pir.motion_detected:
logger.warning("MOTION DETECTED")
images = camera.capture_image(2)
logging.info("Send images to email: %s", images)
sendmail.send_email("alarm", images)
sleep(10)
if __name__ == '__main__':
main()
答案 0 :(得分:0)
经过一番研究后我找到了问题的解决方案:出现了问题,因为我已经通过pyenv在系统python版本旁边安装了最新的python版本。 它看起来像安装系统的python可以访问低级系统接口,如套接字,然后新安装的python没有。 所以问题解决了,然后我用system python(版本3.4.2)运行我的代码。