diff options
-rw-r--r-- | apioforum/__init__.py | 6 | ||||
-rw-r--r-- | apioforum/db.py | 4 | ||||
-rw-r--r-- | apioforum/forum.py | 31 | ||||
-rw-r--r-- | apioforum/static/style.css | 5 | ||||
-rw-r--r-- | apioforum/templates/common.html | 37 | ||||
-rw-r--r-- | apioforum/templates/view_forum.html | 7 | ||||
-rw-r--r-- | apioforum/templates/view_thread.html | 9 | ||||
-rw-r--r-- | apioforum/thread.py | 6 | ||||
-rw-r--r-- | setup.py | 1 |
9 files changed, 99 insertions, 7 deletions
diff --git a/apioforum/__init__.py b/apioforum/__init__.py index 30dd813..e20f67b 100644 --- a/apioforum/__init__.py +++ b/apioforum/__init__.py @@ -17,6 +17,9 @@ def create_app(): except OSError: pass + app.jinja_env.trim_blocks = True + app.jinja_env.lstrip_blocks = True + from . import db db.init_app(app) from . import permissions @@ -40,6 +43,9 @@ def create_app(): from .fuzzy import fuzzy app.jinja_env.filters['fuzzy']=fuzzy + from .util import gen_colour + app.jinja_env.filters['gen_colour']=gen_colour + @app.context_processor def path_for_next(): p = request.path diff --git a/apioforum/db.py b/apioforum/db.py index 97bd0e2..abcd774 100644 --- a/apioforum/db.py +++ b/apioforum/db.py @@ -151,6 +151,10 @@ CREATE VIEW most_recent_posts AS CREATE VIEW number_of_posts AS SELECT thread, count(*) AS num_replies FROM posts GROUP BY thread; """, +""" +CREATE VIEW total_vote_counts AS + SELECT poll, count(*) AS total_votes FROM votes WHERE current AND NOT is_retraction GROUP BY poll; +""", ] def init_db(): diff --git a/apioforum/forum.py b/apioforum/forum.py index 1d26f3a..a736af9 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -37,7 +37,7 @@ def view_forum(forum_id): threads = db.execute( """SELECT threads.id, threads.title, threads.creator, threads.created, - threads.updated, number_of_posts.num_replies, + 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, @@ -49,6 +49,7 @@ def view_forum(forum_id): ORDER BY threads.updated DESC; """,(forum_id,)).fetchall() thread_tags = {} + thread_polls = {} #todo: somehow optimise this for thread in threads: thread_tags[thread['id']] = db.execute( @@ -58,6 +59,29 @@ def view_forum(forum_id): ORDER BY tags.id; """,(thread['id'],)).fetchall() + 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() + options = db.execute(""" + SELECT poll_options.*, vote_counts.num + FROM poll_options + LEFT OUTER JOIN vote_counts ON poll_options.poll = vote_counts.poll + AND poll_options.option_idx = vote_counts.option_idx + WHERE poll_options.poll = ? + ORDER BY option_idx asc; + """,(poll_row['id'],)).fetchall() + + poll = {} + poll.update(poll_row) + poll['options'] = options + poll['total_votes']=poll['total_votes'] or 0 + thread_polls[thread['id']]=poll + + subforums_rows = db.execute(""" SELECT max(threads.updated) as updated, forums.* FROM forums LEFT OUTER JOIN threads ON threads.forum=forums.id @@ -74,11 +98,16 @@ def view_forum(forum_id): subforums.append(a) + + + + print(thread_polls) return render_template("view_forum.html", forum=forum, subforums=subforums, threads=threads, thread_tags=thread_tags, + thread_polls=thread_polls, ) @bp.route("/<int:forum_id>/create_thread",methods=("GET","POST")) diff --git a/apioforum/static/style.css b/apioforum/static/style.css index 62215c7..237cad6 100644 --- a/apioforum/static/style.css +++ b/apioforum/static/style.css @@ -138,6 +138,11 @@ nav#navbar .links { display: flex; } .thread-preview-post { font-style: italic; } .thread-preview-ts { font-weight: bold; } +.thread-vote-summary { + margin-top: 4px; + margin-bottom: -8px; +} + /* wide screens */ @media all and (min-width: 600px) { .listing-title { font-size: larger; } diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html index 44cfbce..286bec8 100644 --- a/apioforum/templates/common.html +++ b/apioforum/templates/common.html @@ -76,3 +76,40 @@ <li>{{ thread.title }}</li> {% endcall -%} {% endmacro %} + +{% macro vote_meter(poll) %} + {% set total_votes = poll.total_votes %} + {% set n = namespace() %} + {% set n.runningtotal = 0 %} + <svg width="100%" height="15px" xmlns="http://www.w3.org/2000/svg"> + {% if total_votes == 0 %} + <text text-anchor="middle" dominant-baseline="middle" x="11%" y="55%" fill="black" style="font-size:15px">no votes</text> + {% else %} + {% for opt in poll.options %} + {% set opt_count = opt.num or 0 %} + {% set colour = (loop.count|string + opt.text)|gen_colour %} + {% if opt_count != 0 %} + {% set percentage = 100*(opt_count/total_votes) %} + {# todo: do this in css somehow #} + {% if opt.text|length > 10 %} + {% set opt_text = opt.text[:7] + "..." %} + {% else %} + {% set opt_text = opt.text %} + {% endif %} + <rect y="0" height="100%" x="{{n.runningtotal}}%" width="{{percentage}}%" stroke="black" fill="{{colour}}" /> + <text text-anchor="middle" dominant-baseline="middle" y="55%" fill="black" style="font-size:15px" x="{{n.runningtotal+(percentage/2)}}%"> + {{opt_text}}: {{opt_count}} + </text> + {% set n.runningtotal = n.runningtotal + percentage %} + {% endif %} + {% endfor %} + {% endif %} + <desc> + poll: {{poll.title}} + {% for opt in poll.options %} + option "{{opt.text}}": {{opt.num or 0}} votes + {% endfor %} + total votes: {{total_votes}} + </desc> + </svg> +{% endmacro %} diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html index d075d85..88be22f 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 %} +{% from 'common.html' import ts, tag, disp_user, post_url, forum_breadcrumb, vote_meter %} {% block header %} <h1>{% block title %}{{forum.name}}{%endblock%}</h1> {% if forum.id != 1 %} @@ -76,6 +76,11 @@ </span> </div> {#{% endif %}#} + {% if thread_polls[thread.id] %} + <div class="thread-vote-summary"> + {{ vote_meter(thread_polls[thread.id]) }} + </div> + {% endif %} </div> {%endfor%} </div> diff --git a/apioforum/templates/view_thread.html b/apioforum/templates/view_thread.html index d4a43ef..29914e8 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 %} +{% from 'common.html' import disp_post,tag,thread_breadcrumb,vote_meter %} {% extends 'base.html' %} {% block header %} <h1>{%block title %}{{thread.title}}{% endblock %}</h1> @@ -8,11 +8,12 @@ {%block content%} {% if poll %} <p>{{poll.title}}</p> -<ul> +<ol> {%for opt in poll.options%} - <li>#{{opt.option_idx}} - {{opt.text}} - {{opt.num or 0}}</li> + <li value="{{opt.option_idx}}"><i>{{opt.text}}</i>: {{opt.num or 0}} votes</li> {%endfor%} -</ul> +</ol> +{{ vote_meter(poll) }} {% endif %} <div class="thread-top-bar"> <span class="thread-top-bar-a"> diff --git a/apioforum/thread.py b/apioforum/thread.py index daf0b85..f8e8036 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -33,7 +33,11 @@ def view_thread(thread_id): poll = None votes = None if thread['poll'] is not None: - poll_row = db.execute("SELECT * FROM polls where id = ?",(thread['poll'],)).fetchone() + 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() options = db.execute(""" SELECT poll_options.*, vote_counts.num FROM poll_options @@ -10,5 +10,6 @@ setup( 'markdown', 'bleach', 'pymdown-extensions', + 'hsluv', ], ) |