Not sure why my email script is not sending an email - python-2.7

It was working but after updating my Raspberry Pi, my python script to send an email is not sending and I'm not sure why. It seems to just hang without throwing any error messages and I have to Ctrl+C to stop it every time, otherwise it'll just sit there indefinitely.
Here is my code...
import smtplib, datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
email_send = [sender email]
email_receive = [my email]
password = [password]
subject = 'Test Subject'
#sYMD = datetime.date.today().strftime('%y%m%d')
#lpath = 'C:/Path/to/files/'
files = ['log1.txt', 'log2.txt']
msg = MIMEMultipart()
msg['From'] = email_send
msg['To'] = email_receive
msg['Subject'] = subject
body = """\
Test Message."""
msg.attach(MIMEText(body, 'plain'))
#filename = x.strftime("%y%m%d")+'_log.txt'
for file in files:
part = MIMEBase('application', "octet-stream")
part.set_payload(open(file, "rb").read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % file)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.office365.com', 587)
server.starttls()
server.login(email_send, password)
server.sendmail(email_send, email_receive, text)
server.quit()
Here is what its doing when I run the script...
pi#raspberrypi: python send_email.py
^CTraceback (most recent call last):
File "send_email.py", line 36, in <module>
server = smtplib.SMTP('smtp.office365.com', 587)
File "/usr/lib/python2.7/smtplib.py", line 265, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python2.7/smtplib.py", line 317, in connect
(code, msg) = self.getreply()
File "/usr/lib/python2.7/smtplib.py", line 361, in getreply
line = self.file.readline(_MAXLINE + 1)
File "/usr/lib/python2.7/socket.py", line 480, in readline
data = self._sock.recv(self._rbufsize)
KeyboardInterrupt
Thanks for any help you can give.

Hmm sounds like the connection is timing out. Is it possible the client is unable to connect to the specified server and port? Try connecting directly with nc or telnet to confirm.
You can also pass a timeout value in seconds to the SMTP call:
server = smtplib.SMTP('smtp.office365.com', 587, timeout=5)

Related

ssl.SSLEOFError while sending emails through Django

Settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER = 'no_reply#domain.com'
SERVER_EMAIL = 'no_reply#domain.com'
DEFAULT_DO_NOT_REPLY = 'User <no_reply#domain.com>'
EMAIL_HOST_PASSWORD = 'xxxxxxxxx'
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
Class
class EmailThread(threading.Thread):
def __init__(self, subject, context, recipient, template):
self.subject = subject
self.recipient = recipient
self.message = get_template(template).render(context)
threading.Thread.__init__(self)
def run(self):
msg = EmailMessage(
subject=self.subject,
from_email=settings.DEFAULT_DO_NOT_REPLY,
to=self.recipient,
body=self.message
)
msg.content_subtype = "html"
try:
msg.send(fail_silently=False)
log.info("E-mail triggered. Subject: '%s', to: %s" % (self.subject, self.recipient))
except Exception as e:
log.exception(e)
Usage
def notify_admin_blocked_account(user):
"""
Sends sends an email when the account is blocked
:return:
"""
email = EmailThread(
subject='{}, your account has been blocked'.format(user),
context={
'user': user,
'login_attempts': settings.MAX_STAFF_PWD_ATTEMPTS,
},
recipient=[user.email,],
template='mail/notify_admin_blocked_account.html'
)
email.start()
Error
[ERROR][2017-08-01 10:40:26,835][mail] EOF occurred in violation of protocol (_ssl.c:645)
Traceback (most recent call last):
File "./bin/mail.py", line 27, in run
msg.send(fail_silently=False)
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/message.py", line 348, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 104, in send_messages
new_conn_created = self.open()
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 69, in open
self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile)
File "/usr/lib/python3.5/smtplib.py", line 766, in starttls
server_hostname=self._host)
File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
_context=self)
File "/usr/lib/python3.5/ssl.py", line 752, in __init__
self.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
self._sslobj.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:645)
I have some weird behavior when I try to send an e-mail (async) with Django. I really wanted to avoid third-party apps being installed to reduce code fragmentation - specially with some of them that seem to use crontab.
It is worth noticing that the error doesn't happen all the time. However, even though it doesn't happen, sometimes e-mails are not sent either. Only some of them manage to go through.
On my development environment it runs fine, and I can send the e-mails. However, on my production environment (EC2 instance) it simply doesn't work.
If I trigger an e-mail through the normal process, it is not sent. If I login to the server, open the manage.py shell, import a project and call the function that sends e-mail, sometimes I receive both triggered and manually-triggered e-mails or get an error (the one bellow).
My solution was to use Django-Mailer. It fragments the project, something I wanted to avoid, but its usage is pretty minimalist.

