def main(): """Main script""" plex = PlexServer(PLEX_URL, PLEX_TOKEN) plex_users = get_user_tokens(plex.machineIdentifier) plex_playlists = {playlist.title: playlist.items() for playlist in plex.playlists()} for playlist in PLAYLISTS: playlist_items = plex_playlists.get(playlist) if not playlist_items: print("Playlist '{playlist}' not found on the server. Skipping.".format(playlist=playlist)) continue print("Cloning the '{title}' playlist...".format(title=playlist)) for user in USERS: user_token = plex_users.get(user) if not user_token: print("...User '{user}' not found in shared users. Skipping.".format(user=user)) continue user_plex = PlexServer(PLEX_URL, user_token) # Delete the old playlist try: user_playlist = user_plex.playlist(playlist) user_playlist.delete() except: pass # Create a new playlist user_plex.createPlaylist(playlist, playlist_items) print("...Created playlist for '{user}'.".format(user=user)) return
def sync_all(): global user_plex plex = PlexServer(PLEX_URL, PLEX_TOKEN) plex_users = get_user_tokens(plex.machineIdentifier) user_token = plex_users.get(FROM_USER) playlists_to_sync = get_playlists_from_user(user_token) for playlist in playlists_to_sync: playlist_items = playlist.items() for user in TO_USERS: user_token = plex_users.get(user) user_plex = PlexServer(PLEX_URL, user_token) # Delete the old playlist try: logging.info( f'Syncing Playlist {playlist.title} to user {user}') user_playlist = user_plex.playlist(playlist.title) user_playlist.delete() except Exception as e: logging.error(e) try: user_plex.createPlaylist(title=playlist.title, items=playlist_items) except Exception as e: logging.error(e)
def main(): database = r"/var/www/html/databases/grindhouse.db" grindhouseId = str(sys.argv[1]) # create a database connection conn = create_connection(database) with conn: #print("1. Query task by priority:") baseurl = get_setting(conn, 'plex-url') token = get_setting(conn, 'plex-api-token') grindhouse = get_grindhouse(conn, grindhouseId) grindhouse_title = grindhouse[0] grindhouse_command = grindhouse[1] grindhouse_command_version = grindhouse[2] plex = PlexServer(baseurl, token) command = json.loads(grindhouse_command) total_videos = [] for entry in command: if type(entry['data']) is dict: # dict is anything but a trailer #pprint(entry) plex_video = plex.library.sectionByID(entry['data']['libraryId']).get(entry['data']['title']) total_videos.append(plex_video) if type(entry['data']) is list: # trailers for trailer in entry['data']: #pprint(trailer) plex_video = plex.library.sectionByID(trailer['libraryId']).get(trailer['title']) total_videos.append(plex_video) plex.createPlaylist(grindhouse_title, total_videos) response = {'status':"ok", 'data': {}} print json.dumps(response)
def createPlaylist(plex: PlexServer, sp: spotipy.Spotify, playlist: []): playlistName = playlist['owner']['display_name'] + " - " + playlist['name'] logging.info('Starting playlist %s' % playlistName) plexTracks = getPlexTracks(plex, getSpotifyTracks(sp, playlist)) if len(plexTracks) > 0: try: plexPlaylist = plex.playlist(playlistName) logging.info('Updating playlist %s' % playlistName) plexPlaylist.addItems(plexTracks) except: logging.info("Creating playlist %s" % playlistName) plex.createPlaylist(playlistName, plexTracks)
def main(): """Main script""" global PLAYLISTS plex_server = PlexServer(PLEX_URL, PLEX_TOKEN) plex_users = get_user_tokens(plex_server.machineIdentifier) plex_users[plex_server.myPlexUsername] = plex_server._token plex_user = PlexServer(PLEX_URL, plex_users[FROM_USER]) plex_playlists = { playlist.title: playlist.items() for playlist in plex_user.playlists() } if not PLAYLISTS: PLAYLISTS = plex_playlists # Default to all playlists for playlist in PLAYLISTS: if playlist in SKIP_PLAYLISTS: print("Skipping '{playlist}'...".format(playlist=playlist)) continue playlist_items = plex_playlists.get(playlist) if not playlist_items: print("Playlist '{playlist}' not found on the server. Skipping.". format(playlist=playlist)) continue print("Cloning the '{title}' playlist...".format(title=playlist)) for user in TO_USERS: user_token = plex_users.get(user) if not user_token: print("...User '{user}' not found in shared users. Skipping.". format(user=user)) continue user_plex = PlexServer(PLEX_URL, user_token) # Delete the old playlist try: user_playlist = user_plex.playlist(playlist) user_playlist.delete() except: pass # Create a new playlist user_plex.createPlaylist(playlist, playlist_items) print("...Created playlist for '{user}'.".format(user=user)) return
def change_playlist_content(plex: PlexServer, name: str, tracks: List[Track]) -> Playlist: """ Connects to the PlexServer, and fills the named playlist with the given track list. If the playlist does not yet exist, it will be created. :param plex: the PlexServer object :param name: the name of the playlist to replace the contents of :param tracks: list of Tracks that will be the contents of the playlist :return: the Playlist object """ timer = Stopwatch() timer.start() logger = config.logger if not any([name == pl.title for pl in plex.playlists()]): playlist = plex.createPlaylist(name, tracks) logger.debug(f"Created new playlist {name} in {timer.click():.2f}s") else: playlist = plex.playlist(name) [playlist.removeItem(item) for item in playlist.items()] logger.debug(f"Emptied playlist {name} in {timer.click():.2f}s") playlist.addItems(tracks) logger.debug( f"Added {len(tracks)} track to the playlist {name} in {timer.click():.2f}s" ) return playlist
def main(): """Main script""" num_cores = multiprocessing.cpu_count() l = Library(FILEPATH) playlists = l.getPlaylistNames() PLEX = PlexServer(PLEX_URL, PLEX_TOKEN) PLEX_USERS = get_user_tokens(PLEX.machineIdentifier) PLEX_MUSIC = PLEX.library.section('Music') PLEX_TRACK_LIST = PLEX_MUSIC.searchTracks() PLEX_ARTIST_LIST = PLEX_MUSIC.searchArtists() for playlist in playlists: playlist_items = [] DATA_FILE = playlist + '.pickle' if playlist not in PLAYLISTS: continue # Check if .pickle exists try: print("Loading the '{title}' playlist from disk...".format(title=playlist)) with open(DATA_FILE, 'rb') as fp: playlist_items = pickle.load(fp) fp.close() # HACK playlist_items = [playlist_item for playlist_item in playlist_items if playlist_item] except FileNotFoundError: print("Building the '{title}' playlist...".format(title=playlist)) PLAYLIST_TRACKS = l.getPlaylist(playlist).tracks # Multiprocessing implementation # playlist_items = Parallel(n_jobs=num_cores, prefer='processes')( # delayed(match_track)(PLAYLIST_TRACK, PLEX_MUSIC, PLEX_ARTIST_LIST, PLEX_TRACK_LIST) for PLAYLIST_TRACK in PLAYLIST_TRACKS) # Standard implementation for PLAYLIST_TRACK in PLAYLIST_TRACKS: track_match = match_track(PLAYLIST_TRACK, PLEX_MUSIC, PLEX_ARTIST_LIST, PLEX_TRACK_LIST) if track_match: playlist_items.append(track_match) # Save data (just in case) with open(DATA_FILE, 'wb') as fp: pickle.dump(playlist_items, fp) fp.close() # Create playlist (per user) for user in USERS: user_token = PLEX_USERS.get(user) if not user_token: print("...User '{user}' not found in shared users. Skipping.".format(user=user)) continue user_plex = PlexServer(PLEX_URL, user_token) # Delete the old playlist try: user_playlist = user_plex.playlist(playlist) user_playlist.delete() except: pass # Create a new playlist user_plex.createPlaylist(playlist, playlist_items) print("...Created playlist for '{user}'.".format(user=user)) return
baseurl = 'http://plex.example.com:32400' token = 'abcdefghijklmnopqrstuvwxyz' plex = PlexServer(baseurl, token) playlist_title = 'Treehouse of Horror' for playlist in plex.playlists(): if playlist.title == playlist_title: playlist.delete() print('{} already exists. Deleting. Will rebuild.'.format(playlist_title)) tv_shows = plex.library.section(title='TV Shows') episode_list = [] for show in tv_shows.all(): match = re.search(r'Simpsons', show.title) if match is not None: print('{}:'.format(show.title)) for episode in show.episodes(): match = re.search(r'Treehouse', episode.title) if match is not None: print('\t{}'.format(episode.title)) episode_list += episode print('Adding {} to playlist {}.'.format(len(episode_list), playlist_title)) playlist = plex.createPlaylist(playlist_title, episode_list) playlist.copyToUser('*****@*****.**')
for section in opts.libraries: playlist += build_tracks(plex.library.section(section).all()) elif opts.libraries and opts.artists and not opts.random: for artist in opts.artists: for section in opts.libraries: artist_objects = [x for x in plex.library.section(section).all() if x.title == artist] playlist += build_tracks(artist_objects) elif not opts.libraries and opts.artists and not opts.random: for artist in opts.artists: for section in music_sections: artist_objects = [x for x in plex.library.section(section).all() if x.title == artist] playlist += build_tracks(artist_objects) elif not opts.libraries and not opts.artists and opts.random: rand_artists = random.sample((artist_lst), opts.random) for artist in rand_artists: for section in music_sections: artist_objects = [x for x in plex.library.section(section).all() if x.title == artist] playlist += build_tracks(artist_objects) if opts.tracks and opts.random: playlist = random.sample((playlist), opts.tracks) elif opts.tracks and not opts.random: playlist = playlist[:opts.tracks] # Create Playlist plex.createPlaylist(opts.name, playlist)
# Set starting position to the 2nd item if startItem demo. startItem = libraryItems[1] if args.startitem else None # Print info media_info(libraryItems, libraryItems) start_item_info(libraryItems[1]) elif args.demo == "playqueue": # Convert list into a playqueue for media. media = plex_server.createPlayQueue(libraryItems) # Set starting position to the 3rd item if startItem demo. startItem = libraryItems[2] if args.startitem else None # Print info media_info(media, media.items) start_item_info(libraryItems[2]) elif args.demo == "playlist": # Convert list into a playlist for media. media = plex_server.createPlaylist("pychromecast test playlist", libraryItems) # Set starting position to the 4th item if startItem demo. startItem = libraryItems[3] if args.startitem else None # Print info media_info(media, media.items()) start_item_info(libraryItems[2]) plex_c = PlexController() cast.register_handler(plex_c) cast.wait() # Plays the media item, list, playlist, or playqueue. # If startItem = None it is ignored and playback starts at first item, # otherwise playback starts at the position of the media item given. plex_c.block_until_playing(media, startItem=startItem)
default='', metavar='', help='Exclude playlists') opts = parser.parse_args() excludes = opts.exclude.split(',') items = [] merged_playlist = None for playlist in playlists: if playlist.title == opts.name: merged_playlist = playlist continue if playlist.title in excludes: continue items = items + playlist.items() if merged_playlist is None: merged_playlist = plex.createPlaylist(opts.name, items[:1]) # remove existing items first for playlist_item in merged_playlist.items(): merged_playlist.removeItem(playlist_item) while len(items) > 0: merged_playlist.addItems(items[:100]) items = items[100:]
class PlexInstance: def __init__(self, url: str, token: str, api, server_name: str = None, server_alt_name: str = None, server_number: int = 0, credentials_folder: str = None, tautulli_info=None, ombi_info=None, libraries=None): # Server info self.url = url self.token = token if not url or not token: raise Exception("Must include Plex Media Server url and token") self._api = api self.server = PlexServer(self.url, self.token) self.name = server_name if server_name else self.server.friendlyName self.alt_name = server_alt_name if server_alt_name else self.server.friendlyName self.number = server_number self.id = self.server.machineIdentifier # Auth self.auth_header = {'X-Plex-Token': token} self.cloud_key = None # Crypt self.crypt = None if credentials_folder: self.crypt = Encryption(key_file=f'{credentials_folder}/key.txt', key_folder=credentials_folder) # Libraries self.shows = defaultdict(list) self.movies = defaultdict(list) self.libraries = libraries # Ombi self.use_ombi = False self.ombi = None if ombi_info: self.set_ombi_connection(ombi_info) # Tautulli self.use_tautulli = False self.tautulli = None if tautulli_info: self.set_tautulli_connection(tautulli_info) def set_tautulli_connection(self, tautulli_info): self.use_tautulli = tautulli_info.get('enable', False) if self.use_tautulli: self.tautulli = TautulliConnector(url=tautulli_info.get('url'), api_key=tautulli_info.get('api_key')) def set_ombi_connection(self, ombi_info): self.use_ombi = ombi_info.get('enable', False) if self.use_ombi: self.ombi = OmbiConnector(url=ombi_info.get('url'), api_key=ombi_info.get('api_key')) def get_user_creds(self, user_id) -> dict: if self.crypt: creds_dict = {'username': None, 'password': None} if self.crypt.exists(f"{user_id}.json"): creds = self.crypt.decrypt_file(f'{self.crypt.key_folder}/{user_id}.json').splitlines() creds_dict = {'username': creds[0], 'password': creds[1]} return creds_dict return {} def ping(self) -> bool: response = requests.get(f"{self.url}/identity", timeout=10) if response: return True return False def save_user_creds(self, user_id, username, password) -> bool: if self.crypt: text = '{}\n{}'.format(username, password) return self.crypt.encrypt_file(text=text, filename=f'{self.crypt.key_folder}/{user_id}.json') return False def get_media_item(self, title: str, rating_key=None, library_id=None): library = self.server.library if library_id: library = library.sectionByID(str(library_id)) results = library.search(title=title) if results: if rating_key: # find exact match for item in results: if item.ratingKey == rating_key: return item return results[0] # assume first result is correct return None def get_watch_now_link(self, rating_key: str) -> str: return f"https://app.plex.tv/desktop#!/server/{self.id}//details?key=%2Flibrary%2Fmetadata%2F{rating_key}" def get_media_info(self, rating_key) -> Tuple[str, str]: r = requests.get(f'{self.url}/library/metadata/{rating_key}?X-Plex-Token={self.token}').content tree = ET.fromstring(r) return tree.get('librarySectionID'), tree[0].get('title') def get_rating_key(self, url = None) -> str: if not url: url = self.url return str(re.search('metadata%2F(\d*)', url).group(1)) def find_url(self, text) -> str: pattern = '{}\S*'.format(self.url.replace('.', '\.')) return str(re.search(pattern, text).group(0)) def get_playlist(self, playlist_name): for playlist in self.server.playlists(): if playlist.title == playlist_name: return playlist return None def add_to_playlist(self, playlist_title, rating_key, item_to_add) -> str: playlist = self.get_playlist(playlist_name=playlist_title) if playlist: for item in playlist.items(): if str(item.ratingKey) == str(rating_key): return "That item is already on your {}list".format( 'play' if item_to_add.type in ['artist', 'track', 'album'] else 'watch') playlist.addItems([item_to_add]) return "Item added to your {}list".format( 'play' if item_to_add.type in ['artist', 'track', 'album'] else 'watch') else: self.server.createPlaylist(title=playlist_title, items=[item_to_add]) return "New {}list created and item added.".format( 'play' if item_to_add.type in ['artist', 'track', 'album'] else 'watch') def url_in_message(self, message) -> Union[str, None]: server_id = self.server.machineIdentifier if server_id in message.content and 'metadata%2F' in message.content: return self.find_url(text=message.content) if message.embeds: for embed in message.embeds: if server_id in embed.title and 'metadata%2F' in embed.title: return self.find_url(text=embed.title) elif server_id in embed.description and 'metadata%2F' in embed.description: return self.find_url(embed.description) elif server_id in embed.description and 'metadata%2F' in embed.url: return self.find_url(embed.url) return None return None @property def sub_count(self) -> int: count = 0 for user in self.server.myPlexAccount().users(): for server in user.servers: if server.name in [self.name, self.alt_name]: count += 1 break return count @property def users(self) -> List[MyPlexUser]: try: return self.server.myPlexAccount().users() except Exception as e: print(f"Error in getServerUsers: {e}") return [] def get_user(self, username) -> Union[MyPlexUser, None]: try: return self.server.myPlexAccount().user(username=username) except Exception as e: print(f"Error in getServerUser: {e}") return None @property def plex_friends(self) -> List[MyPlexUser]: """ # Returns all Plex Friends (access in + access out) """ friends = [] for user in self.users: if user.friend: friends.append(user) return friends def user_has_access(self, plex_username: str) -> bool: for user in self.users: if user.username == plex_username: return True return False def add_user(self, plex_username: str) -> utils.StatusResponse: try: self.server.myPlexAccount().inviteFriend(user=plex_username, server=self.server, sections=None, allowSync=False, allowCameraUpload=False, allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None) return utils.StatusResponse(success=True) except plex_exceptions.NotFound: return utils.StatusResponse(success=False, issue="Invalid Plex username") except Exception as e: return utils.StatusResponse(success=False, issue=e.__str__()) def remove_user(self, plex_username: str) -> utils.StatusResponse: try: self.server.myPlexAccount().removeFriend(user=plex_username) return utils.StatusResponse(success=True) except plex_exceptions.NotFound: return utils.StatusResponse(success=False, issue="Invalid Plex username") except Exception as e: return utils.StatusResponse(success=False, issue=e.__str__()) def refresh_tautulli_users(self) -> bool: if self.use_tautulli: return self.tautulli.refresh_users() return False def delete_user_from_tautulli(self, plex_username) -> bool: if self.use_tautulli: return self.tautulli.delete_user(plex_username=plex_username) return False def refresh_ombi_users(self) -> bool: if self.use_ombi: return self.ombi.refresh_users() return False def delete_user_from_ombi(self, username: str) -> bool: if self.use_ombi: return self.ombi.delete_user(plex_username=username) return False def get_live_tv_dvrs(self): data = self._get(hdr=self.auth_header, endpoint='/livetv/dvrs') if data: if data.get('MediaContainer').get('Dvr'): return [DVR(item) for item in data.get('MediaContainer').get('Dvr')] return None def get_cloud_key(self): if not self.cloud_key: data = self._get(hdr=self.auth_header, endpoint='/tv.plex.providers.epg.cloud') if data: self.cloud_key = data.get('MediaContainer').get('Directory')[1].get('title') else: return None return self.cloud_key def get_live_tv_sessions(self): data = self._get(hdr=self.auth_header, endpoint='/livetv/sessions') if data: if data.get('MediaContainer').get('Metadata'): return [TVSession(item) for item in data.get('MediaContainer').get('Metadata')] return None def get_hubs(self, identifier=None): data = self._get(hdr=self.auth_header, endpoint=f'/{self.get_cloud_key()}/hubs/discover') if data: if identifier: for hub in data['MediaContainer']['Hub']: if hub['title'] == identifier: return Hub(hub) return None return [Hub(hub) for hub in data['MediaContainer']['Hub']] return None def get_dvr_schedule(self): data = self._get(hdr=self.auth_header, endpoint='/media/subscriptions/scheduled') if data: return DVRSchedule(data.get('MediaContainer')) return None def get_dvr_items(self): data = self._get(hdr=self.auth_header, endpoint='/media/subscriptions') if data: return [DVRItem(item) for item in data.get('MediaContainer').get('MediaSubscription')] return None def delete_dvr_item(self, itemID): data = self._delete(hdr=self.auth_header, endpoint='/media/subscription/{}'.format(itemID)) if str(data.status_code).startswith('2'): return True return False def get_homepage_items(self): data = self._get(hdr=self.auth_header, endpoint='/hubs') if data: return [Hub(item) for item in data.get('MediaContainer').get('Hub')] return None def _get(self, hdr, endpoint, data=None): """ Returns JSON """ hdr = {'accept': 'application/json', **hdr} res = requests.get(f'{self.url}{endpoint}', headers=hdr, data=json.dumps(data)).json() return res def _post(self, hdr, endpoint, data=None) -> requests.Response: """ Returns response """ hdr = {'accept': 'application/json', **hdr} res = requests.post(f'{self.url}{endpoint}', headers=hdr, data=json.dumps(data)) return res def _delete(self, hdr, endpoint, data=None) -> requests.Response: """ Returns response """ hdr = {'accept': 'application/json', **hdr} res = requests.delete(f'{self.url}{endpoint}', headers=hdr, data=json.dumps(data)) return res def get_defined_libraries(self): names = [name for name in self.libraries.keys()] ids = [] for _, vs in self.libraries.items(): for v in vs: if v not in ids: ids.append(str(v)) return {'names': names, 'IDs': ids} def get_plex_share(self, share_name_or_number): if not self.libraries: return False if utils.is_positive_int(share_name_or_number): return [int(share_name_or_number)] else: for name, numbers in self.libraries.items(): if name == share_name_or_number: return numbers return False def _get_server_from_user_share(self, plex_user): try: return plex_user.server(self.name) except: return plex_user.server(self.alt_name) def get_user_restrictions(self, plex_username): user = self.get_user(username=plex_username) if user: if user.friend: try: sections = self._get_server_from_user_share(plex_user=user).sections() except: raise Exception("Could not load Plex user sections.") return {'allowSync': user.allowSync, 'filterMovies': user.filterMovies, 'filterShows': user.filterTelevision, 'sections': ([section.title for section in sections] if sections else []) } else: raise Exception(f"Plex user {plex_username} is not a Plex Friend.") else: raise Exception(f"Could not locate Plex user: {plex_username}") def update_user_restrictions(self, plex_username, sections_to_share=[], rating_limit={}, allow_sync: bool = None) -> bool: """ :param plex_username: :param sections_to_share: :param rating_limit: ex. {'Movie': 'PG-13', 'TV': 'TV-14'} :param allow_sync: :return: """ try: sections = [] for section in sections_to_share: section_numbers = self.get_plex_share(share_name_or_number=section) if section_numbers: for number in section_numbers: sections.append(str(number)) allowed_movie_ratings = [] allowed_tv_ratings = [] if rating_limit: # add max rating and all below it to allowed ratings # if non_existent rating is used as limit, all ratings will be added if rating_limit.get('Movie') and rating_limit.get('Movie') in all_movie_ratings: for rating in all_movie_ratings: allowed_movie_ratings.append(rating) if rating == rating_limit.get('Movie'): break if rating_limit.get('TV') and rating_limit.get('TV') in all_tv_ratings: for rating in all_tv_ratings: allowed_tv_ratings.append(rating) if rating == rating_limit.get('TV'): break self.server.myPlexAccount().updateFriend(user=plex_username, server=self.server, sections=(sections if sections else None), removeSections=False, allowSync=allow_sync, allowCameraUpload=None, allowChannels=None, filterMovies=( { 'contentRating': allowed_movie_ratings} if allowed_movie_ratings else None ), filterTelevision=( { 'contentRating': allowed_tv_ratings} if allowed_tv_ratings else None ), filterMusic=None) return True except: print(f"Could not update restrictions for Plex user: {plex_username}") return False
baseurl = input("Type ip and port of your Plex server:") token = input("Type your authentication token (https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/):") plex = PlexServer("http://" + baseurl, token) TVShows = [] Episodes = [] PlayList = [] fileoftvshows = open("Shows.txt", "r") for show in fileoftvshows: found = plex.search(show, mediatype="show") TVShows.append(found[0]) for i in range(len(TVShows)): reversedepisodes = TVShows[i].episodes() reversedepisodes.reverse() Episodes.append(reversedepisodes) while len(Episodes) != 0: show = random.randint(0, len(Episodes)-1) PlayList.append(Episodes[show].pop()) if len(Episodes[show]) == 0: del Episodes[show] nameofplaylist = input("Type name of playlist:") plex.createPlaylist(nameofplaylist, items=PlayList)
def find_air_dates(content_lst): # Find what aired with today's month-day aired_lst = [] for video in content_lst: try: ad_month = str(video.originallyAvailableAt.month) ad_day = str(video.originallyAvailableAt.day) if ad_month == str(today.month) and ad_day == str(today.day): aired_lst += [[video] + [str(video.originallyAvailableAt)]] except Exception as e: # print(e) pass # Sort by original air date, oldest first aired_lst = sorted(aired_lst, key=operator.itemgetter(1)) # Remove date used for sorting play_lst = [x[0] for x in aired_lst] return play_lst remove_old() play_lst = find_air_dates(get_all_content(LIBRARY_NAMES)) # Create Playlist if play_lst: plex.createPlaylist(PLAYLIST_TITLE, play_lst) else: print('Found nothing aired on this day in history.')
pass return child_lst def find_air_dates(content_lst): # Find what aired with today's month-day aired_lst = [] for video in content_lst: try: ad_month = str(video.originallyAvailableAt.month) ad_day = str(video.originallyAvailableAt.day) if ad_month == str(today.month) and ad_day == str(today.day): aired_lst += [[video] + [str(video.originallyAvailableAt)]] except Exception as e: # print(e) pass # Sort by original air date, oldest first aired_lst = sorted(aired_lst, key=operator.itemgetter(1)) # Remove date used for sorting play_lst = [x[0] for x in aired_lst] return play_lst remove_old() play_lst = find_air_dates(get_all_content(LIBRARY_NAMES)) # Create Playlist plex.createPlaylist(TODAY_PLAY_TITLE, play_lst)
class SpotiPlex: def __init__(self, spotifyInfo, plexInfo): self.credManager = SpotifyClientCredentials( client_id=spotifyInfo['clientId'], client_secret=spotifyInfo['clientSecret']) self.user = spotifyInfo['user'] self.sp = spotipy.Spotify(client_credentials_manager=self.credManager) self.plex = PlexServer(plexInfo['url'], plexInfo['token']) def getSpotifyPlaylist(self, plId): 'Generate and return a list of tracks of the Spotify playlist' #playlist = self.sp.user_playlist(self.user, plId) playlist = self.sp.user_playlist_tracks(self.user, playlist_id=plId) tracks = playlist['items'] while playlist['next']: playlist = self.sp.next(playlist) tracks.extend(playlist['items']) items = [] for item in tracks: items.append({ 'title': item['track']['name'], 'album': item['track']['album']['name'], 'artist': item['track']['artists'][0]['name'], 'isrc': item['track']['external_ids']['isrc'] #'number': item['track']['track_number'], #'img': item['track']['album']['images'][0]['url'] }) return items def checkPlexFiles(self, playlist): 'Check if the songs in the playlist are present on the Plex server. Returns list of found and missing items' tracks = [] missing = [] for item in playlist: results = self.plex.search(item['title'], mediatype='track') if not results: missing.append(item) continue for result in results: if type(result) != plexapi.audio.Track: continue else: if result.grandparentTitle.lower() == item['artist'].lower( ): # and result.parentTitle == item['album']: tracks.append(result) break else: if result == results[-1]: missing.append(item) break return tracks, missing def checkForPlexPlaylist(self, name): 'Check if a playlist with this name exists in Plex. Returns the playlist if valid, else None' try: return self.plex.playlist(name) except plexapi.exceptions.NotFound: return None def comparePlaylists(self, sPlaylist, pPlaylist): 'Compares the extracted Spotify playlist with the existing Plex playlist. Returns list of tracks to create the new playlist version from and missing songs in Plex' tracksToAdd = sPlaylist plexTracks = pPlaylist.items() plexOnlyItems = [] temp = [] for track in plexTracks: # remove any tracks from Spotify list that are already in Plex lastLen = len(temp) temp = list( filter(lambda item: not item['title'] == track.title, tracksToAdd)) if not len(temp) == lastLen: tracksToAdd = temp else: plexOnlyItems.append(track) return tracksToAdd, plexOnlyItems def createPlexPlaylist(self, name, playlist=None): 'Create the playlist on the Plex server from given name and a item list' newPlaylist = self.plex.createPlaylist(name, items=playlist) return def addToPlexPlaylist(self, plexPlaylist, newItems): 'Add more items to a Plex playlist' return plexPlaylist.addItems(newItems) def removeFromPlexPlaylist(self, plexPlaylist, itemsToRemove): 'Remove given items from a Plex playlist' ## Seems not to work properly yet for item in itemsToRemove: plexPlaylist.removeItem(item)
if len(keep) > 0: play_lst = [] for x in files_to_add: for file, item in keep: if item.lastViewedAt is None: lastViewed = datetime.strptime("1900-01-01", '%Y-%m-%d') else: lastViewed = item.lastViewedAt try: if lastViewed < datetime.strptime(config.start_date, '%Y-%m-%d'): if file == x: play_lst.append(item) except ValueError: play_lst.append(item) except: pass for playlist in plex.playlists(): if playlist.title == config.playlist_name: try: playlist.delete() except: pass plex.createPlaylist(config.playlist_name, play_lst) else: print("No Videos Found, Playlist Not Created")