Add Tautulli triggered scripts
This commit is contained in:
parent
645c43708a
commit
5f99b37cfe
79
utility/add_label_recently_added.py
Normal file
79
utility/add_label_recently_added.py
Normal file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Description: Automatically add a label to recently added items in your Plex library
|
||||
# Author: /u/SwiftPanda16
|
||||
# Requires: requests
|
||||
# Tautulli script trigger:
|
||||
# * Notify on recently added
|
||||
# Tautulli script conditions:
|
||||
# * Filter which media to add labels to using conditions. Examples:
|
||||
# [ Media Type | is | movie ]
|
||||
# [ Show Name | is | Game of Thrones ]
|
||||
# [ Album Name | is | Reputation ]
|
||||
# [ Video Resolution | is | 4k ]
|
||||
# [ Genre | contains | horror ]
|
||||
# Tautulli script arguments:
|
||||
# * Recently Added:
|
||||
# --title {title} --section_id {section_id} --media_type {media_type} --rating_key {rating_key} --parent_rating_key {parent_rating_key} --grandparent_rating_key {grandparent_rating_key} --label "Label"
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import requests
|
||||
|
||||
|
||||
### OVERRIDES - ONLY EDIT IF RUNNING SCRIPT WITHOUT TAUTULLI ###
|
||||
|
||||
PLEX_URL = ''
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
|
||||
### CODE BELOW ###
|
||||
|
||||
PLEX_URL = PLEX_URL or os.getenv('PLEX_URL', PLEX_URL)
|
||||
PLEX_TOKEN = PLEX_TOKEN or os.getenv('PLEX_TOKEN', PLEX_TOKEN)
|
||||
|
||||
MEDIA_TYPES_PARENT_VALUES = {'movie': 1, 'show': 2, 'season': 2, 'episode': 2, 'album': 9, 'track': 9}
|
||||
|
||||
|
||||
def add_label(media_type_value, rating_key, section_id, label):
|
||||
headers = {'X-Plex-Token': PLEX_TOKEN}
|
||||
params = {'type': media_type_value,
|
||||
'id': rating_key,
|
||||
'label.locked': 1,
|
||||
'label[0].tag.tag': label
|
||||
}
|
||||
|
||||
url = '{base_url}/library/sections/{section_id}/all'.format(base_url=PLEX_URL, section_id=section_id)
|
||||
r = requests.put(url, headers=headers, params=params)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--title', required=True)
|
||||
parser.add_argument('--section_id', required=True)
|
||||
parser.add_argument('--media_type', required=True)
|
||||
parser.add_argument('--rating_key', required=True)
|
||||
parser.add_argument('--parent_rating_key', required=True)
|
||||
parser.add_argument('--grandparent_rating_key', required=True)
|
||||
parser.add_argument('--label', required=True)
|
||||
opts = parser.parse_args()
|
||||
|
||||
if opts.media_type not in MEDIA_TYPES_PARENT_VALUES:
|
||||
print("Cannot add label to '{opts.title}': Invalid media type '{opts.media_type}'".format(opts=opts))
|
||||
else:
|
||||
media_type_value = MEDIA_TYPES_PARENT_VALUES[opts.media_type]
|
||||
rating_key = ''
|
||||
|
||||
if opts.media_type in ('movie', 'show', 'album'):
|
||||
rating_key = opts.rating_key
|
||||
elif opts.media_type in ('season', 'track'):
|
||||
rating_key = opts.parent_rating_key
|
||||
elif opts.media_type in ('episode'):
|
||||
rating_key = opts.grandparent_rating_key
|
||||
|
||||
if rating_key and rating_key.isdigit():
|
||||
add_label(media_type_value, int(rating_key), opts.section_id, opts.label)
|
||||
print("The label '{opts.label}' was added to '{opts.title}' ({rating_key}).".format(opts=opts, rating_key=rating_key))
|
||||
else:
|
||||
print("Cannot add label to '{opts.title}': Invalid rating key '{rating_key}'".format(opts=opts, rating_key=rating_key))
|
110
utility/hide_episode_spoilers.py
Normal file
110
utility/hide_episode_spoilers.py
Normal file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Description: Automatically change episode artwork in Plex to hide spoilers.
|
||||
# Author: /u/SwiftPanda16
|
||||
# Requires: plexapi, requests
|
||||
# Tautulli script trigger:
|
||||
# * Notify on recently added
|
||||
# * Notify on watched (optional - to remove the artwork after being watched)
|
||||
# Tautulli script conditions:
|
||||
# * Condition {1}:
|
||||
# [ Media Type | is | episode ]
|
||||
# * Condition {2} (optional):
|
||||
# [ Library Name | is | DVR ]
|
||||
# [ Show Namme | is | Game of Thrones ]
|
||||
# Tautulli script arguments:
|
||||
# * Recently Added:
|
||||
# To use an image file (can be image in the same directory as this script, or full path to an image):
|
||||
# --rating_key {rating_key} --file {file} --image spoilers.png
|
||||
# To blur the episode artwork (optional blur in pixels):
|
||||
# --rating_key {rating_key} --file {file} --blur 25
|
||||
# * Watched (optional):
|
||||
# --rating_key {rating_key} --file {file} --remove
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import requests
|
||||
import shutil
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
TAUTULLI_URL = ''
|
||||
TAUTULLI_APIKEY = ''
|
||||
PLEX_URL = ''
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
# Environmental Variables
|
||||
TAUTULLI_URL = os.getenv('TAUTULLI_URL', TAUTULLI_URL)
|
||||
TAUTULLI_APIKEY = os.getenv('TAUTULLI_APIKEY', TAUTULLI_APIKEY)
|
||||
PLEX_URL = os.getenv('PLEX_URL', PLEX_URL)
|
||||
PLEX_TOKEN = os.getenv('PLEX_TOKEN', PLEX_TOKEN)
|
||||
|
||||
|
||||
def get_blurred_image(rating_key, blur=25):
|
||||
params = {'apikey': TAUTULLI_APIKEY,
|
||||
'cmd': 'pms_image_proxy',
|
||||
'img': '/library/metadata/{}/thumb'.format(rating_key),
|
||||
'width': 545,
|
||||
'height': 307,
|
||||
'opacity': 100,
|
||||
'background': '000000',
|
||||
'blur': blur,
|
||||
'img_format': 'png',
|
||||
'fallback': 'art'
|
||||
}
|
||||
|
||||
r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=params, stream=True)
|
||||
if r.status_code == 200:
|
||||
r.raw.decode_content = True
|
||||
return r.raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--rating_key', required=True, type=int)
|
||||
parser.add_argument('--file', required=True)
|
||||
parser.add_argument('--image')
|
||||
parser.add_argument('--blur', type=int, default=25)
|
||||
parser.add_argument('--remove', action='store_true')
|
||||
opts = parser.parse_args()
|
||||
|
||||
if opts.image:
|
||||
# File path to episode artwork using the same episode file name
|
||||
episode_artwork = os.path.splitext(opts.file)[0] + os.path.splitext(opts.image)[1]
|
||||
|
||||
# Copy the image to the episode artwork
|
||||
shutil.copy2(opts.image, episode_artwork)
|
||||
|
||||
# Refresh metadata for the TV show
|
||||
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
|
||||
plex.fetchItem(opts.rating_key).show().refresh()
|
||||
|
||||
elif opts.blur:
|
||||
# File path to episode artwork using the same episode file name
|
||||
episode_artwork = os.path.splitext(opts.file)[0] + '.png'
|
||||
|
||||
# Get the blurred artwork from Tautulli
|
||||
blurred_artwork = get_blurred_image(opts.rating_key, opts.blur)
|
||||
if blurred_artwork:
|
||||
# Copy the image to the episode artwork
|
||||
with open(episode_artwork, 'wb') as f:
|
||||
shutil.copyfileobj(blurred_artwork, f)
|
||||
|
||||
# Refresh metadata for the TV show
|
||||
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
|
||||
plex.fetchItem(opts.rating_key).show().refresh()
|
||||
|
||||
elif opts.remove:
|
||||
# File path to episode artwork using the same episode file name without extension
|
||||
episode_path = os.path.dirname(opts.file)
|
||||
episode_filename = os.path.splitext(os.path.basename(opts.file))[0]
|
||||
|
||||
# Find image files with the same name as the episode
|
||||
for filename in os.listdir(episode_path):
|
||||
if filename.startswith(episode_filename) and filename.endswith(('.jpg', '.png')):
|
||||
# Delete the episode artwork image file
|
||||
os.remove(os.path.join(episode_path, filename))
|
||||
|
||||
# Refresh metadata for the TV show
|
||||
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
|
||||
plex.fetchItem(opts.rating_key).show().refresh()
|
46
utility/mark_multiepisode_watched.py
Normal file
46
utility/mark_multiepisode_watched.py
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Description: Automatically mark a multi-episode file as watched in Plex.
|
||||
# Author: /u/SwiftPanda16
|
||||
# Requires: plexapi
|
||||
# Tautulli script trigger:
|
||||
# * Notify on watched
|
||||
# Tautulli script conditions:
|
||||
# * Condition {1}:
|
||||
# [ Media Type | is | episode ]
|
||||
# * Condition {2} (optional):
|
||||
# [ Username | is | username ]
|
||||
# Tautulli script arguments:
|
||||
# * Watched:
|
||||
# --rating_key {rating_key} --filename {filename}
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
PLEX_URL = ''
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
# Environmental Variables
|
||||
PLEX_URL = os.getenv('PLEX_URL', PLEX_URL)
|
||||
PLEX_USER_TOKEN = os.getenv('PLEX_USER_TOKEN', PLEX_TOKEN)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--rating_key', required=True, type=int)
|
||||
parser.add_argument('--filename', required=True)
|
||||
opts = parser.parse_args()
|
||||
|
||||
plex = PlexServer(PLEX_URL, PLEX_USER_TOKEN)
|
||||
|
||||
for episode in plex.fetchItem(opts.rating_key).season().episodes():
|
||||
if episode.ratingKey == opts.rating_key:
|
||||
continue
|
||||
if any(opts.filename in part.file for media in episode.media for part in media.parts):
|
||||
print("Marking multi-episode file '{grandparentTitle} - S{parentIndex}E{index}' as watched.".format(
|
||||
grandparentTitle=episode.grandparentTitle.encode('UTF-8'),
|
||||
parentIndex=str(episode.parentIndex).zfill(2),
|
||||
index=str(episode.index).zfill(2)))
|
||||
episode.markWatched()
|
50
utility/recently_added_collection.py
Normal file
50
utility/recently_added_collection.py
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Description: Automatically add a movie to a collection based on release date.
|
||||
# Author: /u/SwiftPanda16
|
||||
# Requires: plexapi
|
||||
# Tautulli script trigger:
|
||||
# * Notify on recently added
|
||||
# Tautulli script conditions:
|
||||
# * Filter which media to add to collection.
|
||||
# [ Media Type | is | movie ]
|
||||
# [ Library Name | is | Movies ]
|
||||
# Tautulli script arguments:
|
||||
# * Recently Added:
|
||||
# --rating_key {rating_key} --collection "New Releases" --days 180
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
PLEX_URL = ''
|
||||
PLEX_TOKEN = ''
|
||||
|
||||
# Environmental Variables
|
||||
PLEX_URL = os.getenv('PLEX_URL', PLEX_URL)
|
||||
PLEX_TOKEN = os.getenv('PLEX_TOKEN', PLEX_TOKEN)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--rating_key', required=True, type=int)
|
||||
parser.add_argument('--collection', required=True)
|
||||
parser.add_argument('--days', required=True, type=int)
|
||||
opts = parser.parse_args()
|
||||
|
||||
threshold_date = datetime.now() - timedelta(days=opts.days)
|
||||
|
||||
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
|
||||
|
||||
movie = plex.fetchItem(opts.rating_key)
|
||||
|
||||
if movie.originallyAvailableAt >= threshold_date:
|
||||
movie.addCollection(opts.collection)
|
||||
print("Added collection '{}' to '{}'.".format(opts.collection, movie.title.encode('UTF-8')))
|
||||
|
||||
for m in movie.section().search(collection=opts.collection):
|
||||
if m.originallyAvailableAt < threshold_date:
|
||||
m.removeCollection(opts.collection)
|
||||
print("Removed collection '{}' from '{}'.".format(opts.collection, m.title.encode('UTF-8')))
|
BIN
utility/spoilers.png
Normal file
BIN
utility/spoilers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue
Block a user