From 5e2951c9febc7cadf84913a1b21c79a7200a1c1e Mon Sep 17 00:00:00 2001 From: aj Date: Mon, 26 Aug 2019 18:31:21 +0100 Subject: [PATCH] fixed alphabetical sort, added part_generator --- spotify/api/api.py | 2 +- spotify/api/database.py | 32 ------------- spotify/auth/auth.py | 2 +- spotify/db/__init__.py | 0 spotify/db/database.py | 73 +++++++++++++++++++++++++++++ spotify/db/part_generator.py | 55 ++++++++++++++++++++++ spotify/tasks/play_user_playlist.py | 30 +++--------- spotify/tasks/run_user_playlist.py | 30 ++---------- src/js/Playlist/PlaylistView.js | 16 +++---- src/js/Playlist/PlaylistsView.js | 4 +- 10 files changed, 152 insertions(+), 92 deletions(-) delete mode 100644 spotify/api/database.py create mode 100644 spotify/db/__init__.py create mode 100644 spotify/db/database.py create mode 100644 spotify/db/part_generator.py diff --git a/spotify/api/api.py b/spotify/api/api.py index b450f83..b22c10c 100644 --- a/spotify/api/api.py +++ b/spotify/api/api.py @@ -14,7 +14,7 @@ from werkzeug.security import check_password_hash, generate_password_hash from spotify.tasks.run_user_playlist import run_user_playlist as run_user_playlist from spotify.tasks.play_user_playlist import play_user_playlist as play_user_playlist -import spotify.api.database as database +import spotify.db.database as database blueprint = Blueprint('api', __name__) db = firestore.Client() diff --git a/spotify/api/database.py b/spotify/api/database.py deleted file mode 100644 index d0d876d..0000000 --- a/spotify/api/database.py +++ /dev/null @@ -1,32 +0,0 @@ -from google.cloud import firestore -db = firestore.Client() - - -def get_user_query_stream(user): - - users = db.collection(u'spotify_users').where(u'username', u'==', user).stream() - users = [i for i in users] - - return users - - -def get_user_doc_ref(user): - - users = get_user_query_stream(user) - - if len(users) == 1: - - return db.collection(u'spotify_users').document(u'{}'.format(users[0].id)) - - else: - print(len(users)) - raise ValueError - - -def get_user_playlists_collection(user_id): - - playlists = db.document(u'spotify_users/{}'.format(user_id)).collection(u'playlists') - - return playlists - - diff --git a/spotify/auth/auth.py b/spotify/auth/auth.py index 1081a84..0bd46ae 100644 --- a/spotify/auth/auth.py +++ b/spotify/auth/auth.py @@ -8,7 +8,7 @@ import logging from base64 import b64encode import requests -import spotify.api.database as database +import spotify.db.database as database blueprint = Blueprint('authapi', __name__) diff --git a/spotify/db/__init__.py b/spotify/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spotify/db/database.py b/spotify/db/database.py new file mode 100644 index 0000000..cb79b2b --- /dev/null +++ b/spotify/db/database.py @@ -0,0 +1,73 @@ +from google.cloud import firestore +import logging + +db = firestore.Client() + +logger = logging.getLogger(__name__) + + +def get_user_query_stream(user): + + users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', user).stream()] + + if len(users) > 0: + return users + else: + logger.warning(f'{user} not found') + return [] + + +def get_user_doc_ref(user): + + users = get_user_query_stream(user) + + if len(users) > 0: + if len(users) == 1: + return db.collection(u'spotify_users').document(u'{}'.format(users[0].id)) + + else: + logger.error(f"multiple {user}'s found") + return None + + else: + logger.error(f'{user} not found') + return None + + +def get_user_playlists_collection(user_id): + + playlists = db.document(u'spotify_users/{}'.format(user_id)).collection(u'playlists') + + return playlists + + +def get_user_playlist_ref(user, playlist): + + user_ref = get_user_doc_ref(user) + + if user_ref: + + playlist_collection = get_user_playlists_collection(user_ref.id) + + if playlist_collection: + query = [i for i in playlist_collection.where(u'name', u'==', playlist).stream()] + + if len(query) > 0: + if len(query) > 1: + return playlist_collection.document(u'{}'.format(query[0].id)) + + else: + logger.error(f'{user} multiple response playlists found for {playlist}') + return query + + else: + logger.error(f'{user} no playlist found for {playlist}') + return None + + else: + logger.error(f'{user} playlist collection not found, looking up {playlist}') + return None + + else: + logger.error(f'{user} not found, looking up {playlist}') + return None diff --git a/spotify/db/part_generator.py b/spotify/db/part_generator.py new file mode 100644 index 0000000..3245ab2 --- /dev/null +++ b/spotify/db/part_generator.py @@ -0,0 +1,55 @@ +from google.cloud import firestore +import spotify.db.database as database +import logging + +db = firestore.Client() +logger = logging.getLogger(__name__) + + +class PartGenerator: + + def __init__(self, user_id=None, username=None): + self.queried_playlists = [] + self.parts = [] + + if user_id: + self.user_id = user_id + elif username: + user_doc = database.get_user_doc_ref(username) + if user_doc: + self.user_id = user_doc.id + else: + raise LookupError(f'{username} not found') + else: + raise NameError('no user info provided') + + def get_recursive_parts(self, name): + logger.info(f'getting part from {name} for {self.user_id}') + + self.queried_playlists = [] + self.parts = [] + self._generate_parts(name) + + return [i for i in {i for i in self.parts}] + + def _generate_parts(self, name): + self.queried_playlists.append(name) + + playlist_query = [i.to_dict() for i in + database.get_user_playlists_collection(self.user_id).where(u'name', '==', name).stream()] + + if len(playlist_query) > 0: + if len(playlist_query) == 1: + + playlist_doc = playlist_query[0] + self.parts += playlist_doc['parts'] + + for i in playlist_doc['playlist_references']: + if i not in self.queried_playlists: + self._generate_parts(i) + + else: + logger.warning(f"multiple {name}'s found") + + else: + logger.warning(f'playlist {name} not found') diff --git a/spotify/tasks/play_user_playlist.py b/spotify/tasks/play_user_playlist.py index f98f3e7..345bd8e 100644 --- a/spotify/tasks/play_user_playlist.py +++ b/spotify/tasks/play_user_playlist.py @@ -11,6 +11,9 @@ from spotframework.engine.filter.deduplicatebyid import DeduplicateByID from spotframework.net.network import Network from spotframework.net.user import User +import spotify.db.database as database +from spotify.db.part_generator import PartGenerator + db = firestore.Client() captured_playlists = [] @@ -29,7 +32,7 @@ def play_user_playlist(username, add_this_month=False, add_last_month=False): - users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', username).stream()] + users = database.get_user_query_stream(username) logger.info(f'playing for {username}') @@ -68,13 +71,12 @@ def play_user_playlist(username, else: processors.append(SortReverseReleaseDate()) - global captured_playlists - captured_playlists = [] - submit_parts = parts + part_generator = PartGenerator(user_id=users[0].id) + for part in playlists: - submit_parts += generate_parts(users[0].id, part) + submit_parts += part_generator.get_recursive_parts(part) submit_parts = [i for i in {j for j in submit_parts}] @@ -98,21 +100,3 @@ def play_user_playlist(username, else: logger.critical(f'multiple/no user(s) found ({username})') return None - - -def generate_parts(user_id, name): - - playlist_doc = [i.to_dict() for i in - db.document(u'spotify_users/{}'.format(user_id)) - .collection(u'playlists') - .where(u'name', '==', name).stream()][0] - - return_parts = playlist_doc['parts'] - - captured_playlists.append(name) - - for i in playlist_doc['playlist_references']: - if i not in captured_playlists: - return_parts += generate_parts(user_id, i) - - return return_parts diff --git a/spotify/tasks/run_user_playlist.py b/spotify/tasks/run_user_playlist.py index 2a0dd73..27dab06 100644 --- a/spotify/tasks/run_user_playlist.py +++ b/spotify/tasks/run_user_playlist.py @@ -10,6 +10,8 @@ from spotframework.engine.filter.deduplicatebyid import DeduplicateByID from spotframework.net.network import Network from spotframework.net.user import User +import spotify.db.database as database +from spotify.db.part_generator import PartGenerator db = firestore.Client() @@ -20,7 +22,7 @@ logger = logging.getLogger(__name__) def run_user_playlist(username, playlist_name): - users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', username).stream()] + users = database.get_user_query_stream(username) logger.info(f'running {username} / {playlist_name}') @@ -61,12 +63,8 @@ def run_user_playlist(username, playlist_name): else: processors.append(SortReverseReleaseDate()) - global captured_playlists - captured_playlists = [] - - submit_parts = playlist_dict['parts'] + generate_parts(users[0].id, playlist_dict['name']) - - submit_parts = [i for i in {j for j in submit_parts}] + part_generator = PartGenerator(user_id=users[0].id) + submit_parts = part_generator.get_recursive_parts(playlist_dict['name']) if playlist_dict['type'] == 'recents': boundary_date = datetime.datetime.now() - datetime.timedelta(days=int(playlist_dict['day_boundary'])) @@ -100,21 +98,3 @@ def run_user_playlist(username, playlist_name): else: logger.critical(f'multiple/no user(s) found ({username}/{playlist_name})') return None - - -def generate_parts(user_id, name): - - playlist_doc = [i.to_dict() for i in - db.document(u'spotify_users/{}'.format(user_id)) - .collection(u'playlists') - .where(u'name', '==', name).stream()][0] - - return_parts = playlist_doc['parts'] - - captured_playlists.append(name) - - for i in playlist_doc['playlist_references']: - if i not in captured_playlists: - return_parts += generate_parts(user_id, i) - - return return_parts diff --git a/src/js/Playlist/PlaylistView.js b/src/js/Playlist/PlaylistView.js index e9edd66..5922aaa 100644 --- a/src/js/Playlist/PlaylistView.js +++ b/src/js/Playlist/PlaylistView.js @@ -74,14 +74,14 @@ class PlaylistView extends Component{ .then(axios.spread((info, playlists) => { info.data.parts.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } + if(a.toLowerCase() < b.toLowerCase()) { return -1; } + if(a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); info.data.playlist_references.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } + if(a.toLowerCase() < b.toLowerCase()) { return -1; } + if(a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); @@ -221,8 +221,8 @@ class PlaylistView extends Component{ parts.push(this.state.newPlaylistName); parts.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } + if(a.toLowerCase() < b.toLowerCase()) { return -1; } + if(a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); @@ -256,8 +256,8 @@ class PlaylistView extends Component{ playlist_references.push(this.state.newReferenceName); playlist_references.sort(function(a, b){ - if(a < b) { return -1; } - if(a > b) { return 1; } + if(a.toLowerCase() < b.toLowerCase()) { return -1; } + if(a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); diff --git a/src/js/Playlist/PlaylistsView.js b/src/js/Playlist/PlaylistsView.js index d0c3a09..564faa4 100644 --- a/src/js/Playlist/PlaylistsView.js +++ b/src/js/Playlist/PlaylistsView.js @@ -25,8 +25,8 @@ class PlaylistsView extends Component { var playlists = response.data.playlists.slice(); playlists.sort(function(a, b){ - if(a.name < b.name) { return -1; } - if(a.name > b.name) { return 1; } + if(a.name.toLowerCase() < b.name.toLowerCase()) { return -1; } + if(a.name.toLowerCase() > b.name.toLowerCase()) { return 1; } return 0; });