diff options
-rw-r--r-- | apioforum/forum.py | 31 | ||||
-rw-r--r-- | apioforum/templates/base.html | 2 | ||||
-rw-r--r-- | apioforum/templates/view_forum.html | 13 | ||||
-rw-r--r-- | apioforum/thread.py | 35 |
4 files changed, 71 insertions, 10 deletions
diff --git a/apioforum/forum.py b/apioforum/forum.py index 2931df9..87d4022 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -13,8 +13,11 @@ from .roles import get_forum_roles,has_permission,is_bureaucrat,get_user_role, p from .permissions import is_admin from sqlite3 import OperationalError import datetime +import math import functools +THREADS_PER_PAGE = 20 + bp = Blueprint("forum", __name__, url_prefix="/") @bp.route("/") @@ -46,7 +49,7 @@ def forum_path(forum_id): ancestors.reverse() return ancestors -def forum_route(relative_path, **kwargs): +def forum_route(relative_path, pagination=False, **kwargs): def decorator(f): path = "/<int:forum_id>" if relative_path != "": @@ -62,6 +65,9 @@ def forum_route(relative_path, **kwargs): abort(404) return f(forum, *args, **kwargs) + if pagination: + wrapper = bp.route(path+"/page/<int:page>", **kwargs)(wrapper) + return decorator def requires_permission(permission, login_required=True): @@ -83,9 +89,12 @@ def requires_bureaucrat(f): return f(forum, *args, **kwargs) return wrapper -@forum_route("") + +@forum_route("",pagination=True) @requires_permission("p_view_forum", login_required=False) -def view_forum(forum): +def view_forum(forum,page=1): + if page < 1: + abort(400) db = get_db() threads = db.execute( """SELECT @@ -100,8 +109,18 @@ def view_forum(forum): 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; - """,(forum['id'],)).fetchall() + ORDER BY threads.updated DESC + LIMIT ? OFFSET ?; + """,( + forum['id'], + THREADS_PER_PAGE, + (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'] + max_pageno = math.ceil(num_threads/THREADS_PER_PAGE) + thread_tags = {} thread_polls = {} @@ -169,6 +188,8 @@ def view_forum(forum): bureaucrats=bureaucrats, thread_polls=thread_polls, avail_tags=avail_tags, + max_pageno=max_pageno, + page=page, ) @forum_route("create_thread",methods=("GET","POST")) diff --git a/apioforum/templates/base.html b/apioforum/templates/base.html index ca1dd87..b97117f 100644 --- a/apioforum/templates/base.html +++ b/apioforum/templates/base.html @@ -10,7 +10,7 @@ <link rel="icon" href="//gh0.pw/favicon.ico"> </head> <body> - <nav id="navbar"> + <nav aria-label="main" id="navbar"> <p style="font-family: monospace;"><b>apio</b><i>forum</i>™</p> <form class="inline-form" action="/search"> <input type="search" placeholder="query" name="q"> diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html index 0eada1a..dec9234 100644 --- a/apioforum/templates/view_forum.html +++ b/apioforum/templates/view_forum.html @@ -133,6 +133,19 @@ you do not have permission to create threads in this forum </div> {%endfor%} </div> +<nav aria-label="pagination" id="pages"> + {% if page > 1 %} + <a href="{{url_for('forum.view_forum',forum_id=forum.id)}}" aria-label="first page"><<</a> + <a href="{{url_for('forum.view_forum',forum_id=forum.id,page=page-1)}}" aria-label="previous page"><</a> + {% endif %} + page {{page}} of {{max_pageno}} + {% if page < max_pageno %} {# > #} + <a href="{{url_for('forum.view_forum',forum_id=forum.id,page=page+1)}}" aria-label="next page">></a> + <a href="{{url_for('forum.view_forum',forum_id=forum.id,page=max_pageno)}}" aria-label="last page">>></a> + {% endif %} +</nav> + + {% else %} <p>you do not have permission to view threads in this forum</p> {% endif %} diff --git a/apioforum/thread.py b/apioforum/thread.py index 2fc9dca..b281d0a 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -1,6 +1,6 @@ # view posts in thread -import itertools +import itertools, math from flask import ( Blueprint, render_template, abort, request, g, redirect, @@ -12,11 +12,33 @@ from .forum import get_avail_tags bp = Blueprint("thread", __name__, url_prefix="/thread") +POSTS_PER_PAGE = 20 + +def which_page(post_id): + # on which page lieth the post in question? + # forget not that page numbers employeth a system that has a base of 1. + # the + # we need impart the knowledgf e into ourselves pertaining to the + # number of things + # before the thing + # yes + + db = get_db() + # ASSUMES THAT post ids are consecutive and things + # this is probably a reasonable assumption + number_of_things_before_the_thing = db.execute('select count(*) as c from posts where thread = (select thread from posts where id = ?) and id < ?;',(post_id,post_id)).fetchone()['c'] + + return 1+math.floor(number_of_things_before_the_thing/POSTS_PER_PAGE) + + def post_jump(thread_id, post_id): return url_for("thread.view_thread",thread_id=thread_id)+"#post_"+str(post_id) @bp.route("/<int:thread_id>") -def view_thread(thread_id): +@bp.route("/<int:thread_id>/page/<int:page>") +def view_thread(thread_id,page=1): + if page < 1: + abort(400) db = get_db() thread = db.execute("SELECT * FROM threads WHERE id = ?;",(thread_id,)).fetchone() if thread is None: @@ -26,8 +48,13 @@ def view_thread(thread_id): posts = db.execute(""" SELECT * FROM posts WHERE posts.thread = ? - ORDER BY created ASC; - """,(thread_id,)).fetchall() + ORDER BY created ASC + LIMIT ? OFFSET ?; + """,( + thread_id, + POSTS_PER_PAGE, + (page-1)*POSTS_PER_PAGE, + )).fetchall() tags = db.execute( """SELECT tags.* FROM tags INNER JOIN thread_tags ON thread_tags.tag = tags.id |