# Get songs for current profile
profile_userid = profile_data["userid"]
- profile_songs_data = query_db("select * from songs where userid = ?", [profile_userid])
- tags, collabs = get_tags_and_collabs_for_songs(profile_songs_data)
+ songs = Song.get_all_for_user(profile_userid)
return render_template(
"profile.html",
name=profile_username,
userid=profile_userid,
- songs=profile_songs_data,
- songs_tags=tags,
- songs_collaborators=collabs)
+ songs=songs)
@app.get("/edit-song")
def edit_song():
abort(404)
try:
- song = Song.from_db(songid)
+ song = Song.by_id(songid)
if not song.userid == session["userid"]:
# Can't edit someone else's song - 401 unauthorized
abort(401)
@app.get("/songs-by-tag/<tag>")
def songs_by_tag(tag):
- songs_data = query_db("select * from song_tags inner join songs on song_tags.songid = songs.songid where tag = ?", [tag])
- tags, collabs = get_tags_and_collabs_for_songs(songs_data)
+ songs = Song.get_all_for_tag(tag)
return render_template(
"songs-by-tag.html",
tag=tag,
username=session["username"],
- songs=songs_data,
- songs_tags=tags,
- songs_collaborators=collabs)
+ songs=songs)
################################################################################
# Database
db.cursor().executescript(f.read())
db.commit()
-def get_tags_and_collabs_for_songs(songs):
- tags = {}
- collabs = {}
- for song in songs:
- songid = song["songid"]
- tags[songid] = query_db("select (tag) from song_tags where songid = ?", [songid])
- collabs[songid] = query_db("select (name) from song_collaborators where songid = ?", [songid])
- return tags, collabs
-
################################################################################
# Generate Session Key
################################################################################
collaborators: list[str]
@classmethod
- def from_db(cls, songid):
- song_data = query_db("select * from songs where songid = ?", [songid], one=True)
- if song_data is None:
+ def by_id(cls, songid):
+ songs = cls._from_db("select * from songs where songid = ?", [songid])
+ if not songs:
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 = ?", [songid])
+ return songs[0]
+
+ @classmethod
+ def get_all_for_user(cls, userid):
+ return cls._from_db("select * from songs where userid = ?", [userid])
+
+ @classmethod
+ def get_all_for_tag(cls, tag):
+ return cls._from_db("select * from song_tags inner join songs on song_tags.songid = songs.songid where tag = ?", [tag])
+
+ @classmethod
+ def _from_db(cls, query, args=()):
+ songs_data = query_db(query, args)
+ tags, collabs = cls._get_tags_and_collabs_for_songs(songs_data)
+ songs = []
+ for sd in songs_data:
+ song_tags = [t["tag"] for t in tags[sd["songid"]]]
+ song_collabs = [c["name"] for c in collabs[sd["songid"]]]
+ songs.append(cls(sd["songid"], sd["userid"], sd["title"], sd["description"], song_tags, song_collabs))
- tags = [t["tag"] for t in tags_data]
- collabs = [c["name"] for c in collaborators_data]
+ return songs
- return cls(song_data["songid"], song_data["userid"], song_data["title"], song_data["description"], tags, collabs)
+ @classmethod
+ def _get_tags_and_collabs_for_songs(cls, songs):
+ tags = {}
+ collabs = {}
+ for song in songs:
+ songid = song["songid"]
+ tags[songid] = query_db("select (tag) from song_tags where songid = ?", [songid])
+ collabs[songid] = query_db("select (name) from song_collaborators where songid = ?", [songid])
+ return tags, collabs
{% for song in songs %}
<div class="song">
<!-- Song Title -->
- <div class="song-title"><h3>{{ song["title"] }}</h3></div>
+ <div class="song-title"><h3>{{ song.title }}</h3></div>
<!-- Owner-Specific Buttons (Edit/Delete) -->
{% if session["userid"] == userid %}
<div class="song-edit-button">
- <a href="/edit-song?songid={{ song["songid"] }}">Edit</a>
+ <a href="/edit-song?songid={{ song.songid }}">Edit</a>
</div>
<div class="song-delete-button">
- <a href="/delete-song/{{ song["userid"] }}/{{ song["songid"] }}">Delete</a>
+ <a href="/delete-song/{{ song.userid }}/{{ song.songid }}">Delete</a>
</div>
{% endif %}
<!-- Play Button -->
- <audio src="/song/{{ song["userid"] }}/{{ song["songid"] }}" controls></audio>
+ <audio src="/song/{{ song.userid }}/{{ song.songid }}" controls></audio>
<!-- Song Description -->
- <div class="song-description">{{ song["description"] }}</div>
+ <div class="song-description">{{ song.description }}</div>
<!-- Song Tags -->
<div class="song-tags">
- {% for tag in songs_tags[song["songid"]] %}
- <a href="/songs-by-tag/{{ tag["tag"] }}">{{ tag["tag"] }}</a>
+ {% for tag in song.tags %}
+ <a href="/songs-by-tag/{{ tag }}">{{ tag }}</a>
{% endfor %}
</div>
<!-- Song Collaborators -->
<div class="song-collabs">
- {% for collab in songs_collaborators[song["songid"]] %}
- {% if collab["name"].startswith("@") %}
- <a href="/users/{{ collab["name"][1:] }}" class="collab-link">{{ collab["name"] }}</a>
+ {% for collab in song.collaborators %}
+ {% if collab.startswith("@") %}
+ <a href="/users/{{ collab }}" class="collab-link">{{ collab }}</a>
{% else %}
- <span class="collab-name">{{ collab["name"] }}</span>
+ <span class="collab-name">{{ collab }}</span>
{% endif %}
{% endfor %}
</div>
{% for song in songs %}
<div class="song">
- <div class="song-title">{{ song["title"] }}</div>
- <audio src="/song/{{ song["userid"] }}/{{ song["songid"] }}" controls></audio>
- <div class="song-description">{{ song["description"] }}</div>
+ <!-- Song Title -->
+ <div class="song-title"><h3>{{ song.title }}</h3></div>
+
+ <!-- Owner-Specific Buttons (Edit/Delete) -->
+ {% if session["userid"] == userid %}
+ <div class="song-edit-button">
+ <a href="/edit-song?songid={{ song.songid }}">Edit</a>
+ </div>
+ <div class="song-delete-button">
+ <a href="/delete-song/{{ song.userid }}/{{ song.songid }}">Delete</a>
+ </div>
+ {% endif %}
+
+ <!-- Play Button -->
+ <audio src="/song/{{ song.userid }}/{{ song.songid }}" controls></audio>
+
+ <!-- Song Description -->
+ <div class="song-description">{{ song.description }}</div>
+
+ <!-- Song Tags -->
<div class="song-tags">
- {% for tag in songs_tags[song["songid"]] %}
- <a href="/songs-by-tag/{{ tag["tag"] }}">{{ tag["tag"] }}</a>
+ {% for tag in song.tags %}
+ <a href="/songs-by-tag/{{ tag }}">{{ tag }}</a>
{% endfor %}
</div>
+
+ <!-- Song Collaborators -->
<div class="song-collabs">
- {% for collab in songs_collaborators[song["songid"]] %}
- {% if collab["name"].startswith("@") %}
- <a href="/users/{{ collab["name"][1:] }}" class="collab-link">{{ collab["name"] }}</a>
+ {% for collab in song.collaborators %}
+ {% if collab.startswith("@") %}
+ <a href="/users/{{ collab[1:] }}" class="collab-link">{{ collab }}</a>
{% else %}
- <span class="collab-name">{{ collab["name"] }}</span>
+ <span class="collab-name">{{ collab }}</span>
{% endif %}
{% endfor %}
</div>