JBOPS/fun/playlist_manager.py

736 lines
29 KiB
Python
Raw Normal View History

2018-09-26 13:10:40 +00:00
"""
Description: Create and share playlists based on Most Popular TV/Movies from Tautulli
and Aired this day in history.
Author: blacktwin
Requires: requests, plexapi
Create, share, and clean Playlists for users.
optional arguments:
-h, --help show this help message and exit
--jbop Playlist selector.
2018-12-21 14:13:06 +00:00
Choices: (historyToday, historyWeek, historyMonth, popularTv, popularMovies)
--action Action selector.
add - create new playlist for admin or users
remove - remove playlist type or name from admin or users
update - remove playlist type and create new playlist type for admin or users
show - show contents of playlist type or admin or users current playlists
share - share existing playlist by title from admin to users
2018-10-19 06:31:55 +00:00
2018-09-26 13:10:40 +00:00
--users {] The Plex usernames to create/share to or delete from.
Choices: (USERNAMES)
--libraries [ ...] Space separated list of case sensitive names to
process. Allowed names are:
Choices: (LIBRARIES)
--allLibraries Select all libraries.
2018-09-26 13:10:40 +00:00
--self Create playlist for admin.
Default: False
--days DAYS The time range to calculate statistics.
Default: 30
--top TOP The number of top items to list.
Default: 5
--playlists Space separated list of case sensitive names to
2018-10-19 06:31:55 +00:00
process. Allowed names are:
Choices: (PLAYLISTS)
2019-01-03 16:14:32 +00:00
--allPlaylist Select all playlists.
--name NAME Custom name for playlist.
--limit LIMIT Limit the amount items to be added to a playlist.
--filter FILTER Search filtered metadata fields
Filters: (mood unwatched country contentRating collection label director duplicate
studio actor year genre guid resolution decade network).
--search SEARCH Search non-filtered metadata fields for keywords in title, summary, etc.
2018-09-26 13:10:40 +00:00
Example:
Use with cron or task to schedule runs
2018-10-07 13:15:20 +00:00
Create Aired Today Playlist from Movies and TV Shows libraries for admin user
2018-12-21 14:13:06 +00:00
python playlist_manager.py --jbop historyToday --libraries Movies "TV Shows" --action add
2018-09-26 13:10:40 +00:00
Create Aired Today Playlist from Movies and TV Shows libraries and share to users bob, Black Twin and admin user
2018-12-21 14:13:06 +00:00
python playlist_manager.py --jbop historyToday --libraries Movies "TV Shows" --action add --users bob "Black Twin" --self
2018-09-26 13:10:40 +00:00
Update previous Aired Today Playlist(s) from Movies and TV Shows libraries and share to users bob and Black Twin
2018-12-21 14:13:06 +00:00
python playlist_manager.py --jbop historyToday --libraries Movies "TV Shows" --action update --users bob "Black Twin"
2018-09-26 13:10:40 +00:00
Delete all previous Aired Today Playlist(s) from users bob and Black Twin
2018-12-21 14:13:06 +00:00
python playlist_manager.py --jbop historyToday --action remove --users bob "Black Twin"
2018-09-26 13:10:40 +00:00
Create 5 Most Popular TV Shows (30 days) Playlist and share to users bob and Black Twin
python playlist_manager.py --jbop popularTv --action add --users bob "Black Twin"
2018-09-26 13:10:40 +00:00
Create 10 Most Popular Movies (60 days) Playlist and share to users bob and Black Twin
python playlist_manager.py --jbop popularMovies --action add --users bob "Black Twin" --days 60 --top 10
2018-10-19 06:31:55 +00:00
Show 5 Most Popular TV Shows (30 days) Playlist
python playlist_manager.py --jbop popularTv --action show
2018-10-19 06:31:55 +00:00
Show all users current playlists
python playlist_manager.py --action show --allUsers
Share existing admin Playlists "My Custom Playlist" and "Another Playlist" with all users
python playlist_manager.py --action share --allUsers --playlists "My Custom Playlist" "Another Playlist"
2018-10-19 06:31:55 +00:00
Excluding;
--user becomes excluded if --allUsers is set
python playlist_manager.py --action show --allUsers --user USER
- Show all users current Playlists... all users but USER
--libraries becomes excluded if --allLibraries is set
python playlist_manager.py --jbop historyToday --allLibraries --libraries Movies --action add
- Create Aired Today Playlist from every library by Movies for admin user
2018-09-26 13:10:40 +00:00
"""
import sys
2019-02-03 21:58:40 +00:00
import random
2018-09-26 13:10:40 +00:00
import requests
import argparse
import operator
import datetime
import unicodedata
2018-09-26 13:10:40 +00:00
from plexapi.server import PlexServer, CONFIG
### EDIT SETTINGS ###
PLEX_URL = ''
PLEX_TOKEN = ''
TAUTULLI_URL = ''
TAUTULLI_APIKEY = ''
## CODE BELOW ##
if not PLEX_URL:
PLEX_URL = CONFIG.data['auth'].get('server_baseurl')
if not PLEX_TOKEN:
PLEX_TOKEN = CONFIG.data['auth'].get('server_token')
if not TAUTULLI_URL:
TAUTULLI_URL = CONFIG.data['auth'].get('tautulli_baseurl')
if not TAUTULLI_APIKEY:
TAUTULLI_APIKEY = CONFIG.data['auth'].get('tautulli_apikey')
# Defaults
DAYS = 30
TOP = 5
sess = requests.Session()
# Ignore verifying the SSL certificate
sess.verify = False # '/path/to/certfile'
# If verify is set to a path to a directory,
# the directory must have been processed using the c_rehash utility supplied
# with OpenSSL.
if sess.verify is False:
# Disable the warning that the request is insecure, we know that...
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
account = plex.myPlexAccount()
user_lst = [x.title for x in plex.myPlexAccount().users() if x.servers]
sections = plex.library.sections()
sections_dict = {x.key: x.title for x in sections}
filter_lst = list(set([y for x in sections if x.type != 'photo' for y in x.ALLOWED_FILTERS]))
playlist_lst = [x.title for x in plex.playlists()]
2018-09-26 13:10:40 +00:00
today = datetime.datetime.now().date()
weeknum = datetime.date(today.year, today.month, today.day).isocalendar()[1]
2018-09-26 13:10:40 +00:00
def actions():
"""
add - create new playlist for admin or users
remove - remove playlist type or name from admin or users
update - remove playlist type and create new playlist type for admin or users
show - show contents of playlist type or admin or users current playlists
share - share existing playlist by title from admin to users
"""
return ['add', 'remove', 'update', 'show', 'share']
def selectors():
"""Predefined Playlist selections and titles
"""
selections = {'historyToday':'Aired Today {month}-{day} in History',
'historyWeek': 'Aired This Week ({week}) in History',
'historyMonth': 'Aired in {month}',
2018-11-23 20:45:21 +00:00
'popularTv': 'Most Popular TV Shows ({days} days)',
'popularMovies': 'Most Popular Movies ({days} days)',
2019-01-01 04:38:30 +00:00
'custom':'{custom} Playlist',
2019-02-03 21:58:40 +00:00
'random': '{count} Random {libraries} Playlist'
}
return selections
2019-01-04 18:09:43 +00:00
def exclusions(all_true, select, all_items):
2019-01-04 18:49:05 +00:00
"""
Parameters
----------
all_true: bool
All of something (allLibraries, allPlaylists, allUsers)
select: list
List from arguments (user, playlists, libraries)
all_items: list or dict
List or Dictionary of all possible somethings
Returns
-------
2019-01-05 06:05:30 +00:00
output: list or dict
2019-01-04 18:49:05 +00:00
List of what was included/excluded
"""
2019-01-04 18:09:43 +00:00
output = ''
if isinstance(all_items, list):
output = []
if all_true and not select:
output = all_items
elif not all_true and select:
output = select
elif all_true and select:
for x in select:
all_items.remove(x)
output = all_items
2019-01-05 06:05:30 +00:00
2019-01-04 18:09:43 +00:00
elif isinstance(all_items, dict):
output = {}
if all_true and not select:
output = all_items
elif not all_true and select:
for key, value in all_items.items():
if value in select:
output[key] = value
elif all_true and select:
for key, value in all_items.items():
if value not in select:
output[key] = value
return output
2018-09-26 13:10:40 +00:00
def get_home_stats(time_range, stats_count):
# Get the homepage watch statistics.
payload = {'apikey': TAUTULLI_APIKEY,
'cmd': 'get_home_stats',
'time_range': time_range,
'stats_count': stats_count,
'stats_type': 0} # stats_type = plays
try:
r = requests.get(TAUTULLI_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']
return res_data
except Exception as e:
sys.stderr.write("Tautulli API 'get_home_stats' request failed: {0}.".format(e))
def sort_by_dates(video, date_type):
"""Find air dates of content
2018-09-26 13:10:40 +00:00
Parameters
----------
video
video object to find air date
Returns
-------
list
list of rating key and date aired
"""
try:
ad_year = video.originallyAvailableAt.year
ad_month = video.originallyAvailableAt.month
ad_day = video.originallyAvailableAt.day
ad_week = int(datetime.date(ad_year, ad_month, ad_day).isocalendar()[1])
if date_type == 'historyToday':
if ad_month == today.month and ad_day == today.day:
return [[video.ratingKey] + [str(video.originallyAvailableAt)]]
if date_type == 'historyWeek':
if ad_week == weeknum:
return [[video.ratingKey] + [str(video.originallyAvailableAt)]]
if date_type == 'historyMonth':
if ad_month == today.month:
return [[video.ratingKey] + [str(video.originallyAvailableAt)]]
# todo-me return object
2018-09-26 13:10:40 +00:00
except Exception as e:
# print(e)
return
2019-02-03 21:58:40 +00:00
def get_content(libraries, jbop, filters=None, search=None, limit=None):
2018-09-26 13:10:40 +00:00
"""Get all movies or episodes from LIBRARY_NAME
Parameters
----------
libraries: dict
dict of libraries key and name
jbop: str
jbop value for searching
2018-09-26 13:10:40 +00:00
Returns
-------
list
Sorted list of Movie and episodes that
aired on today's date.
"""
child_lst = []
2019-01-01 04:38:30 +00:00
filter_lst = []
search_lst = []
2019-01-01 07:46:48 +00:00
keyword = ''
2019-01-01 04:38:30 +00:00
if search or filters:
if search:
# todo-me replace with documentation showing the available search operators
keyword = {key + '__icontains': value for key, value in search.items()}
2019-01-01 07:46:48 +00:00
# Loop through each library
for library in libraries.keys():
plex_library = plex.library.sectionByID(library)
2019-01-01 07:46:48 +00:00
library_type = plex_library.type
# Find media type, if show then search/filter episodes
if library_type == 'movie':
# Decisions to stack filter and search
if keyword:
search_lst = [movie.ratingKey for movie in plex_library.all(**keyword)]
child_lst += search_lst
2019-01-01 07:46:48 +00:00
if filters:
filter_lst = [movie.ratingKey for movie in plex_library.search(**filters)]
child_lst += filter_lst
2019-01-01 07:46:48 +00:00
if keyword and filters:
child_lst += list(set(filter_lst) & set(search_lst))
2019-01-01 07:46:48 +00:00
elif library_type == 'show':
2019-02-03 21:58:40 +00:00
# Decisions to stack filter and search
2019-01-01 07:46:48 +00:00
if keyword:
for show in plex_library.all():
for episode in show.episodes(**keyword):
search_lst += [episode.ratingKey]
child_lst += search_lst
2019-01-01 07:46:48 +00:00
if filters:
for show in plex_library.search(**filters):
for episode in show.episodes():
filter_lst += [episode.ratingKey]
child_lst += filter_lst
2019-01-01 07:46:48 +00:00
if keyword and filters:
child_lst += list(set(filter_lst) & set(search_lst))
2019-01-01 07:46:48 +00:00
else:
pass
2019-01-01 04:38:30 +00:00
play_lst = child_lst
2019-02-03 21:58:40 +00:00
else:
for library in libraries.keys():
2019-02-03 21:58:40 +00:00
plex_library = plex.library.sectionByID(library)
library_type = plex_library.type
if jbop == 'random' and library_type == 'movie':
child_lst += [movie.ratingKey for movie in random.sample((plex_library.all()), limit)]
elif jbop == 'random' and library_type == 'show':
all_eps = [eps for show in plex_library.all() for eps in show.episodes()]
child_lst += [show.ratingKey for show in random.sample((all_eps), limit)]
else:
for child in plex_library.all():
if child.type == 'movie':
if sort_by_dates(child, jbop):
item_date = sort_by_dates(child, jbop)
child_lst += item_date
2019-02-03 21:58:40 +00:00
elif child.type == 'show':
for episode in child.episodes():
if sort_by_dates(episode, jbop):
item_date = sort_by_dates(episode, jbop)
child_lst += item_date
else:
pass
# check if sort_by_dates was used
if isinstance(child_lst[0], list):
# Sort by original air date, oldest first
# todo-me move sorting and add more sorting options
aired_lst = sorted(child_lst, key=operator.itemgetter(1))
# Remove date used for sorting
play_lst = [x[0] for x in aired_lst]
else:
play_lst = child_lst
2018-09-26 13:10:40 +00:00
return play_lst
2019-02-03 21:58:40 +00:00
def build_playlist(jbop, libraries=None, days=None, top=None, filters=None, search=None, limit=None):
"""
Parameters
----------
jbop: str
The predefined Playlist type
libraries: dict
{key: name}
Libraries to use to build Playlist
days: int
Days to search for Top Movies/Tv Shows
top: int
Limit to search for Top Movies/Tv Shows
Returns
-------
key_list, title
"""
keys_list = []
title = ''
if jbop == 'historyToday':
try:
2019-01-01 04:38:30 +00:00
keys_list = get_content(libraries, jbop, filters, search)
except TypeError as e:
print("Libraries are not defined for {}. Use --libraries.".format(jbop))
exit("Error: {}".format(e))
title = selectors()['historyToday'].format(month=today.month, day=today.day)
elif jbop == 'historyWeek':
try:
2019-01-01 04:38:30 +00:00
keys_list = get_content(libraries, jbop, filters, search)
except TypeError as e:
print("Libraries are not defined for {}. Use --libraries.".format(jbop))
exit("Error: {}".format(e))
title = selectors()['historyWeek'].format(week=weeknum)
elif jbop == 'historyMonth':
try:
2019-01-01 04:38:30 +00:00
keys_list = get_content(libraries, jbop, filters, search)
except TypeError as e:
print("Libraries are not defined for {}. Use --libraries.".format(jbop))
exit("Error: {}".format(e))
title = selectors()['historyMonth'].format(month=today.strftime("%B"))
2019-01-01 04:38:30 +00:00
elif jbop == 'custom':
try:
2019-01-01 04:38:30 +00:00
keys_list = get_content(libraries, jbop, filters, search)
except TypeError as e:
print("Libraries are not defined for {}. Use --libraries.".format(jbop))
exit("Error: {}".format(e))
2019-01-01 04:38:30 +00:00
if search and not filters:
title = ' '.join(search.values()).capitalize()
elif filters and not search:
title = ' '.join(filters.values()).capitalize()
elif search and filters:
search_title = ' '.join(search.values()).capitalize()
filters_title = ' '.join(filters.values()).capitalize()
title = filters_title + ' ' + search_title
title = selectors()['custom'].format(custom=title)
2019-02-03 21:58:40 +00:00
elif jbop == 'random':
try:
keys_list = get_content(libraries, jbop, filters, search, limit)
except TypeError as e:
print("Libraries are not defined for {}. Use --libraries.".format(jbop))
exit("Error: {}".format(e))
title = selectors()['random'].format(count=limit, libraries='/'.join(libraries.values()))
elif jbop == 'popularTv':
home_stats = get_home_stats(days, top)
for stat in home_stats:
if stat['stat_id'] == 'popular_tv':
if libraries:
keys_list = [x['rating_key'] for x in stat['rows'] if
str(x['section_id']) in libraries.keys()]
else:
keys_list = [x['rating_key'] for x in stat['rows']]
title = selectors()['popularTv'].format(days=days)
elif jbop == 'popularMovies':
home_stats = get_home_stats(days, top)
for stat in home_stats:
if stat['stat_id'] == 'popular_movies':
if libraries:
keys_list = [x['rating_key'] for x in stat['rows']
if str(x['section_id']) in libraries.keys()]
else:
keys_list = [x['rating_key'] for x in stat['rows']]
title = selectors()['popularMovies'].format(days=days)
return keys_list, title
def share_playlists(playlist_titles, users):
"""
Parameters
----------
2019-01-05 06:05:30 +00:00
playlist_titles: list
list of playlist titles
users: list
list of user names
"""
for user in users:
for title in playlist_titles:
print("...Shared {title} playlist to '{user}'.".format(title=title, user=user))
plex.playlist(title).copyToUser(user)
exit()
def show_playlist(playlist_title, playlist_keys):
"""
Parameters
----------
2019-01-05 06:05:30 +00:00
playlist_title: str
playlist's title
playlist_keys: list
list of rating keys for playlist
"""
playlist_list = []
for key in playlist_keys:
# todo-me add try to catch when Tautulli reports a rating key that is now missing from Plex
plex_obj = plex.fetchItem(key)
if plex_obj.type == 'show':
for episode in plex_obj.episodes():
2019-01-01 07:46:48 +00:00
title = u"{}".format(episode._prettyfilename())
title = unicodedata.normalize('NFKD', title).encode('ascii', 'ignore').translate(None, "'")
playlist_list.append(title)
else:
title = u"{} ({})".format(plex_obj._prettyfilename(), plex_obj.year)
title = unicodedata.normalize('NFKD', title).encode('ascii', 'ignore').translate(None, "'")
playlist_list.append(title)
print(u"Contents of Playlist {title}:\n{playlist}".format(title=playlist_title,
playlist=', '.join(playlist_list)))
exit()
2018-09-26 13:10:40 +00:00
def create_playlist(playlist_title, playlist_keys, server, user):
"""
Parameters
----------
2019-01-05 06:05:30 +00:00
playlist_title: str
playlist title
playlist_keys: list
list of rating keys for playlist
server: class
server instance
user: str
users name
2018-09-26 13:10:40 +00:00
"""
playlist_list = []
for key in playlist_keys:
try:
plex_obj = server.fetchItem(key)
if plex_obj.type == 'show':
for episode in plex_obj.episodes():
playlist_list.append(episode)
else:
playlist_list.append(plex_obj)
except Exception as e:
try:
obj = plex.fetchItem(key)
print("{} may not have permission to this title: {}".format(user, obj.title))
# print("Error: {}".format(e))
pass
except Exception as e:
print('Rating Key: {}, may have been deleted or moved.'.format(key))
# print("Error: {}".format(e))
2018-09-26 13:10:40 +00:00
if playlist_list:
server.createPlaylist(playlist_title, playlist_list)
2019-01-04 18:44:11 +00:00
print("...Added Playlist: {title} to '{user}'.".format(title=playlist_title, user=user))
2018-09-26 13:10:40 +00:00
2019-01-03 16:14:32 +00:00
def delete_playlist(playlist_dict, jbop):
2018-09-26 13:10:40 +00:00
"""
Parameters
----------
playlist_dict
2018-09-26 13:10:40 +00:00
"""
server = playlist_dict['server']
user = playlist_dict['user']
pop_movie = playlist_dict['pop_movie']
pop_tv = playlist_dict['pop_tv']
user_selected = playlist_dict['user_selected']
2018-09-26 13:10:40 +00:00
try:
# todo-me this needs improvement
2018-09-26 13:10:40 +00:00
for playlist in server.playlists():
if jbop == 'historyToday':
2018-09-26 13:10:40 +00:00
if playlist.title.startswith('Aired Today'):
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
2018-09-26 13:10:40 +00:00
.format(playlist=playlist, user=user))
elif jbop == 'historyWeek':
if playlist.title.startswith('Aired This Week'):
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
.format(playlist=playlist, user=user))
elif jbop == 'historyMonth':
if playlist.title.startswith('Aired in'):
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
.format(playlist=playlist, user=user))
elif jbop == 'popularMovies':
if playlist.title == pop_movie:
2018-09-26 13:10:40 +00:00
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
2018-09-26 13:10:40 +00:00
.format(playlist=playlist, user=user))
elif jbop == 'popularTv':
if playlist.title == pop_tv:
2018-09-26 13:10:40 +00:00
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
2018-09-26 13:10:40 +00:00
.format(playlist=playlist, user=user))
elif playlist.title in user_selected:
playlist.delete()
print("...Deleted Playlist: {playlist.title} for '{user}'."
.format(playlist=playlist, user=user))
2018-09-26 13:10:40 +00:00
except:
# print("Playlist not found on '{user}' account".format(user=user))
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Create, share, and clean Playlists for users.",
formatter_class = argparse.RawTextHelpFormatter)
# todo-me use parser grouping instead of choices for action and jbop?
parser.add_argument('--jbop', choices=selectors().keys(), metavar='',
2018-09-26 13:10:40 +00:00
help='Playlist selector.\n'
'Choices: (%(choices)s)')
parser.add_argument('--action', required=True, choices=actions(),
help='Action selector.'
'{}'.format(actions.__doc__))
parser.add_argument('--user', nargs='+', choices=user_lst, metavar='',
2018-12-21 05:14:11 +00:00
help='The Plex usernames to create/share to or delete from. Allowed names are:\n'
2018-09-26 13:10:40 +00:00
'Choices: %(choices)s')
2018-10-19 03:57:42 +00:00
parser.add_argument('--allUsers', default=False, action='store_true',
help='Select all users.')
parser.add_argument('--libraries', nargs='+', choices=sections_dict.values(), metavar='',
2018-12-21 05:14:11 +00:00
help='Space separated list of case sensitive names to process. Allowed names are:\n'
2018-09-26 13:10:40 +00:00
'Choices: %(choices)s')
parser.add_argument('--allLibraries', default=False, action='store_true',
help='Select all libraries.')
2018-09-26 13:10:40 +00:00
parser.add_argument('--self', default=False, action='store_true',
2018-12-21 05:14:11 +00:00
help='Create playlist for admin.\n'
2018-09-26 13:10:40 +00:00
'Default: %(default)s')
parser.add_argument('--days', type=str, default=DAYS,
2018-12-21 05:14:11 +00:00
help='The time range to calculate statistics.\n'
2018-09-26 13:10:40 +00:00
'Default: %(default)s')
parser.add_argument('--top', type=str, default=TOP,
2018-12-21 05:14:11 +00:00
help='The number of top items to list.\n'
2018-09-26 13:10:40 +00:00
'Default: %(default)s')
parser.add_argument('--playlists', nargs='+', metavar='',
help='Enter Playlist name to be managed.')
2019-01-03 16:14:32 +00:00
parser.add_argument('--allPlaylists', default=False, action='store_true',
help='Select all playlists.')
parser.add_argument('--name', type=str,
help='Custom name for playlist.')
parser.add_argument('--limit', type=int, default=False,
help='Limit the amount items to be added to a playlist.')
parser.add_argument('--filter', action='append', type=lambda kv: kv.split("="),
2018-12-23 07:03:01 +00:00
help='Search filtered metadata fields.\n'
'Filters: ({}).'.format(', '.join(filter_lst)))
parser.add_argument('--search', type=lambda kv: kv.split("="),
help='Search non-filtered metadata fields for keywords '
'in title, summary, etc.')
2018-09-26 13:10:40 +00:00
opts = parser.parse_args()
2019-01-01 04:38:30 +00:00
title = ''
2018-12-21 21:24:32 +00:00
search = ''
2019-01-01 04:38:30 +00:00
filters = ''
2019-01-03 16:14:32 +00:00
playlists = []
2019-01-01 04:38:30 +00:00
keys_list = []
pop_movie_title = selectors()['popularMovies'].format(days=opts.days)
pop_tv_title = selectors()['popularTv'].format(days=opts.days)
2019-01-03 16:14:32 +00:00
playlist_dict = {'pop_tv': pop_tv_title,
'pop_movie': pop_movie_title,
'data': []}
if opts.search:
2019-01-01 04:38:30 +00:00
search = dict([opts.search])
if opts.filter:
filters = dict(opts.filter)
# Check if provided filter exist, exit if it doesn't exist
if not (set(filters.keys()) & set(filter_lst)):
print('({}) was not found in filters list: [{}]'
.format(' '.join(filters.keys()), ', '.join(filter_lst)))
exit()
2018-10-19 03:57:42 +00:00
# Defining users
2019-01-04 18:09:43 +00:00
users = exclusions(opts.allUsers, opts.user, user_lst)
# Defining libraries
2019-01-04 18:09:43 +00:00
libraries = exclusions(opts.allLibraries, opts.libraries, sections_dict)
2018-12-21 05:14:11 +00:00
# Defining selected playlists
selected_playlists = exclusions(opts.allPlaylists, opts.playlists, playlist_lst)
2019-01-03 16:14:32 +00:00
2018-12-21 05:14:11 +00:00
# Create user server objects
2018-10-19 03:57:42 +00:00
if users:
for user in users:
2019-02-02 14:23:54 +00:00
# todo-me smart playlists will have to recreated in users server instance
if opts.action == 'share' and selected_playlists:
print("Sharing playlist(s)...")
share_playlists(selected_playlists, users)
2018-09-26 13:10:40 +00:00
user_acct = account.user(user)
user_server = PlexServer(PLEX_URL, user_acct.get_token(plex.machineIdentifier))
all_playlists = [pl.title for pl in user_server.playlists()]
user_selected = exclusions(opts.allPlaylists, opts.playlists, all_playlists)
playlist_dict['data'].append({
'server': user_server,
'user': user,
'user_selected': user_selected,
'all_playlists': all_playlists})
if opts.self or not users:
playlist_dict['data'].append({'server': plex,
2019-01-04 18:30:07 +00:00
'user': 'admin',
'user_selected': selected_playlists,
'all_playlists': playlist_lst})
if not opts.jbop and opts.action == 'show':
2019-01-05 06:07:01 +00:00
print("Displaying the user's playlist(s)...")
2019-02-02 14:23:54 +00:00
for data in playlist_dict['data']:
user = data['user']
playlists = data['all_playlists']
2019-01-05 06:07:01 +00:00
print("{}'s current playlist(s): {}".format(user, ', '.join(playlists)))
exit()
2019-01-03 16:14:32 +00:00
# Remove or build playlists
2018-09-26 13:10:40 +00:00
if opts.action == 'remove':
print("Deleting the playlist(s)...")
2019-02-02 14:23:54 +00:00
for data in playlist_dict['data']:
delete_playlist(data, opts.jbop)
2018-09-26 13:10:40 +00:00
else:
if libraries:
2019-02-03 21:58:40 +00:00
keys_list, title = build_playlist(opts.jbop, libraries, opts.days, opts.top, filters, search, opts.limit)
else:
print('This function requires libraries to be listed.')
exit()
# Check if limit exist and if it's greater than the pulled list of rating keys
if opts.limit and len(keys_list) > int(opts.limit):
2019-02-03 21:58:40 +00:00
if opts.jbop == 'random':
keys_list = random.sample((keys_list), opts.limit)
else:
keys_list = keys_list[:opts.limit]
2019-01-03 16:14:32 +00:00
# Setting custom name if provided
if opts.name:
title = opts.name
if opts.jbop and opts.action == 'show':
show_playlist(title, keys_list)
2018-09-26 13:10:40 +00:00
if opts.action == 'update':
print("Deleting the playlist(s)...")
for data in playlist_dict['data']:
delete_playlist(data, opts.jbop)
2018-09-26 13:10:40 +00:00
print('Creating playlist(s)...')
for data in playlist_dict['data']:
create_playlist(title, keys_list, data['server'], data['user'])
2018-09-26 13:10:40 +00:00
if opts.action == 'add':
print('Creating playlist(s)...')
for data in playlist_dict['data']:
create_playlist(title, keys_list, data['server'], data['user'])
2018-09-26 13:10:40 +00:00
print("Done.")