aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcitrons <citrons@mondecitronne.com>2025-06-16 21:25:10 -0500
committerubq323 <ubq323@ubq323.website>2025-06-17 12:05:16 +0100
commit866e64f6a3dcfb93a107ce2a04099f4013a329f0 (patch)
tree11d3cd92e5a6cbc947180a54f4c7be01c87b15e5
parent0e27f0d095c64a75f52a53860b138da923ad3555 (diff)
forum tag editor
-rw-r--r--apioforum/__init__.py3
-rw-r--r--apioforum/db.py3
-rw-r--r--apioforum/forum.py42
-rw-r--r--apioforum/static/style.css6
-rw-r--r--apioforum/templates/common.html3
-rw-r--r--apioforum/templates/tags.html48
-rw-r--r--apioforum/templates/view_forum.html1
-rw-r--r--apioforum/util.py6
8 files changed, 105 insertions, 7 deletions
diff --git a/apioforum/__init__.py b/apioforum/__init__.py
index 8a917c9..2281fde 100644
--- a/apioforum/__init__.py
+++ b/apioforum/__init__.py
@@ -43,8 +43,9 @@ def create_app():
from .fuzzy import fuzzy
app.jinja_env.filters['fuzzy']=fuzzy
- from .util import gen_colour
+ from .util import gen_colour, sanitize_color
app.jinja_env.filters['gen_colour']=gen_colour
+ app.jinja_env.filters['sanitize_color']=sanitize_color
@app.context_processor
def path_for_next():
diff --git a/apioforum/db.py b/apioforum/db.py
index 620749f..0305167 100644
--- a/apioforum/db.py
+++ b/apioforum/db.py
@@ -242,6 +242,9 @@ CREATE TABLE read (
);
ALTER TABLE forums ADD COLUMN updated TIMESTAMP;
""",
+"""
+ALTER TABLE tags ADD COLUMN enabled INT NOT NULL DEFAULT 1;
+""",
]
diff --git a/apioforum/forum.py b/apioforum/forum.py
index c3bf1c0..c44afe6 100644
--- a/apioforum/forum.py
+++ b/apioforum/forum.py
@@ -25,16 +25,20 @@ bp = Blueprint("forum", __name__, url_prefix="/")
def not_actual_index():
return redirect("/1")
-def get_avail_tags(forum_id):
+def get_avail_tags(forum_id,all=False):
db = get_db()
+ enabled_filter = ""
+ if not all:
+ enabled_filter = "AND enabled = 1"
tags = db.execute("""
WITH RECURSIVE fs AS
(SELECT * FROM forums WHERE id = ?
UNION ALL
SELECT forums.* FROM forums, fs WHERE fs.parent=forums.id)
SELECT * FROM tags
- WHERE tags.forum in (SELECT id FROM fs)
- ORDER BY id;
+ WHERE tags.forum in (SELECT id FROM fs)""" + enabled_filter + \
+ """
+ ORDER BY forum, id;
""",(forum_id,)).fetchall()
return tags
@@ -486,6 +490,38 @@ def edit_forum(forum):
def create_forum(forum):
return forum_config_page(forum,create=True)
+@forum_route("tags", methods=("GET","POST"))
+@requires_bureaucrat
+def edit_tags(forum):
+ db = get_db()
+ if request.method == "POST":
+ f = request.form
+ for t in db.execute("select * from tags where forum = ?;", (forum['id'],)):
+ id = "tag-" + str(t['id']) + "-"
+ if not id+'name' in f or not id+'fg' in f or not id+'bg' in f:
+ continue
+ enabled = id+'enabled' in f
+ db.execute("""update tags set
+ name = ?, text_colour = ?, bg_colour = ?, enabled = ?
+ where id = ? AND forum = ?;""",
+ (f[id+'name'], f[id+'fg'], f[id+'bg'], enabled, t['id'], forum['id']))
+ db.commit()
+ flash("tags tagged tagfully")
+ return redirect(url_for("forum.view_forum",forum_id=forum['id']))
+ tags = get_avail_tags(forum['id'],all=True)
+ return render_template("tags.html",forum=forum,tags=tags)
+
+@forum_route("tags/new", methods=("POST",))
+@requires_bureaucrat
+def new_tag(forum):
+ db = get_db()
+ db.execute("""insert into tags
+ (name, text_colour, bg_colour, enabled, forum) values
+ ("new tag", "black", "white", 0, ?)""", (forum['id'],))
+ db.commit()
+ flash("tag entagged tagously")
+ return redirect(url_for("forum.edit_tags",forum_id=forum['id']))
+
#@forum_route("unlisted")
#def view_unlisted(forum):
# if not is_admin: abort(403) # why doesn't this fucking work
diff --git a/apioforum/static/style.css b/apioforum/static/style.css
index c15dc35..3a7824b 100644
--- a/apioforum/static/style.css
+++ b/apioforum/static/style.css
@@ -352,6 +352,12 @@ fieldset { margin-bottom: 15px; }
white-space: nowrap;
}
+.tag-editor { margin-left: 20px; display: inline-block; }
+.tag-editor td { text-align: center; width: 12ch; }
+.tag-editor input[type="text"] { width: 12ch; }
+.tag-editor input[type="checkbox"] { width: 12ch; }
+.new-tag { float: right; text-align: center; width: 12ch; margin-top: 10px }
+
.md table {
border: 1px solid var(--gray);
border-collapse: collapse;
diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html
index a24272b..96d00a2 100644
--- a/apioforum/templates/common.html
+++ b/apioforum/templates/common.html
@@ -75,7 +75,8 @@
{% endif %}
<{{el}}
class="tag"
- style="color: {{the_tag.text_colour}}; background-color: {{the_tag.bg_colour}}"
+ style="color: {{the_tag.text_colour|sanitize_color}}; background-color: {{the_tag.bg_colour|sanitize_color}}"
+ title="{{-the_tag.name-}}"
{% if href is not none -%}
href="{{href}}"
{%- endif -%}>
diff --git a/apioforum/templates/tags.html b/apioforum/templates/tags.html
new file mode 100644
index 0000000..11377df
--- /dev/null
+++ b/apioforum/templates/tags.html
@@ -0,0 +1,48 @@
+{% from 'common.html' import tag with context %}
+{% extends 'base.html' %}
+{% block header %}
+<h1>{% block title %}tags in '{{forum.name}}'{% endblock %}</h1>
+{% endblock %}
+
+{% macro tag_form(t) %}
+<tr>
+ {%set id = "tag-" + t.id|string + "-"%}
+ {% if not t or t.forum == forum.id%}
+ {%set disabled = ""%}
+ {%else%}
+ {%set disabled = " disabled "%}
+ {%endif%}
+ <td>{%if t%}{{tag(t)}}{%endif %}
+ <td><input {{disabled}} type="text" required form="tags" name="{{id}}name" value="{{t.name}}"/>
+ <td><input {{disabled}} type="text" required form="tags" name="{{id}}fg" value="{{t.text_colour}}"/>
+ <td><input {{disabled}} type="text" required form="tags" name="{{id}}bg" value="{{t.bg_colour}}"/>
+ <td><input {{disabled}} type="checkbox" form="tags" name="{{id}}enabled"
+ {% if t.enabled == 1%}checked{% endif %}/>
+</tr>
+{% endmacro %}
+
+{% block content %}
+<h2>tags</h2>
+<div class="tag-editor">
+ <table>
+ <tr><th><th>name<th>foreground<th>background<th>enabled
+ {%for tag in tags%}
+ {{tag_form(tag)}}
+ {%endfor %}
+ </table>
+
+ <form class="new-tag" method="POST" action="{{url_for('forum.new_tag',forum_id=forum.id)}}">
+ <input type="submit" value="create new tag"/>
+ </form>
+</div>
+
+<form id="tags" method="POST">
+ <p>confirm changes?</p>
+ <p>
+ <input type="submit" value="confirm">
+ <a href="{{url_for('forum.view_forum',forum_id=forum.id)}}">cancel</a>
+ </p>
+</form>
+
+{% endblock %}
+
diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html
index 7640439..b7309bf 100644
--- a/apioforum/templates/view_forum.html
+++ b/apioforum/templates/view_forum.html
@@ -33,6 +33,7 @@
{{ab("forum settings",url_for('forum.edit_forum',forum_id=forum.id))}}
{{ab("role/permission settings",url_for('forum.edit_roles',forum_id=forum.id))}}
{{ab("assign roles",url_for('forum.view_user_role',forum_id=forum.id))}}
+ {{ab("edit tags",url_for('forum.edit_tags',forum_id=forum.id))}}
{% endif %}
{% if has_permission(forum.id, g.user, "p_create_subforum") %}
{{ab("create subforum",url_for('forum.create_forum',forum_id=forum.id))}}
diff --git a/apioforum/util.py b/apioforum/util.py
index 8f836d1..c8dd8fd 100644
--- a/apioforum/util.py
+++ b/apioforum/util.py
@@ -2,6 +2,7 @@
import hsluv
import hashlib
+import re
# same algorithm as xep-0392
def gen_colour(s):
@@ -12,5 +13,6 @@ def gen_colour(s):
angle = 360*(val/65536)
col = hsluv.hsluv_to_hex([angle, 80, 70])
return col
-
-
+
+def sanitize_color(color):
+ return re.match("[a-zA-Z0-9-_#]*", color).group()