Created
January 29, 2020 16:49
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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