Skip to content

Instantly share code, notes, and snippets.

@nwithan8
Created January 29, 2020 16:49
Show Gist options
  • Select an option

  • Save nwithan8/5f8d7be00294d4fc3ec056d57526abd0 to your computer and use it in GitHub Desktop.

Select an option

Save nwithan8/5f8d7be00294d4fc3ec056d57526abd0 to your computer and use it in GitHub Desktop.
Play a random Plex Server media item on a connected device (can specify library, musical artist, or TV series)
#!/usr/bin/python3
# RUN THIS COMMAND TO INSTALL DEPENDENCIES
# pip3 install plexapi argparse
import plexapi
from plexapi.server import PlexServer
import argparse
import sys
import random
import inspect
import time
import os
PLEX_URL = ''
PLEX_TOKEN = ''
PLEX_SERVER_ID = ''
plex = PlexServer(PLEX_URL, PLEX_TOKEN)
plex_sections = {}
plex_devices = {}
library = None
section = None
sectionID = None
show = None
artist = None
""" Handling arguments """
parser = argparse.ArgumentParser()
parser.add_argument('mediatype', choices=['movie','episode','song'], help="Which type of media to play (Required)")
parser.add_argument('-l', "--library", help="Select only from a specific library")
parser.add_argument('-a', "--artist", help="Select only from a specific music artist")
parser.add_argument('-s', "--show", help="Select only from a specific show")
parser.add_argument('device', help="Which device to play the media on (Required)")
args = parser.parse_args()
""" Validating arguments and issuing warnings """
if args.artist:
if args.mediatype != 'song':
print('Non-music library was selected. --artist argument will be ignored.')
else:
if args.library:
print("Artists cannot be filtered down to specific libraries. Any song by '{}' in any music library will be considered when shuffling.".format(args.artist))
artist = args.artist
if args.show:
if args.mediatype.strip() != 'episode':
print('Non-show library was selected. --show argument will be ignored.')
else:
show = args.show
for sec in plex.library.sections():
name = ("song" if sec.type == 'artist' else ("episode" if sec.type == 'show' else sec.type))
if name in plex_sections.keys():
plex_sections[name].append(sec)
else:
plex_sections[name] = [sec]
valid_library = False
if args.library:
for sec in plex_sections[args.mediatype]:
if sec.title == args.library:
valid_library = True
library = {args.mediatype: sec}
break
if not valid_library:
print("{} is not a valid {} library".format(args.library, args.mediatype))
sys.exit(0)
else:
library = {args.mediatype: plex_sections[args.mediatype]}
valid_device = False
for dev in plex.myPlexAccount().devices():
if dev.name == args.device:
device = dev
valid_device = True
break
if not valid_device:
print("{} is not a valid device.".format(args.device))
sys.exit(0)
if show:
valid_show = False
for sec in library.get(args.mediatype):
results = sec.search(show)
if results:
section = sec
sectionID = sec.key
# Use the first section that has the media. Issue may arise if, e.g., lower-quality versions stored in this section versus other sections. Specify library section with --library in that case.
show = results[0]
valid_show = True
break
if not valid_show:
print("{} was not found in the specified library(s)".format(show))
sys.exit(0)
if artist:
valid_artist = False
for sec in library.get(args.mediatype):
results = sec.search(artist)
if results:
section = sec
sectionID = sec.key
# See issue with 'show' above.
artist = results[0]
valid_artist = True
break
if not valid_artist:
print("{} was not found in the specificed library(s)".format(artist))
sys.exit(0)
""" Selecting media """
media = []
if artist: # filter by artist
for track in artist.tracks(): # uses artist in general (not library specific)
if sectionID and track.librarySectionID != sectionID:
pass
else:
media.append(track)
elif show: # filter by show
for episode in section.get(show.title).episodes(): # uses defined section
media.append(episode)
else: # filter by library ('all libraries' also handled here)
for name in library.keys():
for sec in library[name]: # uses defined section (or all sections if not specified)
for item in sec.search():
media.append(item)
if args.mediatype == 'episode' and not show:
selected = random.choice(random.choice(media).episodes()) # random episode of random show
elif args.mediatype == 'song' and not artist:
selected = random.choice(random.choice(media).tracks()) # random track of random artist
else:
selected = random.choice(media)
""" Playing media """
print('{title}: {base}/web/index.html#!/server/{id}/details?key=%2Flibrary%2Fmetadata%2F{key}'.format(title=(selected.title if args.mediatype == 'movie' else (selected.grandparentTitle + " - " + selected.title)), base=PLEX_URL, id=PLEX_SERVER_ID, key=selected.ratingKey))
try:
client = device.connect()
client.playMedia(selected)
except Exception as e:
print("{} is not available.".format(device.name ))
""" Exit when done """
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment