From d2653fa0c4ffee03723424533c3b4c4e856347d3 Mon Sep 17 00:00:00 2001 From: sigma67 Date: Tue, 2 Feb 2021 10:18:31 +0100 Subject: [PATCH] Remove all code relating to Google Play Music --- GoogleMusic.py | 148 ------------------------------------------ GoogleMusicManager.py | 27 -------- README.md | 36 ++++------ Setup.py | 10 +-- requirements | 3 +- settings.ini.example | 2 - 6 files changed, 14 insertions(+), 212 deletions(-) delete mode 100644 GoogleMusic.py delete mode 100644 GoogleMusicManager.py diff --git a/GoogleMusic.py b/GoogleMusic.py deleted file mode 100644 index f181ddc..0000000 --- a/GoogleMusic.py +++ /dev/null @@ -1,148 +0,0 @@ -from gmusicapi import session, Mobileclient -from SpotifyExport import Spotify -import os -import re -import json -import difflib -import settings -import argparse -from datetime import datetime - -path = os.path.dirname(os.path.realpath(__file__)) + os.sep - - -class GoogleMusic: - def __init__(self): - self.api = Mobileclient(debug_logging=False) - refresh_token = json.loads(settings['google']['mobileclient'])['refresh_token'] - credentials = session.credentials_from_refresh_token(refresh_token, session.Mobileclient.oauth) - self.api.oauth_login(Mobileclient.FROM_MAC_ADDRESS, credentials) - - def createPlaylist(self, name, description, songs, public): - playlistId = self.api.create_playlist(name=name, description=description, public=public) - self.addSongs(playlistId, songs) - print("Success: created playlist \"" + name + "\"") - - def addSongs(self, playlistId, songs): - songIds = [] - songlist = list(songs) - notFound = list() - for i, song in enumerate(songlist): - query = song['artist'] + ' ' + song['name'] - query = query.replace(" &", "") - result = self.api.search(query=query, max_results=2) - if len(result['song_hits']) == 0: - notFound.append(query) - else: - songIds.append(self.get_best_fit_song_id(result['song_hits'], song)) - if i % 20 == 0: - print(str(i) + ' searched') - - self.api.add_songs_to_playlist(playlistId, songIds) - - with open(path + 'noresults.txt', 'w', encoding="utf-8") as f: - f.write("\n".join(notFound)) - f.close() - - def removeSongs(self, playlistId): - pl = self.api.get_all_user_playlist_contents() - tracks = next(x for x in pl if x['id'] == playlistId)['tracks'] - self.api.remove_entries_from_playlist([x['id'] for x in tracks]) - - def getPlaylistId(self, name): - pl = self.api.get_all_playlists() - return next(x for x in pl if x['name'].find(name) != -1)['id'] - - def get_best_fit_song_id(self, results, song): - match_score = {} - for res in results: - artist_score = difflib.SequenceMatcher(a=res['track']['artist'].lower(), b=song['artist'].lower()).ratio() - title_score = difflib.SequenceMatcher(a=res['track']['title'].lower(), b=song['name'].lower()).ratio() - album_score = difflib.SequenceMatcher(a=res['track']['album'].lower(), b=song['album'].lower()).ratio() - match_score[res['track']['storeId']] = (artist_score + title_score + album_score) / 3 - - return max(match_score, key=match_score.get) - - def remove_playlists(self, pattern): - pl = self.api.get_all_playlists() - p = re.compile("{0}".format(pattern)) - matches = [song for song in pl if p.match(song['name'])] - print("The following playlists will be removed:") - print("\n".join([song['name'] for song in matches])) - print("Please confirm (y/n):") - - choice = input().lower() - if choice[:1] == 'y': - [self.api.delete_playlist(song['id']) for song in matches] - print(str(len(matches)) + " playlists deleted.") - else: - print("Aborted. No playlists were deleted.") - - -def get_args(): - parser = argparse.ArgumentParser(description='Transfer spotify playlist to Google Play Music.') - parser.add_argument("playlist", type=str, help="Provide a playlist Spotify link. Alternatively, provide a text file (one song per line)") - parser.add_argument("-u", "--update", type=str, help="Delete all entries in the provided Google Play Music playlist and update the playlist with entries from the Spotify playlist.") - parser.add_argument("-n", "--name", type=str, help="Provide a name for the Google Play Music playlist. Default: Spotify playlist name") - parser.add_argument("-i", "--info", type=str, help="Provide description information for the Google Play Music Playlist. Default: Spotify playlist description") - parser.add_argument("-d", "--date", action='store_true', help="Append the current date to the playlist name") - parser.add_argument("-p", "--public", action='store_true', help="Make the playlist public. Default: private") - parser.add_argument("-r", "--remove", action='store_true', help="Remove playlists with specified regex pattern.") - parser.add_argument("-a", "--all", action='store_true', help="Transfer all public playlists of the specified user (Spotify User ID).") - return parser.parse_args() - -def main(): - args = get_args() - gmusic = GoogleMusic() - - if args.all: - s = Spotify() - pl = s.getUserPlaylists(args.playlist) - print(str(len(pl)) + " playlists found. Starting transfer...") - count = 1 - for p in pl: - print("Playlist " + str(count) + ": " + p['name']) - count = count + 1 - try: - playlist = Spotify().getSpotifyPlaylist(p['external_urls']['spotify']) - gmusic.createPlaylist(p['name'], p['description'], playlist['tracks'], args.public) - except Exception as ex: - print("Could not transfer playlist") - return - - if args.remove: - gmusic.remove_playlists(args.playlist) - return - - date = "" - if args.date: - date = " " + datetime.today().strftime('%m/%d/%Y') - - if os.path.isfile(args.playlist): - with open(args.playlist, 'r') as f: - songs = f.readlines() - if args.name: - name = args.name + date - else: - name = os.path.basename(args.playlist).split('.')[0] + date - gmusic.createPlaylist(name, args.info, songs, args.public) - return - - try: - playlist = Spotify().getSpotifyPlaylist(args.playlist) - except Exception as ex: - print("Could not get Spotify playlist. Please check the playlist link.\n Error: " + repr(ex)) - return - - if args.update: - playlistId = gmusic.getPlaylistId(args.update) - gmusic.removeSongs(playlistId) - gmusic.addSongs(playlistId, playlist['tracks']) - else: - name = args.name + date if args.name else playlist['name'] + date - info = playlist['description'] if (args.info is None) else args.info - gmusic.createPlaylist(name, info, playlist['tracks'], args.public) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/GoogleMusicManager.py b/GoogleMusicManager.py deleted file mode 100644 index c02fb87..0000000 --- a/GoogleMusicManager.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys -import os -import json -import settings -from gmusicapi import session, Musicmanager - -path = os.path.dirname(os.path.realpath(__file__)) + os.sep - -class GoogleMusicManager: - def __init__(self): - self.api = Musicmanager(debug_logging=False) - refresh_token = json.loads(settings['google']['musicmanager'])['refresh_token'] - credentials = session.credentials_from_refresh_token(refresh_token, session.Mobileclient.oauth) - self.api.login(credentials) - - def upload_song(self, file): - self.api.upload(file) - - -if __name__ == "__main__": - gmusic = GoogleMusicManager() - for x in sys.argv[1:]: - try: - gmusic.upload_song(x) - print("Successfully uploaded " + x) - except Exception as e: - print("There was an error during the upload for file " + x + ": " + str(e)) diff --git a/README.md b/README.md index 37d46c7..4d53c75 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,13 @@ -# Transfer a Spotify Playlist to Google Play Music +# Transfer a Spotify Playlist to YouTube Music -A simple command line script to clone a Spotify playlist to Google Play Music. +A simple command line script to clone a Spotify playlist to YouTube Music. - Transfer a single Spotify playlist - Transfer all playlists for a Spotify user Also includes interfaces to: -- Create a Play Music playlist from a text file -- Upload local MP3s to Play Music - -**New:** YouTube Music support. Spotify playlists can now be transferred to YouTube Music thanks to [ytmusicapi](https://github.com/sigma67/ytmusicapi). -Usage is identical to GoogleMusic.py, just use `python YouTube.py` with the same parameters. +- Create a YouTube Music playlist from a text file ## Requirements @@ -32,12 +28,9 @@ $ cp settings.ini.example settings.ini 3. Fill in your `client_id` and `client_secret` from your Spotify app -4. For Google Play Music, open a console in the source code folder and run - -`python Setup.py ` +4. For YouTube Music, open a console in the source code folder and run -where `` should be `mobileclient` to setup playlist transfers **or** `musicmanager` to be able to upload files with GoogleMusicManager.py. -For YouTube Music setup, use `youtube`. +`python Setup.py youtube` Then, follow the command line instructions to grant this app access to your account. All credentials are stored locally in the file `settings.ini`. @@ -45,30 +38,25 @@ Then, follow the command line instructions to grant this app access to your acco After you've created the settings file, you can simply run the script from the command line using: -`python GoogleMusic.py ` +`python YouTube.py ` where `` is a link like https://open.spotify.com/user/edmsauce/playlist/3yGp845Tz2duWCORALQHFO Alternatively you can also **use a file name** in place of a spotify link. The file should contain one song per line. -The script will log its progress and output songs that were not found in Google Play Music to **noresults.txt**. +The script will log its progress and output songs that were not found in YouTube Music to **noresults.txt**. ## Transfer all playlists of a Spotify user For migration purposes, it is possible to transfer all public playlists of a user by using the Spotify user's ID (unique username). -`python GoogleMusic.py --all ` - -## Upload songs - -To upload songs, run +`python YouTube.py --all ` -`python GoogleMusicManager.py ` ## Command line options There are some additional command line options for setting the playlist name and determining whether it's public or not. To view them, run -`> python GoogleMusic.py -h` +`> python YouTube.py -h` Arguments: @@ -80,12 +68,12 @@ positional arguments: optional arguments: -h, --help show this help message and exit -u UPDATE, --update UPDATE - Delete all entries in the provided Google Play Music + Delete all entries in the provided YouTube Music playlist and update the playlist with entries from the Spotify playlist. - -n NAME, --name NAME Provide a name for the Google Play Music playlist. + -n NAME, --name NAME Provide a name for the YouTube Music playlist. Default: Spotify playlist name - -i INFO, --info INFO Provide description information for the Google Play + -i INFO, --info INFO Provide description information for the YouTube Music Playlist. Default: Spotify playlist description -d, --date Append the current date to the playlist name -p, --public Make the playlist public. Default: private diff --git a/Setup.py b/Setup.py index 9a29c57..50ca32c 100644 --- a/Setup.py +++ b/Setup.py @@ -2,15 +2,7 @@ import settings if __name__ == "__main__": - if sys.argv[1] == "mobileclient": - from gmusicapi import Mobileclient - api = Mobileclient(debug_logging=True) - settings['google']['mobileclient'] = api.perform_oauth(open_browser=True).to_json() - elif sys.argv[1] == "musicmanager": - from gmusicapi import Musicmanager - api = Musicmanager(debug_logging=True) - settings['google']['musicmanager'] = api.perform_oauth(open_browser=True).to_json() - elif sys.argv[1] == "youtube": + if sys.argv[1] == "youtube": from ytmusicapi import YTMusic api = YTMusic() settings['youtube']['headers'] = api.setup() diff --git a/requirements b/requirements index 9d37c3f..e5e7cf0 100644 --- a/requirements +++ b/requirements @@ -1,3 +1,2 @@ -gmusicapi -ytmusicapi>=0.12.2 +ytmusicapi spotipy \ No newline at end of file diff --git a/settings.ini.example b/settings.ini.example index 344b34e..c55421f 100644 --- a/settings.ini.example +++ b/settings.ini.example @@ -1,5 +1,3 @@ -[google] - [youtube] headers = headers_json_from_browser user_id =