routes.py (12061B) download
1import os
2import secrets
3
4from flask import flash, redirect, render_template, request, url_for, abort
5from flask_login import current_user, login_required, login_user, logout_user
6from PIL import Image
7from calendar import Calendar as Month
8from datetime import datetime
9
10from .server import app, bcrypt, db
11from .forms import LoginForm, NewCourseForm, AdminForm, RegistrationForm, SearchForm, SubscribeForm, UnsubscribeForm, UpdateAccountForm
12from .models import Course, CourseMember, User
13
14
15""" calendar-function to calculate days, etc. for calendar """
16def make_calendar():
17 weekdays = list(enumerate(['Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za', 'Zo']))
18
19 courses = [ None, None, None, None, None, None, None ]
20 if current_user.is_authenticated:
21 subscriptions = [ cm.course_id for cm in CourseMember.query.filter_by(user_id=current_user.id) ]
22 courses = [ ' +\n'.join([ c.name for c in Course.query.filter_by(weekday=i) if c.id in subscriptions ]) for i in range(7) ]
23
24 today = datetime.today()
25 m = Month()
26
27 rows = []
28 for days in m.monthdayscalendar(today.year, today.month):
29 rows.append([ (i, d, courses[i]) for i, d in enumerate(days) ])
30
31 return { 'weekdays': weekdays, 'rows': rows }
32
33""" index.html (home-page) route """
34@app.route("/")
35def index():
36 courses = Course.query.all()
37 subscriptions = []
38 teachers = User.query.filter_by(type='teacher')
39 if current_user.is_authenticated:
40 subscriptions = [ cm.course_id for cm in CourseMember.query.filter_by(user_id=current_user.id) ]
41 return render_template('index.html', calendar=make_calendar(), courses=courses, subs=subscriptions, teachers=teachers)
42
43""" about.html route """
44@app.route("/about")
45def about():
46 return render_template('about.html', calendar=make_calendar(), title='Over ons')
47
48""" register.html route """
49@app.route("/register", methods=['GET', 'POST'])
50def register():
51 if current_user.is_authenticated:
52 flash('U bent al ingelogd', 'warning')
53 return redirect('/')
54 form = RegistrationForm()
55 if form.validate_on_submit():
56 hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
57 user = User(username=form.username.data, email=form.email.data, password=hashed_password)
58 db.session.add(user)
59 db.session.commit()
60 flash('Uw profiel werd toegevoegd! U kan nu inloggen.', 'success')
61 return redirect(url_for('login'))
62 return render_template('register.html', calendar=make_calendar(), title='Registeren', form=form)
63
64""" login.html route """
65@app.route("/login", methods=['GET', 'POST'])
66def login():
67 if current_user.is_authenticated:
68 flash('U bent al ingelogd', 'warning')
69 return redirect('/')
70 form = LoginForm()
71 if form.validate_on_submit():
72 user = User.query.filter_by(email=form.email.data).first()
73 if user and bcrypt.check_password_hash(user.password, form.password.data):
74 login_user(user, remember=form.remember.data)
75 if bcrypt.check_password_hash(user.password, form.email.data):
76 flash('Wij zullen aanbevelen uw wachtwoord weer te veranderen', 'warning')
77 next_page = request.args.get('next')
78 return redirect(next_page if next_page else '/')
79 else:
80 flash('Kon niet inloggen, is uw e-mail en wachtwoord juist?', 'danger')
81 return render_template('login.html', calendar=make_calendar(), title='Inloggen', form=form)
82
83""" logout route """
84@app.route("/logout")
85def logout():
86 logout_user()
87 return redirect('/')
88
89""" save-picture function for account.html """
90def save_picture(form_picture):
91 random_hex = secrets.token_hex(8)
92 _, f_ext = os.path.splitext(form_picture.filename)
93 picture_fn = random_hex + f_ext
94 picturepath = os.path.join(app.root_path, 'static/profile_pics', picture_fn)
95
96 output_size = (125, 125)
97 i = Image.open(form_picture)
98 i.thumbnail(output_size)
99 i.save(picturepath)
100
101 return picture_fn
102
103""" account.html route """
104@app.route("/user/self", methods=[ 'GET', 'POST' ])
105@login_required
106def account():
107 form = UpdateAccountForm()
108 if form.validate_on_submit():
109 current_user.username = form.username.data
110 current_user.email = form.email.data
111 if form.picture.data:
112 picture_file = save_picture(form.picture.data)
113 current_user.image_file = picture_file
114 if form.password.data:
115 current_user.password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
116 db.session.commit()
117 flash('Uw profiel is bewerkt!', 'success')
118 return redirect(url_for('account'))
119 elif request.method == 'GET':
120 form.username.data = current_user.username
121 form.email.data = current_user.email
122 image_file = url_for('static', filename='profile_pics/' + current_user.image_file)
123 return render_template('account.html', calendar=make_calendar(), title='Profiel', image_file=image_file, form=form)
124
125""" course.html (course-info) route """
126@app.route("/course/<int:course_id>", methods=[ 'GET', 'POST' ])
127def course(course_id):
128 sub_form = SubscribeForm()
129 unsub_form = UnsubscribeForm()
130 teachers = User.query.filter_by(type='teacher')
131 subscribed = None
132 if current_user.is_authenticated:
133 subscribed = CourseMember.query.filter_by(user_id=current_user.id, course_id=course_id).first()
134
135 if sub_form.validate_on_submit() and not subscribed:
136 course = CourseMember(user_id=current_user.id, course_id=course_id)
137 db.session.add(course)
138 db.session.commit()
139 flash('U bent nu ingeschreven!', 'success')
140 return redirect('/')
141
142 if unsub_form.validate_on_submit() and subscribed:
143 db.session.delete(subscribed)
144 db.session.commit()
145 flash('U bent nu uitgeschreven!', 'success')
146 return redirect('/')
147
148 course = Course.query.get_or_404(course_id)
149 return render_template('course.html', calendar=make_calendar(), title=course.name, course=course, sub_form=sub_form, unsub_form=unsub_form, subscribed=subscribed is not None, teachers=teachers)
150
151""" course_overview.html route """
152@app.route("/courses")
153@login_required
154def course_overview():
155 if current_user.type not in [ "admin", "teacher" ]:
156 flash('U mag deze website niet bereiken', 'error')
157 return redirect('/')
158 courses = [ (c, User.query.filter_by(id=c.teacher_id).first() ) for c in Course.query.all() ]
159 return render_template('course_overview.html', calendar=make_calendar(), legend='Lesoverzicht', courses=courses)
160
161""" new_course.html route """
162@app.route("/course/new", methods=['GET', 'POST'])
163@login_required
164def new_course():
165 if current_user.type not in [ "admin", "teacher" ]:
166 flash('U mag deze website niet bereiken', 'error')
167 return redirect('/')
168 form = NewCourseForm()
169 form.teacher_id.choices = [ (g.id, g.username) for g in User.query.filter_by(type='teacher') ]
170 if form.validate_on_submit():
171 course = Course(name=form.name.data, description=form.description.data, teacher_id=form.teacher_id.data, weekday=form.weekday.data, start=form.start.data, end=form.end.data, location=form.location.data)
172 db.session.add(course)
173 db.session.commit()
174 flash('De les is toegevoegd!', 'success')
175 return redirect(url_for('course_overview'))
176 return render_template('new_course.html', calendar=make_calendar(), legend='Nieuwe les aanmaken', form=form)
177
178""" new_course.html (update course) route """
179@app.route("/course/<int:course_id>/update", methods=['GET', 'POST'])
180@login_required
181def update_course(course_id):
182 if current_user.type not in [ "admin", "teacher" ]:
183 flash('U mag deze website niet bereiken', 'error')
184 return redirect('/')
185 form = NewCourseForm()
186 form.teacher_id.choices = [ (g.id, g.username) for g in User.query.filter_by(type='teacher') ]
187 course = Course.query.get_or_404(course_id)
188 if form.validate_on_submit():
189 course.name = form.name.data
190 course.description = form.description.data
191 course.teacher_id = form.teacher_id.data
192 course.weekday = form.weekday.data
193 course.start = form.start.data
194 course.end = form.end.data
195 course.location = form.location.data
196 db.session.commit()
197 flash('De les is bewerkt!', 'success')
198 return redirect(url_for('course_overview'))
199 elif request.method == 'GET':
200 form.name.data = course.name
201 form.description.data = course.description
202 form.teacher_id.data = course.teacher_id
203 form.weekday.data = course.weekday
204 form.start.data = course.start
205 form.end.data = course.end
206 form.location.data = course.location
207 return render_template('new_course.html', calendar=make_calendar(), form=form, legend='Les aanpassen')
208
209""" delete-course route """
210@app.route("/course/<int:course_id>/delete", methods=['GET','POST'])
211@login_required
212def delete_course(course_id):
213 if current_user.type not in [ "admin", "teacher" ]:
214 flash('U mag deze website niet bereiken', 'error')
215 return redirect('/')
216 course = Course.query.get_or_404(course_id)
217 db.session.delete(course)
218 db.session.commit()
219 return redirect(url_for('course_overview'))
220
221""" admin.html route """
222@app.route("/users", methods=['GET','POST'])
223@login_required
224def admin():
225 if current_user.type != "admin":
226 flash('U mag deze website niet bereiken', 'error')
227 return redirect('/')
228 form = SearchForm()
229 if form.validate_on_submit():
230 user = User.query.filter_by(username=form.username.data).first()
231 if user == None:
232 flash(f'Geen gebrukers gevonden met de gebruikersnaam: {form.username.data}!', 'danger')
233 else:
234 flash(f'Gebruiker gevonden met gebruikersnaam: {form.username.data}!', 'success')
235 return redirect(url_for('admin_user', user_id= user.id))
236 return render_template('admin.html', calendar=make_calendar(), form=form)
237
238""" account-admin route """
239@app.route("/user/<int:user_id>", methods=['GET','POST'])
240@login_required
241def admin_user(user_id):
242 if current_user.type != "admin":
243 flash('U mag deze website niet bereiken', 'error')
244 return redirect('/')
245 form = AdminForm()
246 user = User.query.filter_by(id=user_id).first()
247 image_file = url_for('static', filename='profile_pics/' + user.image_file)
248 if form.validate_on_submit():
249 user.type = form.type.data
250 db.session.commit()
251 flash(f'De gebruiker {user.username} is nu een {user.type}', 'success')
252 return redirect(url_for('admin'))
253 elif request.method == 'GET':
254 form.type.data = user.type
255 return render_template('admin_user.html', calendar=make_calendar(), form=form, user=user, image_file=image_file)
256
257""" delete-user route """
258@app.route("/user/<int:user_id>/delete", methods=['GET','POST'])
259@login_required
260def delete_user(user_id):
261 if current_user.type != "admin":
262 flash('U mag deze website niet bereiken', 'error')
263 return redirect('/')
264 user = User.query.get_or_404(user_id)
265 db.session.delete(user)
266 db.session.commit()
267 flash(f'De gebruiker {user.username} werd verwijdert', 'success')
268 return redirect(url_for('admin'))
269
270""" reset user's password route """
271@app.route("/user/<int:user_id>/reset", methods=['GET','POST'])
272@login_required
273def reset_user(user_id):
274 if current_user.type != "admin":
275 flash('U mag deze website niet bereiken', 'error')
276 return redirect('/')
277 user = User.query.get_or_404(user_id)
278 user.password = bcrypt.generate_password_hash(user.email).decode('utf-8')
279 db.session.commit()
280 flash(f'{user.username}\'s is nu zijn/haar e-mail', 'success')
281 return redirect(url_for('admin'))
282
283""" 404 not found handler """
284@app.errorhandler(404)
285def not_found(error):
286 flash(f"Deze pagina werd niet gevonden", 'danger')
287 return index() # geen redirect om de '/bla' te houden