return render_template(
"profile.html",
name=profile_username,
- username=username,
+ userid=profile_userid,
songs=profile_songs_data,
songs_tags=tags,
songs_collaborators=collabs)
-@app.get("/edit-song/<int:songid>")
-def edit_song(songid=None):
+@app.get("/edit-song")
+def edit_song():
if not "userid" in session:
return redirect("/login") # Must be logged in to edit
- if songid:
+ song = None
+
+ if "songid" in request.args:
+ try:
+ songid = int(request.args["songid"])
+ except ValueError:
+ # Invalid song id - file not found
+ abort(404)
+
try:
song = Song.from_db(songid)
+ if not song.userid == session["userid"]:
+ # Can't edit someone else's song - 401 unauthorized
+ abort(401)
except ValueError:
+ # Song doesn't exist - 404 file not found
abort(404)
- return render_template("edit-song.html", song=song)
+ return render_template("edit-song.html", song=song)
-@app.post("/upload-song/<int:songid>")
-def upload_song(songid=None):
+@app.post("/upload-song")
+def upload_song():
if not "userid" in session:
return redirect("/login") # Must be logged in to edit
if not error:
userid = session["userid"]
- if songid:
- error = update_song(file, userid, title, description, tags, collaborators, songid)
+ if "songid" in request.args:
+ error = update_song()
else:
- error = create_song(file, userid, title, description, tags, collaborators)
+ error = create_song()
if not error:
username = session["username"]
- return redirect("/users/{username}")
+ return redirect(f"/users/{username}")
else:
return redirect(request.referrer)
os.makedirs(userpath)
return userpath
-def update_song(file, userid, title, description, tags, collaborators):
+def update_song():
songid = request.args["songid"]
try:
int(songid)
except ValueError:
abort(400)
+ file = request.files["song"]
+ title = request.form["title"]
+ description = request.form["description"]
+ tags = [t.strip() for t in request.form["tags"].split(",")]
+ collaborators = [c.strip() for c in request.form["collabs"].split(",")]
+
# Make sure song exists and the logged-in user owns it
song_data = query_db("select userid from songs where songid = ?", [songid], one=True)
if song_data is None:
abort(400)
- elif userid != song_data["userid"]:
+ elif session["userid"] != song_data["userid"]:
abort(401)
+ error = False
if file:
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
file.save(tmp_file)
# Update songs table
query_db(
"update songs set userid = ?, title = ?, description = ? where songid = ?",
- [userid, title, description, songid])
+ [session["userid"], title, description, songid])
# Update song_tags table
query_db("delete from song_tags where songid = ?", [songid])
get_db().commit()
flash(f"Successfully updated '{title}'", "success")
-def create_song(file, userid, title, description, tags, collaborators):
+def create_song():
+ file = request.files["song"]
+ title = request.form["title"]
+ description = request.form["description"]
+ tags = [t.strip() for t in request.form["tags"].split(",")]
+ collaborators = [c.strip() for c in request.form["collabs"].split(",")]
+
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
file.save(tmp_file)
tmp_file.close()
# Create song
song_data = query_db(
"insert into songs (userid, title, description) values (?, ?, ?) returning (songid)",
- [userid, title, description], one=True)
+ [session["userid"], title, description], one=True)
songid = song_data["songid"]
- filepath = get_user_path() / (str(song_data["songid"]) + ".mp3")
+ filepath = get_user_path(session["userid"]) / (str(song_data["songid"]) + ".mp3")
# Move file to permanent location
shutil.move(tmp_file.name, filepath)
@dataclass
class Song:
- id: int
+ songid: int
+ userid: int
title: str
description: str
tags: list[str]
raise ValueError(f"No song for ID {songid:d}")
tags_data = query_db("select * from song_tags where songid = ?", [songid])
- collaborators_data = query_db("select * from song_collaborators where songid = ?", [song])
+ collaborators_data = query_db("select * from song_collaborators where songid = ?", [songid])
tags = [t["tag"] for t in tags_data]
collabs = [c["name"] for c in collaborators_data]
- return cls(song_data["songid"], song_data["title"], song_data["description"], tags, collabs)
+ return cls(song_data["songid"], song_data["userid"], song_data["title"], song_data["description"], tags, collabs)
{% block body %}
-<form action="/uploadsong" method="post" enctype="multipart/form-data">
+{% if song %}
+<form action="/upload-song?songid={{ song.songid }}" method="post" enctype="multipart/form-data">
+{% else %}
+<form action="/upload-song" method="post" enctype="multipart/form-data">
+{% endif %}
<h2>Upload a new song</h2>
<div class="upload-form">
- <label for="song">{% if editing %}Replace {% endif %}mp3 File</label>
- <input type="file" name="song" accept=".mp3" id="file-select" required></input>
+ <label for="song">{% if song %}Replace {% endif %}mp3 File</label>
+ <input type="file" name="song" accept=".mp3" id="file-select" {% if not song %}required{% endif %}>
</div>
<div class="upload-form">
<label for="title">Title</label>
- <input type="text" name="title" id="song-title" value="{{ title }}" required></input>
+ <input type="text" name="title" id="song-title" value="{{ song.title }}" required>
</div>
<div class="upload-form">
<label for="description">Description</label>
- <textarea name="description" value="{{ description }}"></textarea>
+ <textarea name="description">{{ song.description }}</textarea>
</div>
<div class="upload-form">
<label for="tags">Tags</label>
- <input type="text" name="tags" placeholder="country, extratone, vocals, ..." value="{{ tags }}"></input>
+ <input type="text" name="tags" placeholder="country, extratone, vocals, ..." value="{{ ", ".join(song.tags) }}">
</div>
<div class="upload-form">
<label for="collabs">Collaborators</label>
- <input type="text" name="collabs" placeholder="@fren_user, John Doe, ..." value="{{ collaborators }}"></input>
+ <input type="text" name="collabs" placeholder="@fren_user, John Doe, ..." value="{{ ", ".join(song.collaborators) }}">
</div>
<div class="upload-form">
- <input type="submit" value="Upload"></input>
+ <input type="submit" value="Upload">
</div>
</form>
}
});
</script>
-{% endif %}
{% endblock %}