depauw
Posts: 44
Joined: Mon Nov 09, 2015 2:12 pm

placing a list of variables in one line of html - newbie!

Mon Jun 19, 2017 3:08 pm

Hello,
I'm struggling with this:
I'm writing a script that looks at the image (jpg) files in a directory.
Then it should add those images to an email....

so far, I have some code (see below) for 2 images, or 3 or 5 or 10 if you want, but it's manually done and I don't always know how many files there will be in the directory

Code: Select all

path = "I:/raspberry/scripts python/email templates/images/"
image1 = 'foto_1.jpg'
image2 = 'foto_2.jpg'
image_name1 = path + image1
image_name2 = path + image2

# This example assumes the image1 is in the directory 'path'
fp = open(image_name1, 'rb')
msgImage = MIMEImage(fp.read(), _subtype='jpg')

# Define the image1's ID as referenced below
msgImage.add_header('Content-ID', '<' + image1 + '>')
msgRoot.attach(msgImage)

# This example assumes the image2 is in the directory 'path'
fp = open(image_name2, 'rb')
msgImage = MIMEImage(fp.read(), _subtype='jpg')
fp.close()

# Define the image2's ID as referenced below
msgImage.add_header('Content-ID', '<' + image2 + '>')
msgRoot.attach(msgImage)

# We reference the image in the IMG SRC attribute by the ID we gave it above
msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:' + image1 + '"><br><img src="cid:' + image2 + '"><br>Nifty!', 'html')
msgAlternative.attach(msgText)
My challenge is: let's say there are 5 files: how do I get the 5 variables (image1 to image5) into the line [codemsgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:' + image1 + '"><br><img src="cid:' + image2 + '"><br>Nifty!', 'html')][/code]

I thnk I have to somehow go over names of the files in the directory and assign those to image_name1, image_name2 ,.....
I also think it has something to do with lists, but I'm not sure how to handle this to place the image_name variables in the one line of code.
I'm learning by try and error, assisted by Google and.... you guys from the forum!!

kind regards,
Christophe

User avatar
davef21370
Posts: 872
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: placing a list of variables in one line of html - newbie

Mon Jun 19, 2017 4:24 pm

Have a look at lists.

Code: Select all

imageList = ["image_1.jpg", "image_2.jpg", etc...]
then access each image(or path to the file or whatever)

Code: Select all

print imageList[0]
print imageList[1]

or

for img in imageList:
    print img
That's the general idea. Also a list object has functions like append, pop, shuffle which may come in useful. Do a little googling.

Dave.
Apple say... Monkey do !!

scotty101
Posts: 2221
Joined: Fri Jun 08, 2012 6:03 pm

Re: placing a list of variables in one line of html - newbie

Mon Jun 19, 2017 4:28 pm

Some more code that might help. Untested as I haven't got anything to send the messages to. (I've never dealt with MIME before)
This should find all .jpg images in a folder and attach them to a MIME email. Also creates some body text that contains the HTML for each image.

Code: Select all

from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

import os

path = "I:/raspberry/scripts python/email templates/images/"
#Grab all the images (files that have .jpg as file extension)
images = [f for f in os.listdir(path) if f.endswith('.jpg')]
print(images)

#Create container email with a dummy subject
msg = MIMEMultipart()
msg['Subject'] = 'Test'

#Create a blank string to contain the text of our email
email_body = ""

#Step through each of the images
for img in images:
    image_path = os.path.join(path,img)
    #Open the image, read it and add a header
    with open(image_path,'rb') as fp:
        imgObj = MIMEImage(fp.read())
        imgObj.add_header('Content-ID', '<{}>'.format(img))
    #attach the email to the message
    msg.attach(imgObj)
    #Add the html for the current image to the text
    email_body += '<img src="cid:{}"><br>'.format(img)
    
#Create the email text and add it to the message
msgText = MIMEText(email_body)
msg.attach(msgText)


The official python examples are similar to what you are looking for
https://docs.python.org/3/library/email-examples.html
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

depauw
Posts: 44
Joined: Mon Nov 09, 2015 2:12 pm

Re: placing a list of variables in one line of html - newbie

Wed Jun 21, 2017 10:08 pm

I've been working with the suggestions given by scotty101 and incorporated it in my code.

Code: Select all

# Send an HTML email with an embedded image and a plain text message for
# email clients that don't want to display the HTML.
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

path = "I:/raspberry/scripts python/email templates/images/"
#Grab all the images (files that have .jpg as file extension)
images = [f for f in os.listdir(path) if f.endswith('.JPG')]
print(images)

