How to add pho­tos to your dig­i­tal pic­ture frame via email

-

Do you want to email a pic­ture from your phone to your dig­i­tal pic­ture frame at home? And allow friends & fam­i­ly to do the same?

Here is a sim­ple solu­tion using a free ded­i­cat­ed Google Gmail account and a Python script run­ning on your dig­i­tal pic­ture frame.

Once installed, every per­son who has the email address of your frame and adds the secret hash­tag in the sub­ject line can send you images that will be auto­mat­i­cal­ly added to your pho­tos repos­i­to­ry.

Sim­ple is as sim­ple does

Reg­u­lar­ly adding images to the col­lec­tion on your dig­i­tal pic­ture frame is a cru­cial ingre­di­ent to enjoy­ing the expe­ri­ence every day a bit more.

I have described a solu­tion to share your dig­i­tal pic­ture frame image fold­er with fam­i­ly & friends using Resilio Sync. But some­times even this is too much has­sle, and you want an even sim­pler solu­tion.

This is why it is help­ful to have alter­na­tive ways to add images that are both ful­ly auto­mat­ed and require no main­te­nance.

One approach is to send one or sev­er­al images to a ded­i­cat­ed dig­i­tal pic­ture frame email account. The emails have to be marked with a secret hash­tag, and only emails with a valid hash­tag are scanned. The pho­tos will then be down­loaded and added to your frame - with­out you hav­ing to do a thing.

Fol­low­ing this scan, all emails are being moved to a "Processed" fold­er, includ­ing those that did not have a match­ing hash­tag - keep­ing your inbox always tidy.

I chose not to delete emails but move them to anoth­er fold­er instead because it makes debug­ging eas­i­er should there be any issues. As Gmail grants 15 GB of stor­age quo­ta, you are unlike­ly to run out of space.

The fol­low­ing instruc­tions assume that you have read the arti­cle "How to set up your Rasp­berry Pi for your dig­i­tal pic­ture frame".

Cre­ate a Gmail account and set it up for your frame

Go to Gmail and cre­ate a new Email account. Always remem­ber to use a ran­dom, unique and long pass­word.

When you are done, log into your account. The first thing, we need to do is to acti­vate IMAP. Under the gear­wheel, go to "Set­tings" and enable IMAP.

Next, cre­ate a label (this is what fold­ers are called in Gmail) and call it "Processed".

Third, change the secu­ri­ty set­tings so that you can access it from the Rasp­berry Pi.

Go to your account set­tings and "Allow less secure apps".

And last, send an email from your new dig­i­tal pic­ture frame email account to your stan­dard email address and reply. This seems to be help­ful to show Google at least once that you are not a robot as your dig­i­tal pic­ture frame email will only receive emails in the future.

That's it. You have now con­fig­ured your dig­i­tal pic­ture frame's email address.

The Python script to down­load the images

The Python script does the fol­low­ing:

It checks your Gmail account if you have any new emails. If there are new emails, it will ver­i­fy if the sub­ject line includes your secret hash­tag like "#myp­ic­tures". The hash­tag can be any­where in the sub­ject line.

If new mails with the secret hash­tag are being found, the script will check to see if there are any images and will down­load them into a fold­er called "attach­ments" in the Pi home direc­to­ry. Sev­er­al images can be includ­ed in one email, and all are down­loaded.

Just tell your friends & fam­i­ly to send the pho­tos with the high­est res­o­lu­tion set­ting and to not resize them in the email pro­gram. That way, you will have the best pho­to qual­i­ty on your dig­i­tal pic­ture frame.

