Merge pull request #3 from Tucan444/Development

First working version of WikiSpot Server and app
This commit is contained in:
Untriex Programming
2021-05-09 12:05:55 +02:00
committed by GitHub
169 changed files with 10061 additions and 679 deletions

6
server/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

55
server/.idea/workspace.xml generated Normal file
View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="7d87058b-045e-4cef-a58c-742b2c4128db" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Merge.Settings">
<option name="BRANCH" value="Development" />
</component>
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$/.." value="Development" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectId" id="1ptaObqar0IjON5s6ejh3akwf0j" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../../Mabasej_work_server" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="7d87058b-045e-4cef-a58c-742b2c4128db" name="Default Changelist" comment="" />
<created>1616004808992</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1616004808992</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
</project>

BIN
server/cache/1/test.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

View File

@@ -1,4 +1,8 @@
from datetime import datetime
import json
import requests
import os
import subprocess
class Log:
@@ -18,23 +22,104 @@ class Log:
if self.print_error:
print(f"{datetime.now()} -> ERROR: {error}")
if self.save_error:
with open("log.txt", "a") as file:
with open("log.txt", "a", encoding='utf-8') as file:
file.write(f"\n{datetime.now()} -> ERROR: {error}")
def warning(self, warning):
if self.print_warning:
print(f"{datetime.now()} -> Warning: {warning}")
if self.save_warning:
with open("log.txt", "a") as file:
with open("log.txt", "a", encoding='utf-8') as file:
file.write(f"\n{datetime.now()} -> Warning: {warning}")
def message(self, message):
if self.print_messages:
print(f"{datetime.now()} -> message: {message}")
if self.save_messages:
with open("log.txt", "a") as file:
with open("log.txt", "a", encoding='utf-8') as file:
file.write(f"\n{datetime.now()} -> message: {message}")
def debug(self, debug):
if self.debug_e:
print(f"{datetime.now()} -> DEBUG: {debug}")
class Update:
def __init__(self):
with open("version.json", "r", encoding='utf-8') as f: # loading settings
version = json.load(f)
self.url = "https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json"
self.version = version["version"]
self.id = version["id"]
def get_updates(self):
return json.loads(requests.get(self.url).text)
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", encoding='utf-8') 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):
o = subprocess.check_output(["python3", "system.py", "update"])
print(o)

View File

@@ -1 +1 @@
toto je test číslo 1 zo serveru s ID 2
toto je test číslo 1

View File

@@ -1 +0,0 @@
toto je test n. 2 zo serveru ID2

View File

