Skip to content

Instantly share code, notes, and snippets.

@cdchris12
Forked from blacktwin/notify_added_lastweek.py
Last active February 21, 2017 17:41
Show Gist options
  • Save cdchris12/65bd50d85635753cabe5c860c5091a48 to your computer and use it in GitHub Desktop.
Save cdchris12/65bd50d85635753cabe5c860c5091a48 to your computer and use it in GitHub Desktop.
Send an email with what was added to Plex in the past week using PlexPy.
#!/usr/bin/python
"""
Send an email with what was added to Plex in the past week using PlexPy.
Email includes title (TV: Show Name: Episode Name; Movie: Movie Title), time added, image, and summary.
"""
import requests
import sys
import time
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import email.utils
import smtplib
import urllib
import cgi
import uuid
TODAY = int(time.time())
LASTWEEK = int(TODAY - 7 * 24 * 60 * 60)
## EDIT THESE SETTINGS ##
PLEXPY_APIKEY = '' # Your PlexPy API key
PLEXPY_URL = 'http://server:8181/' # Your PlexPy URL
LIBRARY_NAMES = ['TV Shows', 'Movies'] # Name of libraries you want to check.
# Email settings
name = '' # Your name
sender = '@gmail.com' # From email address
to = [sender, ''] # Whoever you want to email [sender, 'name@example.com']
# Emails will be sent as BCC.
email_server = 'smtp.gmail.com' # Email server (Gmail: smtp.gmail.com)
email_port = 587 # Email port (Gmail: 587)
email_username = '@gmail.com' # Your email username
email_password = '' # Your email password
email_subject = 'Media Added To Plex In The Past Week - Generated by PlexPy' # The email subject
class METAINFO(object):
def __init__(self, data=None):
d = data or {}
self.added_at = d['added_at']
self.parent_rating_key = d['parent_rating_key']
self.title = d['title']
self.rating_key = d['rating_key']
self.media_type = d['media_type']
self.grandparent_title = d['grandparent_title']
self.file_size = d['file_size']
self.thumb = d['art']
self.summary = d['summary']
self.season = d['parent_media_index']
self.episode = d['media_index']
self.air_date = d['originally_available_at']
def get_get_recent(section_id, start, count):
# Get the metadata for a media item. Count matters!
payload = {'apikey': PLEXPY_APIKEY,
'start': str(start),
'count': str(count),
'section_id': section_id,
'cmd': 'get_recently_added'}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
res_data = response['response']['data']['recently_added']
return res_data
except Exception as e:
sys.stderr.write("PlexPy API 'get_recently_added' request failed: {0}.".format(e))
def get_get_metadata(rating_key):
# Get the metadata for a media item.
payload = {'apikey': PLEXPY_APIKEY,
'rating_key': rating_key,
'cmd': 'get_metadata',
'media_info': True}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
if response['response']['result'] == 'success':
res_data = response['response']['data']['metadata']
return METAINFO(data=res_data)
except Exception as e:
sys.stderr.write("PlexPy API 'get_metadata' request failed: {0}.".format(e))
def get_get_libraries_table():
# Get the data on the PlexPy libraries table.
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_libraries_table'}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['data']
return [d['section_id'] for d in res_data if d['section_name'] in LIBRARY_NAMES]
except Exception as e:
sys.stderr.write("PlexPy API 'get_libraries_table' request failed: {0}.".format(e))
def update_library_media_info(section_id):
# Get the data on the PlexPy media info tables.
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_library_media_info',
'section_id': section_id,
'refresh': True}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.status_code
if response != 200:
print(r.content)
except Exception as e:
sys.stderr.write("PlexPy API 'update_library_media_info' request failed: {0}.".format(e))
def get_pms_image_proxy(thumb):
# Gets an image from the PMS and saves it to the image cache directory.
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'pms_image_proxy',
'img': thumb,
'fallback': 'art'}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload, stream=True)
return r.url
except Exception as e:
sys.stderr.write("PlexPy API 'pms_image_proxy' request failed: {0}.".format(e))
recent_lst = []
notify_lst = []
image_lst = []
msg_text_lst = []
message_image_lst = []
# Find the libraries from LIBRARY_NAMES
glt = [lib for lib in get_get_libraries_table()]
# Update media info for libraries.
[update_library_media_info(i) for i in glt]
# Get the rating_key for what was recently added
count = 25
for section_id in glt:
start = 0
while True:
# Assume all items will be returned in descending order of added_at
recent_items = get_get_recent(section_id, start, count)
if all([recent_items]):
start += count
for item in recent_items:
if LASTWEEK <= int(item['added_at']) <= TODAY:
recent_lst.append(item['rating_key'])
continue
elif not all([recent_items]):
break
start += count
# Gather metadata on recently added media.
for i in sorted(recent_lst):
meta = get_get_metadata(str(i))
added = time.ctime(float(meta.added_at))
# Check if media was added between TODAY and LASTWEEK
if LASTWEEK <= int(meta.added_at) <= TODAY:
# Pull image url
thumb_url = "{}.jpeg".format(get_pms_image_proxy(meta.thumb))
image = "{}.jpg".format(meta.rating_key)
# Saving image in current path
urllib.urlretrieve(thumb_url, image)
image = dict(title=meta.rating_key, path=image, cid=str(uuid.uuid4()))
if meta.grandparent_title == '' or meta.media_type == 'movie':
# Movies
notify_lst += [u"<dt><u>{x.title}</u> was added {when}.</dt>"
u"</dt> <dd> <table> <tr> <th>"
'<img src="cid:{cid}" alt="{alt}" width="205" height="100"> </th>'
u" <th id=t11> {x.summary} </th> </tr> </table> </dd> <br>"
.format(x=meta, when=added, alt=cgi.escape(meta.rating_key), quote=True, **image)]
else:
# Shows
notify_lst += [u"<dt><u>{x.grandparent_title}</u>: {x.title}(<b>S{x.season} E{x.episode}</b>), originally aired on <b>{x.air_date}</b>, was added {when}."
u"</dt> <dd> <table> <tr> <th>"
'<img src="cid:{cid}" alt="{alt}" width="205" height="100"> </th>'
u" <th id=t11> {x.summary} </th> </tr> </table> </dd> <br>"
.format(x=meta, when=added, alt=cgi.escape(meta.rating_key), quote=True, **image)]
msg_text_lst += [MIMEText(u'[image: {title}]'.format(**image), 'plain', 'utf-8')]
image_lst += [image]
"""
Using info found here: http://stackoverflow.com/a/20485764/7286812
to accomplish emailing inline images
"""
msg_html = MIMEText("""\
<html>
<head>
<style>
th#t11 {{ padding: 6px; vertical-align: top; text-align: left; }}
</style>
</head>
<body>
<p>Hi!<br>
<br>Below is the list of content added to Plex's {LIBRARY_NAMES} this week.<br>
<dl>
{notify_lst}
</dl>
</p>
</body>
</html>
""".format(notify_lst="\n".join(notify_lst).encode("utf-8"), LIBRARY_NAMES=" & ".join(LIBRARY_NAMES)
, quote=True, ), 'html', 'utf-8')
message = MIMEMultipart('related')
message['Subject'] = email_subject
message['From'] = email.utils.formataddr((name, sender))
message_alternative = MIMEMultipart('alternative')
message.attach(message_alternative)
for msg_text in msg_text_lst:
message_alternative.attach(msg_text)
message_alternative.attach(msg_html)
for img in image_lst:
with open(img['path'], 'rb') as file:
message_image_lst = [MIMEImage(file.read(), name=os.path.basename(img['path']))]
for msg in message_image_lst:
message.attach(msg)
msg.add_header('Content-ID', '<{}>'.format(img['cid']))
mailserver = smtplib.SMTP(email_server, email_port)
mailserver.ehlo()
mailserver.starttls()
mailserver.ehlo()
mailserver.login(email_username, email_password)
mailserver.sendmail(sender, to, message.as_string())
mailserver.quit()
print 'Email sent'
# Delete images in current path
for img in image_lst:
os.remove(img['path'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment