Create notify_added_custom.py
https://gist.github.com/blacktwin/1094dcf38249f36c8d374e0cba7a86cd
This commit is contained in:
parent
02fb076746
commit
015d965ef7
355
notify_added_custom.py
Normal file
355
notify_added_custom.py
Normal file
@ -0,0 +1,355 @@
|
||||
"""
|
||||
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.
|
||||
|
||||
Uses:
|
||||
notify_added_lastweek.py -t poster -d 1 -u all -i user1 user2 -s 250 100
|
||||
# email all users expect user1 & user2 what was added in the last day using posters that are 250x100
|
||||
|
||||
notify_added_lastweek.py -t poster -d 7 -u all
|
||||
# email all users what was added in the last 7 days(week) using posters that are default sized
|
||||
|
||||
notify_added_lastweek.py -t poster -d 7 -u all -s 1000 500
|
||||
# email all users what was added in the last 7 days(week) using posters that are 1000x500
|
||||
|
||||
notify_added_lastweek.py -t art -d 7 -u user1
|
||||
# email user1 & self what was added in the last 7 days(week) using artwork that is default sized
|
||||
|
||||
notify_added_lastweek.py -t art -d 7
|
||||
# email self what was added in the last 7 days(week) using artwork that is default sized
|
||||
|
||||
"""
|
||||
|
||||
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
|
||||
import argparse
|
||||
|
||||
|
||||
## EDIT THESE SETTINGS ##
|
||||
PLEXPY_APIKEY = 'xxx' # Your PlexPy API key
|
||||
PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
|
||||
LIBRARY_NAMES = ['Movies', 'TV Shows'] # Name of libraries you want to check.
|
||||
|
||||
# Email settings
|
||||
name = '' # Your name
|
||||
sender = '' # 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 = '' # Your email username
|
||||
email_password = '' # Your email password
|
||||
email_subject = 'PlexPy Added Last {} day(s) Notification' #The email subject
|
||||
|
||||
# Default sizing for pictures
|
||||
# Poster
|
||||
poster_h = 205
|
||||
poster_w = 100
|
||||
# Artwork
|
||||
art_h = 100
|
||||
art_w = 205
|
||||
|
||||
## /EDIT THESE SETTINGS ##
|
||||
|
||||
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']
|
||||
|
||||
|
||||
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}
|
||||
|
||||
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 'get_get_users_tables' request failed: {0}.".format(e))
|
||||
|
||||
|
||||
def get_get_users():
|
||||
# Get the user list from PlexPy.
|
||||
payload = {'apikey': PLEXPY_APIKEY,
|
||||
'cmd': 'get_users'}
|
||||
|
||||
try:
|
||||
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
|
||||
response = r.json()
|
||||
res_data = response['response']['data']
|
||||
return [d for d in res_data]
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write("PlexPy API 'get_user' request failed: {0}.".format(e))
|
||||
|
||||
|
||||
def get_rating_keys(TODAY, LASTDATE):
|
||||
|
||||
recent_lst = []
|
||||
# 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 LASTDATE <= int(item['added_at']) <= TODAY:
|
||||
recent_lst.append(item['rating_key'])
|
||||
continue
|
||||
elif not all([recent_items]):
|
||||
break
|
||||
|
||||
start += count
|
||||
return recent_lst
|
||||
|
||||
|
||||
def build_html(rating_key, height, width, pic_type):
|
||||
|
||||
meta = get_get_metadata(str(rating_key))
|
||||
|
||||
added = time.ctime(float(meta.added_at))
|
||||
# Pull image url
|
||||
thumb_url = "{}.jpeg".format(get_pms_image_proxy(meta.thumb))
|
||||
if pic_type == 'poster':
|
||||
thumb_url = thumb_url.replace('%2Fart%', '%2Fposter%')
|
||||
image_name = "{}.jpg".format(str(rating_key))
|
||||
# Saving image in current path
|
||||
urllib.urlretrieve(thumb_url, image_name)
|
||||
image = dict(title=meta.rating_key, path=image_name, cid=str(uuid.uuid4()))
|
||||
if meta.grandparent_title == '' or meta.media_type == 'movie':
|
||||
# Movies
|
||||
notify = u"<dt>{x.title} ({x.rating_key}) was added {when}.</dt>" \
|
||||
u"</dt> <dd> <table> <tr> <th>" \
|
||||
'<img src="cid:{cid}" alt="{alt}" width="{width}" height="{height}"> </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, width=width, height=height,**image)
|
||||
else:
|
||||
# Shows
|
||||
notify = u"<dt>{x.grandparent_title}: {x.title} ({x.rating_key}) was added {when}." \
|
||||
u"</dt> <dd> <table> <tr> <th>" \
|
||||
'<img src="cid:{cid}" alt="{alt}" width="{width}" height="{height}"> </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, width=width, height=height, **image)
|
||||
|
||||
image_text = MIMEText(u'[image: {title}]'.format(**image), 'plain', 'utf-8')
|
||||
|
||||
return image_text, image, notify
|
||||
|
||||
|
||||
def send_email(msg_text_lst, notify_lst, image_lst, to, days):
|
||||
"""
|
||||
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.format(days)
|
||||
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'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser(description="Send an email with what was added to Plex in the past week using PlexPy.")
|
||||
parser.add_argument('-t', '--type', help='Metadata picture type from Plex.',
|
||||
required= True, choices=['art', 'poster'])
|
||||
parser.add_argument('-s', '--size', help='Metadata picture size from Plex {Height Width}.', nargs='*')
|
||||
parser.add_argument('-d', '--days', help='Time frame for which to check recently added to Plex.',
|
||||
required= True, type=int)
|
||||
parser.add_argument('-u', '--users', help='Which users from Plex will be emailed.',
|
||||
nargs='+', default='self', type=str)
|
||||
parser.add_argument('-i', '--ignore', help='Which users from Plex to ignore.',
|
||||
nargs='+', type=str)
|
||||
|
||||
|
||||
opts = parser.parse_args()
|
||||
|
||||
TODAY = int(time.time())
|
||||
LASTDATE = int(TODAY - opts.days * 24 * 60 * 60)
|
||||
|
||||
# Image sizing based on type or custom size
|
||||
if opts.type == 'poster' and not opts.size:
|
||||
height = poster_h
|
||||
width = poster_w
|
||||
elif opts.size:
|
||||
height = opts.size[0]
|
||||
width = opts.size[1]
|
||||
else:
|
||||
height = art_h
|
||||
width = art_w
|
||||
|
||||
# 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]
|
||||
|
||||
# Gather all users email addresses
|
||||
if opts.users == ['all']:
|
||||
[to.append(x['email']) for x in get_get_users() if x['email'] != '' and x['email'] not in to
|
||||
and x['username'] not in opts.ignore]
|
||||
elif opts.users != ['all'] and opts.users != 'self':
|
||||
for get_users in get_get_users():
|
||||
for arg_users in opts.users:
|
||||
if arg_users in get_users['username']:
|
||||
to = to + [str(get_users['email'])]
|
||||
print('Sending email(s) to {}'.format(', '.join(to)))
|
||||
|
||||
# Gather rating_keys on recently added media.
|
||||
rating_keys_lst = get_rating_keys(TODAY, LASTDATE)
|
||||
|
||||
# Build html elements from rating_key
|
||||
image_lst = []
|
||||
msg_text_lst = []
|
||||
notify_lst = []
|
||||
|
||||
build_parts = [build_html(rating_key, height, width, opts.type) for rating_key in sorted(rating_keys_lst)]
|
||||
for parts in build_parts:
|
||||
msg_text_lst.append(parts[0])
|
||||
image_lst.append(parts[1])
|
||||
notify_lst.append(parts[2])
|
||||
|
||||
# Send email
|
||||
send_email(msg_text_lst, notify_lst, image_lst, to, opts.days)
|
||||
|
||||
# Delete images in current path
|
||||
for img in image_lst:
|
||||
os.remove(img['path'])
|
Loading…
Reference in New Issue
Block a user