@@ -1,22 +1,23 @@
{
"ID": 0,
"location": "izba",
"descrpition": {
"title": "legionrpi",
"description_s": "krátky popis, ktorý bude zobrazený iba v náhladovom okne",
"description_l": "dlhší popis zariadenia, ktorý bude zobrazený po otvorení",
"photo_s": "mala_fotka.png",
"photo_b": "velka fotka.png"
"location": "25.997417761947318, -97.15738221291177",
"description": {
"title": "WikiSpot-demo",
"description_s": "Krátky popis",
"description_l": "Dlhší popis",
"photo_s": "test.jpg",
"photo_b": "test.png"
},
"files": [
{
"name": "test",
"format": ".jpg",
"description": "This is jpg test file"
},
"files": [
{
"name": "test",
"format": ".jpg",
"description": "toto je jpg test file"
}, {
"name": "test2",
"format": ".txt",
"description": "toto je txt test file"
}
]
{
"name": "test",
"format": ".txt",
"description": "This is txt test file"
}
]
}

View File

@@ -1,3 +1,3 @@
2021-03-15 10:13:26.660898 -> Warning: 192.168.1.232 disconnected/is not available
2021-03-15 11:23:33.589998 -> Warning: 192.168.1.231 disconnected/is not available
2021-05-08 16:11:06.311275 -> Warning: 192.168.1.231 disconnected/is not available
2021-05-08 16:11:37.323462 -> Warning: 192.168.1.231 disconnected/is not available

View File

@@ -1,27 +1,79 @@
from fastapi import FastAPI, Request
from fastapi.responses import FileResponse
from pydantic import BaseModel
import engine
import requests
import time
import hashlib
import json
import os
import threading
import hashlib
import time
import engine
import requests
import uuid
import subprocess
import socket
import shutil
from pathlib import Path
from fastapi import FastAPI, Request, File, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from pydantic import BaseModel
with open("settings.json", "r") as f: # loading settings
devs = {
"Matej Justus": {
"git": "https://github.com/UntriexTv", "mail": "maco.justus@gmail.com"},
"Benjamin Kojda": {
"git": "https://github.com/Tucan444", "mail": "ben4442004@gmail.com"
},
"Jakub Ďuriš": {
"git": "https://github.com/ff0082", "mail": "jakub1.duris@gmail.com"
},
"Samuel Šubika": {
"git": "https://github.com/JustSteel", "mail": "SteelSamko2000@gmail.com"}
}
check = engine.Scan()
check.check_to_go()
if check.state_list["error"]:
for error in check.errors:
print(error)
check.fix_version()
with open("settings.json", "r", encoding='utf-8') as f: # loading settings
settings = json.load(f)
with open("filesystem.json", "r") as f: # loading settings
with open("filesystem.json", "r", encoding='utf-8') as f: # loading filesystem
filesystem = json.load(f)
IP = settings["IP"]
ID = settings["ID"]
location = settings["location"]
if settings["clear_cache_on_startup"]:
shutil.rmtree("cache")
os.mkdir("cache")
def get_my_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
IP = get_my_ip()
ID = filesystem["ID"]
location = filesystem["location"]
time_to_save = settings["time_to_save"]
settings["location"]
settings["ID"]
app = FastAPI() # init of FastAPI
origins = ["*", ]
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
log = engine.Log(settings["log"]) # init of LOG
update = engine.Update()
offline = []
save_time = time.time()
time_to_heartbeat = settings["time_to_heartbeat"] # Raspberry will be requesting heartbeat every __ seconds
time_to_heartbeat_offline = settings[
@@ -29,22 +81,17 @@ 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 = {}
heartbeat_table["ID"].append(ID)
heartbeat_table["IP"].append(IP)
heartbeat_table["location"].append(location)
heartbeat_table["file_system"].append(filesystem)
heartbeat_table["last_heartbeat"].append(time_to_heartbeat)
messages = [] # {user: "", timestamp: time.Time(), message: ""}
if ID not in heartbeat_table["ID"]:
heartbeat_table["ID"].append(ID)
heartbeat_table["IP"].append(IP)
heartbeat_table["location"].append(location)
heartbeat_table["file_system"].append(filesystem)
heartbeat_table["last_heartbeat"].append(time_to_heartbeat)
# Todo better "host" ID handeling
class ServerTable(BaseModel): # table of content for heartbeat request
ID: list
IP: list
@@ -53,6 +100,21 @@ class ServerTable(BaseModel): # table of content for heartbeat request
last_heartbeat: list
class Sensor(BaseModel):
name: str
value: str
class Message(BaseModel):
m_sender: str
message: str
@app.get("/")
def read_root():
return "wikispot"
@app.post("/heartbeat")
def heartbeat(s_table: ServerTable, request: Request):
log.message(f"server requested heartbeat {request.client.host}:{request.client.port}")
@@ -65,41 +127,60 @@ def heartbeat(s_table: ServerTable, request: Request):
s_table.last_heartbeat[position]:
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(server_id)] = s_table.last_heartbeat[
position]
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
heartbeat_table["file_system"][heartbeat_table["ID"].index(server_id)] = s_table.file_system[
position]
elif server_id == ID:
log.debug(f"Updated my heartbeat from {s_table.last_heartbeat[position]} to {time_to_heartbeat}")
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(ID)] = time_to_heartbeat
else:
heartbeat_table["ID"].append(s_table.ID[position])
log.message(f"Heartbeat from new server:\n ID: {server_id} IP: {request.client}")
heartbeat_table["ID"].append(int(s_table.ID[position]))
heartbeat_table["IP"].append(s_table.IP[position])
heartbeat_table["location"].append(s_table.location[position])
heartbeat_table["file_system"].append(s_table.file_system[position])
heartbeat_table["last_heartbeat"].append(s_table.last_heartbeat[position])
heartbeat_table["last_heartbeat"].append(int(s_table.last_heartbeat[position]))
log.debug(f"Created {server_id}`s heartbeat: {s_table.last_heartbeat[position]}")
except Exception as error:
log.error(f"heartbeat > {error}")
if heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)] in offline:
offline.remove(heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)])
log.message(f"{request.client.host} gone online")
log.warning(f"{request.client.host} gone online")
return heartbeat_table, {"ID": ID, "file_system": filesystem, "location": location}
@app.get("/sensors")
def get_sensors(request: Request):
log.message(f"sensor data sent to {request.client.host}:{request.client.port}")
log.debug(f"sensor data: {sensors}")
return sensors
@app.get("/{IDx}/sensors")
def get_sensors(IDx: int, request: Request):
global sensors
if IDx == ID:
log.debug(f"Sensor data sent to {request.client.host} :\n {sensors}")
return sensors
else:
try:
r = requests.get(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/{IDx}/sensors""")
log.debug(f"Sensor data from {IDx} sent to {request.client.host} :\n {r.json()}")
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:
log.warning(f"{request.client} tried to access file ({file}) that does not exist on this server.")
return f"ERROR: File {file} does not exist."
if IDx not in heartbeat_table["ID"]:
log.warning(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:
@@ -108,37 +189,149 @@ 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}")
elif sum(file.stat().st_size for file in Path("cache").rglob('*'))/1024**2 > settings["cache_size_mb"]:
shutil.rmtree("cache")
os.mkdir("cache")
log.message(f"""Clearing cache, because of limit of {settings["cache_size_mb"]}MB""")
os.mkdir(f"cache/{IDx}")
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.warning(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("/{IDx}/update_sensor")
def update_sensors(data: Sensor, request: Request, IDx: int):
global sensors
if IDx == ID:
if data.name in sensors:
if not data.value:
log.message(f"{request.client.host} removed sensor {data.name}")
del sensors[data.name]
else:
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 new sensor"
else:
r = requests.post(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/{IDx}/update_sensor""",
json={"name": data.name, "value": data.value})
return r.text
@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")
def get_devices_list():
return heartbeat_table["file_system"]
returning_value = [{"connected_id": ID}, *heartbeat_table["file_system"]]
while "" in returning_value:
returning_value.remove("")
return returning_value
@app.get("/admin/get/{command}")
def admin_get(command: str, request: Request):
log.message(f"{request.client} used admin command.")
if command == "get_updates":
return [update.get_version(), update.get_updates()]
if "update-" in command:
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.error(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")})
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.message(state.decode("utf-8"))
return state.decode("utf-8")
if command == "heartbeat_table":
return heartbeat_table
if command == "filesystem":
return filesystem
@app.post("/admin/{id_server}/upload_file")
async def create_upload_file(id_server: int, uploaded_file: UploadFile = File(...), patch: str = ""):
file_location = f"{patch}{uploaded_file.filename}"
if id_server == ID:
with open(file_location, "wb+") as file_object:
file_object.write(uploaded_file.file.read())
else:
with open(f"cache/{uploaded_file.filename}", "wb+") as file_object:
file_object.write(uploaded_file.file.read())
file = open(f"cache/{uploaded_file.filename}", "rb")
requests.post(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(id_server)]}:8000/admin/{id_server}/upload_file""",
files={"uploaded_file": file, "patch": patch})
file.close()
return {"info": f"""file '{uploaded_file.filename}' saved at '{id_server}/{file_location}'"""}
@app.get("/messages/get")
def get_messages(timestamp: str = None):
if timestamp:
for position, message in enumerate(reversed(messages)):
if float(message["timestamp"]) <= float(timestamp):
return list(reversed(list(reversed(messages))[:position]))
if timestamp == "0":
return messages
return []
else:
return messages[:10]
@app.get("/messages/register")
def register():
return [uuid.uuid4().hex[24:], messages[:9]]
@app.get("/discovery")
def discovery():
return "Success"
@app.post("/messages/post")
def post_messages(data: Message):
log.debug(f"Message was posted. Sender: {data.m_sender}\n MESSAGE: {data.message}")
if len(messages) >= settings["max_mess"]:
del messages[:len(messages) - settings["max_mess"]]
if data.m_sender and data.message:
messages.append({"sender": data.m_sender, "message": data.message, "timestamp": time.time()})
return "successful"
else:
return "Empty message/sender"
def send_heartbeat(ip, id):
@@ -150,32 +343,51 @@ def send_heartbeat(ip, id):
def mainloop():
global save_time
while True:
for device_number, device_ID in enumerate(heartbeat_table["ID"]):
if device_ID != ID:
if heartbeat_table["last_heartbeat"][device_number] < 0:
if int(heartbeat_table["last_heartbeat"][device_number]) < 0:
try:
send_heartbeat(heartbeat_table["IP"][device_number], heartbeat_table["ID"][device_number])
except requests.exceptions.ConnectionError:
if heartbeat_table["ID"][device_number] not in offline:
log.warning(f"""{heartbeat_table["IP"][device_number]} disconnected/is not available""")
offline.append(heartbeat_table["ID"][device_number])
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat_offline)
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat_offline)
else:
offline.remove(heartbeat_table["ID"][device_number])
log.message(f"""Removing {device_ID} because of long inactivity.""")
del heartbeat_table["ID"][device_number]
del heartbeat_table["IP"][device_number]
del heartbeat_table["location"][device_number]
del heartbeat_table["file_system"][device_number]
del heartbeat_table["last_heartbeat"][device_number]
else:
if heartbeat_table["ID"][device_number] in offline:
offline.remove(heartbeat_table["ID"][device_number])
log.message(f"""{heartbeat_table["IP"][device_number]} gone online""")
heartbeat_table["last_heartbeat"][int(device_number)] = int(time_to_heartbeat) + 5
log.debug(f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
heartbeat_table["last_heartbeat"][device_number] -= 1
try:
log.debug(
f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
heartbeat_table["last_heartbeat"][device_number] = int(heartbeat_table["last_heartbeat"][device_number]) - 1
except IndexError:
pass
if time.time() - time_to_save > save_time and settings["save_table"]:
save_time = time.time()
log.message("Saving heartbeat table.")
log.debug(f"Saving heartbeat table: {heartbeat_table}")
settings["heartbeat_table"] = heartbeat_table
with open("settings.json", "w", encoding='utf-8') as file:
json.dump(settings, file, indent=2)
time.sleep(1)
print(f"""Starting WikiSpot V{update.get_version()["version"]} on http://{IP}:8000""")
print("GitHub: https://github.com/Tucan444/Mabasej_Team")
print("Developers of this project: ")
for dev in devs:
print(f"""{dev}, GitHub: {devs[dev]["git"]}, mail: {devs[dev]["mail"]}""")
thread_1 = threading.Thread(target=mainloop, daemon=True)
thread_1.start()
# Todo in next release: disconnect offline client after set time
# Todo send to mobile
# Todo new filesystem handeling
# Todo implement update system
# Todo settings for easy adding/editing files/id/text

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
#! /usr/bin/python3
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import imutils
import numpy as np
import requests
protopath = "MobileNetSSD_deploy.prototxt"
modelpath = "MobileNetSSD_deploy.caffemodel"
detector = cv2.dnn.readNetFromCaffe(prototxt=protopath, caffeModel=modelpath)
person_counter = 0
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
"dog", "horse", "motorbike", "person", "pottedplant", "sheep",
"sofa", "train", "tvmonitor"]
# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
rawCapture = PiRGBArray(camera)
# allow the camera to warmup
time.sleep(0.1)
# grab an image from the camera
while True:
camera.capture(rawCapture, format="bgr")
image = rawCapture.array
image = imutils.resize(image, width=1024, height=1024)
(H, W) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 0.007843, (W, H), 127.5)
detector.setInput(blob)
person_detections = detector.forward()
for i in np.arange(0, person_detections.shape[2]):
confidence = person_detections[0, 0, i, 2]
if confidence > 0.2:
idx = int(person_detections[0, 0, i, 1])
if CLASSES[idx] == "person":
person_counter += 1
r = requests.post("http://127.0.0.1:8000/update_sensor", json={"name": "pocet ludi", "value": str(person_counter)})
time.sleep(60)

