]> littlesong.place Git - littlesongplace.git/commitdiff
Refactor song queries
authorChris Fulljames <christianfulljames@gmail.com>
Thu, 9 Jan 2025 12:08:09 +0000 (07:08 -0500)
committerChris Fulljames <christianfulljames@gmail.com>
Thu, 9 Jan 2025 12:08:09 +0000 (07:08 -0500)
main.py
templates/profile.html
templates/songs-by-tag.html
todo.txt

diff --git a/main.py b/main.py
index 220caa2bc5908342c24e8604299879b274cfd8c3..579255239e25603634bfe503a9674ba92e62413c 100644 (file)
--- a/main.py
+++ b/main.py
@@ -113,16 +113,13 @@ def users_profile(profile_username):
 
     # 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():
@@ -139,7 +136,7 @@ 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)
@@ -354,16 +351,13 @@ def song(userid, songid):
 
 @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
@@ -398,15 +392,6 @@ def init_db():
             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
 ################################################################################
@@ -428,16 +413,40 @@ class Song:
     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
 
index 642a0b090449bc392cfdd9b3ae70198bcec60a0c..4e029978be6abc0a9002fcd23fccf727663fa567 100644 (file)
 {% 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>
index 2342f86bc02718f935ac9823bf18a64b357cdeba..7d67edbbfb04b880585ea70bd94b54dec41ac20f 100644 (file)
@@ -8,20 +8,39 @@
 
 {% 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>
index e918c77387ce6b3974f9bedcf8a7b0a922a67085..996604fcfa92b44109deb9033ae3ba3335da1523 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -1,9 +1,7 @@
-- edit-song.html: use song object
-- delete song
-- edit song info
 - user bio
 - edit user bio
 - delete user account
+- sort songs by upload timestamp
 
 - javascript song player