diff options
-rw-r--r-- | apioforum/forum.py | 53 | ||||
-rw-r--r-- | apioforum/static/style.css | 3 | ||||
-rw-r--r-- | apioforum/templates/common.html | 16 | ||||
-rw-r--r-- | apioforum/templates/view_forum.html | 58 |
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%} |