View File

@@ -0,0 +1,15 @@
[Unit]
Description=WikiSpot official computer vision plugin
After=wikispot.service
StartLimitIntervalSec=4
[Service]
Type=simple
Restart=always
RestartSec=10
User=root
WorkingDirectory=/root/test_directory/plugins/computer_vision
ExecStart=/root/test_directory/plugins/computer_vision
[Install]
WantedBy=multi-user.target

View File

@@ -1,9 +1,11 @@
{
"ID": 0,
"IP": "192.168.1.99",
"location": "izba",
"time_to_heartbeat": 20,
"time_to_heartbeat_offline": 25,
"save_table": true,
"time_to_save": 60,
"max_mess": 20,
"cache_size_mb": 1000,
"clear_cache_on_startup": false,
"log": {
"save_error": true,
"print_error": true,
@@ -19,5 +21,5 @@
"location": [],
"file_system": [],
"last_heartbeat": []
}
}
}

View File

@@ -1,12 +0,0 @@
import tkinter
import json
height = 750
width = 1200
with open("settings.json", "r") as file:
settings = json.load(file)
with open("settings.json", "r") as file:
filesystem = json.load(file)
canvas = tkinter.Canvas(height=height, width=width)
canvas.pack()
canvas.mainloop()

81
server/system.py Normal file
View File

@@ -0,0 +1,81 @@
#! /usr/bin/python3
import sys
import os
import json
import zipfile
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"]:
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]
except IndexError:
print("Version argument is empty.")
sys.exit()
if version_download not in list(server_version.keys()):
print("Version not found.")
sys.exit()
else:
try:
with open("version.json", "r", encoding='utf-8') as f: # loading settings
version = json.load(f)
except:
version = {"id": 0, "version": "recovery"}
for ver, data in enumerate(server_version.values()):
if data["id"] > version["id"]:
version_download = list(server_version.keys())[ver]
try:
with open("update.zip", "wb", encoding='utf-8') 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 zipfile.ZipFile("update.zip", "r") as zip_ref:
zip_ref.extractall("")
os.remove("update.zip")
print("SUCCESS")
print(f"""Update from version {version["version"]} to {version_download} was sucesfull""")
if command == "clean":
if arguments[1] == "all":
open("log.txt", "w").close()
with open("settings.json", "r", encoding='utf-8') as file:
settings = json.load(file)
for line in settings["heartbeat_table"]:
settings["heartbeat_table"][line] = []
with open("settings.json", "w", encoding='utf-8') as file:
json.dump(settings, file, indent=2)
if arguments[1] == "log":
open("log.txt", "w").close()
if arguments[1] == "heartbeat_table":
with open("settings.json", "r", encoding='utf-8') as file:
settings = json.load(file)
for line in settings["heartbeat_table"]:
settings["heartbeat_table"][line] = []
with open("settings.json", "w", encoding='utf-8') as file:
json.dump(settings, file, indent=2)

