diff options
-rw-r--r-- | apioforum/templates/config_thread.html | 25 | ||||
-rw-r--r-- | apioforum/thread.py | 80 |
2 files changed, 101 insertions, 4 deletions
diff --git a/apioforum/templates/config_thread.html b/apioforum/templates/config_thread.html index b26a73d..2c9804e 100644 --- a/apioforum/templates/config_thread.html +++ b/apioforum/templates/config_thread.html @@ -2,6 +2,7 @@ {% from 'common.html' import tag %} {% block header %}<h1>{% block title %}configure thread '{{thread.title}}'{% endblock %}</h1>{% endblock %} {% block content %} +<h2>thread options</h2> <form method="post"> <fieldset> <legend>title</legend> @@ -27,4 +28,28 @@ <input type="submit" value="confirm"> <a href="{{url_for('thread.view_thread',thread_id=thread.id)}}">cancel</a> </form> + +{% if thread.poll is none %} +<h2>create poll</h2> +<form method="post" action="{{url_for('thread.create_poll',thread_id=thread.id)}}"> + <fieldset> + <legend>create poll</legend> + <label for="polltitle">question title</label> + <input type="title" id="polltitle" name="polltitle"> + <br> + <label for="polloptions">potential options (one per line)</label> + <textarea name="polloptions" id="polloptions"></textarea> + </fieldset> + <p>important: once a poll is created, you will not be able to modify it except to delete it entirely</p> + <input type="submit" value="create"> +</form> +{% else %} +<h2>delete poll</h2> +<p>there is already a poll attached to this thread. you can delete it, which will allow you to create a new one, but this will erase all existing votes and data for the current poll.</p> +<form action="{{url_for('thread.delete_poll',thread_id=thread.id)}}" method="post"> + <input type="submit" value="confirm: delete poll"> +</form> + +{% endif %} + {% endblock %} diff --git a/apioforum/thread.py b/apioforum/thread.py index ce451ab..ec98d89 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -1,8 +1,10 @@ # view posts in thread +import itertools + from flask import ( Blueprint, render_template, abort, request, g, redirect, - url_for, flash + url_for, flash, jsonify ) from .db import get_db @@ -48,7 +50,7 @@ def view_thread(thread_id): if post['vote'] is not None: votes[post['id']] = db.execute("SELECT * FROM votes WHERE id = ?",(post['vote'],)).fetchone() - if g.user is None: + if g.user is None or poll is None: has_voted = None else: v = db.execute("SELECT * FROM votes WHERE poll = ? AND user = ? AND current AND NOT is_retraction;",(poll['id'],g.user)).fetchone() @@ -89,8 +91,78 @@ def register_vote(thread,pollval): """,(g.user,thread['poll'],option_idx,is_retraction)) vote_id = cur.lastrowid return vote_id - - + +@bp.route("/<int:thread_id>/create_poll",methods=["POST"]) +def create_poll(thread_id): + fail = redirect(url_for('thread.config_thread',thread_id=thread_id)) + success = redirect(url_for('thread.view_thread',thread_id=thread_id)) + err = None + db = get_db() + thread = db.execute('select * from threads where id = ?',(thread_id,)).fetchone() + + polltitle = request.form.get('polltitle','').strip() + polloptions = [q.strip() for q in request.form.get('polloptions','').split("\n") if len(q.strip()) > 0] + + if thread is None: + err = "that thread does not exist" + elif g.user is None: + err = "you need to be logged in to do that" + elif g.user != thread['creator']: + err = "you can only create polls on threads that you own" + elif thread['poll'] is not None: + err = "a poll already exists for that thread" + elif not len(polltitle) > 0: + err = "poll title can't be empty" + elif len(polloptions) < 2: + err = "you must provide at least 2 options" + + if err is not None: + flash(err) + return fail + else: + cur = db.cursor() + cur.execute("INSERT INTO polls (title) VALUES (?)",(polltitle,)) + pollid = cur.lastrowid + cur.execute("UPDATE threads SET poll = ? WHERE threads.id = ?",(pollid,thread_id)) + cur.executemany( + "INSERT INTO poll_options (poll,option_idx,text) VALUES (?,?,?)", + zip(itertools.repeat(pollid),range(len(polloptions)),polloptions) + ) + db.commit() + flash("poll created successfully") + return success + +@bp.route("/<int:thread_id>/delete_poll",methods=["POST"]) +def delete_poll(thread_id): + fail = redirect(url_for('thread.config_thread',thread_id=thread_id)) + success = redirect(url_for('thread.view_thread',thread_id=thread_id)) + err = None + db = get_db() + thread = db.execute('select * from threads where id = ?',(thread_id,)).fetchone() + + if thread is None: + err = "that thread does not exist" + elif g.user is None: + err = "you need to be logged in to do that" + elif g.user != thread['creator']: + err = "you can only delete polls on threads that you own" + elif thread['poll'] is None: + err = "there is no poll to delete on this thread" + + if err is not None: + flash(err) + return fail + else: + pollid = thread['poll'] + + db.execute("UPDATE posts SET vote = NULL WHERE thread = ?",(thread_id,)) # this assumes only max one poll per thread + db.execute("DELETE FROM votes WHERE poll = ?",(pollid,)) + db.execute("DELETE FROM poll_options WHERE poll = ?",(pollid,)) + db.execute("UPDATE THREADS set poll = NULL WHERE id = ?",(thread_id,)) + db.execute("DELETE FROM polls WHERE id = ?",(pollid,)) + db.commit() + flash("poll deleted successfully") + return success @bp.route("/<int:thread_id>/create_post", methods=("POST",)) def create_post(thread_id): |