escape element in a list when it return Error

In order to get better skills I'am making this scripte so it takes a list of website and create a dict and take every website and crawle it to find the "conatct-us" page, But I see that my script stops when one of the websites is not working so what I am trying to do is to escape that website and continue to the others
here's my code :
import requests
from bs4 import BeautifulSoup
from urlparse import urlparse
from mechanize import Browser
import re
headers = [('User-Agent','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0')]
urls = 'http://www.officialusa.com/stateguides/chambers/georgia.html'
links_dict = []
response = requests.get(urls, headers)
bsObj = BeautifulSoup(response.text,'lxml')
for tag in bsObj.find_all('li'):
links_dict.append(tag.a.get('href'))
for ink in links_dict:
r = requests.get(ink)
#get domain name only
parsed_uri = urlparse(ink)
domain = parsed_uri.netloc
br = Browser()
br.set_handle_robots(False)
br.addheaders = headers
try:
br.open(str(ink))
for link in br.links():
siteMatch = re.compile(ink).search(link.url)
print link.url
except:
pass
Everything is okey with the other links
here's the Error:
Traceback (most recent call last):
File "/home/qunix/PycharmProjects/challange/crawel.py", line 20, in <module>
r = requests.get(ink)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 487, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='www.quitmangeorgia.org', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7facf68cca50>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution',))
thank You !!
Try wrapping the line
r = requests.get(ink)
in a try catch like so:
try:
r = requests.get(ink)
except ConnectionError:
continue
This will mean that if the call to requests.get throws a ConnectionError as it does in your example, it will pass over to the next website in the list.

Problems using Gmail with Python 2.7

New guy here....
I have searched all over this site and tried multiple variations on my code, but I am still receiving a login error when I attempt to send an email through Gmail using Python 2.7. I have enabled the "less secure apps" thing on my Gmail account and I am still receiving this error:
Traceback (most recent call last):
File "T:\OC\Projects\Aquadat\Scripting\RawArcPyScripts\sendEmailWithAttachment_Aquadat.py", line 28, in
svr.login(sender,pwd)
File "C:\Python27\ArcGIS10.3\lib\smtplib.py", line 615, in login
raise SMTPAuthenticationError(code, resp)
SMTPAuthenticationError: (534, '5.7.14 Please log in via your web browser and\n5.7.14 then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/answer/78754 z33sm11383168qta.48 - gsmtp')
Here is the problematic code. I grabbed a lot of it off of this site and tried to adapt it to my application. Any help would be most appreciated.
import smtplib
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.utils import COMMASPACE, formatdate
svr = smtplib.SMTP_SSL('smtp.gmail.com',465)
svr.ehlo()
svr.starttls()
svr.ehlo()
sender = 'my_name'
pwd = 'my_pwd'
svr.login(sender,pwd)
rcvr = sender #Change to arcpy.GetParameterAsText(x) when working
def send_mail(send_from,send_to,subject,text,files,
server):
assert isinstance(send_to, list)
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(text))
for f in 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)
smtp = smtplib.SMTP_SSL(server)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()

Pesky server error on Python web app

