routes.py (7485B) download
1import json
2import os
3import secrets
4from datetime import datetime, timedelta
5
6from flask import flash, redirect, render_template, request, url_for, jsonify
7from flask_login import current_user, login_required, login_user, logout_user
8from PIL import Image
9
10from .app import app, bcrypt, db, socket
11from .forms import ConnectTrapForm, LoginForm, RegistrationForm, UpdateAccountForm, UpdateTrapForm
12from .models import Trap, User, UserType
13
14def clean_traps():
15 query = Trap.query.filter((Trap.connect_expired < datetime.utcnow()) & (Trap.owner == None))
16 i = len(query.all())
17 query.delete()
18 db.session.commit()
19 print(f'[*] {i} traps cleaned')
20
21@app.route("/api/update_status", methods=['POST', 'GET'])
22def update_status():
23 if not request.json:
24 return jsonify({ "error": "invalid-json" })
25 trap = Trap.query.filter_by(mac=request.json['mac']).first()
26 if not trap:
27 return jsonify({ "error": "not-found" })
28
29 trap.caught = request.json['status']
30 db.session.commit()
31
32 if trap.owner:
33 socket.emit('trap-change', { 'user': trap.owner })
34
35 return jsonify({ "error": "ok" })
36
37@app.route("/api/search_connect", methods=['POST', 'GET'])
38def search_connect():
39 if not request.json:
40 return jsonify({ "error": "invalid-json" })
41
42 trap = Trap.query.filter_by(mac=request.json['mac']).first()
43 if not trap:
44 trap = Trap(mac=request.json['mac'])
45 db.session.add(trap)
46
47 trap.owner = None
48 trap.connect_expired = datetime.utcnow() + timedelta(minutes=5)
49
50 db.session.commit()
51
52 return jsonify({ "error": "ok" })
53
54
55""" index.html (home-page) route """
56@app.route("/")
57def index():
58 form = LoginForm()
59 return render_template('index.html', form=form)
60
61""" about.html route """
62@app.route("/about")
63def about():
64 return render_template('about.html', title='Over ons')
65
66""" register.html route """
67@app.route("/register", methods=['GET', 'POST'])
68def register():
69 if current_user.is_authenticated:
70 flash('U bent al ingelogd', 'warning')
71 return redirect('/')
72
73 form = RegistrationForm()
74 if form.validate_on_submit():
75 hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
76 address = f"{form.street} {form.housenumber}\n{form.zipcode} {form.place}"
77 user = User(
78 name=form.name.data,
79 email=form.email.data,
80 password=hashed_password,
81 phone=form.phone.data,
82 address = address
83 )
84 db.session.add(user)
85 db.session.commit()
86 flash('Uw profiel werd toegevoegd! U kan nu inloggen.', 'success')
87 return redirect(url_for('login'))
88 return render_template('register.html', title='Registeren', form=form)
89
90
91@app.route("/producten")
92def producten():
93 return render_template('producten.html')
94
95""" login.html route """
96@app.route("/login", methods=['GET', 'POST'])
97def login():
98 if current_user.is_authenticated:
99 flash('U bent al ingelogd', 'warning')
100 return redirect('/')
101 form = LoginForm()
102 if form.validate_on_submit():
103 user = User.query.filter_by(email=form.email.data).first()
104 if user and bcrypt.check_password_hash(user.password, form.password.data):
105 login_user(user, remember=form.remember.data)
106 if bcrypt.check_password_hash(user.password, form.email.data):
107 flash('Wij zullen aanbevelen uw wachtwoord weer te veranderen', 'warning')
108 next_page = request.args.get('next')
109 return redirect(next_page if next_page else '/')
110 else:
111 flash('Kon niet inloggen, is uw e-mail en wachtwoord juist?', 'danger')
112 return render_template('login.html', title='Inloggen', form=form)
113
114""" logout route """
115@app.route("/logout")
116def logout():
117 logout_user()
118 return redirect('/')
119
120""" save-picture function for account.html """
121def save_picture(form_picture):
122 random_hex = secrets.token_hex(8)
123 _, f_ext = os.path.splitext(form_picture.filename)
124 picture_fn = random_hex + f_ext
125 picturepath = os.path.join(app.root_path, 'static/profile_pics', picture_fn)
126
127 output_size = (125, 125)
128 i = Image.open(form_picture)
129 i.thumbnail(output_size)
130 i.save(picturepath)
131
132 return picture_fn
133
134""" account.html route """
135@app.route("/user/self", methods=[ 'GET', 'POST' ])
136@login_required
137def account():
138 form = UpdateAccountForm()
139 if form.validate_on_submit():
140 current_user.name = form.name.data
141 current_user.email = form.email.data
142 if form.picture.data:
143 picture_file = save_picture(form.picture.data)
144 current_user.image_file = picture_file
145 if form.password.data:
146 current_user.password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
147 db.session.commit()
148 flash('Uw profiel is bewerkt!', 'success')
149 return redirect(url_for('account'))
150
151 elif request.method == 'GET':
152 form.name.data = current_user.name
153 form.email.data = current_user.email
154 image_file = url_for('static', filename='profile_pics/' + current_user.image_file)
155 return render_template('account.html', title='Profiel', image_file=image_file, form=form)
156
157
158@app.route('/traps')
159@login_required
160def traps():
161 if current_user.type == UserType.ADMIN:
162 clean_traps()
163 query = Trap.query.all()
164 else:
165 query = Trap.query.filter_by(owner=current_user.id)
166
167 trap_json = [ { c.name: str(getattr(trap, c.name)) for c in trap.__table__.columns } for trap in query ]
168
169 return render_template('trap.html', traps=query, trap_json=trap_json)
170
171@app.route('/traps/connect', methods=['POST', 'GET'])
172@login_required
173def trap_connect():
174 form = ConnectTrapForm()
175 if form.validate_on_submit() and form.mac.data:
176 trap = Trap.query.filter_by(mac=form.mac.data.replace(':', '').replace(' ', '')).filter(Trap.connect_expired > datetime.utcnow()).first()
177 if not trap:
178 flash('Muizenval niet gevonden', 'danger')
179 return redirect(url_for('trap_connect'))
180
181 trap.owner = current_user.id
182 db.session.commit()
183 flash('Muizenval toegevoegd!', 'success')
184 return redirect(url_for('traps'))
185
186 return render_template('connect.html', form=form)
187
188
189@app.route('/trap/<trap_id>/update', methods=['POST', 'GET'])
190@login_required
191def trap_update(trap_id):
192 form = UpdateTrapForm()
193 trap = Trap.query.filter_by(mac=trap_id).first()
194 if form.validate_on_submit():
195 trap.name = form.name.data
196 if form.email.data:
197 user = User.query.filter_by(email=form.email.data).first()
198 trap.owner = user.id
199 db.session.commit()
200 return redirect(url_for('traps'))
201 elif not trap:
202 flash('Muizeval niet gevonden', 'danger')
203 return redirect(url_for('traps'))
204 elif request.method == 'GET':
205 form.mac.data = trap.mac
206 form.name.data = trap.name
207 return render_template('updatetrap.html', form=form, trap=trap)
208
209@app.route('/trap/<trap_id>/delete')
210@login_required
211def trap_delete(trap_id):
212 trap = Trap.query.filter_by(mac=trap_id).first()
213 db.session.delete(trap)
214 db.session.commit()
215
216 return redirect(url_for('traps'))
217
218""" 404 not found handler """
219@app.errorhandler(404)
220def not_found(error):
221 flash(f"Deze pagina werd niet gevonden", 'danger')
222 return index() # geen redirect om de '/bla' te houden