pythonbashemail-attachments

python code to get (latest) file with timestamp as name to attach to a e-mail


  1. I have a BASH script that takes a photo with a webcam.

     #!/bin/bash
    
     # datum (in swedish) = date
    
     datum=$(date +'%Y-%m-%d-%H:%M')
    
     fswebcam -r --no-banner /home/pi/webcam/$datum.jpg
    
  2. I have a Python code to take run the BASH script when it received a signal from a motion detector and also call a module which send the e-mail

     import RPi.GPIO as GPIO
     import time
     import gray_camera
     import python_security_mail
    
     GPIO.setmode(GPIO.BCM)
     GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    
     while True:
         if(GPIO.input (23)== 1):
             print('discovered!!!')
             gray_camera.camera()
         time.sleep(1)
         python_security_mail.mail()
         time.sleep(1.5)
     GPIO.cleanup()
    

And the mail code:

    import os
    import smtplib
    import userpass
    from email.mime.text import MIMEText
    from email.mime.image import MIMEImage
    from email.mime.multipart import MIMEMultipart

    def SendMail(ImgFileName):
        img_data = open('/home/pi/solstol.png', 'rb').read() 
        msg = MIMEMultipart()
        msg['Subject'] = 'subject'
        msg['From'] = userpass.fromaddr
        msg['To'] = userpass.toaddr
    fromaddr = userpass.fromaddr
    toaddr = userpass.toaddr

    text = MIMEText("test")
    msg.attach(text)
    image = MIMEImage(img_data, name=os.path.basename('/home/pi/solstol.png'))  
    msg.attach(image)

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login(fromaddr, userpass.password)
    s.sendmail(fromaddr, toaddr, msg.as_string())
    s.quit()

I have just learned how to attach a file to a e-mail. The code works so far. But I would like to get the latest photo taken and attach to the email.

I am still just a beginner in Python. The code in here I have mostly copied from various tutorials and changed a little bit to work for me. I have no deep understanding in all of this. In some few parts I may perhaps have intermediate knowledge. I have no idea how to write the code to get Python to find the file (photo with jpg format) I want and attach it to the mail.

So I am very glad if there is someone who can guide me how to fill in the missing part.


I put in wrong code for the mail function. I got a little bit better result with this one:

#!/usr/bin/python

import userpass
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os

def send_a_picture():
    gmail_user = userpass.fromaddr
    gmail_pwd = userpass.password

    def mail(to, subject, text, attach):
       msg = MIMEMultipart()

       msg['From'] = gmail_user
       msg['To'] = userpass.toaddr
       msg['Subject'] = subject

       msg.attach(MIMEText(text))

       part = MIMEBase('application', 'octet-stream')
       part.set_payload(open(attach, 'rb').read())
       Encoders.encode_base64(part)
       part.add_header('Content-Disposition',
               'attachment; filename="%s"' % os.path.basename(attach))
       msg.attach(part)

       mailServer = smtplib.SMTP("smtp.gmail.com", 587)
       mailServer.ehlo()
       mailServer.starttls()
       mailServer.ehlo()
       mailServer.login(gmail_user, gmail_pwd)
       mailServer.sendmail(gmail_user, to, msg.as_string())
       mailServer.close()

    mail(userpass.toaddr,
       "One step further",
       "Hello. Thanks for the link. I am a bit closer now.",
       "solstol.png")


send_a_picture()  

Edit.

Hello. I have now added seconds to the filename. If there is no picture in the folder when running glob.glob("/home/pi/.jgp") I got: Traceback (most recent call last): File "<pyshell#1>", line 1, in last_photo_taken = glob.glob("/home/pi/.jpg")[-1] IndexError: list index out of range.

When I take a picture I got a return ('/home/pi/2017-01-16-23:39:46.jpg'). If I then takes another picture the return still is '/home/pi/2017-01-16-23:39:46.jpg'. If I restart the shell I got the next picture as return. Thank you for your help today. I will write more tomorrow.


Solution

  • Here's an example of some code to list all files and folders in a specific folder:

    import os
    files = os.listdir("myfolder")
    

    And here's one way to take that list and filter for names that match a specific regular expression (I've used filenames of the format YYYYMMDD-HHMM.jpg, but you can change that):

    import re
    jpgre = re.compile(r"\d{8}-\d{4}\.jpg")
    jpgs = [s for s in files if jpgre.match(s)]
    

    Now we need to sort by date/time because the list is in arbitrary order. Note that all my filenames are of the form YYYYMMDD-HHMM.jpg, so we can easily sort it by date/time, as follows:

    jpgs.sort()
    

    And finally, the newest JPG filename is the last in the list:

    file = jpgs[-1]
    

    Hope this gets you started. Note that I've assumed that you may have other JPGs in the same folder so a listing of *.jpg might yield undesirable files, and that's why I gave a general solution using regular expression matching. If you don't have other JPGs then you could use glob("folder/*.jpg").