Sending a mass-email with Python using data from several .txt files - python

I am currently writing a small program to ease my workload sending a couple hundred of emails daily. I have edited code I found somewhere and came up with this so far:
import smtplib
from email.mime.text import MIMEText
from time import sleep
from random import choice
import re
import io
user_email = input('Enter your E-mail: ')
user_password = input('Enter your Password: ')
try:
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
# re-identify ourselves as an encrypted connection
s.ehlo()
# If using TLS, uncomment the line below.
#s.starttls()
s.login(user_email, user_password)
s.set_debuglevel(1)
except IOError:
print (IOError)
SUBJECT = open('1subject.txt', 'r')
variation0 = [SUBJECT.read(), SUBJECT.read(), SUBJECT.read()]
SUBJECT.close()
GREETING = open('2greeting.txt', 'r')
variation1 = [GREETING.read(), GREETING.read(), GREETING.read()]
GREETING.close()
BODY = open('3body.txt', 'r')
variation2 = [BODY.read(), BODY.read(), BODY.read()]
BODY.close()
OUTRO = open('4outro.txt', 'r')
variation3 = [OUTRO.read(), OUTRO.read(), OUTRO.read()]
OUTRO.close()
# Where the {}'s are, is where a variation(0-3) will be substituted in.
template = """Insert your {}
Multiline email body
HERE {} {}
-transposed messenger
"""
sender = 'sender#email.com'
recipients = []
names = []
mailTxt = open("listOfRecipients.txt", 'r')
for line in mailTxt:
line = line.replace('\n',"")
names.append(re.split(':', line)[0])
recipients.append(re.split(':',line)[1])
for k in range(len(recipients)):
msg = MIMEText(template.format(choice(variation1), names[k]+",", recipients[k], choice(variation2), choice(variation3)))
msg['Subject'] = choice(variation0)
msg['From'] = sender
msg['To'] = recipients[k]
print ("Sending...")
print (msg)
try:
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
s.sendmail(sender, recipients[k], msg.as_string())
except Exception as e:
str(e)
print ((e, "error: logging in and cont with nxt address..."))
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
s.ehlo()
s.login(user_email, user_password)
s.set_debuglevel(1)
continue
with io.open('log.txt', 'a', encoding='utf-8') as f:
try:
f.write(unicode(msg))
except:
f.write("Error handling ASCII encoded names: "+ Unicode
(recipients[k]))
print ("Messages have been sent.")
f.close()
s.quit()
This is the first time I'm adding code on here so I don't know if I've done that right. However whatever I do I keep receiving errors.
The files that are being opened are files containing email addresses and names (like mail#email.com:mailman Johnson and then a new line continuing like this)
the other files are containing text for the email that is sent.
my ridiculous question is: how do I get this to work? What am I doing wrong.
My current error is
ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:847)
Again, my apologies if this isn't a real question!

Related

Receiving file not found error when attempting to attach a csv to an email from tempfile

