137 lines
5.2 KiB
Python
137 lines
5.2 KiB
Python
#!/usr/bin/env python
|
|
'''
|
|
Build playlist from popular tracks.
|
|
|
|
optional arguments:
|
|
-h, --help show this help message and exit
|
|
--name [] Name your playlist
|
|
--libraries [ ...] Space separated list of case sensitive names to process. Allowed names are:
|
|
(choices: ALL MUSIC LIBRARIES)*
|
|
--artists [ ...] Space separated list of case sensitive names to process. Allowed names are:
|
|
(choices: ALL ARTIST NAMES)
|
|
--tracks [] Specify the track length you would like the playlist.
|
|
--random [] Randomly select N artists.
|
|
|
|
* LIBRARY_EXCLUDE are excluded from libraries choice.
|
|
|
|
'''
|
|
|
|
|
|
import requests
|
|
from plexapi.server import PlexServer, CONFIG
|
|
import argparse
|
|
import random
|
|
|
|
# Edit
|
|
PLEX_URL = ''
|
|
PLEX_TOKEN = ''
|
|
PLEX_URL = CONFIG.data['auth'].get('server_baseurl', PLEX_URL)
|
|
PLEX_TOKEN = CONFIG.data['auth'].get('server_token', PLEX_TOKEN)
|
|
|
|
LIBRARY_EXCLUDE = ['Audio Books', 'Podcasts', 'Soundtracks']
|
|
DEFAULT_NAME = 'Popular Music Playlist'
|
|
|
|
# /Edit
|
|
|
|
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)
|
|
|
|
music_sections = [x.title for x in plex.library.sections() if x.type == 'artist' and x.title not in LIBRARY_EXCLUDE]
|
|
|
|
artist_lst = []
|
|
for section in music_sections:
|
|
artist_lst += [x.title.encode('utf-8') for x in plex.library.section(section).all() if section not in LIBRARY_EXCLUDE]
|
|
|
|
|
|
def fetch(path):
|
|
url = PLEX_URL
|
|
|
|
header = {'Accept': 'application/json'}
|
|
params = {'X-Plex-Token': PLEX_TOKEN,
|
|
'includePopularLeaves': '1'
|
|
}
|
|
|
|
r = requests.get(url + path, headers=header, params=params, verify=False)
|
|
return r.json()['MediaContainer']['Metadata'][0]['PopularLeaves']['Metadata']
|
|
|
|
|
|
def build_tracks(music_lst):
|
|
ratingKey_lst = []
|
|
track_lst = []
|
|
|
|
for artist in music_lst:
|
|
try:
|
|
ratingKey_lst += fetch('/library/metadata/{}'.format(artist.ratingKey))
|
|
for tracks in ratingKey_lst:
|
|
track_lst.append(plex.fetchItem(int(tracks['ratingKey'])))
|
|
except KeyError as e:
|
|
print('Artist: {} does not have any popular tracks listed.'.format(artist.title))
|
|
print('Error: {}'.format(e))
|
|
|
|
return track_lst
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
parser = argparse.ArgumentParser(description="Build playlist from popular tracks.",
|
|
formatter_class=argparse.RawTextHelpFormatter)
|
|
parser.add_argument('--name', nargs='?', default=DEFAULT_NAME, metavar='',
|
|
help='Name your playlist')
|
|
parser.add_argument('--libraries', nargs='+', default=False, choices=music_sections, metavar='',
|
|
help='Space separated list of case sensitive names to process. Allowed names are: \n'
|
|
'(choices: %(choices)s)')
|
|
parser.add_argument('--artists', nargs='+', default=False, choices=artist_lst, metavar='',
|
|
help='Space separated list of case sensitive names to process. Allowed names are: \n'
|
|
'(choices: %(choices)s)')
|
|
|
|
parser.add_argument('--tracks', nargs='?', default=False, type=int, metavar='',
|
|
help='Specify the track length you would like the playlist.')
|
|
parser.add_argument('--random',nargs='?', default=False, type=int, metavar='',
|
|
help='Randomly select N artists.')
|
|
|
|
opts = parser.parse_args()
|
|
playlist = []
|
|
|
|
if opts.libraries and not opts.artists and not opts.random:
|
|
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)
|