Human error prevention, sensor updates, etc.
This commit is contained in:
parent
03246b5f43
commit
154a52e30d
@ -1,6 +1,8 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
import requests
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
class Log:
|
||||
@ -46,7 +48,7 @@ class Update:
|
||||
def __init__(self):
|
||||
with open("version.json", "r") as f: # loading settings
|
||||
version = json.load(f)
|
||||
self.url = version["url"]
|
||||
self.url = "https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json"
|
||||
self.version = version["version"]
|
||||
self.id = version["id"]
|
||||
|
||||
@ -55,3 +57,68 @@ class Update:
|
||||
|
||||
def get_version(self):
|
||||
return {"version": self.version, "id": self.id}
|
||||
|
||||
|
||||
class Scan:
|
||||
def __init__(self):
|
||||
self.cache_exist = os.path.isdir("cache")
|
||||
self.files_exist = os.path.isdir("files")
|
||||
if os.path.isfile("update.zip"):
|
||||
os.remove("update.zip")
|
||||
self.filesystem_exist = os.path.isfile("filesystem.json")
|
||||
self.settings_exist = os.path.isfile("settings.json")
|
||||
self.version_exist = os.path.isfile("version.json")
|
||||
self.errors = []
|
||||
self.state_list = {
|
||||
"error": [],
|
||||
"files": [], # 0 = does not exist, 1 = cant read, 2 = some values missing
|
||||
"filesystem": [],
|
||||
"settings": [],
|
||||
"version": [],
|
||||
"system": []
|
||||
}
|
||||
|
||||
def check_to_go(self):
|
||||
filesystem = ""
|
||||
if self.cache_exist is False:
|
||||
os.mkdir("cache")
|
||||
if self.filesystem_exist is False:
|
||||
self.state_list["error"].append("filesystem")
|
||||
self.state_list["filesystem"].append(0)
|
||||
self.errors.append("Filesystem is missing")
|
||||
else:
|
||||
try:
|
||||
with open("filesystem.json", "r") as f:
|
||||
filesystem = json.load(f)
|
||||
except:
|
||||
self.state_list["error"].append("filesystem")
|
||||
self.state_list["filesystem"].append(1)
|
||||
self.errors.append("Filesystem is corrupted")
|
||||
else:
|
||||
filesystem_keys = filesystem.keys()
|
||||
for check in ["ID", "location", "description", "files"]:
|
||||
if check not in filesystem_keys:
|
||||
self.state_list["error"].append("filesystem")
|
||||
self.state_list["filesystem"].append(2)
|
||||
if self.files_exist is False:
|
||||
self.state_list["error"].append("files")
|
||||
self.state_list["files"].append(0)
|
||||
self.errors.append("Files folder does not exists")
|
||||
elif filesystem:
|
||||
for file in dict(filesystem)["files"]:
|
||||
if not os.path.isfile(f"""files/{dict(file)["name"]}{dict(file)["format"]}"""):
|
||||
self.errors.append(f"""{dict(file)["name"]}{dict(file)["format"]} does not exists in file folder.""")
|
||||
if "files" not in self.state_list["error"]:
|
||||
self.state_list["error"].append("files")
|
||||
self.state_list["files"].append(2)
|
||||
if self.settings_exist is False:
|
||||
self.state_list["error"].append("settings")
|
||||
self.state_list["settings"].append(0)
|
||||
if self.version_exist is False:
|
||||
self.state_list["error"].append("version")
|
||||
self.state_list["version"].append(0)
|
||||
|
||||
|
||||
def fix_version(self):
|
||||
subprocess.check_output(["python3", "system.py", "update"])
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"ID": "0",
|
||||
"ID": 0,
|
||||
"location": "izba",
|
||||
"description": {
|
||||
"title": "legionrpi",
|
||||
|
132
server/main.py
132
server/main.py
@ -1,20 +1,29 @@
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import engine
|
||||
import requests
|
||||
import uuid
|
||||
import subprocess
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
check = engine.Scan()
|
||||
check.check_to_go()
|
||||
if check.state_list["error"]:
|
||||
for error in check.errors:
|
||||
print(error)
|
||||
sys.exit()
|
||||
|
||||
with open("settings.json", "r") as f: # loading settings
|
||||
settings = json.load(f)
|
||||
|
||||
with open("filesystem.json", "r") as f: # loading settings
|
||||
with open("filesystem.json", "r") as f: # loading filesystem
|
||||
filesystem = json.load(f)
|
||||
|
||||
IP = settings["IP"]
|
||||
@ -32,7 +41,6 @@ app.add_middleware(
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
log = engine.Log(settings["log"]) # init of LOG
|
||||
update = engine.Update()
|
||||
offline = []
|
||||
@ -44,12 +52,7 @@ time_to_heartbeat_offline = settings[
|
||||
|
||||
# json variables
|
||||
heartbeat_table = settings["heartbeat_table"]
|
||||
sensors = { # List of "live" data like tempeature, etc.
|
||||
"teplota": 24,
|
||||
"vlhkosť": 25,
|
||||
"počet ľudí": 10,
|
||||
"doba čakania": 2
|
||||
}
|
||||
sensors = {}
|
||||
|
||||
messages = []
|
||||
|
||||
@ -68,9 +71,14 @@ class ServerTable(BaseModel): # table of content for heartbeat request
|
||||
last_heartbeat: list
|
||||
|
||||
|
||||
class Sensor(BaseModel):
|
||||
name: str
|
||||
value: str
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
return "wikispot"
|
||||
|
||||
|
||||
@app.post("/heartbeat")
|
||||
@ -107,19 +115,35 @@ def heartbeat(s_table: ServerTable, request: Request):
|
||||
return heartbeat_table, {"ID": ID, "file_system": filesystem, "location": location}
|
||||
|
||||
|
||||
@app.get("/sensors")
|
||||
def get_sensors(request: Request):
|
||||
@app.get("/{IDx}/sensors")
|
||||
def get_sensors(IDx: int, request: Request):
|
||||
global sensors
|
||||
log.message(f"sensor data sent to {request.client.host}:{request.client.port}")
|
||||
log.debug(f"sensor data: {sensors}")
|
||||
return sensors
|
||||
if IDx == ID:
|
||||
return sensors
|
||||
else:
|
||||
try:
|
||||
r = requests.get(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/{IDx}/sensors""")
|
||||
return r.json()
|
||||
except Exception as error:
|
||||
log.error(f"Sensor data download from {IDx} failed.\n ERROR: {error}")
|
||||
return f"Sensor data download from {IDx} failed.\n ERROR: {error}"
|
||||
|
||||
|
||||
@app.get("/files/{IDx}/{file}")
|
||||
def get_file(IDx: int, file: str):
|
||||
def get_file(IDx: int, file: str, request: Request):
|
||||
log.debug(f"""{request.client} requested {file} from {"this server" if IDx == ID else f"id {IDx}"}""")
|
||||
server_ip = heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]
|
||||
if IDx == ID:
|
||||
return FileResponse(f"files/{file}")
|
||||
elif IDx in heartbeat_table["ID"]:
|
||||
if os.path.isfile(f"files/{file}"):
|
||||
return FileResponse(f"files/{file}")
|
||||
else:
|
||||
return f"File {file} does not exist."
|
||||
if IDx not in heartbeat_table["ID"]:
|
||||
log.error(f"{request.client} tried to access id ({IDx}) that does not exist.")
|
||||
return f"ERROR: {IDx} does not exist."
|
||||
else:
|
||||
if os.path.isdir(f"cache/{IDx}"):
|
||||
if os.path.isfile(f"cache/{IDx}/{file}"):
|
||||
with open(f"cache/{IDx}/{file}", "rb") as compared_file:
|
||||
@ -128,32 +152,44 @@ def get_file(IDx: int, file: str):
|
||||
m.update(line)
|
||||
rr = requests.get(f"""http://{server_ip}:8000/compare/{file}""")
|
||||
if rr.text.strip('"') != str(m.hexdigest()):
|
||||
log.message(f"{file} on server {server_ip} is changed.")
|
||||
log.warning(f"{file} on server {server_ip} is changed.")
|
||||
else:
|
||||
log.debug(f"returning cached file cache/{IDx}{file}")
|
||||
return FileResponse(f"cache/{IDx}/{file}")
|
||||
else:
|
||||
os.mkdir(f"cache/{IDx}")
|
||||
log.message(f"downloading {file} from {server_ip}")
|
||||
r = requests.get(f"http://{server_ip}:8000/files/{IDx}/{file}")
|
||||
if "does not exist" in r.text:
|
||||
log.error(f"{request.client} tried to access file ({file}) on id {IDx} that does not exist.")
|
||||
return f"ERROR: {file} does not exist."
|
||||
log.message(f"Downloaded {file} from {server_ip}")
|
||||
with open(f"cache/{IDx}/{file}", "wb") as save:
|
||||
save.write(bytes(r.content))
|
||||
return FileResponse(f"cache/{IDx}/{file}")
|
||||
|
||||
|
||||
@app.post("/update")
|
||||
def update_sensors():
|
||||
pass
|
||||
# Todo Make option to upload "live data" manually to rpi
|
||||
@app.post("/update_sensor")
|
||||
def update_sensors(data: Sensor, request: Request):
|
||||
global sensors
|
||||
if data.name in sensors:
|
||||
log.message(f"{request.client.host} updated sensor {data.name} with value {data.value}")
|
||||
sensors[data.name] = data.value
|
||||
else:
|
||||
log.warning(f"{request.client} created new sensor.\n SENSOR: {data}")
|
||||
sensors[data.name] = data.value
|
||||
return f"Successfuly made"
|
||||
|
||||
|
||||
@app.get("/compare/{file}")
|
||||
def comparision(file: str):
|
||||
with open(f"files/{file}", "rb") as compared_file:
|
||||
m = hashlib.md5()
|
||||
for line in compared_file:
|
||||
m.update(line)
|
||||
return m.hexdigest()
|
||||
try:
|
||||
with open(f"files/{file}", "rb") as compared_file:
|
||||
m = hashlib.md5()
|
||||
for line in compared_file:
|
||||
m.update(line)
|
||||
return m.hexdigest()
|
||||
except FileNotFoundError:
|
||||
return f"ERROR {file} does not exist"
|
||||
|
||||
|
||||
@app.get("/devices_list")
|
||||
@ -161,12 +197,41 @@ def get_devices_list():
|
||||
return [{"connected_id": ID}, *heartbeat_table["file_system"]]
|
||||
|
||||
|
||||
@app.get("/admin/{command}")
|
||||
def admin(command: str):
|
||||
@app.get("/admin/get/{command}")
|
||||
def admin_get(command: str):
|
||||
if command == "get_updates":
|
||||
return [update.get_version(), update.get_updates()]
|
||||
if "update-" in command:
|
||||
os.system(f"""python3 system.py update -version {command.split("-")[1]}""")
|
||||
state = []
|
||||
version = command.split("-")[1]
|
||||
for rpi in heartbeat_table["IP"]:
|
||||
if rpi != IP:
|
||||
r = requests.get(f"""http://{rpi}:8000/admin/get/update_one-{version}""")
|
||||
if r.text.strip('"').split("\\n")[0] == "SUCCESS":
|
||||
log.message(f"{rpi} was updated to {version}")
|
||||
else:
|
||||
log.warning(f"""{rpi} failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {r.text}""")
|
||||
state.append({rpi: r.text.strip('"').split("\\n")})
|
||||
# Todo Remove development comments
|
||||
# subprocess.check_output(f"""python3 system.py update -version {version}""")
|
||||
log.message(f"All devices in network should be updated to {version}")
|
||||
state.append({IP: "updated"})
|
||||
return state
|
||||
if "update_one-" in command:
|
||||
state = subprocess.check_output(["python3", "system.py", "update", "-version", f"""{command.split("-")[1]}"""])
|
||||
log.warning(state.decode("utf-8"))
|
||||
return state.decode("utf-8")
|
||||
if command == "setting":
|
||||
return settings
|
||||
|
||||
|
||||
@app.post("admin/post/{command}")
|
||||
def admin_post(command: str, data):
|
||||
pass
|
||||
|
||||
|
||||
# Todo upload of update file and settings
|
||||
|
||||
|
||||
@app.get("/messages/get")
|
||||
@ -183,11 +248,16 @@ def get_messages():
|
||||
def get_messages(m_sender: str = None, message: str = None):
|
||||
if m_sender and message:
|
||||
messages.append({"sender": m_sender, "message": message})
|
||||
return "successfull"
|
||||
return "successful"
|
||||
else:
|
||||
return "Empty message/sender"
|
||||
|
||||
|
||||
@app.get("/debug")
|
||||
def debug_esp():
|
||||
return "test successful"
|
||||
|
||||
|
||||
def send_heartbeat(ip, id):
|
||||
global heartbeat_table
|
||||
log.message(f"""sending heartbeat to {ip}({"offline" if id in offline else "online"})""")
|
||||
@ -238,6 +308,8 @@ def mainloop():
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
print(f"""Starting WikiSpot V{update.get_version()["version"]}""")
|
||||
print("GitHub: https://github.com/Tucan444/Mabasej_Team")
|
||||
thread_1 = threading.Thread(target=mainloop, daemon=True)
|
||||
thread_1.start()
|
||||
|
||||
|
@ -6,16 +6,18 @@ import requests
|
||||
|
||||
arguments = sys.argv
|
||||
arguments.remove(sys.argv[0])
|
||||
url = "https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json"
|
||||
|
||||
if len(arguments) == 0:
|
||||
sys.exit()
|
||||
|
||||
command = arguments[0]
|
||||
if command in ["u", "update"]:
|
||||
with open("version.json", "r") as f: # loading settings
|
||||
version = json.load(f)
|
||||
url = version["url"]
|
||||
server_version = json.loads(requests.get(url).text)
|
||||
try:
|
||||
server_version = json.loads(requests.get(url).text)
|
||||
except Exception as error:
|
||||
print(f"CAN'T DOWNLOAD VERSION LIST. ERROR: {error}")
|
||||
sys.exit()
|
||||
if "-version" in arguments:
|
||||
try:
|
||||
version_download = arguments[arguments.index("-version") + 1]
|
||||
@ -27,23 +29,32 @@ if command in ["u", "update"]:
|
||||
sys.exit()
|
||||
|
||||
else:
|
||||
version_download = 0
|
||||
try:
|
||||
with open("version.json", "r") as f: # loading settings
|
||||
version = json.load(f)
|
||||
except:
|
||||
version = {"id": 0}
|
||||
for ver, data in enumerate(server_version.values()):
|
||||
if data["id"] > version["id"]:
|
||||
if data["id"] > version["id"] and ver > version_download:
|
||||
version_download = list(server_version.keys())[ver]
|
||||
try:
|
||||
with open("update.zip", "wb") as save:
|
||||
save.write(
|
||||
bytes(requests.get(
|
||||
f"https://github.com/UntriexTv/test_directory/releases/download/{version_download}/update.zip").content))
|
||||
except Exception as error:
|
||||
print(f"FAILED TO DOWNLOAD UPDATE. ERROR: {error}")
|
||||
sys.exit()
|
||||
|
||||
with open("update.zip", "wb") as save:
|
||||
save.write(
|
||||
bytes(requests.get(
|
||||
f"https://github.com/UntriexTv/test_directory/releases/download/{version_download}/update.zip").content))
|
||||
print("Download succefull")
|
||||
print("Extracting update")
|
||||
if not os.path.isdir("update"):
|
||||
os.mkdir("update")
|
||||
with zipfile.ZipFile("update.zip", "r") as zip_ref:
|
||||
zip_ref.extractall("")
|
||||
zip_ref.extractall("update")
|
||||
os.rmdir("update")
|
||||
os.remove("update.zip")
|
||||
print(f"update to {version_download} was succefull.")
|
||||
print("SUCCESS")
|
||||
print(f"""Update from version {version["version"]} to {version_download} was sucesfull""")
|
||||
|
||||
if command == "clean":
|
||||
if arguments[1] == "all":
|
||||
|
@ -1,5 +1,4 @@
|
||||
{
|
||||
"version": "0.6",
|
||||
"id": 4,
|
||||
"url": "https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json"
|
||||
"version": "0.9",
|
||||
"id": 6
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user