joining html header, body and trailer using Python - python

I'm trying to join htm header with the body and trailer like this
message1 = """<html>
<head></head>
<body><p>"""
message2 = 'Hello World!'
message3 = """</p></body>
</html>"""
html_message = join(message1,message2,message3)
but when I print "html_message" the result is "\Hello World!\", why themthe backslashes appear , how could I remove

I suppose that you are using a (wrong) imported method, but you can use the percent operand with strings
template = """
<html>
<head></head>
<body>
<p>%(text)s</p>
</body>
</html>
"""
html_message = template % {"text":"Hello World!"}
Don't forget, the variable name format is: percent sign + name in parentheses + format (s for string)

Here is how I would join the string:
message1 = """<html>
<head></head>
<body><p>"""
message2 = 'Hello World!'
message3 = """</p></body>
</html>"""
html_message = "".join([message1,message2,message3])
The join you are referring to merges files together, which are usually in the form Something/another/thing, hence the back slashes. No need for from os.path import basename, join

To join strings, use the + symbol
html_message = message1 + message2 + message3
os.path.join is used to create file path like os.path.join('my', 'script.py') => my/script.py

Related

How to reference variable in python html email?

I am trying to send an email with python and i have a variable ("string") from my flask route which i would like to reference in my email html.
#app.route('/edit', methods=['GET','POST'])
def edit():
...
s_list = S.query.all()
strings = '\n'.join([str(s) for s in s_list])
global string
string = str(strings)
print(string)
However, nothing appears in the variable part when the email is sent. I tried to print it on terminal and could see the results.
Can anyone let me know what am i doing wrongly please?
message = MIMEMultipart("alternative")
message["Subject"] = "Thank you."
message["From"] = sender_email
message["To"] = user_mail
# Write the plain text part
text = "Thank you for your submission! " + string
# write the HTML part
html = """\
<html>
<head></head>
<body>
<p>Thank you for your submission! <br>
""" + string + """
<br></br>
</p>
</body>
</html>
""".format(string=string)
# convert both parts to MIMEText objects and add them to the MIMEMultipart message
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)

how to break line in list in python email

I am trying to query a list from my Flask database and then send it out as a html email. However, i am unable to break them into different lines.
for example, instead of:
a
b
c
i get abc currently in the email. i've tried adding "\n" in the loop but it doesnt seem to work. does anyone know how i can break it into different rows?
def mail():
sender_email = "xx#gmail.com"
message = MIMEMultipart("alternative")
message["Subject"] = "xx"
message["From"] = sender_email
message["To"] = user_mail
add = '\n'
list = Lines.query.all()
for s in list:
add += str(s.title) + '\r\n'
print(add)
# Write the plain text part
text = "Thank you for submitting a xx! Here are the lines submitted: " + add
# write the HTML part
html = """\
<html>
<head><head style="margin:0;padding:0;">
<table role="presentation" style="width:100%;border-collapse:collapse;border:20;border-spacing:20;background:#cc0000;">
<tr>
<td align="center" style="padding:20;color:#ffffff;">
Your xxxxx was submitted!
</td>
</tr>
</table>
</head>
<p>Thank you for submitting a xx! Here are the lines submitted for your reference:<br><br>
""" + add + """
<br></br>
</p>
</html>
"""
# convert both parts to MIMEText objects and add them to the MIMEMultipart message
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
...
server.sendmail("xx#gmail.com", user_mail, message.as_string())
return redirect(url_for('complete'))
I believe what you're looking for is this:
list = Lines.query.all()
for s in list:
add += str(s.title) + '<br>'
or (using format vs string concatenation):
list = Lines.query.all()
for s in list:
add += '{}<br>'.format(str(s.title))
or (python 3.6+ f strings):
list = Lines.query.all()
for s in list:
add += f"{s.title}<br>"
\n is not for HTML, but <br> is.
You can use an empty string and keep adding in the loop.
str = ""
for s in list:
str += f"{s.title}\n"

Using Templates Safe Substitute Function in a Loop

I have this simple code:
html_string = '''<html lang="en-US">
'<head>
<title>My Python articles</title>
</head>
<body>'''
for i in range(2):
html_string += '''
<p>
<span style="white-space: pre-line">$''' + str(i) + '''</span>
</p>'''
html_string += '''</body>
</html>'''
html_template = Template(html_string)
output_dir = "./html/"
output_path = os.path.join(output_dir, 'my_page.html')
with io.open(output_path, 'w+', encoding='UTF-8', errors='replace') as html_output:
for i in range(2):
html_output.write(html_template.safe_substitute(i="Hallo"))
html_output.truncate()
It looks like the i in the html_output.write(html_template.safe_substitute(i="Hello")) doesn't correspond to the i in the for loop and all I get is:
$0
$1
$0
$1
$0 and $1 need to exist only once and each of them have to be replaced with the word Hello. Later I'll be replacing $0 and $1 each with a different input.
The docs for template strings have this to say about substitution identifiers:
By default, "identifier" is restricted to any case-insensitive ASCII alphanumeric string (including underscores) that starts with an underscore or ASCII letter.
Identifiers like "$0" and "$1" don't satisfy this condition, because they start with an ASCII digit.
Inserting a letter between the "$" and the digit like this ought to work:
html_string = '''<html lang="en-US">
'<head>
<title>My Python articles</title>
</head>
<body>'''
# Make substitution identifiers like "$Ti"
for i in range(2):
html_string += '''
<p>
<span style="white-space: pre-line">$T''' + str(i) + '''</span>
</p>'''
html_string += '''</body>
</html>'''
html_template = Template(html_string)
# Map identifiers to values
mapping = {'T' + str(i): 'Hello' for i in range(2)}
output_dir = "./html/"
output_path = os.path.join(output_dir, 'my_page.html')
with open(output_path, 'w+', encoding='UTF-8', errors='replace') as html_output:
html_output.write(html_template.safe_substitute(mapping))
html_output.truncate()

