]> littlesong.place Git - littlesongplace.git/commitdiff
Multi-line, html comments and descriptions
authorChris Fulljames <christianfulljames@gmail.com>
Sat, 1 Feb 2025 02:34:24 +0000 (21:34 -0500)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 1 Feb 2025 02:34:24 +0000 (21:34 -0500)
main.py
templates/comment.html
templates/edit-song.html
templates/profile.html
templates/song-list.html
todo.txt

diff --git a/main.py b/main.py
index 57774fa6a472cee7d8a1c3082d953d22862d337b..5fe09554307f676278d1b9070d0cc71b50140708 100644 (file)
--- a/main.py
+++ b/main.py
@@ -156,26 +156,7 @@ def users_profile(profile_username):
     # Sanitize bio
     profile_bio = ""
     if profile_data["bio"] is not None:
-        allowed_tags = bleach.sanitizer.ALLOWED_TAGS.union({
-            'area', 'br', 'div', 'img', 'map', 'hr', 'header', 'hgroup', 'table', 'tr', 'td',
-            'th', 'thead', 'tbody', 'span', 'small', 'p', 'q', 'u', 'pre',
-        })
-        allowed_attributes = {
-            "*": ["style"], "a": ["href", "title"], "abbr": ["title"], "acronym": ["title"],
-            "img": ["src", "alt", "usemap", "width", "height"], "map": ["name"],
-            "area": ["shape", "coords", "alt", "href"]
-        }
-        allowed_css_properties = {
-            "font-size", "font-style", "font-variant", "font-family", "font-weight", "color",
-            "background-color", "background-image", "border", "border-color",
-            "border-image", "width", "height"
-        }
-        css_sanitizer = CSSSanitizer(allowed_css_properties=allowed_css_properties)
-        profile_bio = bleach.clean(
-                profile_data["bio"],
-                tags=allowed_tags,
-                attributes=allowed_attributes,
-                css_sanitizer=css_sanitizer)
+        profile_bio = sanitize_user_text(profile_data["bio"])
 
     return render_template(
             "profile.html",
@@ -646,6 +627,28 @@ def flash_and_log(msg, category=None):
     else:
         app.logger.info(logmsg)
 
+def sanitize_user_text(text):
+        allowed_tags = bleach.sanitizer.ALLOWED_TAGS.union({
+            'area', 'br', 'div', 'img', 'map', 'hr', 'header', 'hgroup', 'table', 'tr', 'td',
+            'th', 'thead', 'tbody', 'span', 'small', 'p', 'q', 'u', 'pre',
+        })
+        allowed_attributes = {
+            "*": ["style"], "a": ["href", "title"], "abbr": ["title"], "acronym": ["title"],
+            "img": ["src", "alt", "usemap", "width", "height"], "map": ["name"],
+            "area": ["shape", "coords", "alt", "href"]
+        }
+        allowed_css_properties = {
+            "font-size", "font-style", "font-variant", "font-family", "font-weight", "color",
+            "background-color", "background-image", "border", "border-color",
+            "border-image", "width", "height"
+        }
+        css_sanitizer = CSSSanitizer(allowed_css_properties=allowed_css_properties)
+        return bleach.clean(
+                text,
+                tags=allowed_tags,
+                attributes=allowed_attributes,
+                css_sanitizer=css_sanitizer)
+
 ################################################################################
 # Database
 ################################################################################
@@ -715,6 +718,10 @@ class Song:
 
     def get_comments(self):
         comments = query_db("select * from song_comments inner join users on song_comments.userid == users.userid where songid = ?", [self.songid])
+        comments = [dict(c) for c in comments]
+        for c in comments:
+            c["content"] = sanitize_user_text(c["content"])
+
         # Top-level comments
         song_comments = sorted([dict(c) for c in comments if c["replytoid"] is None], key=lambda c: c["created"])
         song_comments = list(reversed(song_comments))
@@ -760,7 +767,7 @@ class Song:
         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["username"], sd["title"], sd["description"], song_tags, song_collabs))
+            songs.append(cls(sd["songid"], sd["userid"], sd["username"], sd["title"], sanitize_user_text(sd["description"]), song_tags, song_collabs))
 
         return songs
 
index e005d727db6c5ef124bdf5944dff7b9bf99c494f..dc6cbb086cb140843099b00782e4c7cc6ed6bfad 100644 (file)
@@ -18,6 +18,8 @@ In reply to
 </p>
 {% endif %}
 
+<p>Common HTML tags (&lt;a&gt;, &lt;b&gt;, &lt;i&gt;, &lt;img&gt;, etc.) are allowed.</p>
+
 <form method="post">
     <textarea name="content">{% if comment %}{{ comment['content'] }}{% endif %}</textarea>
     <input type="submit" value="Post Comment">
index 94e49f9769394814c991462ce59e9e61f7ba6c04..7b47df025b74291aa9d71281489f473292f1e96c 100644 (file)
@@ -26,7 +26,7 @@ Most standard audio/video formats are supported - .wav, .mp3, .ogg, .mp4, etc.
         <input type="text" name="title" id="song-title" value="{{ song.title }}" maxlength="80" required>
     </div>
     <div class="upload-form">
-        <label for="description">Description</label><br>
+        <label for="description">Description</label> (Common HTML tags (&lt;a&gt;, &lt;b&gt;, &lt;i&gt;, &lt;img&gt;, etc.) are allowed.)<br>
         <textarea name="description" maxlength="10000">{{ song.description }}</textarea>
     </div>
     <div class="upload-form">
index 9662de4fabb8aa89c35f8ecebbc3ee8f9e93684e..3f8bceebf1dd666ba6ef1456bccdbecdd7717f62 100644 (file)
 <form id="profile-edit-form" action="/update-bio" method="post" hidden>
     <h2> Edit Bio </h2>
     <p>Common HTML tags (&lt;a&gt;, &lt;b&gt;, &lt;i&gt;, &lt;img&gt;, etc.) are allowed.</p>
+    <p>Examples:</p>
+    <ul>
+        <li>&lt;b&gt;<b>bold</b>&lt;/b&gt;</li>
+        <li>&lt;i&gt;<i>italic</i>&lt;/i&gt;</li>
+        <li>&lt;a href=&quot;https://littlesong.place&quot;&gt;<a href="https://littlesong.place">link</a>&lt;/a&gt;</li>
+        <li>&lt;span style=&quot;color: blue;&quot;&gt;<span style="color: blue">blue</span>&lt;/span&gt;</li>
+    </ul>
     <div>
         <textarea name="bio" maxlength="10000">{{ bio }}</textarea>
     </div>
index 8251c88becc18031a0c39470fd055f934f0bafda..6b6b98c039b792aca88a7600188275f0993221b8 100644 (file)
@@ -52,7 +52,7 @@
         <div class="song-details" {% if request.endpoint != 'song' %}hidden{% endif %}>
             <!-- Song Description -->
             {% if song.description %}
-            <div class="song-description">{{ song.description }}</div>
+            <div class="song-description">{{ (song.description.replace("\n", "<br>"))|safe  }}</div>
             {% endif %}
 
             <!-- Song Tags -->
@@ -74,7 +74,7 @@
                 <div class="top-level-comment">
 
                     <a href="/users/{{ comment['username'] }}" class="profile-link">{{ comment['username'] }}</a>:
-                    {{ comment['content'] }}
+                    {{ (comment['content'].replace("\n", "<br>"))|safe }}
 
                     {% if session['userid'] == comment['userid'] or session['userid'] == song.userid %}
                     <div class="comment-button-container">
index 3d0b34cc4b1be1bff0a67164f25d758c6b114f2a..54e50c6c1e3a0e96441a1b2b3b7c70c02e0897e5 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,4 @@
 UPDATE 1.1
-- Activity indicator
-- Tips and Tricks (or html helper for bio/descriptions?)
-- Multiline/html descriptions, comments
-- Title gif spacing? worse on mobile?
 - Update news
 
 UNSORTED