I am trying to obtain a result set from SQL query and add it to my email template which is an HTML file.
Two Functions:
One for mail summary and the other one to change the email body.
I am using smtplib and email packages from python to send out a mail.
#send a email
from fileOps import fileOps
from dbOps import dbOps
import smtplib
from smtplib import SMTP, SMTPException
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
mailFrom = ''
password = ''
mailTo = ''
mailServer = 'smtp.gmail.com'
port = 587
s = smtplib.SMTP(mailServer,port)
#function for email summary
def emailSummary():
try:
#security
s.starttls()
s.login(mailFrom,password)
#for fetching all the records
dbObj = dbOps()
db = dbObj.connectDB()
sql = "SELECT DISTINCT CASE_MASTER.AGREEMENTID, CASE_MASTER.NO_OF_FILES FROM " \
"CASE_MASTER LEFT JOIN CASE_FILE_STATUS ON CASE_FILE_STATUS.MOVED_TO_AWS_FLAG = CASE_MASTER.MOVED_TO_AWS_FLAG " \
"AND CASE_FILE_STATUS.MOVED_TO_AWS_Date AND CASE_MASTER.MOVED_TO_AWS_FLAG IS NOT NULL " \
"WHERE CASE_FILE_STATUS.MOVED_TO_AWS_FLAG = 1 AND CASE_FILE_STATUS.MOVED_TO_AWS_Date IS NOT NULL"
resultSet = dbObj.readData(db, sql)
getEmailBody(resultSet)
emailBody = getEmailBody(resultSet)
s.sendmail(mailFrom, mailTo,emailBody)
s.quit()
# print("Email Successfully sent !!! ")
except smtplib.SMTPException as e :
print(e)
#function to get emailBody
def getEmailBody(resultSet):
try:
htmlTemplate = open('summaryTemplate.html', 'r')
alert_msg = MIMEText(htmlTemplate.read(), "html", "utf-8")
html = htmlTemplate.read()
part1 = MIMEText(html, 'html')
part2 = """<table>
% for r in resultSet:
<tr>
% for cell in r:
<td>${cell}</td>
% endfor</tr>
% endfor</table>""".format(**locals())
msg = MIMEMultipart('alternative')
msg['Subject'] = "HERO_FC_DM_DB"
msg['From'] = mailFrom
msg['To'] = mailTo
msg.attach(part1)
except Exception as e:
print(e)
emailSummary()
I am getting the row but not getting the content from that row
['81173'] 'cell'
File "C:\Users\sailee.pawar\AppData\Local\Programs\Python\Python37-32\lib\smtplib.py", line 858, in sendmail
esmtp_opts.append("size=%d" % len(msg))
'cell'
TypeError: object of type 'NoneType' has no len()
I am getting the above error
Traceback (most recent call last):
line 68, in emailSummary()
line 37, in emailSummary
s.sendmail(mailFrom, mailTo,emailBody)
line 858, in sendmail esmtp_opts.append("size=%d" % len(msg))
'cell'
TypeError: object of type 'NoneType' has no len()
expected o/p :
['81173']
'file1.jpg'
'file2.txt'
Related
I have the following code where the Cc email list is not working meaning emails are not received to the folks/groups in Cc list,email to To list is working,I just can't figure out what is wrong?any guidance on how to debug and fix it?
import time,smtplib
import pprint,logging,os,time,json
from subprocess import Popen, PIPE, call
from pprint import pprint
from email.mime.text import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
email = 'username2#company.com'
gerriturl = ""
def sendEmail2(type,data):
global originalchange
global gerriturl,email,username1
body = '''%s''' % (data)
#msg = MIMEMultipart(body)
msg = MIMEMultipart()
sender = 'techci#company.com'
receivers = []
cc = ['username1#company.com']
REPLY_TO_ADDRESS = 'embedded-tech-integrators#group.company.com'
if type =='failure':
print("Inside failure email %s"%email)
b = '\U0001F6A8'
print("b.decode('unicode-escape')")
receivers.append('username2#company.com')
#receivers.append(email)
print('%s'%receivers)
msg['Subject'] = '%s AUTO FAILED FOR GERRIT %s :PLEASE TAKE IMMEDIATE ACTION!!!'%(b.decode('unicode-escape'),gerriturl)
msg['From'] = sender
msg['To'] = ', '.join(receivers)
msg['Cc'] = ', '.join(cc)
msg["Content-Type"] = "text/html"
try:
mail = smtplib.SMTP('relay.company.com', 25)
msg.attach(MIMEText(body, 'html'))
msg.add_header('reply-to', REPLY_TO_ADDRESS)
print('Email sent successfully %s %s'%(receivers,cc))
except Exception as e:
logger.error('Problem sending email')
logger.error('%s' % e)
def main():
data = "THIS IS A TEST EMAIL"
sendEmail2('failure',data)
if __name__ == "__main__":
main()
The important thing is to pass the complete list of recipient email addresses to the sendmail() method - you need to concatenate the email addresses for the To, CC and BCC fields into a single list, not a string.
import smtplib
def send_email(subject, body_text, emails_to, emails_cc=[], emails_bcc=[]):
# Configuration
host = "localhost"
port = 1025
from_addr = "nobody#somewhere.com"
# Build the email body
body = "\r\n".join([
"From: %s" % from_addr,
"To: %s" % ', '.join(emails_to),
"CC: %s" % ', '.join(emails_cc),
"Subject: %s" % subject ,
"",
body_text
])
# Prepare the complete list of recipient emails for the message envelope
emails = emails_to + emails_cc + emails_bcc
# Connect to the server
server = smtplib.SMTP(host, port)
# Send the email
server.sendmail(from_addr, emails, body)
# Close the server connection
server.quit()
I am trying to insert a select statement into an email. The table
has 10 rows and 3 columns but I'm not able to do it. Code and errors below.
#!/usr/bin/env python
import csv
import MySQLdb
import pysftp
import smtplib
import sys
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
conn = MySQLdb.connect(XXXX)
#Email Part1 Msg
part1 = """
To: To Person <>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP HTML e-mail test
"""
sender = ''
receivers =
x = conn.cursor()
query1= ("""select * from table""")
smtpObj=smtplib.SMTP('smtp', 25)
smtpObj.sendmail(sender, receivers, x.execute(query1))
This is the error messsage:
Traceback (most recent call last):
File "test3.py", line 33, in <module>
smtpObj.sendmail(sender, receivers, x.execute(query1))
File "/usr/lib/python2.7/smtplib.py", line 729, in sendmail
esmtp_opts.append("size=%d" % len(msg))
TypeError: object of type 'long' has no len(
You have to pass in a string as the 3rd argument to smtpObj.sendmail(). After you do x.execute(query1), you have to fetch the results and turn them into a string.
x.execute(query1)
msg = ""
for row in x.fetchall():
msg += str(row) # or however you turn a row into a string
smtpObj.sendmail(sender, receivers, msg)
So I'll try to explain this the best I can.
The task I have at hand is to gather data from a database and to put that information into a custom coded/formatted HTML/CSS email.
The error I get when running this code is: TypeError: Can't convert 'list' object to 'str' implicitly.
The data I am getting from the database bring back a result of 8 strings within a list in each section so I know why that error is coming back. I'm just not too sure how to get around it to be able to embed all the data within an email automatically and send it with proper formatting for email like this.
import smtplib
import sys
import sqlite3
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
DATABASE = 'Blocs.db'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
print("Getting blocs from server...")
conn = sqlite3.connect(DATABASE)
cur = conn.cursor()
cur.execute("SELECT weburl FROM Blocs")
weburl_data = cur.fetchall()
cur.execute("SELECT imgurl FROM Blocs")
imgurl_data = cur.fetchall()
cur.execute("SELECT title FROM Blocs")
title_data = cur.fetchall()
cur.execute("SELECT notes FROM Blocs")
notes_data = cur.fetchall()
conn.commit()
conn.close()
from_email = "test#email.com"
from_pwd = "Password"
to_email = "sendHere#email.com"
msg = MIMEMultipart('html')
msg['Subject'] = "Test SMTPlib Message"
msg['From'] = "test#email.com"
msg['To'] = "sendHere#email.com"
firstHTML = '<html> <head></head> <body><table> <tr>'
bloc_one = weburl_data
secondHTML = '</tr></table></body></html>'
new_html = firstHTML + bloc_one + secondHTML
msg.attach(MIMEText(new_html, 'html'))
print(msg)
mail = smtplib.SMTP('outlook.office365.com', 587)
mail.ehlo()
mail.starttls()
mail.login("test#email.com", "Password")
mail.sendmail("test#email.com", "sendHere#email.com", msg.as_string())
print("email sent")
mail.quit()
I am not really an expert in the mail sending department but if you only problem is converting list to str why not try and do it with join?
new_string = ''.join(name_of_the_list)
I hope it helps :)
I have a piece of code to get emails from messages from my inbox (gmail). Getting emails work correct when I print email_from but I would like to do some operation on data split name and email etc. but then code broke after print first loop step and I got the error:
Traceback (most recent call last):
File "C:\Users\loc\Desktop\extract_gmail.py", line 24, in <module>
email_message_raw = email.message_from_bytes(data[0][1])
AttributeError: 'str' object has no attribute 'message_from_bytes'
Can you give me some advice how to solve this problem?
Code:
import imaplib
import email
from email.header import Header, decode_header, make_header
# Connection settings
HOST = 'imap.gmail.com'
USERNAME = '***'
PASSWORD = '***'
m = imaplib.IMAP4_SSL(HOST, 993)
m.login(USERNAME, PASSWORD)
m.select('INBOX')
result, data = m.uid('search', None, "ALL")
if result == 'OK':
for num in data[0].split()[:5]:
result, data = m.uid('fetch', num, '(RFC822)')
if result == 'OK':
# Get raw message
email_message_raw = email.message_from_bytes(data[0][1])
# Decode headers
email_from = str(make_header(decode_header(email_message_raw['From'])))
# Print each name and email
name, email = email_from.split('<')
email.replace(">", "")
print(name + "|" + email)
# When i swap to just print email_from then works
# print(email_from)
# Close server connection
m.close()
m.logout()
In your code you replaced the email variable..
Try this...
import imaplib
import email
from email.header import Header, decode_header, make_header
# Connection settings
HOST = 'imap.gmail.com'
USERNAME = '***'
PASSWORD = '***'
m = imaplib.IMAP4_SSL(HOST, 993)
m.login(USERNAME, PASSWORD)
m.select('INBOX')
result, data = m.uid('search', None, "ALL")
if result == 'OK':
for num in data[0].split()[:5]:
result, data = m.uid('fetch', num, '(RFC822)')
if result == 'OK':
# Get raw message
email_message_raw = email.message_from_bytes(data[0][1])
# Decode headers
email_from = str(make_header(decode_header(email_message_raw['From'])))
# Print each name and email
name, email_addr = email_from.split('<')
email_addr.replace(">", "")
print(name + "|" + email_addr)
# When i swap to just print email_from then works
# print(email_from)
# Close server connection
m.close()
m.logout()
I had the same error [happily solved], my mistake was in the shebang. That should point to python3.
#! /usr/bin/env python3
from smtplib import SMTP_SSL as SMTP
from email.MIMEText import MIMEText
import traceback
#from_field is a dictionary with smtp_host, name, email, and password
def send(from_field, to_email):
subject = 'how do you know it'
body="""\
hello there
"""
try:
msg = MIMEText(body, 'plain')
msg['Subject']= subject
msg['From'] = from_field['name'] + ' <'+from_field['email']+'>'
print msg
conn = SMTP(from_field['smtp'])
conn.set_debuglevel(False)
conn.login(from_field['email'],from_field['password'])
try:
conn.sendmail(from_field.email,[to_email], msg.as_string())
pass
finally:
conn.close()
except Exception, exc:
traceback.print_exc()
sys.exit( "mail failed; %s" % str(exc) ) # give a error message
I get this error message when I run it:
AttributeError: 'dict' object has no attribute 'email' on the conn.sendmail line
from_field is a dictionary. That line should be:
conn.sendmail(from_field['email'], to_email, msg.as_string())