From b136285c00ae39f8b8406734484657a1b68b6976 Mon Sep 17 00:00:00 2001 From: Alvie Rahman Date: Tue, 10 Jan 2023 20:56:55 +0000 Subject: [PATCH] replace playlist delete page with playlist manage page --- common/db.py | 2 +- web/requirements.txt | 1 + web/src/app.py | 79 +++++++++++++++++++++---- web/src/templates/base.html | 1 + web/src/templates/delete.html | 15 ----- web/src/templates/index_authorised.html | 2 +- web/src/templates/manage.html | 56 ++++++++++++++++++ 7 files changed, 128 insertions(+), 28 deletions(-) delete mode 100644 web/src/templates/delete.html create mode 100644 web/src/templates/manage.html diff --git a/common/db.py b/common/db.py index 9ffce83..11a8798 100644 --- a/common/db.py +++ b/common/db.py @@ -64,7 +64,7 @@ class Db: self.rdb.set(Key.playlist_count(playlist_id), count) self.rdb.set(Key.playlist_counttype(playlist_id), counttype) - def user_del_playlist(self, spotify_id, playlist_id): + def user_del_playlist(self, spotify_id, playlist_id, delete_on_spotify = True): self.rdb.srem(Key.user_playlists(spotify_id), playlist_id) self.rdb.delete(Key.playlist_count(playlist_id)) self.rdb.delete(Key.playlist_counttype(playlist_id)) diff --git a/web/requirements.txt b/web/requirements.txt index 877cfbf..7cea37b 100644 --- a/web/requirements.txt +++ b/web/requirements.txt @@ -10,6 +10,7 @@ Jinja2==3.1.2 MarkupSafe==2.1.1 redis==4.4.0 requests==2.28.1 +requests-futures==1.0.0 six==1.16.0 urllib3==1.26.13 Werkzeug==2.2.2 diff --git a/web/src/app.py b/web/src/app.py index d60b3ba..2405a9c 100644 --- a/web/src/app.py +++ b/web/src/app.py @@ -1,6 +1,7 @@ import os from flask import Flask, render_template, request, make_response, redirect, url_for import requests as rq +from requests_futures.sessions import FuturesSession import urllib.parse import base64 from datetime import date, datetime @@ -51,6 +52,9 @@ def isauth(cookies): return user_secret == db.get_user_client_secret(user_id) +def create_empty_message(): + return { 'type':'', 'text': u'\u00A0'} + @app.route("/", methods=['GET', 'POST']) def index(): @@ -67,7 +71,7 @@ def index(): 'redirect_uri': BASE_URL + url_for('cb'), 'response_type': 'code' }), - message = { 'type':'', 'text': ''} + message = create_empty_message() )) resp.set_cookie( 'user_secret', @@ -81,7 +85,7 @@ def index(): if request.method=='GET': message = request.args.get('message') - return render_template("index_authorised.html", message = json.loads(message) if message else "" ) + return render_template("index_authorised.html", message = json.loads(message) if message else create_empty_message()) playlist_name = request.form.get('pname') @@ -180,20 +184,73 @@ def logout(): resp.set_cookie('user_secret', '') return resp -@app.route('/delete') -def delete(): +@app.route('/manage') +def manage(): if not isauth(request.cookies): return redirect(url_for('index')) user_id = request.cookies.get('spotify_id') - playlist_id = request.args.get('playlist') + playlist_id = request.args.get('playlist_id') + action = request.args.get('action') + + def gen_populated_response(message = False): + session = FuturesSession() + futures = [] + ids = db.get_user_playlists(user_id) + playlists = [] + headers = { 'Authorization': f'Bearer {db.get_user_auth_token(user_id)}' } + for pl_id in ids: + futures.append(session.get(f"{SPOTIFY_API_ENDPOINT}/playlists/{pl_id}?fields=id,name", headers = headers)) + + for future in futures: + resp = future.result() + if resp.status_code != 200: + # fail silently for now... + # TODO maybe report this error l8r to user, log + print(f"NONZERO STATUS CODE: {resp.status_code=}") + print(f"{resp.content=}") + continue + resp = resp.json() + playlists.append(resp) + + if not message: + message = create_empty_message() + if len(ids) == 0: + message['type'] = 'info' + message['text'] = 'no playlists managed by heartbeats' + message_str = request.args.get('message') + if message_str: + message = json.loads(message_str) + + return render_template("manage.html", message=message, playlists=playlists) if not playlist_id: - return render_template("delete.html", message={'type':'', 'text': ''}, playlist_ids=db.get_user_playlists(user_id)) + return gen_populated_response() - db.user_del_playlist(user_id, playlist_id) + if action in [ 'delete', 'unlink' ]: + actioned = 'deleted' if action == 'delete' else 'unlinked' + if action == 'delete': + headers = { 'Authorization': f'Bearer {db.get_user_auth_token(user_id)}' } + resp = rq.delete( + f"{SPOTIFY_API_ENDPOINT}/playlists/{playlist_id}/followers", + headers = headers + ) + print(resp.content) + if resp.status_code != 200: + return redirect(url_for('manage', message=json.dumps({ + 'type': 'error', + 'text': f'unable to {action} playlist {playlist_name}' + }))) - return render_template("delete.html", message={ - 'type': 'info', - 'text': f'successfully deleted playlist {playlist_id=}' - }, playlist_ids=db.get_user_playlists(user_id)) + + db.user_del_playlist(user_id, playlist_id) + playlist_name = request.args.get('playlist_name') + return redirect(url_for('manage', message=json.dumps({ + 'type': 'info', + 'text': f'successfully {actioned} playlist {playlist_name}' + }))) + + return gen_populated_response(message={ + 'type': 'error', + 'text': f'action not recognised: {action}' + }) diff --git a/web/src/templates/base.html b/web/src/templates/base.html index aa9fbbd..1e7688e 100644 --- a/web/src/templates/base.html +++ b/web/src/templates/base.html @@ -28,6 +28,7 @@ a, a:visited { #message { padding: 1em; } {% block title %}{% endblock %} +{% block extrahead %}{% endblock %}

{{message['text']}}

diff --git a/web/src/templates/delete.html b/web/src/templates/delete.html deleted file mode 100644 index 49c05ac..0000000 --- a/web/src/templates/delete.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "base.html" %} - -{% block title %}heartbeats | delete a playlist{% endblock %} - -{% block body %} -

delete a playlist

- - -home - -{% endblock %} diff --git a/web/src/templates/index_authorised.html b/web/src/templates/index_authorised.html index 53e62cd..375132d 100644 --- a/web/src/templates/index_authorised.html +++ b/web/src/templates/index_authorised.html @@ -22,5 +22,5 @@
-

delete a playlist, logout

+

manage playlists, logout

{% endblock %} diff --git a/web/src/templates/manage.html b/web/src/templates/manage.html new file mode 100644 index 0000000..8748210 --- /dev/null +++ b/web/src/templates/manage.html @@ -0,0 +1,56 @@ +{% extends "base.html" %} + +{% block title %}heartbeats | manage playlists{% endblock %} + +{% block extrahead %} + +{% endblock %} + +{% block body %} +

manage playlists

+
+{% for playlist in playlists %} +
+ {{playlist['name']}} + +
+{% endfor %} +
+ + + +{% endblock %}