summaryrefslogtreecommitdiffhomepage
path: root/apioforum/thread.py
blob: ad02b68e303042d8ca2c963aa7e745e609e81e77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# view posts in thread

from flask import (
    Blueprint, render_template, abort, request, g, redirect,
    url_for, flash
)
from .db import get_db
from .mdrender import render

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)

@bp.route("/<int:thread_id>")
def view_thread(thread_id):
    db = get_db()
    thread = db.execute("SELECT * FROM threads WHERE id = ?;",(thread_id,)).fetchone()
    if thread is None:
        abort(404)
    else:
        posts = db.execute(
            "SELECT * FROM posts WHERE thread = ? ORDER BY created ASC;",
            (thread_id,)
        ).fetchall()
        tags = 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()
        rendered_posts = [render(q['content']) for q in posts]
        return render_template("view_thread.html",posts=posts,thread=thread,rendered_posts=rendered_posts,tags=tags)

@bp.route("/<int:thread_id>/create_post", methods=("POST",))
def create_post(thread_id):
    if g.user is None:
        flash("you need to log in before you can post")
        return redirect(url_for('thread.view_thread',thread_id=thread_id))
    else:
        db = get_db()
        content = request.form['content']
        thread = db.execute("SELECT * FROM threads WHERE id = ?;",(thread_id,)).fetchone()
        if len(content.strip()) == 0:
            flash("you cannot post an empty message")
        elif not thread:
            flash("that thread does not exist")
        else:
            cur = db.cursor()
            cur.execute(
                "INSERT INTO posts (thread,author,content,created) VALUES (?,?,?,current_timestamp);",
                (thread_id,g.user,content)
            )
            post_id = cur.lastrowid
            cur.execute(
                "UPDATE threads SET updated = current_timestamp WHERE id = ?;",
                (thread_id,)
            )
            db.commit()
            flash("post posted postfully")
    return redirect(post_jump(thread_id, post_id))

@bp.route("/delete_post/<int:post_id>", methods=["GET","POST"])
def delete_post(post_id):
    db = get_db()
    post = db.execute("SELECT * FROM posts WHERE id = ?",(post_id,)).fetchone()
    if post is None:
        flash("that post doesn't exist")
        return redirect("/")
    if post['author'] != g.user:
        flash("you can only delete posts that you created")
        return redirect(url_for("thread.view_thread",thread_id=post["thread"]))
    if request.method == "POST":
        # todo: don't actually delete, just mark as deleted or something (and wipe content)
        # so that you can have a "this post was deleted" thing
        db.execute("DELETE FROM posts WHERE id = ?",(post_id,))
        db.commit()
        flash("post deleted deletedly")
        return redirect(url_for("thread.view_thread",thread_id=post["thread"]))
    else:
        return render_template("delete_post.html",post=post,rendered_content=render(post["content"]))
        

@bp.route("/edit_post/<int:post_id>",methods=["GET","POST"])
def edit_post(post_id):
    db = get_db()
    post = db.execute("SELECT * FROM posts WHERE id = ?",(post_id,)).fetchone()
    if post is None:
        flash("that post doesn't exist")
        # todo: index route
        return redirect("/")

    if post['author'] != g.user:
        flash("you can only edit posts that you created")
        return redirect(url_for("thread.view_thread",thread_id=post['thread']))
    # note: i am writing this while i am very tired, so probably
    # come back and test this properly later
    if request.method == "POST":
        err = None 
        newcontent = request.form['newcontent']
        if len(newcontent.strip()) == 0:
            err="post contents can't be empty"
        print(err)
        if err is None:
            db.execute(
                "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))
        else:
            flash(err)
    return render_template("edit_post.html",post=post)
            
@bp.route("/<int:thread_id>/config",methods=["GET","POST"])
def config_thread(thread_id):
    db = get_db()
    thread = db.execute("select * from threads where id = ?",(thread_id,)).fetchone()
    thread_tags = [r['tag'] for r in db.execute("select tag from thread_tags where thread = ?",(thread_id,)).fetchall()]
    avail_tags = db.execute("select * from tags order by id").fetchall()
    err = None
    if g.user is None:
        err = "you need to be logged in to do that"
    elif g.user != thread['creator']:
        err = "you can only configure threads that you own"

    if err is not None:
        flash(err)
        return redirect(url_for("thread.view_thread",thread_id=thread_id))

    if request.method == "POST":
        err = []
        if 'do_title' in request.form:
            title = request.form['title']
            if len(title.strip()) == 0:
                err.append("title can't be empty")
            else:
                db.execute("update threads set title = ? where id = ?;",(title,thread_id))
                flash("title updated successfully")
                db.commit()
        if 'do_chtags' in request.form:
            changed = False
            wanted_tags = []
            for tagid in range(1,len(avail_tags)+1):
                current = tagid in thread_tags
                wanted  = f'tag_{tagid}' in request.form
                print(tagid, current, wanted)
                if wanted and not current:
                    db.execute("insert into thread_tags (thread, tag) values (?,?)",(thread_id,tagid))
                    changed = True
                elif current and not wanted:
                    db.execute("delete from thread_tags where thread = ? and tag = ?",(thread_id,tagid))
                    changed = True
            if changed:
                db.commit()
                flash("tags updated successfully")

        if len(err) > 0:
            for e in err:
                flash(e)
        else:
            return redirect(url_for("thread.view_thread",thread_id=thread_id))
            

    return render_template("config_thread.html", thread=thread,thread_tags=thread_tags,avail_tags=avail_tags)