I have implemented function to send email via smtplib in sendmail.py.
In main.py I have imported sendmail and use it. Then I run main.py, it crashes on 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
First of all, I check my sendmail module in interactive python3 and ipython (on same system where code deployed). In interactive python/ipython it works like a charm, email successfully sent, no tracebacks with errors:
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
>>>
Also I have checked how system resolve smtp.gmail.com and use telnet smtp.gmail.com 587
, so it is not connection / network issue.
Note: I have installed latest python via pyenv, so /usr/bin/env python3 runs it. Python/iPython runs same version of python.
Maybe someone countered same problem? Any advice what debug next?
#!/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()
I have found solution of problem after some research: problem occured, because I've installed latest python release via pyenv beside system python version. It's looks like python installed with system have access to low level system interfaces such as sockets, then fresh installed python does not have. So the problem solved, then I run my code with system python (version 3.4.2).