I am receiving a "file not found error" when attempting to attach a csv to an email from tempfile. My end goal is to convert json to csv, attach it to an email, and send via lambda. I can see the files are being created and converted on my local machine but when attempting to attach the csv it errors out at
att = MIMEApplication(open(file_name, 'rb').read())
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\CHRIST~1\AppData\Local\Temp\tmpfkrfwzqo\temp.json\sso.csv'
def sso():
tempdir = tempfile.mkdtemp()
path = os.path.join(tempdir, 'temp.json')
with open(path, 'w') as fp:
json.dump(testjson, fp)
# Changes the data to CSV
def json_to_csv(path, fileInput, fileOutput):
data = json.load(open(os.path.join(path, fileInput)))
with open(os.path.join(path, fileOutput), 'w') as fp:
output = csv.writer(fp)
output.writerow(data[0].keys())
for row in data:
output.writerow(row.values())
json_to_csv(tempdir, 'temp.json', 'sso.csv')
# Sends the email
SENDER = "name <no-reply#name.com>"
sender = "name <no-reply#cname.com>"
# recipients = [" Partners <partners#name.com>"]
recipients = ["Test Name <name#cname.com>"]
RECIPIENT = ", ".join(recipients)
# SMTP
USERNAME_SMTP = secret_ses['username']
PASSWORD_SMTP = secret_ses['password']
HOST = "email-smtp.us-east-1.amazonaws.com"
PORT = 465
# Boto3 SES
AWS_REGION = "us-east-1"
SUBJECT = "All SSO Apps"
BODY_TEXT = (f"Please see attached.")
BODY_HTML = f""" <html>Some words</html>"""
CHARSET = "UTF-8"
# SMTP
msg = MIMEMultipart('alternative')
msg['Subject'] = SUBJECT
msg['From'] = SENDER
msg['To'] = RECIPIENT
part1 = MIMEText(BODY_TEXT, 'plain')
part2 = MIMEText(BODY_HTML, 'html')
msg.attach(part1)
msg.attach(part2)
file_name = "".join([path, "\sso.csv"])
# Define the attachment part and encode it using MIMEApplication.
att = MIMEApplication(open(file_name, 'rb').read())
att.add_header('Content-Disposition', 'attachment', filename=file_name)
if os.path.exists(file_name):
print("File exists")
else:
print("File does not exists")
# Attach the multipart/alternative child container to the multipart/mixed
# parent container.
msg.attach(msg)
# Add the attachment to the parent container.
msg.attach(att)
try:
with SMTP_SSL(HOST, PORT) as server:
server.login(USERNAME_SMTP, PASSWORD_SMTP)
server.sendmail(SENDER, RECIPIENT, msg.as_string())
server.close()
except SMTPException as e:
print("Error: ", e)
json_to_csv(tempdir, 'temp.json', 'sso.csv')
sso()
So as I had mentioned, the error occurs with att = MIMEApplication(open(file_name, 'rb').read()). When I try to pass this along instead file_name = path, it returns "file exists" but I then receive a very long recursion error: "RecursionError: maximum recursion depth exceeded while calling a Python object" along several errors coming before it. I'd be so grateful for any help with this.

Python Sending E-Mail with Umlauts

I want to create a program in python that receives every new unread email from one of my email accounts to another email account.
So far I got everything set up. Unfortunately I have really big issues with umlauts (ä,ö,ü). For some reason I con not make it to work properly.
Here is my code:
# -*- coding: utf-8 -*-
import os, sys
import imaplib
import email
import smtplib
from email.mime.multipart import MIMEMultipart
servername = 'SERVERNAME'
username='USERNAME'
password='PASSWORD'
mail = imaplib.IMAP4_SSL(servername)
(retcode, capabilities) = mail.login(username,password)
mail.list()
mail.select('inbox')
server_smtp = smtplib.SMTP_SSL('SMTP')
n=0
(retcode, messages) = mail.search(None, '(UNSEEN)')
if retcode == 'OK':
for num in messages[0].split() :
n=n+1
typ, data = mail.fetch(num,'(RFC822)')
for response_part in data:
if isinstance(response_part, tuple):
original = email.message_from_string(response_part[1])
print original['From']
typ, data = mail.store(num,'+FLAGS','\\Seen')
body = ""
if original.is_multipart():
for part in original.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
if ctype == 'text/plain' and 'attachment' not in cdispo:
body = part.get_payload(decode=True) # decode
break
else:
body = original.get_payload(decode=True)
body = body.encode('UTF-8')
body = str(body)
print(body)
body = "Betreff: " + str(original['Subject']) + "\n\n\n" + body.encode('UTF-8')
SUBJECT = original['From']
server_smtp.login(username, password)
msg = 'Subject: {}\n\n{}'.format(SUBJECT, body.decode('UTF-8'))
server_smtp.sendmail(username, 'TARGET', msg)
For example: if I want to send this message: "ÄäÖöÜü&ß" I will receive this: "������������&��
���"
Do you know what I am doing wrong?
I would really appreciate your help!

Sending email:Attach file-Python [duplicate]

