]> git.lizzy.rs Git - cheatdb.git/blob - app/views/threads.py
Fix 2 filter_by bugs
[cheatdb.git] / app / views / threads.py
1 # Content DB
2 # Copyright (C) 2018  rubenwardy
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17
18 from flask import *
19 from flask_user import *
20 from app import app
21 from app.models import *
22 from app.utils import triggerNotif, clearNotifications
23
24 from flask_wtf import FlaskForm
25 from wtforms import *
26 from wtforms.validators import *
27
28 @app.route("/threads/")
29 def threads_page():
30         query = Thread.query
31         if not Permission.SEE_THREAD.check(current_user):
32                 query = query.filter_by(private=False)
33         return render_template("threads/list.html", threads=query.all())
34
35 @app.route("/threads/<int:id>/", methods=["GET", "POST"])
36 def thread_page(id):
37         clearNotifications(url_for("thread_page", id=id))
38
39         thread = Thread.query.get(id)
40         if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD):
41                 abort(404)
42
43         if current_user.is_authenticated and request.method == "POST":
44                 comment = request.form["comment"]
45
46                 if len(comment) <= 500 and len(comment) > 3:
47                         reply = ThreadReply()
48                         reply.author = current_user
49                         reply.comment = comment
50                         db.session.add(reply)
51
52                         thread.replies.append(reply)
53                         if not current_user in thread.watchers:
54                                 thread.watchers.append(current_user)
55
56                         msg = None
57                         if thread.package is None:
58                                 msg = "New comment on '{}'".format(thread.title)
59                         else:
60                                 msg = "New comment on '{}' on package {}".format(thread.title, thread.package.title)
61
62
63                         for user in thread.watchers:
64                                 if user != current_user:
65                                         triggerNotif(user, current_user, msg, url_for("thread_page", id=thread.id))
66
67                         db.session.commit()
68
69                         return redirect(url_for("thread_page", id=id))
70
71                 else:
72                         flash("Comment needs to be between 3 and 500 characters.")
73
74         return render_template("threads/view.html", thread=thread)
75
76
77 class ThreadForm(FlaskForm):
78         title   = StringField("Title", [InputRequired(), Length(3,100)])
79         comment = TextAreaField("Comment", [InputRequired(), Length(10, 500)])
80         private = BooleanField("Private")
81         submit  = SubmitField("Open Thread")
82
83 @app.route("/threads/new/", methods=["GET", "POST"])
84 @login_required
85 def new_thread_page():
86         form = ThreadForm(formdata=request.form)
87
88         package = None
89         if "pid" in request.args:
90                 package = Package.query.get(int(request.args.get("pid")))
91                 if package is None:
92                         flash("Unable to find that package!", "error")
93
94         # Don't allow making threads on approved packages for now
95         if package is None or package.approved:
96                 abort(403)
97
98         def_is_private   = request.args.get("private") or False
99         if not package.approved:
100                 def_is_private = True
101         allow_change     = package.approved
102         is_review_thread = package is not None and not package.approved
103
104         # Check that user can make the thread
105         if is_review_thread and not (package.author == current_user or \
106                         package.checkPerm(current_user, Permission.APPROVE_NEW)):
107                 flash("Unable to create thread!", "error")
108                 return redirect(url_for("home_page"))
109
110         # Only allow creating one thread when not approved
111         elif is_review_thread and package.review_thread is not None:
112                 flash("A review thread already exists!", "error")
113                 if request.method == "GET":
114                         return redirect(url_for("thread_page", id=package.review_thread.id))
115
116         # Set default values
117         elif request.method == "GET":
118                 form.private.data = def_is_private
119                 form.title.data   = request.args.get("title") or ""
120
121         # Validate and submit
122         elif request.method == "POST" and form.validate():
123                 thread = Thread()
124                 thread.author  = current_user
125                 thread.title   = form.title.data
126                 thread.private = form.private.data if allow_change else def_is_private
127                 thread.package = package
128                 db.session.add(thread)
129
130                 thread.watchers.append(current_user)
131                 if package is not None and package.author != current_user:
132                         thread.watchers.append(package.author)
133
134                 reply = ThreadReply()
135                 reply.thread  = thread
136                 reply.author  = current_user
137                 reply.comment = form.comment.data
138                 db.session.add(reply)
139
140                 thread.replies.append(reply)
141
142                 db.session.commit()
143
144                 if is_review_thread:
145                         package.review_thread = thread
146
147                 if package is not None:
148                         triggerNotif(package.author, current_user,
149                                         "New thread '{}' on package {}".format(thread.title, package.title), url_for("thread_page", id=thread.id))
150
151                 db.session.commit()
152
153                 return redirect(url_for("thread_page", id=thread.id))
154
155
156         return render_template("threads/new.html", form=form, allow_private_change=allow_change)