I've been having a problem with a website that I'm working on not attaching pictures to html emails. Thought I had it fixed but then every time someone tries to register on it I get a Server Error (500). I've only changed a couple of references so no idea what went wrong there, anyways error log is as follows:
2016-08-31 08:26:15,757 :Internal Server Error: /register/
Traceback (most recent call last):
File "/home/asranet/.virtualenvs/testenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/asranet/.virtualenvs/testenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "./register/views.py", line 14, in index
form.save(commit=True)
File "/home/asranet/.virtualenvs/testenv/local/lib/python2.7/site-packages/django/forms/models.py", line 451, in save
self.instance.save()
File "./register/models.py", line 35, in save
email_client(self, site_settings.site_name + "Conference Registration", "You are officially registered for AdWind 2017")
File "./adWind/email_functionality.py", line 31, in email_client
fp = open(os.path.join(os.path.dirname(__file__), f), 'rb')
IOError: [Errno 2] No such file or directory: u'./adWind/static/Images/asranetLogo.jpg'
I checked and the file is there. No idea how to proceed, could really use some help. Thank you in advance!
P.S. here's the code for email functionality:
from __future__ import unicode_literals
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
import os
from email.mime.image import MIMEImage
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.platypus import Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from django.http import HttpResponse
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
def email_client(self, subject, text):
# Send the client an email
html_content = render_to_string("../templates/baseTemplates/emailToUser.html", {'salutation': self.salutation,
'last_name':
self.last_name,
'text_body': text})
msg = EmailMultiAlternatives(subject, 'Dear ' + self.salutation + ' ' +
self.last_name + '/n' + text,
'adwind#asranet.co.uk', [self.email], )
msg.attach_alternative(html_content, "text/html")
msg.attach_file('/static/Images/asranetLogo.jpg')
msg.mixed_subtype = 'related'
f = '/static/Images/asranetLogo.jpg'
fp = open(os.path.join(os.path.dirname(__file__), f), 'rb')
msg_img = MIMEImage(fp.read())
fp.close()
msg_img.add_header('Content-ID', '<{}>'.format(f))
msg.attach(msg_img)
msg.send(fail_silently=True)
def email_admin(self, subject, text, sorted_self):
styleSheet = getSampleStyleSheet()
# Send the admin a PDF of client details
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="clientDetails.pdf"'
string_buffer = StringIO()
new_pdf = []
header = Paragraph("AdWind Attendee Details", styleSheet['Heading1'])
new_pdf.append(header)
for element in sorted_self:
new_pdf.append(Paragraph(element[0], styleSheet['Heading3']))
new_pdf.append(Paragraph(element[1], styleSheet['BodyText']))
new_pdf.append(Spacer(1, 2))
doc = SimpleDocTemplate(string_buffer)
doc.build(new_pdf)
pdf = string_buffer.getvalue()
string_buffer.close()
msg = EmailMultiAlternatives(subject, text, "adwind#asranet.co.uk", ["adwind#asranet.co.uk"])
msg.attach(self.first_name + self.last_name + "adWind.pdf", pdf, "application/pdf")
msg.send(fail_silently=True)
In Django the static directory is usually under a module_name directory. I suggest changing your paths into a relative one:
msg.attach_file('static/[module_name]/Images/asranetLogo.jpg')
and
f = 'static/[module_name]/Images/asranetLogo.jpg'

can't send mails using flask, any ideas?

L.T:
Ok now it works. I had to instantiate Mail() class after configuration(ie. app.config) :)
i have this error:
host = smtplib.SMTP(self.mail.server, self.mail.port)
File "C:\Python27\lib\smtplib.py", line 256, in __init__
(code, msg) = self.connect(host, port)
File "C:\Python27\lib\smtplib.py", line 316, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Python27\lib\smtplib.py", line 291, in _get_socket
return socket.create_connection((host, port), timeout)
File "C:\Python27\lib\socket.py", line 571, in create_connection
raise err
error: [Errno 10061] No connection could be made because the target machine actively refused it
I'm trying to build a site for myself, and i'm stuck at the part of sending e-mails because of the above error. Thing is i opened my port (that's because i'm behind a router). One thing to note is that using 'standalone' smtplib works but the one from flask doesn't. I'll post what works and does not. I don't know what is the problem. I modified address from socket.py to my 'localhost' and port 465 because i thought that was the problem. Hence i tried almost everything i could but in avail. Could someone help me a little bit here? Thanks.
This doesn't work(hello.py):
from flask import Flask
from flask_mail import Mail
from flask_mail import Message
from flask.ext.script import Manager
import os
mail = Mail()
app = Flask(__name__)
mail.init_app(app)
mail = Mail(app)
manager = Manager(app)
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
#app.route('/')
def index():
msg = Message('Hello',
sender = 'my_mail#gmail.com',
recipients = ['my_mail#gmail.com'])
msg.body = 'testing'
msg.html = '<b>testing</b>'
mail.send(msg)
app.debug = True
if __name__ == '__main__':
manager.run()
And tried a more minimalist way to see if this works, and it works, i can send mail to myself(mail.py):
import smtplib
from hello import app
gmail_user = app.config['MAIL_USERNAME']
gmail_pwd = app.config['MAIL_PASSWORD']
FROM = 'my_mail#gmail.com'
TO = ['my_mail#gmail.com']
message = 'test'
server_ssl = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server_ssl.ehlo() # optional, called by login()
server_ssl.login(gmail_user, gmail_pwd)
# ssl server doesn't support or need tls, so don't call server_ssl.starttls()
server_ssl.sendmail(FROM, TO, message)
#server_ssl.quit()
server_ssl.close()
print 'successfully sent the mail'
Bump...
It has nothing to do with objects. Functions are designed the way they return a value, and you can assign that value the same way you put the input into the list.
You just run the function, take the value it returned and put it into the variable.