View File

@@ -1,47 +0,0 @@
{
"connected_id": 1,
"1": {
"ID": 1,
"location": "GPS",
"descrpition": {
"title": "nazov rpi ako nazov",
"description_s": "krátky popis, ktorý bude zobrazený iba v náhladovom okne",
"description_l": "dlhší popis zariadenia, ktorý bude zobrazený po otvorení",
"photo_s": "mala_fotka.png",
"photo_b": "velka_fotka.png"
},
"files": [
{
"name": "prehliadky",
"format": ".pdf",
"description": "tento súbor obsahuje prehliadky"
}, {
"name": "prehliadky",
"format": ".pdf",
"description": "tento súbor obsahuje prehliadky"
}
]
},
"2": {
"ID": 2,
"location": "GPS",
"descrpition": {
"title": "nazov rpi ako nazov",
"description_s": "krátky popis, ktorý bude zobrazený iba v náhladovom okne",
"description_l": "dlhší popis zariadenia, ktorý bude zobrazený po otvorení",
"photo_s": "mala_fotka.png",
"photo_b": "velka fotka.png"
},
"files": [
{
"name": "prehliadky",
"format": ".pdf",
"description": "tento súbor obsahuje prehliadky"
}, {
"name": "prehliadky",
"format": ".pdf",
"description": "tento súbor obsahuje prehliadky"
}
]
}
}

View File

@@ -1,60 +0,0 @@
import curses
menu = ['Home', 'Play', 'Scoreboard', 'Exit']
def print_menu(stdscr, selected_row_idx):
stdscr.clear()
h, w = stdscr.getmaxyx()
for idx, row in enumerate(menu):
x = w//2 - len(row)//2
y = h//2 - len(menu)//2 + idx
if idx == selected_row_idx:
stdscr.attron(curses.color_pair(1))
stdscr.addstr(y, x, row)
stdscr.attroff(curses.color_pair(1))
else:
stdscr.addstr(y, x, row)
stdscr.refresh()
def print_center(stdscr, text):
stdscr.clear()
h, w = stdscr.getmaxyx()
x = w//2 - len(text)//2
y = h//2
stdscr.addstr(y, x, text)
stdscr.refresh()
def main(stdscr):
# turn off cursor blinking
curses.curs_set(0)
# color scheme for selected row
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
# specify the current selected row
current_row = 0
# print the menu
print_menu(stdscr, current_row)
while 1:
key = stdscr.getch()
if key == curses.KEY_UP and current_row > 0:
current_row -= 1
elif key == curses.KEY_DOWN and current_row < len(menu)-1:
current_row += 1
elif key == curses.KEY_ENTER or key in [10, 13]:
print_center(stdscr, "You selected '{}'".format(menu[current_row]))
stdscr.getch()
# if user selected last row, exit the program
if current_row == len(menu)-1:
break
print_menu(stdscr, current_row)
curses.wrapper(main)

View File

@@ -1,4 +1,4 @@
{
"version": "0.1",
"type": "Alpha"
}
"version": "1.0",
"id": 7
}