You can copy and paste the fol­low­ing code into a new Python file called get_images_from_emails.py. Or down­load it here.

  1. #!/usr/bin/env python3
  2. # read emails and detach attachment in attachments directory
  3.  
  4. import email
  5. import getpass, imaplib
  6. import os
  7. import sys
  8. import time
  9.  
  10. detach_dir = '.'
  11. if 'attachments' not in os.listdir(detach_dir):
  12.     os.mkdir('attachments')
  13.  
  14. userName = 'enter-your-gmail-account-name-here'
  15. passwd = 'enter-your-password-here'
  16.  
  17. try:
  18.     imapSession = imaplib.IMAP4_SSL('imap.gmail.com',993)
  19.     typ, accountDetails = imapSession.login(userName, passwd)
  20.     if typ != 'OK':
  21.         print ('Not able to sign in!')
  22.         raise Exception
  23.  
  24.     imapSession.select('Inbox')
  25.     typ, data = imapSession.search(None, 'SUBJECT', '"#mypictures"')
  26.     if typ != 'OK':
  27.         print ('Error searching Inbox.')
  28.         raise Exception
  29.  
  30.     # Iterating over all emails
  31.     for msgId in data[0].split():
  32.         typ, messageParts = imapSession.fetch(msgId, '(RFC822)')
  33.  
  34.         if typ != 'OK':
  35.             print ('Error fetching mail.')
  36.             raise Exception
  37.  
  38.         emailBody = messageParts[0][1] 
  39.         mail = email.message_from_bytes(emailBody) 
  40.  
  41.         for part in mail.walk():
  42.  
  43.             if part.get_content_maintype() == 'multipart':
  44.  
  45.                 continue
  46.             if part.get('Content-Disposition') is None:
  47.  
  48.                 continue
  49.  
  50.             fileName = part.get_filename()
  51.  
  52.             if bool(fileName): 
  53.                 filePath = os.path.join(detach_dir, 'attachments', fileName)
  54.                 if not os.path.isfile(filePath) : 
  55.                     print (fileName)
  56.                     print (filePath)
  57.                     fp = open(filePath, 'wb')
  58.                     fp.write(part.get_payload(decode=True))
  59.                     fp.close()
  60.  
  61.     #MOVING EMAILS TO PROCESSED PART BEGINS HERE
  62.     imapSession.select(mailbox='inbox', readonly=False)
  63.     resp, items = imapSession.search(None, 'All')
  64.     email_ids = items[0].split()
  65.     for email in email_ids:
  66.         latest_email_id = email
  67.  
  68.         #move to processed
  69.         result = imapSession.store(latest_email_id, '+X-GM-LABELS', 'Processed')
  70.  
  71.         if result[0] == 'OK':
  72.             #delete from inbox
  73.             imapSession.store(latest_email_id, '+FLAGS', '\\Deleted')
  74.  
  75.     #END OF MOVING EMAILS TO PROCESSED
  76.  
  77.     imapSession.close()
  78.     imapSession.logout()
  79.  
  80. except :
  81.     print ('No attachments were downloaded')

A few notes:

Enter your Gmail account name (with­out "@gmail.com") and your pass­word in

userName = 'enter-your-gmail-account-name-here'
passwd = 'enter-your-password-here'

You can change the down­load direc­to­ry by mod­i­fy­ing this line

os.mkdir('attachments')

You can change your secret code word by edit­ing

#mypictures

Make sure that you keep the sin­gle and dou­ble quotes.

typ, data = imapSession.search(None, 'SUBJECT', '"#mypictures"')

Place the script into your Rasp­berry Pi home direc­to­ry.

To call this script every hour, you have to mod­i­fy your crontab file.

In Ter­mi­nal enter

crontab -e

and add the fol­low­ing line in the edi­tor:

0 * * * * python3 get_images_from_emails.py

Test your set­up with a few emails (don't for­get the hash­tag in the sub­ject line) and see if it works as expect­ed. You will find your images in the "attach­ments" fold­er in the Rasp­berry Pi home direc­to­ry.

Are you ready for the next move?

To make this whole process of adding images even more con­ve­nient, new­ly arrived pho­tos  can be auto­mat­i­cal­ly ver­i­fied and cropped to fit the aspect ratio of your dig­i­tal pic­ture frame. Then, they will be moved to a direc­to­ry based on the EXIF date the pho­to was tak­en.

This automa­tion will be the sub­ject of a forth­com­ing arti­cle.