muizenval

Observe mouse traps remotely
Log | Files | Refs

commit 605f9ff6d2110a6b310ad94c65a37ef373c657b0
parent a63eee89d1974315d063300939948cc260a623d8
Author: Friedel Schön <[email protected]>
Date:   Thu, 19 May 2022 14:48:57 +0200

adding map

Diffstat:
Madd-user.py | 10++++++----
Mreadme.md | 10+++++++---
Mserver/models.py | 1+
Mserver/routes.py | 26+++++++++++++++++++++-----
Mserver/site.db | 0
Mserver/static/main.css | 4++++
Mserver/templates/layout.html | 8++++++++
Mserver/templates/trap.html | 37++++++++++++++++++++++++++++++-------
Mserver/templates/updatetrap.html | 3+--
Aserver/timer.py | 14++++++++++++++
Mtest-client.py | 14+++++++++++---
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: '&copy; <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 })