Is it possible to iterate a dict in python for use in a html email

I am trying to send a email notification, and I would like to send dynamic data(for testing purposes my dictionary is static). How ever when I iterate trough my dictionary only one value shows up in the email. Any help would be greatly appreciated!!!
Here is my email.py
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# me == my email address
# you == recipient's email address
me = "test_email#mydomain.com"
you = "test_email_user#mydomain.com"
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you
justin = "Justin"
p = {u'Contracts that need signed by: Justin': [[u'/contracts/26203', u'/contracts/26194', u'/contracts/26199', u'/contracts/26173']]}
for a in p.keys():
b = p['Contracts that need signed by: Justin']
for c, d in enumerate(b):
e = d
for f in e:
html = """\
<html>
<head></head>
<body>
<p>Contracts that need signed by """ + justin + """<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
part2 = MIMEText(html, 'html')
msg.attach(part2)
s = smtplib.SMTP('localhost')
s.sendmail(me, you, msg.as_string())
s.quit()
Here is the email I get ^
Contracts that need signed by Justin
How are you?
Here is the link you wanted.
Which I want it to look like this
Contracts that need signed by Justin
How are you?
#EACH OF THE LINKS WOULD BE THE NEXT VALUE IN MY DICTONARY.
Here is the link1 you wanted.
Here is the link2 you wanted.
Here is the link3 you wanted.
Here is the link4 you wanted.
You are overwriting the html variable over and over again.
You have to add always 1 line in the for loop like this:
justin = "Justin"
p = {u'Contracts that need signed by: Justin': [[u'/contracts/26203', u'/contracts/26194', u'/contracts/26199', u'/contracts/26173']]}
for a in p.keys():
b = p['Contracts that need signed by: Justin']
for c, d in enumerate(b):
e = d
html = """\
<html>
<head></head>
<body>
<p>Contracts that need signed by """ + justin + """<br>
How are you?<br>
"""
for f in e:
html = html + """Here is the link you wanted. \n"""
html = html + """</p>
</body>
</html>
"""
part2 = MIMEText(html, 'html')
print part2
The problem is you overwrite html variable on each iteration.
You can use string formatting for your problem:
for c, d in enumerate(b):
e = d
html = """\
<html>
<head></head>
<body>
<p>Contracts that need signed by """ + justin + """<br>
How are you?<br>
{0}
</p>
</body>
</html>
"""
s = []
for f in e:
print(f)
s.append('Here is the <a href="http://contract.mydomain.com/{0}>link</a> you wanted.'.format(f))
print(s)
html = html.format('\n'.join(s))
print(html)
output:
<html>
<head></head>
<body>
<p>Contracts that need signed by aaa<br>
How are you?<br>
Here is the <a href="http://contract.mydomain.com//contracts/26203>link</a> you wanted.
Here is the <a href="http://contract.mydomain.com//contracts/26194>link</a> you wanted.
Here is the <a href="http://contract.mydomain.com//contracts/26199>link</a> you wanted.
Here is the <a href="http://contract.mydomain.com//contracts/26173>link</a> you wanted.
</p>
</body>
</html>

Python - sending HTML Mail with Variables

I wanted to make a small cronmailer for my personal use. And here's the part wich do not work
# Create the body of the message (a plain-text and an HTML version).
text = "LOG OUTPUT: " + sys.argv[1] + "\n"
logdata = open(sys.argv[2], "rb")
for row in logdata:
text = text + row
html = """\
<html>
<head></head>
<body>
<p>LOG OUTPUT: {0} <br> {1}
</p>
</body>
</html>
""".format(unicode(str(sys.argv[1]),'utf-8'), unicode(str(logdata),'utf-8'))
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
msg.attach(part1)
msg.attach(part2)
server = smtplib.SMTP(str(server) + ":" + str(port))
server.starttls()
server.login(username,password)
server.sendmail(emailfrom, emailto, msg.as_string())
server.quit()
I get the mail. With the Plain Text and the attachment (left the code out, cause it works). But not the HTML part. The only thing I get there is:
<html>
<head></head>
<body>
<p>LOG OUTPUT: test
Thanks for any help and a Happy New Year
Here are likely-better ways to build that html string (in Python 2):
import cgi
text = "LOG OUTPUT: " + sys.argv[1] + "\n"
with open(sys.argv[2], "rb") as f:
text += f.read()
html = """\
<html>
<head></head>
<body>
<p>LOG OUTPUT: {0}<br/>
<pre>{1}</pre>
</p>
</body>
</html>""".format(unicode(str(sys.argv[1]), 'utf-8'),
unicode(cgi.escape(text), 'utf-8'))
Note that in Python 3 the escaping function is html.escape (so you'd better not name your own variable html as it will clash:-), but for Python 2, where the escaping function is the peculiarly named cgi.escape, this should be OK.

Categories

Resources