diff --git a/.gitignore b/.gitignore index 2eea525..d6cfc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.env \ No newline at end of file +.env +client_secret.json \ No newline at end of file diff --git a/SpotifyAPI.py b/SpotifyAPI.py index 172a056..e2d8887 100644 --- a/SpotifyAPI.py +++ b/SpotifyAPI.py @@ -1,9 +1,7 @@ -from os import access import requests, base64, hashlib, secrets, string from urllib.parse import urlparse, parse_qs import webbrowser from decouple import config -from datetime import datetime, timedelta from os.path import split @@ -48,46 +46,42 @@ def perform_authorization(self, auth_redirect_uri): "code_verifier": self.code_verifier } r = requests.post(self.token_url, data=request_body) - self.response_data = r.json() - self.token_expiry_time = datetime.now() + timedelta(seconds=self.response_data['expires_in']) + self.response_data = r.json() return True - - def get_access_token(self): - data = self.response_data - access_token = data['access_token'] - now = datetime.now() - if now > self.token_expiry_time: - request_body = { - "grant_type": "refresh_token", - "refresh_token": data['refresh_token'], - 'client_id': self.client_id - } - r = requests.post(self.token_url, data=request_body) - access_token = r.json()['access_token'] - return access_token def get_playlist_items(self): - access_token = self.get_access_token() + access_token = self.response_data['access_token'] header = { "Authorization": f"Bearer {access_token}" } playlist_url = config("playlist_url") playlist_path = urlparse(playlist_url).path - playlist_id = split(playlist_path)[1] - playlist_items_url = f"{self.spotify_api}/{playlist_id}/tracks?limit=10" + self.playlist_id = split(playlist_path)[1] + playlist_items_url = f"{self.spotify_api}/{self.playlist_id}/tracks" r = requests.get(playlist_items_url, headers=header) - playlist_items = r.json() - print(playlist_items) + response = r.json() + playlist_items = response['items'] return playlist_items - - -if __name__ == "__main__": - s = SpotifyApi() - s.open_authorize_url() - auth_redirect_uri = input("Copy and paste the url you were redirected to here.\n") - s.perform_authorization(auth_redirect_uri=auth_redirect_uri) - s.get_playlist_items() + def get_track_names_from_playlist_items(self): + playlist_items = self.get_playlist_items() + track_names = [] + for playlist_item in playlist_items: + artists = [artist['name'] for artist in playlist_item['track']['artists']] + for artist in artists: + track_name = playlist_item['track']['name'] + " " + artist + print(f"Fetching {playlist_item['track']['name']} from spotify.") + track_names.append(track_name) + return track_names - + def get_playlist_name(self): + access_token = self.response_data['access_token'] + playlist_id = self.playlist_id + header = { + "Authorization": f"Bearer {access_token}" + } + r = requests.get(f"{self.spotify_api}/{playlist_id}", headers=header) + data = r.json() + playlist_name = data['name'] + return playlist_name \ No newline at end of file diff --git a/YoutubeAPI.py b/YoutubeAPI.py new file mode 100644 index 0000000..cdaf840 --- /dev/null +++ b/YoutubeAPI.py @@ -0,0 +1,73 @@ +from google_auth_oauthlib.flow import InstalledAppFlow +from googleapiclient.discovery import build + + +class YoutubeApi: + def __init__(self) -> None: + self.base_url = "https://www.googleapis.com/youtube/v3" + flow = InstalledAppFlow.from_client_secrets_file( + 'client_secret.json', + scopes=['https://www.googleapis.com/auth/youtube']) + + flow.run_local_server(host="127.0.0.1", port=8888, prompt="consent", authorization_prompt_message="") + + credentials = flow.credentials + self.youtube = build("youtube", "v3", credentials=credentials) + + def create_playlist(self, playlist_name): + make_playlist = self.youtube.playlists().insert( + part="snippet, status", + body={ + "snippet": { + "title": playlist_name, + }, + "status": { + "privacyStatus": "public" + } + } + ) + response = make_playlist.execute() + self.playlist_id = response['id'] + print(f"Playlist {playlist_name} created.") + return True + + + def get_tracks_from_youtube(self, tracks): + # searches fot youtube video which has title similar to + # spotify track and returns the most relevant search result + self.video_ids = [] + for track in tracks: + search_request = self.youtube.search().list( + part="snippet", + maxResults=1, + order="relevance", + q=track + ) + response = search_request.execute() + search_result = response['items'][0] + video_id = search_result['id']['videoId'] + self.title = search_result['snippets']['title'] + self.video_ids.append(video_id) + return True + + def add_track_to_playlist(self): + video_ids = self.video_ids + for video_id in video_ids: + add_video = self.youtube.playlistItems().insert( + part="snippet", + body={ + "snippet": { + "playlistId": "PLyE5TKnn6IC0iJH-zYD1Af0Da6zxH1Y0t", + "resourceId": { + "kind": "youtube#video", + "videoId": video_id + } + } + } + ) + print(f"Adding {self.title} to playlist.") + response = add_video.execute() + + return True + + diff --git a/client_secret.json b/client_secret.json new file mode 100644 index 0000000..f76a195 --- /dev/null +++ b/client_secret.json @@ -0,0 +1,13 @@ +{ + "web": { + "client_id": "", + "project_id": "", + "client_secret": "", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "redirect_uris": [ + "http://127.0.0.1:8888/" + ] + } +} \ No newline at end of file diff --git a/playlist-converter.py b/playlist-converter.py new file mode 100644 index 0000000..4d6d695 --- /dev/null +++ b/playlist-converter.py @@ -0,0 +1,17 @@ +from SpotifyAPI import SpotifyApi +from YoutubeAPI import YoutubeApi + +if __name__ == "__main__": + spotify = SpotifyApi() + + spotify.open_authorize_url() + auth_redirect_uri = input("Copy and paste the url you were redirected to here.\n") + spotify.perform_authorization(auth_redirect_uri=auth_redirect_uri) + spotify_tracks = spotify.get_track_names_from_playlist_items() + playlist_name = spotify.get_playlist_name() + + youtube = YoutubeApi() + youtube.create_playlist(playlist_name=playlist_name) + youtube.get_tracks_from_youtube(tracks=spotify_tracks) + youtube.add_track_to_playlist() + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5eeb208..cdedc4f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,25 @@ +cachetools==4.2.2 certifi==2021.5.30 charset-normalizer==2.0.3 +google-api-core==1.31.0 +google-api-python-client==2.13.0 +google-auth==1.33.0 +google-auth-httplib2==0.1.0 +google-auth-oauthlib==0.4.4 +googleapis-common-protos==1.53.0 +httplib2==0.19.1 idna==3.2 +oauthlib==3.1.1 +packaging==21.0 +protobuf==3.17.3 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pyparsing==2.4.7 python-decouple==3.4 +pytz==2021.1 requests==2.26.0 +requests-oauthlib==1.3.0 +rsa==4.7.2 six==1.16.0 +uritemplate==3.0.1 urllib3==1.26.6