JBOPS/utility/gmusic_playlists_to_plex.py
2020-09-28 08:09:55 -04:00

157 lines
5.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Description: Pull Playlists from Google Music and create Playlist in Plex
Author: Blacktwin, pjft, sdlynx
Requires: gmusicapi, plexapi, requests
Example:
"""
from plexapi.server import PlexServer, CONFIG
from gmusicapi import Mobileclient
import requests
requests.packages.urllib3.disable_warnings()
PLEX_URL = ''
PLEX_TOKEN = ''
MUSIC_LIBRARY_NAME = 'Music'
## 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')
# Connect to Plex Server
sess = requests.Session()
sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
# Connect to Google Music, if not authorized prompt to authorize
# See https://unofficial-google-music-api.readthedocs.io/en/latest/reference/mobileclient.html
# for more information
mc = Mobileclient()
if not mc.oauth_login(device_id=Mobileclient.FROM_MAC_ADDRESS):
mc.perform_oauth()
GGMUSICLIST = mc.get_all_songs()
PLEX_MUSIC_LIBRARY = plex.library.section(MUSIC_LIBRARY_NAME)
def round_down(num, divisor):
"""
Parameters
----------
num (int,str): Number to round down
divisor (int): Rounding digit
Returns
-------
Rounded down int
"""
num = int(num)
return num - (num%divisor)
def compare(ggmusic, pmusic):
"""
Parameters
----------
ggmusic (dict): Contains track data from Google Music
pmusic (object): Plex item found from search
Returns
-------
pmusic (object): Matched Plex item
"""
title = str(ggmusic['title'].encode('ascii', 'ignore'))
album = str(ggmusic['album'].encode('ascii', 'ignore'))
tracknum = int(ggmusic['trackNumber'])
duration = int(ggmusic['durationMillis'])
# Check if track numbers match
if int(pmusic.index) == int(tracknum):
return [pmusic]
# If not track number, check track title and album title
elif title == pmusic.title and (album == pmusic.parentTitle or
album.startswith(pmusic.parentTitle)):
return [pmusic]
# Check if track duration match
elif round_down(duration, 1000) == round_down(pmusic.duration, 1000):
return [pmusic]
# Lastly, check if title matches
elif title == pmusic.title:
return [pmusic]
def get_ggmusic(trackId):
for ggmusic in GGMUSICLIST:
if ggmusic['id'] == trackId:
return ggmusic
def main():
for pl in mc.get_all_user_playlist_contents():
playlistName = pl['name']
# Check for existing Plex Playlists, skip if exists
if playlistName in [x.title for x in plex.playlists()]:
print("Playlist: ({}) already available, skipping...".format(playlistName))
else:
playlistContent = []
shareToken = pl['shareToken']
# Go through tracks in Google Music Playlist
for ggmusicTrackInfo in pl['tracks']:
ggmusic = get_ggmusic(ggmusicTrackInfo['trackId'])
title = str(ggmusic['title'])
album = str(ggmusic['album'])
artist = str(ggmusic['artist'])
# Search Plex for Album title and Track title
albumTrackSearch = PLEX_MUSIC_LIBRARY.searchTracks(
**{'album.title': album, 'track.title': title})
# Check results
if len(albumTrackSearch) == 1:
playlistContent += albumTrackSearch
if len(albumTrackSearch) > 1:
for pmusic in albumTrackSearch:
albumTrackFound = compare(ggmusic, pmusic)
if albumTrackFound:
playlistContent += albumTrackFound
break
# Nothing found from Album title and Track title
if not albumTrackSearch or len(albumTrackSearch) == 0:
# Search Plex for Track title
trackSearch = PLEX_MUSIC_LIBRARY.searchTracks(
**{'track.title': title})
if len(trackSearch) == 1:
playlistContent += trackSearch
if len(trackSearch) > 1:
for pmusic in trackSearch:
trackFound = compare(ggmusic, pmusic)
if trackFound:
playlistContent += trackFound
break
# Nothing found from Track title
if not trackSearch or len(trackSearch) == 0:
# Search Plex for Artist
artistSearch = PLEX_MUSIC_LIBRARY.searchTracks(
**{'artist.title': artist})
for pmusic in artistSearch:
artistFound = compare(ggmusic, pmusic)
if artistFound:
playlistContent += artistFound
break
if not artistSearch or len(artistSearch) == 0:
print(u"Could not find in Plex:\n\t{} - {} {}".format(artist, album, title))
if len(playlistContent) != 0:
print("Adding Playlist: {}".format(playlistName))
print("Google Music Playlist: {}, has {} tracks. {} tracks were added to Plex.".format(
playlistName, len(pl['tracks']), len(playlistContent)))
plex.createPlaylist(playlistName, playlistContent)
else:
print("Could not find any matching tracks in Plex for {}".format(playlistName))
main()