diff --git a/Server/flask_test.py b/Server/flask_test.py new file mode 100644 index 0000000..708fef9 --- /dev/null +++ b/Server/flask_test.py @@ -0,0 +1,55 @@ +import threading +import atexit +from flask import Flask +from server import * + +POOL_TIME = 0 # Seconds + + +class ServerThread(threading.Thread): + def run(self): + server = Server() + server.start() + while True: + pass + + +# variables that are accessible from anywhere +commonDataStruct = {} +# lock to control access to variable +dataLock = threading.Lock() +# thread handler +yourThread = ServerThread() + + +def create_app(): + app = Flask(__name__) + + def interrupt(): + global yourThread + yourThread.cancel() + + def doStuff(): + global commonDataStruct + global yourThread + with dataLock: + print('kek') + yourThread = threading.Timer(POOL_TIME, doStuff, ()) + yourThread.start() + + def doStuffStart(): + # Do initialisation stuff here + global yourThread + # Create your thread + yourThread = threading.Timer(POOL_TIME, doStuff, ()) + yourThread.start() + + # Initiate + doStuffStart() + # When you kill Flask (SIGTERM), clear the trigger for the next thread + atexit.register(interrupt) + return app + + +app = create_app() +app.run(host='0.0.0.0', debug=True) diff --git a/Server/static/css/main.css b/Server/static/css/main.css index a84335e..83cb348 100644 --- a/Server/static/css/main.css +++ b/Server/static/css/main.css @@ -1,19 +1,24 @@ -html, body, .container { +html, body, .my-container { width: 100%; height: 100%; margin: 0; padding: 0; } -body { - padding: 20px; +html { + height: calc(100% - 56px); +} + +.my-container { display: flex; flex-direction: row; + width: 100%; } .table-container { - height: 100%; - width: 70%; + height: calc(100% - 40px); + width: calc(70% - 40px); + padding: 20px; } .button { @@ -29,8 +34,18 @@ body { display: flex; flex-direction: row; flex-wrap: wrap; + padding: 0 0 15px 20px; } -.action-container button { - margin: 10px; +.action-container .my-label { + margin-top: 20px; +} + +.action-container .btn-group { + padding-top: 20px; + width: 100%; +} + +.btn-group button { + width: 100%; } \ No newline at end of file diff --git a/Server/static/css/spinner.css b/Server/static/css/spinner.css new file mode 100644 index 0000000..0014138 --- /dev/null +++ b/Server/static/css/spinner.css @@ -0,0 +1,93 @@ +.lds-spinner { + color: official; + display: inline-block; + position: relative; + width: 40px; + height: 40px; +} + +.lds-spinner div { + transform-origin: 20px 20px; + animation: lds-spinner 1.2s linear infinite; +} + +.lds-spinner div:after { + content: " "; + display: block; + position: absolute; + top: 5px; + left: 25px; + width: 3px; + height: 10px; + border-radius: 20%; + background: #fff; +} + +.lds-spinner div:nth-child(1) { + transform: rotate(0deg); + animation-delay: -1.1s; +} + +.lds-spinner div:nth-child(2) { + transform: rotate(30deg); + animation-delay: -1s; +} + +.lds-spinner div:nth-child(3) { + transform: rotate(60deg); + animation-delay: -0.9s; +} + +.lds-spinner div:nth-child(4) { + transform: rotate(90deg); + animation-delay: -0.8s; +} + +.lds-spinner div:nth-child(5) { + transform: rotate(120deg); + animation-delay: -0.7s; +} + +.lds-spinner div:nth-child(6) { + transform: rotate(150deg); + animation-delay: -0.6s; +} + +.lds-spinner div:nth-child(7) { + transform: rotate(180deg); + animation-delay: -0.5s; +} + +.lds-spinner div:nth-child(8) { + transform: rotate(210deg); + animation-delay: -0.4s; +} + +.lds-spinner div:nth-child(9) { + transform: rotate(240deg); + animation-delay: -0.3s; +} + +.lds-spinner div:nth-child(10) { + transform: rotate(270deg); + animation-delay: -0.2s; +} + +.lds-spinner div:nth-child(11) { + transform: rotate(300deg); + animation-delay: -0.1s; +} + +.lds-spinner div:nth-child(12) { + transform: rotate(330deg); + animation-delay: 0s; +} + +@keyframes lds-spinner { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} diff --git a/Server/static/js/file.js b/Server/static/js/file.js new file mode 100644 index 0000000..4265cc8 --- /dev/null +++ b/Server/static/js/file.js @@ -0,0 +1,55 @@ +let animationInput = document.getElementById('animationFile'); +let configInput = document.getElementById('configFile'); +let arucoInput = document.getElementById('arucoFile'); + +animationInput.onchange = function (e) { + document.getElementById('animationFileLabel').innerText = animationInput.files[0].name; +}; +configInput.onchange = function (e) { + document.getElementById('configFileLabel').innerText = configInput.files[0].name; +}; +arucoInput.onchange = function (e) { + document.getElementById('arucoFileLabel').innerText = arucoInput.files[0].name; +}; + +function sendRows(selectedRows) { + var animationFile = animationInput.files[0]; + var configFile = configInput.files[0]; + var arucoFile = arucoInput.files[0]; + spinner.style.display = 'inline-block'; + setTimeout(function () { + selectedRows.forEach(function (element) { + if (animationFile) { + let animReq = new XMLHttpRequest(); + let animFormData = new FormData(); + animFormData.append("file", animationFile); + animReq.open("POST", '/set/animation?ip=' + element._row.data.ip, false); + animReq.send(animFormData); + } + if (configFile) { + let configReq = new XMLHttpRequest(); + let congifFormData = new FormData(); + congifFormData.append("file", configFile); + configReq.open("POST", '/set/config?ip=' + element._row.data.ip, false); + configReq.send(congifFormData); + } + if (arucoFile) { + let arucoReq = new XMLHttpRequest(); + let arucoFormData = new FormData(); + arucoFormData.append("file", arucoFile); + arucoReq.open("POST", '/set/animation?ip=' + element._row.data.ip, false); + arucoReq.send(arucoFormData); + } + element.deselect(); + }); + spinner.style.display = 'none'; + }, 20); +} + +function sendSelected() { + sendRows(table.getSelectedRows()); +} + +function sendAll() { + sendRows(table.getRows()); +} \ No newline at end of file diff --git a/Server/static/js/main.js b/Server/static/js/main.js index a7258ec..9e91f28 100644 --- a/Server/static/js/main.js +++ b/Server/static/js/main.js @@ -1,3 +1,4 @@ +let spinner = document.getElementById('spinner'); var tabledata = []; updateData(); @@ -11,6 +12,7 @@ function updateData() { var table = new Tabulator("#copters-table", { data: tabledata, reactiveData: true, + selectable: true, layout: "fitColumns", columns: [ {title: "Name", field: "name"}, @@ -22,3 +24,28 @@ var table = new Tabulator("#copters-table", { {title: "Time", field: "time"}, ], }); + +function refreshRows(selectedRows) { + spinner.style.display = 'inline-block'; + setTimeout(function () { + selectedRows.forEach(function (element) { + let req = new XMLHttpRequest(); + req.open('POST', '/selfcheck/selected?ip=' + element._row.data.ip, false); + req.send(); + element.deselect(); + let response = JSON.parse(req.response); + Object.keys(response).forEach(function (item) { + element._row.data[item] = response[item]; + }); + }); + spinner.style.display = 'none'; + }, 20); +} + +function refreshSelected() { + refreshRows(table.getSelectedRows()); +} + +function refreshAll() { + refreshRows(table.getRows()); +} \ No newline at end of file diff --git a/Server/templates/main.html b/Server/templates/main.html index 3da0ec6..a51c576 100644 --- a/Server/templates/main.html +++ b/Server/templates/main.html @@ -2,24 +2,69 @@
-