aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--apioforum/__init__.py1
-rw-r--r--apioforum/forum.py31
-rw-r--r--apioforum/templates/base.html2
-rw-r--r--apioforum/templates/common.html20
-rw-r--r--apioforum/templates/view_forum.html9
-rw-r--r--apioforum/templates/view_post.html2
-rw-r--r--apioforum/templates/view_thread.html3
-rw-r--r--apioforum/thread.py57
8 files changed, 101 insertions, 24 deletions
diff --git a/apioforum/__init__.py b/apioforum/__init__.py
index 087df81..60777fb 100644
--- a/apioforum/__init__.py
+++ b/apioforum/__init__.py
@@ -54,6 +54,7 @@ def create_app():
return dict(path_for_next=p)
app.jinja_env.globals.update(forum_path=forum.forum_path)
+ app.jinja_env.globals.update(post_jump=thread.post_jump)
from .roles import has_permission, is_bureaucrat, get_user_role
app.jinja_env.globals.update(
has_permission=has_permission,
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>&trade;</p>
<form class="inline-form" action="/search">
<input type="search" placeholder="query" name="q">
diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html
index f6b6f29..8eeef70 100644
--- a/apioforum/templates/common.html
+++ b/apioforum/templates/common.html
@@ -2,10 +2,6 @@
<a href="{{url_for('user.view_user',username=username)}}" class="username">{{username}}</a>
{%- endmacro %}
-{% macro post_url(post) -%}
- {{url_for('thread.view_thread', thread_id=post.thread)}}#post_{{post.id}}
-{%- endmacro %}
-
{% macro disp_post(post, buttons=False, forum=None, footer=None) %}
<div class="post {% if post.deleted %}deleted-post{% endif %}" id="post_{{post.id}}">
<div class="post-heading">
@@ -49,7 +45,7 @@
href="{{url_for('thread.view_post',post_id=post.id)}}">src</a>
{% endif %}
- <a class="post-anchor-link" href="{{post_url(post)}}">#{{post.id}}</a>
+ <a class="post-anchor-link" href="{{post_jump(post.id)}}">#{{post.id}}</a>
</span>
</div>
<div class="post-content md">
@@ -142,3 +138,17 @@
</desc>
</svg>
{% endmacro %}
+
+{% macro pagination_nav(page,max_pageno,view) %}
+<nav aria-label="pagination" id="pages">
+ {% if page > 1 %}
+ <a href="{{url_for(view,**kwargs)}}" aria-label="first page">&lt;&lt;</a>
+ <a href="{{url_for(view,page=page-1,**kwargs)}}" aria-label="previous page">&lt;</a>
+ {% endif %}
+ page {{page}} of {{max_pageno}}
+ {% if page < max_pageno %} {# > #}
+ <a href="{{url_for(view,page=page+1,**kwargs)}}" aria-label="next page">&gt;</a>
+ <a href="{{url_for(view,page=max_pageno,**kwargs)}}" aria-label="last page">&gt;&gt;</a>
+ {% endif %}
+</nav>
+{% endmacro %}
diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html
index 0eada1a..75144c8 100644
--- a/apioforum/templates/view_forum.html
+++ b/apioforum/templates/view_forum.html
@@ -1,5 +1,5 @@
{% extends 'base.html' %}
-{% from 'common.html' import ts, tag, disp_user, post_url, forum_breadcrumb, ab, vote_meter %}
+{% from 'common.html' import ts, tag, disp_user, post_url, forum_breadcrumb, ab, vote_meter, pagination_nav %}
{% block header %}
<h1>{% block title %}{{forum.name}}{% endblock %} <span class="thing-id">#{{forum.id}}</span></h1>
{% if forum.id != 1 %}
@@ -112,7 +112,7 @@ you do not have permission to create threads in this forum
{{ ts(thread.mrp_created) }}
</span>
<span class="thread-preview-post">
- <a href="{{url_for('thread.view_thread',thread_id=thread.id)}}#post_{{thread.mrp_id}}">
+ <a href="{{post_jump(thread.mrp_id)}}">
{{ thread.mrp_content[:500]|e }}
</a>
</span>
@@ -120,7 +120,7 @@ you do not have permission to create threads in this forum
{% else %}
<div class="listing-caption">
<a class="thread-preview-post"
- href="{{url_for('thread.view_thread',thread_id=thread.id)}}#post_{{thread.mrp_id}}">
+ href="{{post_jump(thread.mrp_id)}}">
latest post
</a>
</div>
@@ -133,6 +133,9 @@ you do not have permission to create threads in this forum
</div>
{%endfor%}
</div>
+{{ pagination_nav(page,max_pageno,'forum.view_forum',forum_id=forum.id) }}
+
+
{% else %}
<p>you do not have permission to view threads in this forum</p>
{% endif %}
diff --git a/apioforum/templates/view_post.html b/apioforum/templates/view_post.html
index 993c005..fcaf29b 100644
--- a/apioforum/templates/view_post.html
+++ b/apioforum/templates/view_post.html
@@ -8,5 +8,5 @@
{{disp_post(post,False)}}
<p>post source:</p>
<textarea readonly class="new-post-box" name="newcontent">{{post.content}}</textarea>
-<a href="{{url_for('thread.view_thread',thread_id=post.thread)}}">i am satisfied</a>
+<a href="{{post_jump(post.id)}}">i am satisfied</a>
{% endblock %}
diff --git a/apioforum/templates/view_thread.html b/apioforum/templates/view_thread.html
index 132fd44..fe22cfc 100644
--- a/apioforum/templates/view_thread.html
+++ b/apioforum/templates/view_thread.html
@@ -1,4 +1,4 @@
-{% from 'common.html' import disp_post,tag,thread_breadcrumb,vote_meter %}
+{% from 'common.html' import disp_post,tag,thread_breadcrumb,vote_meter,pagination_nav %}
{% extends 'base.html' %}
{% block header %}
<h1>{%block title %}{{thread.title}}{% endblock %} <span class="thing-id">#{{thread.id}}</span></h1>
@@ -69,6 +69,7 @@
{% endif %}
{% endfor %}
</div>
+{{ pagination_nav(page,max_pageno,'thread.view_thread',thread_id=thread.id) }}
{% if g.user and has_permission(thread.forum, g.user, "p_reply_threads") %}
<form class="new-post" action="{{url_for('thread.create_post',thread_id=thread.id)}}" method="POST">
<textarea class="new-post-box" placeholder="your post here..." name="content"></textarea>
diff --git a/apioforum/thread.py b/apioforum/thread.py
index 2fc9dca..f3bcc59 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,41 @@ from .forum import get_avail_tags
bp = Blueprint("thread", __name__, url_prefix="/thread")
-def post_jump(thread_id, post_id):
- return url_for("thread.view_thread",thread_id=thread_id)+"#post_"+str(post_id)
+POSTS_PER_PAGE = 20
+
+def which_page(post_id,return_thread_id=False):
+ # 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
+
+ thread_id = db.execute('select thread from posts where id = ?',(post_id,)).fetchone()['thread']
+
+ number_of_things_before_the_thing = db.execute('select count(*) as c, thread as t from posts where thread = ? and id < ?;',(thread_id,post_id)).fetchone()['c']
+
+
+ page = 1+math.floor(number_of_things_before_the_thing/POSTS_PER_PAGE)
+ if return_thread_id:
+ return page, thread_id
+ else:
+ return page
+
+def post_jump(post_id):
+ page,thread_id=which_page(post_id,True)
+ return url_for("thread.view_thread",thread_id=thread_id,page=page)+"#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 +56,17 @@ 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()
+
+ num_posts = db.execute("SELECT count(*) as count FROM posts WHERE posts.thread = ?",(thread_id,)).fetchone()['count']
+ max_pageno = math.ceil(num_posts/POSTS_PER_PAGE)
+
tags = db.execute(
"""SELECT tags.* FROM tags
INNER JOIN thread_tags ON thread_tags.tag = tags.id
@@ -72,6 +111,8 @@ def view_thread(thread_id):
poll=poll,
votes=votes,
has_voted=has_voted,
+ page=page,
+ max_pageno=max_pageno,
)
def register_vote(thread,pollval):
@@ -215,7 +256,7 @@ def create_post(thread_id):
)
db.commit()
flash("post posted postfully")
- return redirect(post_jump(thread_id, post_id))
+ return redirect(post_jump(post_id))
return redirect(url_for('thread.view_thread',thread_id=thread_id))
@bp.route("/delete_post/<int:post_id>", methods=["GET","POST"])
@@ -287,7 +328,7 @@ def edit_post(post_id):
"UPDATE posts SET content = ?, edited = 1, updated = current_timestamp WHERE id = ?",(newcontent,post_id))
db.commit()
flash("post edited editiously")
- return redirect(post_jump(post['thread'],post_id))
+ return redirect(post_jump(post_id))
else:
flash(err)
return render_template("edit_post.html",post=post)