replace playlist delete page with playlist manage page
This commit is contained in:
parent
b633abdb6e
commit
b136285c00
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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}'
|
||||
})
|
||||
|
@ -28,6 +28,7 @@ a, a:visited {
|
||||
#message { padding: 1em; }
|
||||
</style>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
{% block extrahead %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<p class="messagetype{{message['type']}}"id="message">{{message['text']}}</p>
|
||||
|
@ -1,15 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}heartbeats | delete a playlist{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1> delete a playlist </h1>
|
||||
<ul>
|
||||
{% for pid in playlist_ids %}
|
||||
<li><a href="?playlist={{pid}}">{{pid}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<a href="..">home</a>
|
||||
|
||||
{% endblock %}
|
@ -22,5 +22,5 @@
|
||||
<br>
|
||||
</form>
|
||||
|
||||
<p><a href="./delete">delete a playlist</a>, <a href="./logout">logout</a></p>
|
||||
<p><a href="./manage">manage playlists</a>, <a href="./logout">logout</a></p>
|
||||
{% endblock %}
|
||||
|
56
web/src/templates/manage.html
Normal file
56
web/src/templates/manage.html
Normal file
@ -0,0 +1,56 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}heartbeats | manage playlists{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
<style>
|
||||
.playlists * {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.playlist {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-content: last baseline;
|
||||
}
|
||||
|
||||
.playlist .name {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.playlist .actions a { padding: 0; }
|
||||
.playlist .actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.playlist:nth-child(even) {
|
||||
background-color: var(--bg-lc);
|
||||
}
|
||||
|
||||
.playlists .actions a { padding: 0; }
|
||||
|
||||
span {
|
||||
height: fit-content;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1><span style="color: #1db954">manage</span> playlists</h1>
|
||||
<div class="playlists">
|
||||
{% for playlist in playlists %}
|
||||
<div class="playlist">
|
||||
<span class="name" title="{{playlist['name']}} ({{playlist['id']}})">{{playlist['name']}}</span>
|
||||
<div class="actions">
|
||||
<a href="?playlist_id={{playlist['id']}}&playlist_name={{playlist['name']}}&action=delete">delete</a>
|
||||
<a href="?playlist_id={{playlist['id']}}&playlist_name={{playlist['name']}}&action=unlink">unlink without deleting</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!--a href="..">home</a-->
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user