diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 0000000..15d4407 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,21 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +env +.idea +.spot + +node_modules +#!include:.gitignore diff --git a/alarm.py b/alarm.py index aba232a..fca211c 100644 --- a/alarm.py +++ b/alarm.py @@ -22,7 +22,10 @@ if __name__ == '__main__': try: - network = Network(User()) + network = Network(User(os.environ['SPOTCLIENT'], + os.environ['SPOTSECRET'], + os.environ['SPOTACCESS'], + os.environ['SPOTREFRESH'])) found = False diff --git a/backup.py b/backup.py index 07bc22c..1e85cf4 100644 --- a/backup.py +++ b/backup.py @@ -11,7 +11,10 @@ if __name__ == '__main__': try: - network = Network(User()) + network = Network(User(os.environ['SPOTCLIENT'], + os.environ['SPOTSECRET'], + os.environ['SPOTACCESS'], + os.environ['SPOTREFRESH'])) playlists = network.get_user_playlists() for playlist in playlists: diff --git a/generateplaylists.py b/generateplaylists.py index e952d09..8248b29 100644 --- a/generateplaylists.py +++ b/generateplaylists.py @@ -104,7 +104,10 @@ def go(): log.log('none to execute, terminating') return - net = Network(User()) + net = Network(User(os.environ['SPOTCLIENT'], + os.environ['SPOTSECRET'], + os.environ['SPOTACCESS'], + os.environ['SPOTREFRESH'])) engine = PlaylistEngine(net) engine.load_user_playlists() diff --git a/getaccesstoken.py b/getaccesstoken.py index 87d7f8b..a509eaa 100644 --- a/getaccesstoken.py +++ b/getaccesstoken.py @@ -1,8 +1,13 @@ from spotframework.net.user import User from spotframework.net.network import Network +import os + if __name__ == '__main__': - network = Network(User()) + network = Network(User(os.environ['SPOTCLIENT'], + os.environ['SPOTSECRET'], + os.environ['SPOTACCESS'], + os.environ['SPOTREFRESH'])) print(network.user.access_token) diff --git a/main.py b/main.py index 7cfc494..8bc80c1 100644 --- a/main.py +++ b/main.py @@ -1,36 +1,14 @@ -import spotframework.net.user as userclass -import spotframework.net.network as networkclass -import spotframework.net.network as playlist -import spotframework.io.json as json -if __name__ == '__main__': - print('hello world') +def run_user_playlist(event, context): - # data = json.loadJson('.spot/config.json') + import base64 - # print(data) + name = base64.b64decode(event['data']).decode('utf-8') + username = event['attributes']['username'] - network = networkclass.Network(userclass.User()) + print(f'{username} - {name}') - # tracks = network.getPlaylistTracks("76ynkbkyc4uq11u1FcpOyG") + from spotframework.google.run_user_playlist import run_user_playlist as run - # print(tracks[0]) - - # network.setVolume(105) - - # network.getPlaylist('000Eh2vXzYGgrEFlgcWZj3') - # - # playlist = network.makePlaylist('new playlist') - # - # network.addPlaylistTracks(playlist.playlistid, ["spotify:track:78lC4VmDVSSsCUQ0VNdQva"]*149) - # - # network.replacePlaylistTracks(playlist.playlistid, ["spotify:track:78lC4VmDVSSsCUQ0VNdQva"] * 160) - # - # network.pause() - - #network.getPlayer() - - # playlists = network.getUserPlaylists() - # for playlist in playlists: - # print(playlist.name + ' ' + playlist.playlistid) \ No newline at end of file + run(username, name) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..160ae0f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +cachetools==3.1.1 +certifi==2019.3.9 +chardet==3.0.4 +google-api-core==1.14.2 +google-auth==1.6.3 +google-cloud-core==1.0.3 +google-cloud-firestore==1.3.0 +googleapis-common-protos==1.6.0 +grpcio==1.22.0 +idna==2.8 +protobuf==3.9.0 +pyasn1==0.4.6 +pyasn1-modules==0.2.5 +pytz==2019.2 +requests==2.21.0 +rsa==4.0 +six==1.12.0 +urllib3==1.24.3 diff --git a/spotframework/google/__init__.py b/spotframework/google/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spotframework/google/run_user_playlist.py b/spotframework/google/run_user_playlist.py new file mode 100644 index 0000000..80c96ec --- /dev/null +++ b/spotframework/google/run_user_playlist.py @@ -0,0 +1,65 @@ +from google.cloud import firestore + +from spotframework.engine.playlistengine import PlaylistEngine +from spotframework.engine.filter.shuffle import Shuffle +from spotframework.engine.filter.sortreversereleasedate import SortReverseReleaseDate +from spotframework.engine.filter.deduplicatebyid import DeduplicateByID + +from spotframework.net.network import Network +from spotframework.net.user import User + +db = firestore.Client() + + +def run_user_playlist(username, playlist_name): + + users = db.collection(u'spotify_users').where(u'username', u'==', username).stream() + users = [i for i in users] + + if len(users) == 1: + + user_dict = users[0].to_dict() + + playlist_collection = db.collection(u'spotify_users', u'{}'.format(users[0].id), 'playlists') + + print(user_dict['access_token'], user_dict['refresh_token']) + + playlists = [i for i in playlist_collection.where(u'name', u'==', playlist_name).stream()] + + if len(playlists) == 1: + + playlist_dict = playlists[0].to_dict() + + if playlist_dict['playlist_id'] is None: + raise Exception('no playlist id to populate') + + if len(playlist_dict['parts']) == 0: + raise Exception('no playlists to use for creation') + + spotify_keys = db.document('key/spotify').get().to_dict() + + net = Network(User(spotify_keys['clientid'], + spotify_keys['clientsecret'], + user_dict['access_token'], + user_dict['refresh_token'])) + + engine = PlaylistEngine(net) + engine.load_user_playlists() + + processors = [DeduplicateByID()] + + if playlist_dict['shuffle'] is True: + processors.append(Shuffle()) + else: + processors.append(SortReverseReleaseDate()) + + tracks = engine.make_playlist(playlist_dict['parts'], processors) + + engine.execute_playlist(tracks, playlist_dict['playlist_id']) + engine.change_description(playlist_dict['parts'], playlist_dict['playlist_id']) + + else: + raise Exception('multiple playlists found') + + else: + raise Exception('more than one user found') diff --git a/spotframework/net/network.py b/spotframework/net/network.py index af258f6..ce74fb8 100644 --- a/spotframework/net/network.py +++ b/spotframework/net/network.py @@ -111,7 +111,7 @@ class Network: params = {'offset': offset, 'limit': limit} - resp = self._make_get_request('getPlaylistTracks', 'playlists/{}/tracks'.format(playlistid), params=params) + resp = self._make_get_request('getPlaylistTracks', f'playlists/{playlistid}/tracks', params=params) tracks += resp['items'] @@ -202,8 +202,7 @@ class Network: def make_playlist(self, name, description=None, public=True, collaborative=False): - log.log("makePlaylist", name, 'description:{}'.format(description), 'public:{}'.format(public), - 'collaborative:{}'.format(collaborative)) + log.log("makePlaylist", name, f'description:{description}', f'public:{public}', f'collaborative:{collaborative}') headers = {"Content-Type": "application/json"} @@ -212,8 +211,7 @@ class Network: if description is not None: json["description"] = description - req = self._make_post_request('makePlaylist', 'users/{}/playlists'.format(self.user.username), json=json, - headers=headers) + req = self._make_post_request('makePlaylist', f'users/{self.user.username}/playlists', json=json, headers=headers) if req is not None: resp = req.json() @@ -232,8 +230,7 @@ class Network: json = {"uris": uris[:100]} - req = self._make_put_request('replacePlaylistTracks', 'playlists/{}/tracks'.format(playlistid), json=json, - headers=headers) + req = self._make_put_request('replacePlaylistTracks', f'playlists/{playlistid}/tracks', json=json, headers=headers) if req is not None: resp = req.json() @@ -261,8 +258,7 @@ class Network: if description is not None: json['description'] = description - req = self._make_put_request('changePlaylistDetails', 'playlists/{}'.format(playlistid), json=json, - headers=headers) + req = self._make_put_request('changePlaylistDetails', f'playlists/{playlistid}', json=json, headers=headers) return req def add_playlist_tracks(self, playlistid, uris): @@ -273,8 +269,7 @@ class Network: json = {"uris": uris[:100]} - req = self._make_post_request('addPlaylistTracks', 'playlists/{}/tracks'.format(playlistid), json=json, - headers=headers) + req = self._make_post_request('addPlaylistTracks', f'playlists/{playlistid}/tracks', json=json, headers=headers) if req is not None: resp = req.json() diff --git a/spotframework/net/user.py b/spotframework/net/user.py index ed30b0a..5ec9514 100644 --- a/spotframework/net/user.py +++ b/spotframework/net/user.py @@ -1,24 +1,23 @@ -import os import requests from base64 import b64encode -client_id = os.environ['SPOTCLIENT'] -client_secret = os.environ['SPOTSECRET'] - class User: - def __init__(self): - self.accesstoken = os.environ['SPOTACCESS'] - self.refreshtoken = os.environ['SPOTREFRESH'] - + def __init__(self, client_id, client_secret, access_token, refresh_token): + self.accesstoken = access_token + self.refreshtoken = refresh_token + + self.client_id = client_id + self.client_secret = client_secret + self.refresh_token() self.username = self.get_info()['id'] def refresh_token(self): - idsecret = b64encode(bytes(client_id + ':' + client_secret, "utf-8")).decode("ascii") + idsecret = b64encode(bytes(self.client_id + ':' + self.client_secret, "utf-8")).decode("ascii") headers = {'Authorization': 'Basic %s' % idsecret} data = {"grant_type": "refresh_token", "refresh_token": self.refreshtoken}