summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--apioforum/__init__.py6
-rw-r--r--apioforum/db.py4
-rw-r--r--apioforum/forum.py31
-rw-r--r--apioforum/static/style.css5
-rw-r--r--apioforum/templates/common.html37
-rw-r--r--apioforum/templates/view_forum.html7
-rw-r--r--apioforum/templates/view_thread.html9
-rw-r--r--apioforum/thread.py6
-rw-r--r--setup.py1
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
diff --git a/setup.py b/setup.py
index 089f3a4..15992ed 100644
--- a/setup.py
+++ b/setup.py
@@ -10,5 +10,6 @@ setup(
'markdown',
'bleach',
'pymdown-extensions',
+ 'hsluv',
],
)