routes.py (12061B)
1 import os 2 import secrets 3 4 from flask import flash, redirect, render_template, request, url_for, abort 5 from flask_login import current_user, login_required, login_user, logout_user 6 from PIL import Image 7 from calendar import Calendar as Month 8 from datetime import datetime 9 10 from .server import app, bcrypt, db 11 from .forms import LoginForm, NewCourseForm, AdminForm, RegistrationForm, SearchForm, SubscribeForm, UnsubscribeForm, UpdateAccountForm 12 from .models import Course, CourseMember, User 13 14 15 """ calendar-function to calculate days, etc. for calendar """ 16 def 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("/") 35 def 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") 45 def 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']) 50 def 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']) 66 def 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") 85 def logout(): 86 logout_user() 87 return redirect('/') 88 89 """ save-picture function for account.html """ 90 def 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 106 def 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' ]) 127 def 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 154 def 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 164 def 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 181 def 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 212 def 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 224 def 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 241 def 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 260 def 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 273 def 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) 285 def not_found(error): 286 flash(f"Deze pagina werd niet gevonden", 'danger') 287 return index() # geen redirect om de '/bla' te houden