# Define these once; use them twice!
strFrom = 'from@apotheekdepauw.be'
strTo = 'to@apotheekdepauw.be'

# Create the root message and fill in the from, to, and subject headers
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message imageembedmailalt2.py'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'

# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)

msgText = MIMEText('This is the alternative plain text message.')
msgAlternative.attach(msgText)


for img in images:
	image_path = os.path.join(path,img)
	# Open the image, read it and add a header
	with open(image_path, 'rb') as fp:
		msgImage = MIMEImage(fp.read(), _subtype='jpg')
		msgImage.add_header('Content-ID', '<{}>').format(img)
	msgRoot.attach(msgImage)
	email_body += '<img src="cid:{}"><br>'.format(img)

msgText = MIMEText(email_body)
msgAlternative.attach(msgText)

# Send the email (this example assumes SMTP authentication is required)
import smtplib

# Enter your smtp Server-Connection
server = smtplib.SMTP('server', port)
#if your using gmail: smtp.gmail.com
server.ehlo()
server.starttls()
server.ehlo
# Login
server.login("login", "password")

try:
	server.sendmail(strFrom, strTo, msgRoot.as_string())
	server.quit()
	print ("success")
except Exception:
	print ("failed")
Running it gives this error:
Traceback (most recent call last):
File "I:/raspberry/scripts python/email templates/imageembedmailalt2.py", line 56, in <module>
msgImage.add_header('Content-ID', '<{}>').format(img)
AttributeError: 'NoneType' object has no attribute 'format'
Any suggestions on this?

much appreciated!
Christophe

DirkS
Posts: 7217
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: placing a list of variables in one line of html - newbie

Wed Jun 21, 2017 10:18 pm

Compare location of parentheses in

Code: Select all

msgImage.add_header('Content-ID', '<{}>').format(img)
with the code scotty101 posted:

Code: Select all

imgObj.add_header('Content-ID', '<{}>'.format(img))

scotty101
Posts: 2221
Joined: Fri Jun 08, 2012 6:03 pm

Re: placing a list of variables in one line of html - newbie

Thu Jun 22, 2017 8:53 am

^ What he said!
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

depauw
Posts: 44
Joined: Mon Nov 09, 2015 2:12 pm

Re: placing a list of variables in one line of html - newbie

Thu Jun 22, 2017 2:49 pm

Yes, coding at night in this warm weather makes curly brackets, indentations, etc dance before my eyes :)
Made the change and I also forgot the lin to declare the variable email_body. So fixed that to!
Made a last adjustment to the line

Code: Select all

msgText = MIMEText(email_body) 
I changed it to this: [codemsgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br>'+ email_body + '<br>Cool!', 'html')][/code]

And now the images come ferdectly inline in the email body text.

This is the finished code. Feel free to use it!

Code: Select all

# Send an HTML email with an embedded image and a plain text message for
# email clients that don't want to display the HTML.
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

path = "I:/raspberry/scripts python/email templates/images/"
#Grab all the images (files that have .jpg as file extension)
images = [f for f in os.listdir(path) if f.endswith('.JPG')]
print(images)

# Define these once; use them twice!
strFrom = 'from@apotheekdepauw.be'
strTo = 'to@apotheekdepauw.be'

# Create the root message and fill in the from, to, and subject headers
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message imageembedmailalt2.py'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'

# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)

msgText = MIMEText('This is the alternative plain text message.')
msgAlternative.attach(msgText)

#Create a blank string to contain the text of our email
email_body = ""

for img in images:
   image_path = os.path.join(path,img)
   # Open the image, read it and add a header
   with open(image_path, 'rb') as fp:
      msgImage = MIMEImage(fp.read(), _subtype='jpg')
      msgImage.add_header('Content-ID', '<{}>'.format(img))
   msgRoot.attach(msgImage)
   email_body += '<img src="cid:{}"><br>'.format(img)

msgText = MIMEText(email_body)
msgAlternative.attach(msgText)

# Send the email (this example assumes SMTP authentication is required)
import smtplib

# Enter your smtp Server-Connection
server = smtplib.SMTP('server', port)
#if your using gmail: smtp.gmail.com
server.ehlo()
server.starttls()
server.ehlo
# Login
server.login("login", "password")

try:
   server.sendmail(strFrom, strTo, msgRoot.as_string())
   server.quit()
   print ("success")
except Exception:
   print ("failed")
a big shoutout to davef21370, scotty101 and DirkS for helping me out and a nice learning experience!!!

Return to “Python”

Who is online

Users browsing this forum: California, pcmanbob and 14 guests