I want to write a program that sends email using Python's smtplib. I searched through the document and the RFCs, but couldn't find anything related to attachments. Thus, I'm sure there's some higher-level concept I'm missing out on. Can someone clue me in on how attachments work in SMTP?
Here is an example of a message with a PDF attachment, a text "body" and sending via Gmail.
# Import smtplib for the actual sending function
import smtplib
# For guessing MIME type
import mimetypes
# Import the email modules we'll need
import email
import email.mime.application
# Create a text/plain message
msg = email.mime.Multipart.MIMEMultipart()
msg['Subject'] = 'Greetings'
msg['From'] = 'xyz#gmail.com'
msg['To'] = 'abc#gmail.com'
# The main body is just another attachment
body = email.mime.Text.MIMEText("""Hello, how are you? I am fine.
This is a rather nice letter, don't you think?""")
msg.attach(body)
# PDF attachment
filename='simple-table.pdf'
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
msg.attach(att)
# send via Gmail server
# NOTE: my ISP, Centurylink, seems to be automatically rewriting
# port 25 packets to be port 587 and it is trashing port 587 packets.
# So, I use the default port 25, but I authenticate.
s = smtplib.SMTP('smtp.gmail.com')
s.starttls()
s.login('xyz#gmail.com','xyzpassword')
s.sendmail('xyz#gmail.com',['xyz#gmail.com'], msg.as_string())
s.quit()
Here's an example I snipped out of a work application we did. It creates an HTML email with an Excel attachment.
import smtplib,email,email.encoders,email.mime.text,email.mime.base
smtpserver = 'localhost'
to = ['email#somewhere.com']
fromAddr = 'automated#hi.com'
subject = "my subject"
# create html email
html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>'
html += "</body></html>"
emailMsg = email.MIMEMultipart.MIMEMultipart('alternative')
emailMsg['Subject'] = subject
emailMsg['From'] = fromAddr
emailMsg['To'] = ', '.join(to)
emailMsg['Cc'] = ", ".join(cc)
emailMsg.attach(email.mime.text.MIMEText(html,'html'))
# now attach the file
fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel')
fileMsg.set_payload(file('exelFile.xls').read())
email.encoders.encode_base64(fileMsg)
fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls')
emailMsg.attach(fileMsg)
# send email
server = smtplib.SMTP(smtpserver)
server.sendmail(fromAddr,to,emailMsg.as_string())
server.quit()
What you want to check out is the email module. It lets you build MIME-compliant messages that you then send with smtplib.
Well, attachments are not treated in any special ways, they are "just" leaves of the Message-object tree. You can find the answers to any questions regarding MIME-compliant mesasges in this section of the documentation on the email python package.
In general, any kind of attachment (read: raw binary data) can be represented by using base64
(or similar) Content-Transfer-Encoding.
Here's how to send e-mails with zip file attachments and utf-8 encoded subject+body.
It was not straightforward to figure this one out, due to lack of documentation and samples for this particular case.
Non-ascii characters in replyto needs to be encoded with, for instance, ISO-8859-1. There probably exists a function that can do this.
Tip:Send yourself an e-mail, save it and examine the content to figure out how to do the same thing in Python.
Here's the code, for Python 3:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:set ts=4 sw=4 et:
from os.path import basename
from smtplib import SMTP
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
from base64 import encodebytes
def send_email(recipients=["somebody#somewhere.xyz"],
subject="Test subject æøå",
body="Test body æøå",
zipfiles=[],
server="smtp.somewhere.xyz",
username="bob",
password="password123",
sender="Bob <bob#somewhere.xyz>",
replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <bob#somewhere.xyz>"): #: bool
"""Sends an e-mail"""
to = ",".join(recipients)
charset = "utf-8"
# Testing if body can be encoded with the charset
try:
body.encode(charset)
except UnicodeEncodeError:
print("Could not encode " + body + " as " + charset + ".")
return False
# Split real name (which is optional) and email address parts
sender_name, sender_addr = parseaddr(sender)
replyto_name, replyto_addr = parseaddr(replyto)
sender_name = str(Header(sender_name, charset))
replyto_name = str(Header(replyto_name, charset))
# Create the message ('plain' stands for Content-Type: text/plain)
try:
msgtext = MIMEText(body.encode(charset), 'plain', charset)
except TypeError:
print("MIMEText fail")
return False
msg = MIMEMultipart()
msg['From'] = formataddr((sender_name, sender_addr))
msg['To'] = to #formataddr((recipient_name, recipient_addr))
msg['Reply-to'] = formataddr((replyto_name, replyto_addr))
msg['Subject'] = Header(subject, charset)
msg.attach(msgtext)
for zipfile in zipfiles:
part = MIMEBase('application', "zip")
b = open(zipfile, "rb").read()
# Convert from bytes to a base64-encoded ascii string
bs = encodebytes(b).decode()
# Add the ascii-string to the payload
part.set_payload(bs)
# Tell the e-mail client that we're using base 64
part.add_header('Content-Transfer-Encoding', 'base64')
part.add_header('Content-Disposition', 'attachment; filename="%s"' %
os.path.basename(zipfile))
msg.attach(part)
s = SMTP()
try:
s.connect(server)
except:
print("Could not connect to smtp server: " + server)
return False
if username:
s.login(username, password)
print("Sending the e-mail")
s.sendmail(sender, recipients, msg.as_string())
s.quit()
return True
def main():
send_email()
if __name__ == "__main__":
main()
# -*- coding: utf-8 -*-
"""
Mail sender
"""
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import pystache
import codecs
import time
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
HOST = 'smtp.exmail.qq.com'
PORT = 587
USER = 'your#mail.com'
PASS = 'yourpass'
FROM = 'your#mail.com'
SUBJECT = 'subject'
HTML_NAME = 'tpl.html'
CSV_NAME = 'list.txt'
FAILED_LIST = []
def send(mail_receiver, mail_to):
# text = mail_text
html = render(mail_receiver)
# msg = MIMEMultipart('alternative')
msg = MIMEMultipart('mixed')
msg['From'] = FROM
msg['To'] = mail_to.encode()
msg['Subject'] = SUBJECT.encode()
# msg.attach(MIMEText(text, 'plain', 'utf-8'))
msg.attach(MIMEText(html, 'html', 'utf-8'))
try:
_sender = smtplib.SMTP(
HOST,
PORT
)
_sender.starttls()
_sender.login(USER, PASS)
_sender.sendmail(FROM, mail_to, msg.as_string())
_sender.quit()
print "Success"
except smtplib.SMTPException, e:
print e
FAILED_LIST.append(mail_receiver + ',' + mail_to)
def render(name):
_tpl = codecs.open(
'./html/' + HTML_NAME,
'r',
'utf-8'
)
_html_string = _tpl.read()
return pystache.render(_html_string, {
'receiver': name
})
def main():
ls = open('./csv/' + CSV_NAME, 'r')
mail_list = ls.read().split('\r')
for _receiver in mail_list:
_tmp = _receiver.split(',')
print 'Mail: ' + _tmp[0] + ',' + _tmp[1]
time.sleep(20)
send(_tmp[0], _tmp[1])
print FAILED_LIST
main()

no newline vs. double newline when using zero vs. one newline in a string sent to email

I'm sending a string to an email, and I want one sentence per line like this:
"Loaded LLARY_AR with 0 features
Loaded LLARY_LN with 44 features
Loaded LLARY_PT with 23 features"
But when I add one newline to the string concatenation I get two newlines instead of one, like this:
"Loaded LLARY_AR with 0 features
Loaded LLARY_LN with 44 features
Loaded LLARY_PT with 23 features"
And if I do not include a newline I get this:
"Loaded LLARY_AR with 0 features Loaded LLARY_LN with 44 features Loaded LLARY_PT with 23 features"
Here's the code:
msgemail = ""
for fcl in trnlist:
try:
tofc = param["tsde"]+"\\"+param["trema"]+fcl
fromfc = param["msde"]+"\\"+param["mchema"]+fcl
arcpy.DeleteFeatures_management(tofc)
arcpy.Append_management(fromfc, tofc)
msgemail +="\nLoaded "+fcl+" with "+str(arcpy.GetCount_management(fromfc))+" features"
del fcl, tofc, fromfc
except:
msgemail +="\nUnsuccessful!! "+fcl
emailto = ["email#to","email#to"]
server = smtplib.SMTP('server.here')
header = "Results:\n"
subject = "Data"
mailmessage = header+msgemail+"\n\nCheck log for details"
message = 'Subject: %s\n\n%s' %(subject, mailmessage)
for e in emailto:
try:
server.sendmail("email#from",e, message)
except:
arcpy.AddMessage(e+" was not sent an email.")
server.quit()
I don't understand why the newline acts in this manner..and a newbie..obviously missing something here.
I found that this works to produce an email that is nicely formated (but does not include the necessary information from the ..GetCount..process):
msgemail +="\nLoaded"+fcl
While these do not result in a nicely formated email:
msgemail +="\nLoaded "+fcl+" with "+str(arcpy.GetCount_management(fromfc))+" features"
msgemail +="\nLoaded "+fromcnt
msgemail +="\nLoaded "+fromcnt+" testing for string at end"
There does not appear to be an issue with the code, there should only be one newline between each of your 'Loaded...' lines.
It is possible that the email client you are using to view the email is interpreting newlines as new paragraphs and inserting that spacing automatically. Try replacing the \n with <br> and see if that results in the single spacing you expect.
I ran into the same problem using the smtplib by itself. I found that a better way to do it is this:
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import os
import smtplib
def send_mail(send_from, send_to, subject, text, files=[], server='mail.server.com'):
assert type(send_to)==list
assert type(files)==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:
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 = smtplib.SMTP(server)
mydict = smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()
return mydict
Note the return of the dictionary! The smtp.sendmail will return it with a list of failure tuples if some emails fail to send. If all emails fail to send, an exception is thrown, and if they all succeed, then the dictionary is empty.
You will save yourself grief if you check it.
It may be that the '\n' should come at the end of a line.
It sounds dumb and may not work, but it might be worth a shot.
msgemail = "\n"
for fcl in trnlist:
try:
tofc = param["tsde"]+"\\"+param["trema"]+fcl
fromfc = param["msde"]+"\\"+param["mchema"]+fcl
arcpy.DeleteFeatures_management(tofc)
arcpy.Append_management(fromfc, tofc)
msgemail +="Loaded "+fcl+" with "+str(arcpy.GetCount_management(fromfc))+" features\n"
del fcl, tofc, fromfc
except:
msgemail +="\nUnsuccessful!! "+fcl
emailto = ["email#to","email#to"]
server = smtplib.SMTP('server.here')
header = "Results:\n"
subject = "Data"
mailmessage = header+msgemail+"\n\nCheck log for details"
message = 'Subject: %s\n\n%s' %(subject, mailmessage)
for e in emailto:
try:
server.sendmail("email#from",e, message)
except:
arcpy.AddMessage(e+" was not sent an email.")
server.quit()

How do I send attachments using SMTP?

I want to write a program that sends email using Python's smtplib. I searched through the document and the RFCs, but couldn't find anything related to attachments. Thus, I'm sure there's some higher-level concept I'm missing out on. Can someone clue me in on how attachments work in SMTP?
Here is an example of a message with a PDF attachment, a text "body" and sending via Gmail.
# Import smtplib for the actual sending function
import smtplib
# For guessing MIME type
import mimetypes
# Import the email modules we'll need
import email
import email.mime.application
# Create a text/plain message
msg = email.mime.Multipart.MIMEMultipart()
msg['Subject'] = 'Greetings'
msg['From'] = 'xyz#gmail.com'
msg['To'] = 'abc#gmail.com'
# The main body is just another attachment
body = email.mime.Text.MIMEText("""Hello, how are you? I am fine.
This is a rather nice letter, don't you think?""")
msg.attach(body)
# PDF attachment
filename='simple-table.pdf'
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
msg.attach(att)
# send via Gmail server
# NOTE: my ISP, Centurylink, seems to be automatically rewriting
# port 25 packets to be port 587 and it is trashing port 587 packets.
# So, I use the default port 25, but I authenticate.
s = smtplib.SMTP('smtp.gmail.com')
s.starttls()
s.login('xyz#gmail.com','xyzpassword')
s.sendmail('xyz#gmail.com',['xyz#gmail.com'], msg.as_string())
s.quit()
Here's an example I snipped out of a work application we did. It creates an HTML email with an Excel attachment.
import smtplib,email,email.encoders,email.mime.text,email.mime.base
smtpserver = 'localhost'
to = ['email#somewhere.com']
fromAddr = 'automated#hi.com'
subject = "my subject"
# create html email
html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>'
html += "</body></html>"
emailMsg = email.MIMEMultipart.MIMEMultipart('alternative')
emailMsg['Subject'] = subject
emailMsg['From'] = fromAddr
emailMsg['To'] = ', '.join(to)
emailMsg['Cc'] = ", ".join(cc)
emailMsg.attach(email.mime.text.MIMEText(html,'html'))
# now attach the file
fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel')
fileMsg.set_payload(file('exelFile.xls').read())
email.encoders.encode_base64(fileMsg)
fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls')
emailMsg.attach(fileMsg)
# send email
server = smtplib.SMTP(smtpserver)
server.sendmail(fromAddr,to,emailMsg.as_string())
server.quit()
What you want to check out is the email module. It lets you build MIME-compliant messages that you then send with smtplib.
Well, attachments are not treated in any special ways, they are "just" leaves of the Message-object tree. You can find the answers to any questions regarding MIME-compliant mesasges in this section of the documentation on the email python package.
In general, any kind of attachment (read: raw binary data) can be represented by using base64
(or similar) Content-Transfer-Encoding.
Here's how to send e-mails with zip file attachments and utf-8 encoded subject+body.
It was not straightforward to figure this one out, due to lack of documentation and samples for this particular case.
Non-ascii characters in replyto needs to be encoded with, for instance, ISO-8859-1. There probably exists a function that can do this.
Tip:Send yourself an e-mail, save it and examine the content to figure out how to do the same thing in Python.
Here's the code, for Python 3:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:set ts=4 sw=4 et:
from os.path import basename
from smtplib import SMTP
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
from base64 import encodebytes
def send_email(recipients=["somebody#somewhere.xyz"],
subject="Test subject æøå",
body="Test body æøå",
zipfiles=[],
server="smtp.somewhere.xyz",
username="bob",
password="password123",
sender="Bob <bob#somewhere.xyz>",
replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <bob#somewhere.xyz>"): #: bool
"""Sends an e-mail"""
to = ",".join(recipients)
charset = "utf-8"
# Testing if body can be encoded with the charset
try:
body.encode(charset)
except UnicodeEncodeError:
print("Could not encode " + body + " as " + charset + ".")
return False
# Split real name (which is optional) and email address parts
sender_name, sender_addr = parseaddr(sender)
replyto_name, replyto_addr = parseaddr(replyto)
sender_name = str(Header(sender_name, charset))
replyto_name = str(Header(replyto_name, charset))
# Create the message ('plain' stands for Content-Type: text/plain)
try:
msgtext = MIMEText(body.encode(charset), 'plain', charset)
except TypeError:
print("MIMEText fail")
return False
msg = MIMEMultipart()
msg['From'] = formataddr((sender_name, sender_addr))
msg['To'] = to #formataddr((recipient_name, recipient_addr))
msg['Reply-to'] = formataddr((replyto_name, replyto_addr))
msg['Subject'] = Header(subject, charset)
msg.attach(msgtext)
for zipfile in zipfiles:
part = MIMEBase('application', "zip")
b = open(zipfile, "rb").read()
# Convert from bytes to a base64-encoded ascii string
bs = encodebytes(b).decode()
# Add the ascii-string to the payload
part.set_payload(bs)
# Tell the e-mail client that we're using base 64
part.add_header('Content-Transfer-Encoding', 'base64')
part.add_header('Content-Disposition', 'attachment; filename="%s"' %
os.path.basename(zipfile))
msg.attach(part)
s = SMTP()
try:
s.connect(server)
except:
print("Could not connect to smtp server: " + server)
return False
if username:
s.login(username, password)
print("Sending the e-mail")
s.sendmail(sender, recipients, msg.as_string())
s.quit()
return True
def main():
send_email()
if __name__ == "__main__":
main()
# -*- coding: utf-8 -*-
"""
Mail sender
"""
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import pystache
import codecs
import time
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
HOST = 'smtp.exmail.qq.com'
PORT = 587
USER = 'your#mail.com'
PASS = 'yourpass'
FROM = 'your#mail.com'
SUBJECT = 'subject'
HTML_NAME = 'tpl.html'
CSV_NAME = 'list.txt'
FAILED_LIST = []
def send(mail_receiver, mail_to):
# text = mail_text
html = render(mail_receiver)
# msg = MIMEMultipart('alternative')
msg = MIMEMultipart('mixed')
msg['From'] = FROM
msg['To'] = mail_to.encode()
msg['Subject'] = SUBJECT.encode()
# msg.attach(MIMEText(text, 'plain', 'utf-8'))
msg.attach(MIMEText(html, 'html', 'utf-8'))
try:
_sender = smtplib.SMTP(
HOST,
PORT
)
_sender.starttls()
_sender.login(USER, PASS)
_sender.sendmail(FROM, mail_to, msg.as_string())
_sender.quit()
print "Success"
except smtplib.SMTPException, e:
print e
FAILED_LIST.append(mail_receiver + ',' + mail_to)
def render(name):
_tpl = codecs.open(
'./html/' + HTML_NAME,
'r',
'utf-8'
)
_html_string = _tpl.read()
return pystache.render(_html_string, {
'receiver': name
})
def main():
ls = open('./csv/' + CSV_NAME, 'r')
mail_list = ls.read().split('\r')
for _receiver in mail_list:
_tmp = _receiver.split(',')
print 'Mail: ' + _tmp[0] + ',' + _tmp[1]
time.sleep(20)
send(_tmp[0], _tmp[1])
print FAILED_LIST
main()

Categories