diff options
-rw-r--r-- | apioforum/forum.py | 88 | ||||
-rw-r--r-- | apioforum/orm.py | 5 | ||||
-rw-r--r-- | apioforum/post.py | 3 | ||||
-rw-r--r-- | apioforum/templates/view_forum.html | 25 | ||||
-rw-r--r-- | apioforum/thread.py | 41 | ||||
-rw-r--r-- | apioforum/util.py | 2 |
6 files changed, 100 insertions, 64 deletions
diff --git a/apioforum/forum.py b/apioforum/forum.py index f88900f..93dbddb 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -86,7 +86,7 @@ def view_forum(forum,page=1): 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)) + abort(400) avail_tags = forum.avail_tags() @@ -114,28 +114,37 @@ def view_forum(forum,page=1): abort(400) - threads = db.execute( - 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, - most_recent_posts.author as mrp_author, - most_recent_posts.id as mrp_id, - most_recent_posts.content as mrp_content, - most_recent_posts.deleted as mrp_deleted - 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 - 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, - THREADS_PER_PAGE, - (page-1)*THREADS_PER_PAGE, - )).fetchall() + threads = Thread.from_row_list(db.execute( + f"""select * from threads + left outer join thread_tags on threads.id = thread_tags.thread + where threads.forum = ? {tagfilter_clause} + order by {sortby_by} {sortby_dir} + limit ? offset ?; + """,(forum.id, THREADS_PER_PAGE, (page-1)*THREADS_PER_PAGE)).fetchall()) + + # i want to preserve this + #threads = db.execute( + # 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, + # most_recent_posts.author as mrp_author, + # most_recent_posts.id as mrp_id, + # most_recent_posts.content as mrp_content, + # most_recent_posts.deleted as mrp_deleted + # 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 + # 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, + # THREADS_PER_PAGE, + # (page-1)*THREADS_PER_PAGE, + # )).fetchall() num_threads = db.execute(f""" SELECT count(*) AS count FROM threads @@ -145,24 +154,16 @@ def view_forum(forum,page=1): max_pageno = math.ceil(num_threads/THREADS_PER_PAGE) - thread_tags = {} thread_polls = {} for thread in threads: - thread_tags[thread['id']] = db.execute( - """SELECT tags.* FROM tags - INNER JOIN thread_tags ON thread_tags.tag = tags.id - WHERE thread_tags.thread = ? - ORDER BY tags.id; - """,(thread['id'],)).fetchall() - - if thread['poll'] is not None: + if thread.poll is not None: # todo: make this not be duplicated from thread.py poll_row= db.execute(""" SELECT polls.*,total_vote_counts.total_votes FROM polls LEFT OUTER JOIN total_vote_counts ON polls.id = total_vote_counts.poll WHERE polls.id = ?; - """,(thread['poll'],)).fetchone() + """,(thread.poll,)).fetchone() options = db.execute(""" SELECT poll_options.*, vote_counts.num FROM poll_options @@ -176,7 +177,7 @@ def view_forum(forum,page=1): poll.update(poll_row) poll['options'] = options poll['total_votes']=poll['total_votes'] or 0 - thread_polls[thread['id']]=poll + thread_polls[thread.id]=poll # subforums don't exist any more @@ -191,13 +192,13 @@ def view_forum(forum,page=1): # ORDER BY name ASC # """,(forum.id,)).fetchall() subforums = [] - for s in subforums_rows: - a={} - a.update(s) - if a['updated'] is not None: - a['updated'] = datetime.datetime.fromisoformat(a['updated']) - if has_permission(a['id'],g.user,"p_view_forum",login_required=False): - subforums.append(a) + #for s in subforums_rows: + # a={} + # a.update(s) + # if a['updated'] is not None: + # a['updated'] = datetime.datetime.fromisoformat(a['updated']) + # if has_permission(a['id'],g.user,"p_view_forum",login_required=False): + # subforums.append(a) bureaucrats = db.execute(""" SELECT user FROM role_assignments @@ -209,7 +210,6 @@ def view_forum(forum,page=1): forum=forum, subforums=subforums, threads=threads, - thread_tags=thread_tags, bureaucrats=bureaucrats, thread_polls=thread_polls, max_pageno=max_pageno, @@ -461,3 +461,7 @@ def search(): display_thread_id[ix] = False last_thread = result["thread"] return render_template("search_results.html", results=results, query=query, display_thread_id=display_thread_id) + + +#circular import bees +from .thread import Thread diff --git a/apioforum/orm.py b/apioforum/orm.py index 97124c7..b364be1 100644 --- a/apioforum/orm.py +++ b/apioforum/orm.py @@ -30,3 +30,8 @@ class DBObj: for fieldname in cls.fields: setattr(self,fieldname,row[fieldname]) return self + + @classmethod + def from_row_list(cls, row_list): + """takes a list of database rows and returns a list of item objects""" + return [cls.from_row(r) for r in row_list] diff --git a/apioforum/post.py b/apioforum/post.py index 86753ad..9e35c37 100644 --- a/apioforum/post.py +++ b/apioforum/post.py @@ -1,6 +1,9 @@ # wow, a dedicated module # +import math + +from .db import get_db from .orm import DBObj from .thread import POSTS_PER_PAGE from flask import url_for diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html index 24b9cbe..efdb124 100644 --- a/apioforum/templates/view_forum.html +++ b/apioforum/templates/view_forum.html @@ -66,13 +66,16 @@ <h2>threads</h2> <p> {% if has_permission(forum.id, g.user, "p_create_threads") %} -<a class="actionbutton" href="{{url_for('forum.create_thread',forum_id=forum.id)}}">create new thread</a> + <a class="actionbutton" href="{{url_for('forum.create_thread',forum_id=forum.id)}}"> + create new thread + </a> {% elif has_permission(forum.id, g.user, "p_create_threads", login_required=False) %} -please log in to create a new thread + please log in to create a new thread {% else %} -you do not have permission to create threads in this forum + you do not have permission to create threads in this forum {% endif %} + {% macro sortby_option(code, text) %} {% if current_sortby==code %} <option selected value="{{code}}">{{text}}</option> @@ -81,7 +84,6 @@ you do not have permission to create threads in this forum {% endif %} {% endmacro %} - <details {%- if current_sortby != "ad" or tagfilter_tag is not none %} open @@ -123,6 +125,7 @@ you do not have permission to create threads in this forum {{ pagination_nav(page,max_pageno,'forum.view_forum',forum_id=forum.id) }} <div class="thread-list"> {%for thread in threads%} + {% set mrp = thread.most_recent_post() %} <div class="listing"> <div class="listing-main"> <div class="listing-title"> @@ -131,7 +134,7 @@ you do not have permission to create threads in this forum </a> </div> <div class="thread-listing-tags"> - {% for the_tag in thread_tags[thread.id] %} + {% for the_tag in thread.tags() %} {{tag(the_tag)}} {% endfor %} </div> @@ -142,22 +145,22 @@ you do not have permission to create threads in this forum {{ ts(thread.created) }} </div> </div> - {% if not thread.mrp_deleted %} + {% if not mrp.deleted %} <div class="listing-caption"> - {{ disp_user(thread.mrp_author) }} + {{ disp_user(mrp.author) }} <span class="thread-preview-ts"> - {{ ts(thread.mrp_created) }} + {{ ts(mrp.created) }} </span> <span class="thread-preview-post"> - <a href="{{post_jump(thread.mrp_id)}}"> - {{ thread.mrp_content[:500]|e }} + <a href="{{ mrp.jump_url() }}"> + {{ mrp.content[:500]|e }} </a> </span> </div> {% else %} <div class="listing-caption"> <a class="thread-preview-post" - href="{{post_jump(thread.mrp_id)}}"> + href="{{ mrp.jump_url() }}"> latest post </a> </div> diff --git a/apioforum/thread.py b/apioforum/thread.py index f80786c..a5862ba 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -10,7 +10,6 @@ from flask import ( from .db import get_db from .roles import has_permission from . import webhooks -from .forum import Forum from .orm import DBObj POSTS_PER_PAGE = 28 @@ -18,8 +17,8 @@ POSTS_PER_PAGE = 28 class Thread(DBObj,table="threads"): fields = ["id","title","creator","created","updated","forum","poll"] - # maybe this should be on Post instead????? - @staticmethod + # maybe this should be on Post instead????? + @staticmethod def which_page(post): """ return what page of a thread the given post is on @@ -34,14 +33,33 @@ class Thread(DBObj,table="threads"): page = 1+math.floor(amt_before/POSTS_PER_PAGE) return page - - - - - - + def tags(self): + db = get_db() + tags = db.execute(""" + select * from tags + inner join thread_tags on thread_tags.tag = tags.id + where thread_tags.thread = ? + order by tags.id; + """,(self.id,)).fetchall() + return tags + + def number_of_posts(self): + db = get_db() + return db.execute(""" + select count(*) as c from posts + where thread = ?;""",(self.id,)).fetchone()['c'] + def most_recent_post(self): + db = get_db() + post_row = db.execute(""" + select * from posts + where posts.thread = ? + order by posts.id desc + limit 1;""",(self.id,)).fetchone() + if post_row is None: return None + return Post.from_row(post_row) + bp = Blueprint("thread", __name__, url_prefix="/thread") @@ -453,4 +471,7 @@ def config_thread(thread): return render_template("config_thread.html", thread=thread,thread_tags=thread_tags,avail_tags=avail_tags) - + +# circular import bee +from .forum import Forum +from .post import Post diff --git a/apioforum/util.py b/apioforum/util.py index 64bdf20..976d1a6 100644 --- a/apioforum/util.py +++ b/apioforum/util.py @@ -10,7 +10,7 @@ def gen_colour(s): two_bytes=h.digest()[:2] val = int.from_bytes(two_bytes, 'little') angle = 360*(val/65536) - col = hsluv.hsluv_to_hex([angle, 80, 70]) + col = hsluv.hsluv_to_hex([angle, 90, 85]) return col |