aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2022-06-11 00:24:28 +0100
committerubq323 <ubq323@ubq323.website>2022-06-11 00:24:28 +0100
commit32bbc59c5b57c13b1433ad212b027a3ac694ac24 (patch)
tree7da4b1b4d5fee727087d8967ab8f7e1ba25041de
parent42c6124929d9d85eb94a8c97d3bfa7518f7c1c77 (diff)
parent421e5d579a005214a7ff3f3305b76e8be8037694 (diff)
Merge branch 'thread-filtering-2' into trunk
-rw-r--r--apioforum/forum.py53
-rw-r--r--apioforum/static/style.css3
-rw-r--r--apioforum/templates/common.html16
-rw-r--r--apioforum/templates/view_forum.html58
4 files changed, 110 insertions, 20 deletions
diff --git a/apioforum/forum.py b/apioforum/forum.py
index 305cb51..988c9a5 100644
--- a/apioforum/forum.py
+++ b/apioforum/forum.py
@@ -96,8 +96,42 @@ def view_forum(forum,page=1):
if page < 1:
abort(400)
db = get_db()
+
+ sortby = request.args.get("sortby","ad")
+ try:
+ sortby_dir = {'d':'DESC','a':'ASC'}[sortby[1]]
+ sortby_by = {'a':'threads.updated','c':'threads.created'}[sortby[0]]
+ except KeyError:
+ return redirect(url_for('forum.view_forum',forum_id=forum['id']))
+
+ avail_tags = get_avail_tags(forum['id'])
+
+ tagfilter = request.args.get("tagfilter",None)
+ if tagfilter == "":
+ tagfilter = None
+ tagfilter_clause = ""
+ tagfilter_tag = None
+ if tagfilter is not None:
+ try:
+ tagfilter = int(tagfilter)
+ except ValueError:
+ flash(f'invalid tag id "{tagfilter}"')
+ return redirect(url_for('forum.view_forum',forum_id=forum['id']))
+ else:
+ # there is no risk of sql injection because
+ # we just checked it is an int
+ tagfilter_clause = f"AND thread_tags.tag = {tagfilter}"
+ for the_tag in avail_tags:
+ if the_tag['id'] == tagfilter:
+ tagfilter_tag = the_tag
+ break
+ else:
+ flash("that tag doesn't exist or isn't available here")
+ return redirect(url_for('forum.view_forum',forum_id=forum['id']))
+
+
threads = db.execute(
- """SELECT
+ f"""SELECT
threads.id, threads.title, threads.creator, threads.created,
threads.updated, threads.poll, number_of_posts.num_replies,
most_recent_posts.created as mrp_created,
@@ -108,8 +142,10 @@ def view_forum(forum,page=1):
FROM threads
INNER JOIN most_recent_posts ON most_recent_posts.thread = threads.id
INNER JOIN number_of_posts ON number_of_posts.thread = threads.id
- WHERE threads.forum = ?
- ORDER BY threads.updated DESC
+ LEFT OUTER JOIN thread_tags ON threads.id = thread_tags.thread
+ WHERE threads.forum = ? {tagfilter_clause}
+ GROUP BY threads.id
+ ORDER BY {sortby_by} {sortby_dir}
LIMIT ? OFFSET ?;
""",(
forum['id'],
@@ -117,14 +153,17 @@ def view_forum(forum,page=1):
(page-1)*THREADS_PER_PAGE,
)).fetchall()
- # XXX: update this when thread filtering happens
- num_threads = db.execute("SELECT count(*) AS count FROM threads WHERE threads.forum = ?",(forum['id'],)).fetchone()['count']
+ num_threads = db.execute(f"""
+ SELECT count(*) AS count FROM threads
+ LEFT OUTER JOIN thread_tags ON threads.id = thread_tags.thread
+ WHERE threads.forum = ? {tagfilter_clause};
+ """,(forum['id'],)).fetchone()['count']
+
max_pageno = math.ceil(num_threads/THREADS_PER_PAGE)
thread_tags = {}
thread_polls = {}
- avail_tags = get_avail_tags(forum['id'])
#todo: somehow optimise this
for thread in threads:
@@ -190,6 +229,8 @@ def view_forum(forum,page=1):
avail_tags=avail_tags,
max_pageno=max_pageno,
page=page,
+ current_sortby=sortby,
+ tagfilter_tag=tagfilter_tag,
)
@forum_route("create_thread",methods=("GET","POST"))
diff --git a/apioforum/static/style.css b/apioforum/static/style.css
index d50c7b0..cd275ff 100644
--- a/apioforum/static/style.css
+++ b/apioforum/static/style.css
@@ -291,4 +291,5 @@ fieldset { margin-bottom: 15px; }
content: "/\00a0";
padding: 8px;
}
-
+
+
diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html
index 46402df..fae4b7c 100644
--- a/apioforum/templates/common.html
+++ b/apioforum/templates/common.html
@@ -67,8 +67,20 @@
<time title="{{dt.isoformat(' ')}}" datetime="{{dt.isoformat(' ')}}">{{dt | fuzzy}}</time>
{%- endmacro %}
-{% macro tag(the_tag) -%}
-<span class="tag" style="color: {{the_tag.text_colour}}; background-color: {{the_tag.bg_colour}}">{{the_tag.name}}</span>
+{% macro tag(the_tag,href=None) -%}
+{% if href is none %}
+{% set el = "span" %}
+{% else %}
+{% set el = "a" %}
+{% endif %}
+<{{el}}
+ class="tag"
+ style="color: {{the_tag.text_colour}}; background-color: {{the_tag.bg_colour}}"
+ {% if href is not none -%}
+ href="{{href}}"
+ {%- endif -%}>
+ {{-the_tag.name-}}
+</{{el}}>
{%- endmacro %}
{% macro ab(name,href) -%}
diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html
index 649c87c..b03d51a 100644
--- a/apioforum/templates/view_forum.html
+++ b/apioforum/templates/view_forum.html
@@ -26,13 +26,6 @@
<p>your role in this forum: {{role}}</p>
{% endif %}
- <p>available tags:
- {% for the_tag in avail_tags %}
- {{tag(the_tag)}}
- {% else %}
- <em>(none available)</em>
- {% endfor %}
- </p>
</div>
<p>
@@ -83,7 +76,53 @@ please log in to create a new thread
you do not have permission to create threads in this forum
{% endif %}
-{% if has_permission(forum.id, g.user, "p_view_threads", login_required=False) %}
+{% macro sortby_option(code, text) %}
+{% if current_sortby==code %}
+<option selected value="{{code}}">{{text}}</option>
+{% else %}
+<option value="{{code}}">{{text}}</option>
+{% endif %}
+{% endmacro %}
+
+
+<details
+{%- if current_sortby != "ad" or tagfilter_tag is not none %}
+ open
+{%- endif -%}>
+ <summary>sorting and filtering options</summary>
+
+<form class="inline-form small-form" method="get">
+ <fieldset>
+ <label for="sortby">sort threads by</label>
+ <select name="sortby">
+ {{ sortby_option("ad", "last activity (newest first)") }}
+ {{ sortby_option("aa", "last activity (oldest first)") }}
+ {{ sortby_option("cd", "creation time (newest first)") }}
+ {{ sortby_option("ca", "creation time (oldest first)") }}
+ </select>
+ <p>filter by tag:</p>
+ <input {% if tagfilter_tag is none %}checked{% endif %} type=radio id=tagfilter-none name=tagfilter value="">
+ <label for=tagfilter-none>don't</label>
+
+ {% for the_tag in avail_tags %}
+
+ <input type="radio" id="tagfilter-{{the_tag.id}}"
+ name="tagfilter" value="{{the_tag.id}}"
+ {% if tagfilter_tag.id == the_tag.id %}checked{% endif %}>
+ <label for="tagfilter-{{the_tag.id}}">
+ {{tag(the_tag)}}
+ </label>
+ {% endfor %}
+ <br>
+
+
+ <input type="submit" value="apply">
+ </fieldset>
+</form>
+
+</details>
+</p>
+
{{ pagination_nav(page,max_pageno,'forum.view_forum',forum_id=forum.id) }}
<div class="thread-list">
{%for thread in threads%}
@@ -136,7 +175,4 @@ you do not have permission to create threads in this forum
</div>
-{% else %}
-<p>you do not have permission to view threads in this forum</p>
-{% endif %}
{%endblock%}