commit 605f9ff6d2110a6b310ad94c65a37ef373c657b0
parent a63eee89d1974315d063300939948cc260a623d8
Author: Friedel Schön <[email protected]>
Date: Thu, 19 May 2022 14:48:57 +0200
adding map
Diffstat:
11 files changed, 103 insertions(+), 24 deletions(-)
diff --git a/add-user.py b/add-user.py
@@ -7,8 +7,8 @@ from server.models import User, UserType
#typ = input('Type [admin,manager,technician,catcher,client]? ')
users = [
- (UserType.CLIENT, 'Boer Herman', '[email protected]'),
- (UserType.ADMIN, 'Administrator Ralf', '[email protected]'),
+ (1, UserType.CLIENT, 'Boer Herman', '[email protected]', 2),
+ (2, UserType.ADMIN, 'Administrator Ralf', '[email protected]', None),
]
address = 'Kerklaan 69\n9876XY Groningen'
@@ -17,15 +17,17 @@ hashed_password = bcrypt.generate_password_hash('hallo').decode('utf-8')
db.create_all()
-for typ, name, email in users:
+for id, typ, name, email, contact in users:
phone = '06-' + str(randint(10000000, 99999999))
user = User(
+ id=id,
type=typ,
name=name,
email=email,
password=hashed_password,
phone=phone,
- address = address
+ address = address,
+ contact=contact
)
db.session.add(user)
diff --git a/readme.md b/readme.md
@@ -13,7 +13,7 @@ $ git clone https://github.com/friedelschoen/muizenval.tk/
**Alle afhankelijkheden installeren:**
```
-$ pip3 install flask wtforms flask_sqlalchemy flask-wtf email_validator flask-bcrypt flask-login pillow flask_socketio simple-websocket
+$ pip3 install flask wtforms flask_sqlalchemy flask-wtf email_validator flask-bcrypt flask-login pillow flask_socketio simple-websocket gevent-websocket
```
**Is de database leeg? Test-gebruikers toevoegen:**
@@ -35,4 +35,8 @@ $ python3 run-server.py
**Geen muizenval bij de hand? Interactieve test-muizenval proberen:**
```
$ python3 test-client.py
-```
-\ No newline at end of file
+```
+
+## Known issues
+
+- op Anaconda-python werkt niks (flask zou gewoon ophangen), dus gebruik de officiële Python-versie
+\ No newline at end of file
diff --git a/server/models.py b/server/models.py
@@ -1,5 +1,6 @@
from email.policy import default
from enum import Enum
+import json
from flask_login import UserMixin
from .app import db, login_manager
diff --git a/server/routes.py b/server/routes.py
@@ -1,8 +1,9 @@
+import json
import os
import secrets
from datetime import datetime, timedelta
-from flask import flash, redirect, render_template, request, url_for, abort, request, jsonify
+from flask import flash, redirect, render_template, request, url_for, jsonify
from flask_login import current_user, login_required, login_user, logout_user
from PIL import Image
@@ -10,6 +11,12 @@ from .app import app, bcrypt, db, socket
from .forms import ConnectTrapForm, LoginForm, RegistrationForm, UpdateAccountForm, UpdateTrapForm
from .models import Trap, User, UserType
+def clean_traps():
+ query = Trap.query.filter((Trap.connect_expired < datetime.utcnow()) & (Trap.owner == None))
+ i = len(query.all())
+ query.delete()
+ db.session.commit()
+ print(f'[*] {i} traps cleaned')
@app.route("/api/update_status", methods=['POST', 'GET'])
def update_status():
@@ -37,6 +44,7 @@ def search_connect():
trap = Trap(mac=request.json['mac'])
db.session.add(trap)
+ trap.owner = None
trap.connect_expired = datetime.utcnow() + timedelta(minutes=5)
db.session.commit()
@@ -60,10 +68,11 @@ def register():
if current_user.is_authenticated:
flash('U bent al ingelogd', 'warning')
return redirect('/')
+
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
- address = f"{form.street} {form.housenumber}\n{form.postcode} {form.place}"
+ address = f"{form.street} {form.housenumber}\n{form.zipcode} {form.place}"
user = User(
name=form.name.data,
email=form.email.data,
@@ -149,10 +158,14 @@ def account():
@login_required
def traps():
if current_user.type == UserType.ADMIN:
- traps = Trap.query.all()
+ clean_traps()
+ query = Trap.query.all()
else:
- traps = Trap.query.filter_by(owner=current_user.id)
- return render_template('trap.html', traps=traps)
+ query = Trap.query.filter_by(owner=current_user.id)
+
+ trap_json = [ { c.name: str(getattr(trap, c.name)) for c in trap.__table__.columns } for trap in query ]
+
+ return render_template('trap.html', traps=query, trap_json=trap_json)
@app.route('/traps/connect', methods=['POST', 'GET'])
@login_required
@@ -184,6 +197,9 @@ def trap_update(trap_id):
trap.owner = user.id
db.session.commit()
return redirect(url_for('traps'))
+ elif not trap:
+ flash('Muizeval niet gevonden', 'danger')
+ return redirect(url_for('traps'))
elif request.method == 'GET':
form.mac.data = trap.mac
form.name.data = trap.name
diff --git a/server/site.db b/server/site.db
Binary files differ.
diff --git a/server/static/main.css b/server/static/main.css
@@ -106,4 +106,8 @@ a.article-title:hover {
.form-code {
font-family: 'Source Code Pro';
+}
+
+#trap-map {
+ height: 300px;
}
\ No newline at end of file
diff --git a/server/templates/layout.html b/server/templates/layout.html
@@ -20,6 +20,14 @@
integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA=="
crossorigin="anonymous"></script>
+ <!-- leaflet maps -->
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
+ integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
+ crossorigin="" />
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
+ integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
+ crossorigin=""></script>
+
<script type="text/javascript" charset="utf-8">
var socket = io();
var current_user = {{ current_user.id if current_user.is_authenticated else none | tojson }};
diff --git a/server/templates/trap.html b/server/templates/trap.html
@@ -1,12 +1,10 @@
{% extends "layout.html" %}
{% block content %}
-<script type="text/javascript">
- socket.on('trap-change', function (data) {
- if (data['user'] == current_user)
- location.reload();
- });
-</script>
-
+<article class="media content-section">
+ <div class="media-body">
+ <div id="trap-map"></div>
+ </div>
+</article>
{% for trap in traps %}
<article class="media content-section">
<div class="media-body">
@@ -46,4 +44,29 @@
</div>{#}
</article>
{% endfor %}
+
+<script type="text/javascript">
+ socket.on('trap-change', function (data) {
+ if (data['user'] == current_user)
+ location.reload();
+ });
+
+ // var trap_macs = [
+ /* {% for trap in traps %} */
+ //"{{ trap.mac }}" }
+ /* {% endfor %} */
+ //];
+
+ var traps = {{ trap_json | tojson }};
+
+ var map = L.map('trap-map').setView([52.283333, 5.666667], 7);
+
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+ }).addTo(map);
+
+// L.marker([51.5, -0.09]).addTo(map)
+ // .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
+ // .openPopup();
+</script>
{% endblock content %}
\ No newline at end of file
diff --git a/server/templates/updatetrap.html b/server/templates/updatetrap.html
@@ -49,8 +49,7 @@
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
- <a class="btn btn-secondary btn-sm mt-1 mb-1"
- href="{{ url_for('trap_delete', trap_id=trap.mac) }}">Verwijderen</a>
+ <a class="btn btn btn-danger" href="{{ url_for('trap_delete', trap_id=trap.mac) }}">Verwijderen</a>
</div>
</form>
</div>
diff --git a/server/timer.py b/server/timer.py
@@ -0,0 +1,14 @@
+import time, threading
+
+def repeat_timer(sec):
+ def wrapper(func):
+ def thread():
+ while True:
+ time.sleep(sec)
+ func()
+
+ thd = threading.Thread(target=thread)
+ thd.start()
+
+ return func
+ return wrapper
diff --git a/test-client.py b/test-client.py
@@ -1,4 +1,12 @@
-import requests
+import requests, random
-res = requests.post('http://0.0.0.0:5000/api/search_connect', json={ 'mac': '0000000000000000' })
-print(res.content)
+"""#mac = ''.join([ random.choice('0123456789ABCDEF') for _ in range(16) ])
+mac = '2C5C9A4DBA95D559'
+
+res = requests.post('http://0.0.0.0:5000/api/search_connect', json={ 'mac': mac })
+print('MAC:', mac)
+print('Answer:', res.content)
+"""
+
+mac = '90FD852087386BE9'
+res = requests.post('http://0.0.0.0:5000/api/update_status', json={ 'mac': mac, 'status': False })