diff options
| author | rubenwardy <rw@rubenwardy.com> | 2019-11-15 23:51:42 +0000 |
|---|---|---|
| committer | rubenwardy <rw@rubenwardy.com> | 2019-11-15 23:51:42 +0000 |
| commit | 64f131ae27a7332245b5a4eb8e1e4879d7d99578 (patch) | |
| tree | a0b4101ca9c2132a072f1586c0df693583c91cf7 /app/blueprints/threads | |
| parent | 015abe5a2507ad02273bc89953016c386aae4457 (diff) | |
| download | cheatdb-64f131ae27a7332245b5a4eb8e1e4879d7d99578.tar.xz | |
Refactor endpoints to use blueprints instead
Diffstat (limited to 'app/blueprints/threads')
| -rw-r--r-- | app/blueprints/threads/__init__.py | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/app/blueprints/threads/__init__.py b/app/blueprints/threads/__init__.py new file mode 100644 index 0000000..0eee201 --- /dev/null +++ b/app/blueprints/threads/__init__.py @@ -0,0 +1,214 @@ +# Content DB +# Copyright (C) 2018 rubenwardy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + + +from flask import * + +bp = Blueprint("threads", __name__) + +from flask_user import * +from app.models import * +from app.utils import triggerNotif, clearNotifications + +import datetime + +from flask_wtf import FlaskForm +from wtforms import * +from wtforms.validators import * + +@bp.route("/threads/") +def list_all(): + query = Thread.query + if not Permission.SEE_THREAD.check(current_user): + query = query.filter_by(private=False) + return render_template("threads/list.html", threads=query.all()) + + +@bp.route("/threads/<int:id>/subscribe/", methods=["POST"]) +@login_required +def subscribe(id): + thread = Thread.query.get(id) + if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD): + abort(404) + + if current_user in thread.watchers: + flash("Already subscribed!", "success") + else: + flash("Subscribed to thread", "success") + thread.watchers.append(current_user) + db.session.commit() + + return redirect(url_for("threads.view", id=id)) + + +@bp.route("/threads/<int:id>/unsubscribe/", methods=["POST"]) +@login_required +def unsubscribe(id): + thread = Thread.query.get(id) + if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD): + abort(404) + + if current_user in thread.watchers: + flash("Unsubscribed!", "success") + thread.watchers.remove(current_user) + db.session.commit() + else: + flash("Not subscribed to thread", "success") + + return redirect(url_for("threads.view", id=id)) + + +@bp.route("/threads/<int:id>/", methods=["GET", "POST"]) +def view(id): + clearNotifications(url_for("threads.view", id=id)) + + thread = Thread.query.get(id) + if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD): + abort(404) + + if current_user.is_authenticated and request.method == "POST": + comment = request.form["comment"] + + if not current_user.canCommentRL(): + flash("Please wait before commenting again", "danger") + if package: + return redirect(package.getDetailsURL()) + else: + return redirect(url_for("home_page")) + + if len(comment) <= 500 and len(comment) > 3: + reply = ThreadReply() + reply.author = current_user + reply.comment = comment + db.session.add(reply) + + thread.replies.append(reply) + if not current_user in thread.watchers: + thread.watchers.append(current_user) + + msg = None + if thread.package is None: + msg = "New comment on '{}'".format(thread.title) + else: + msg = "New comment on '{}' on package {}".format(thread.title, thread.package.title) + + + for user in thread.watchers: + if user != current_user: + triggerNotif(user, current_user, msg, url_for("threads.view", id=thread.id)) + + db.session.commit() + + return redirect(url_for("threads.view", id=id)) + + else: + flash("Comment needs to be between 3 and 500 characters.") + + return render_template("threads/view.html", thread=thread) + + +class ThreadForm(FlaskForm): + title = StringField("Title", [InputRequired(), Length(3,100)]) + comment = TextAreaField("Comment", [InputRequired(), Length(10, 500)]) + private = BooleanField("Private") + submit = SubmitField("Open Thread") + +@bp.route("/threads/new/", methods=["GET", "POST"]) +@login_required +def new(): + form = ThreadForm(formdata=request.form) + + package = None + if "pid" in request.args: + package = Package.query.get(int(request.args.get("pid"))) + if package is None: + flash("Unable to find that package!", "error") + + # Don't allow making orphan threads on approved packages for now + if package is None: + abort(403) + + def_is_private = request.args.get("private") or False + if package is None: + def_is_private = True + allow_change = package and package.approved + is_review_thread = package and not package.approved + + # Check that user can make the thread + if not package.checkPerm(current_user, Permission.CREATE_THREAD): + flash("Unable to create thread!", "error") + return redirect(url_for("home_page")) + + # Only allow creating one thread when not approved + elif is_review_thread and package.review_thread is not None: + flash("A review thread already exists!", "error") + return redirect(url_for("threads.view", id=package.review_thread.id)) + + elif not current_user.canOpenThreadRL(): + flash("Please wait before opening another thread", "danger") + + if package: + return redirect(package.getDetailsURL()) + else: + return redirect(url_for("home_page")) + + # Set default values + elif request.method == "GET": + form.private.data = def_is_private + form.title.data = request.args.get("title") or "" + + # Validate and submit + elif request.method == "POST" and form.validate(): + thread = Thread() + thread.author = current_user + thread.title = form.title.data + thread.private = form.private.data if allow_change else def_is_private + thread.package = package + db.session.add(thread) + + thread.watchers.append(current_user) + if package is not None and package.author != current_user: + thread.watchers.append(package.author) + + reply = ThreadReply() + reply.thread = thread + reply.author = current_user + reply.comment = form.comment.data + db.session.add(reply) + + thread.replies.append(reply) + + db.session.commit() + + if is_review_thread: + package.review_thread = thread + + notif_msg = None + if package is not None: + notif_msg = "New thread '{}' on package {}".format(thread.title, package.title) + triggerNotif(package.author, current_user, notif_msg, url_for("threads.view", id=thread.id)) + else: + notif_msg = "New thread '{}'".format(thread.title) + + for user in User.query.filter(User.rank >= UserRank.EDITOR).all(): + triggerNotif(user, current_user, notif_msg, url_for("threads.view", id=thread.id)) + + db.session.commit() + + return redirect(url_for("threads.view", id=thread.id)) + + + return render_template("threads/new.html", form=form, allow_private_change=allow_change, package=package) |
