Merge branch 'Development' of https://github.com/Tucan444/Mabasej_Team into Development
169
README.md
@ -1,22 +1,169 @@
|
||||
# Mabasej_Team
|
||||
We are working on system, that will help tourists in cities to get information about city more easily.
|
||||
|
||||
# Hardware
|
||||
## Hardware
|
||||
- Raspberry PI (for now tested only on rpi4. Works on rpi zero too, but it will be slow if more devices are connected)
|
||||
- External/Internal WiFi antena
|
||||
|
||||
# Software
|
||||
## Software
|
||||
- python 3.9.2 compatible server with basic web interface
|
||||
- Kotlin based mobile app
|
||||
|
||||
# Server
|
||||
To run server you need to install
|
||||
- hypercorn - "pip install hypercorn"
|
||||
- fastapi - "pip install fastapi"
|
||||
- requests - "pip install requests"
|
||||
- aiofiles - "pip install aiofiles"
|
||||
## Install
|
||||
Wikispot is in testing stages, but it is possible to install it using our .img file (link coming soon) based on DietPi or custom script.
|
||||
|
||||
then run by command - "hypercorn main:app --bind <IP:port>"
|
||||
To connect to another rpi you need to edit settings.json with different ID and fill heartbeat table.
|
||||
| Device | Server compatible | Instalation |
|
||||
| :-------------------- | :------------------------------------------------------------------------------------------ | :-----------: |
|
||||
| Ubuntu (I7, 16GB ram) | :heavy_check_mark: WORKING (Only server) | Manual/script |
|
||||
| RPI 4b (2GB) | :heavy_check_mark: WORKING | .img/script |
|
||||
| RPI 400 (4GB) | :grey_question: Untested. Should work. | .img/script |
|
||||
| RPI 3b+ | :grey_question: Untested. Should work. | .img/script |
|
||||
| RPI zero w | :white_check_mark: Working with fewer devices (Only server. No AP, Computer vision) | .img/script |
|
||||
| RPI 2 | :question: Untested. | :x: |
|
||||
| RPI | :question: Untested. | :x: |
|
||||
|
||||
This is not finished product
|
||||
|
||||
### Fresh istall (.img) Only RPI
|
||||
login credentials
|
||||
> login: dietpi
|
||||
|
||||
> password: WikiSpot2021
|
||||
|
||||
|
||||
requirements:
|
||||
1. WikiSpot image file (download: *soon*)
|
||||
2. MicroSd card (recommended: >=16GB, :exclamation: ALL DATA STORED ON SD CARD WILL BE FORMATED :exclamation:)
|
||||
3. BalenaEtcher (or another sd card flasher) *link:* https://www.balena.io/etcher/
|
||||
4. SD card reader
|
||||
|
||||
|
||||
Install:
|
||||
1. Download all required files (wikispot.img and balenaetcher) and install BalenaEtcher
|
||||
2. Insert SD card into computer/reader, open BalenaEtcher -> chose Flash from file -> chose downloaded wikispot.img -> Select your sd in *Select target* -> Flash!
|
||||
3. :exclamation: WINDOWS will show unformated drive. Cancel it. It is because of uncompatible format for windows :exclamation:
|
||||
4. After flashing open partition *boot* (should apear as USB), find file *dietpi.txt* and open it in text editor.
|
||||
- Accept license by changing `AUTO_SETUP_ACCEPT_LICENSE=0` to `AUTO_SETUP_ACCEPT_LICENSE=1`
|
||||
- Change name of WikiSpot `AUTO_SETUP_NET_HOSTNAME=WikiSpot-CHANGE_ME` by changing only *CHANGE_ME* or leave *CHANGE_ME* for random number name *WikiSpot-54346
|
||||
- You can set static ip address by changing `AUTO_SETUP_NET_USESTATIC=0` to `AUTO_SETUP_NET_USESTATIC=1` And entering your setting into required lines.
|
||||
- If you want to use computer vision plugin with rpi camera set `ENABLE_COMPUTER_VISION_PLUGIN=0` to `ENABLE_COMPUTER_VISION_PLUGIN=1` (*recommended only on RPI4)
|
||||
- If you want to use RPI as access point to WikiSpot change `#AUTO_SETUP_INSTALL_SOFTWARE_ID=60` to `AUTO_SETUP_INSTALL_SOFTWARE_ID=60`
|
||||
- *wifi setup in testing*
|
||||
5. :grey_exclamation:For advanced users:grey_exclamation: You can now change contens of WikiSpot server in `/boot/WikiSpot`according to an example in server filesystem
|
||||
6. Eject sd card from computer, insert it in Raspberry Pi and power it on. :bangbang:Raspberry Pi needs to be connected to intenet via Ethernet (*wifi coming soon*) othervise the setup will crash.
|
||||
7. The setup will take approximately 25-40 min (RPI 4b (2gb) and 70 mb download speed)
|
||||
8. Done you can start using WikiSpot and edit contents of WikiSpot with our app (*coming soon*)
|
||||
|
||||
|
||||
### Script install
|
||||
*coming soon*
|
||||
|
||||
|
||||
### Manual install
|
||||
*coming soon*
|
||||
|
||||
|
||||
## Server filesystem
|
||||
|
||||
```
|
||||
└── test_directory
|
||||
├── cache # files forwarded from another servers to client
|
||||
├── engine.py # engine for server (log, recovery, update)
|
||||
├── files # content of WikiSpot server
|
||||
│ └── test.jpg
|
||||
├── filesystem.json # data settings of server (name, description, files)
|
||||
├── main.py # main server file
|
||||
├── plugins # plugins file
|
||||
│ └── computer_vision # oficial WikiSpot computer vision plugin for RPI 4
|
||||
│ ├── MobileNetSSD_deploy.caffemodel
|
||||
│ ├── MobileNetSSD_deploy.prototxt
|
||||
│ └── com_vision.py
|
||||
├── run.py # start script for server
|
||||
├── settings.json # settings (log, debug, connected WikiSpots, cache size,...)
|
||||
├── system.py # update and clean script
|
||||
└── version.json # version of WikiSpot
|
||||
```
|
||||
|
||||
|
||||
### filesystem
|
||||
|
||||
```
|
||||
{
|
||||
"ID": 0, # ID of WikiSpots, Needs to be different, because network will crash
|
||||
"location": "25.997417761947318, -97.15738221291177", # Location of WikiSpot server copied from google maps
|
||||
"description": {
|
||||
"title": "WikiSpot demo", # Name of WikiSpot server (swiming pool, school, ...)
|
||||
"description_s": "This is showcase of WikiSpot", # Short description showed on web/app in list of servers
|
||||
"description_l": "This will show after opening server in app", # Long description showed after opening the server in web/app
|
||||
"photo_s": "test.jpg", # Small image showed on web/app in list of servers
|
||||
"photo_b": "test.png" # Big image showed after opening the server in web/app
|
||||
},
|
||||
"files": [ # files on server in /files that will be mediated to the web/app
|
||||
{
|
||||
"name": "test", # Name of the file, without spaces. App will change "_" to spaces
|
||||
"format": ".jpg", # Format of the file
|
||||
"description": "This is test file" # Description showed next to the file
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To manualy add new file to server (on setup or via ssh) add file to `server_directory/files`
|
||||
and add record for file into `files` list in `filesystem.json`. :exclamation:do not forget "," after last record:exclamation:
|
||||
|
||||
```
|
||||
|
||||
{
|
||||
"name": "new_file_name",
|
||||
"format": ".txt",
|
||||
"description": "This is how you add new file"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### settings.json
|
||||
|
||||
```
|
||||
{
|
||||
"time_to_heartbeat": 20, # Time to ping of another online servers in seconds
|
||||
"time_to_heartbeat_offline": 25, # Time to ping of another offline servers in seconds
|
||||
"save_table": true, # Save connected servers to reconnect after restart
|
||||
"time_to_save": 60, # Time to save server in seconds
|
||||
"max_mess": 20, # Maximum messages stored in RAM
|
||||
"cache_size_mb": 1000, # Maximum size of cache directory in mb
|
||||
"clear_cache_on_startup": false, # Remove contents of cache on startup (slower first downloads)
|
||||
"log": { # Log settings
|
||||
"save_error": true, # Save errors into log.txt
|
||||
"print_error": true, # Print errors into console (if running as service into linux log)
|
||||
"save_warning": true, # Save warnings into log.txt
|
||||
"print_warning": true, # Print warnings into console (if running as service into linux log)
|
||||
"save_message": false, # Save messages (new server, etc. not messages from clients) into log.txt
|
||||
"print_message": true, # Print messages into console (if running as service into linux log)
|
||||
"enable_debug": false # Enable debug into console (if running as service into linux log)
|
||||
},
|
||||
"heartbeat_table": { # Saved servers
|
||||
"ID": [],
|
||||
"IP": [],
|
||||
"location": [],
|
||||
"file_system": [],
|
||||
"last_heartbeat": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to manually add server on first setup or via ssh fill heartbeat table like this.
|
||||
|
||||
```
|
||||
"heartbeat_table": { # Saved servers
|
||||
"ID": [1], # ID of server as integer (number)
|
||||
"IP": ["192.168.1.2"], # IP of server as string
|
||||
"location": [""], # Empty string as placeholder. location will be downloaded after first connection
|
||||
"file_system": [""], # Empty string as placeholder. filesystem will be downloaded after first connection
|
||||
"last_heartbeat": [10] # After how many seconds will server try to connect for the first time
|
||||
}
|
||||
```
|
||||
|
||||
:bangbang:If the server will be offline for long time (heartbeat + offline heartbeat) it will be removed from heartbeat table. If the save function is disabled server will trying to connect after restart:bangbang:
|
||||
|
||||
|
||||
|
||||
*This is not finished product*
|
||||
|
6
app/WikiSpot/.idea/vcs.xml
Normal 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>
|
BIN
new new files/files/Jedálny lístok.pdf
Normal file
22
new new files/files/Podrobnosti.txt
Normal file
@ -0,0 +1,22 @@
|
||||
Vybavenie
|
||||
|
||||
Šatňa - áno
|
||||
Vlastné parkovisko - áno
|
||||
Televízor - áno
|
||||
|
||||
Pre rodiny s deťmi
|
||||
|
||||
Detské stoličky - áno
|
||||
detský kútik - áno
|
||||
|
||||
Služby
|
||||
|
||||
Čapované pivo - áno
|
||||
Organizovanie spoločenských podujatí – áno
|
||||
Koktail bar - áno
|
||||
|
||||
Kontakt
|
||||
|
||||
Adresa: Dlhá 58 , 095 01 Senica
|
||||
Telefón: +421
|
||||
Email: restauracia.kojda@gmail.com
|
BIN
new new files/files/restaurant_in.jpg
Normal file
After Width: | Height: | Size: 315 KiB |
BIN
new new files/files/restaurant_out.jpg
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
new new files/files1/Cenník.pdf
Normal file
17
new new files/files1/Podrobnosti.txt
Normal file
@ -0,0 +1,17 @@
|
||||
Otváracie hodiny:
|
||||
PON-PIA: 09:00 - 17:00
|
||||
SOB: zatvorené
|
||||
NED: 10:00-16:00
|
||||
|
||||
13:00-13:30 (obedná prestávka)
|
||||
|
||||
- Predaj doplnkového tovaru
|
||||
- Výmena peňazí
|
||||
- Telekomunikačné služby
|
||||
- predplatné novín a časopisov
|
||||
|
||||
Kontakt
|
||||
|
||||
Adresa: Športovcov 7212, 017 01 Považská Bystrica
|
||||
Telefón: 0918 221 189
|
||||
email: slovenska.posta@gmail.com
|
BIN
new new files/files1/post_out.jpg
Normal file
After Width: | Height: | Size: 304 KiB |
BIN
new new files/files1/posta_in.jpg
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
new new files/files2/Bazény a cenník.pdf
Normal file
23
new new files/files2/Služby a kontakt.txt
Normal file
@ -0,0 +1,23 @@
|
||||
Služby
|
||||
|
||||
- Plavecký bazén
|
||||
- Relaxačný bazén
|
||||
- Detský bazén
|
||||
|
||||
Sauna
|
||||
|
||||
- fínska
|
||||
- ruská
|
||||
- turecká
|
||||
- bylinková
|
||||
- infra sauna
|
||||
|
||||
|
||||
- Masáže
|
||||
|
||||
Kontakt
|
||||
|
||||
Adresa: Mládežnícka 12,
|
||||
017 01 Považská Bystrica
|
||||
|
||||
Telefón: 032/221 52 97
|
BIN
new new files/files2/plavaren_in.jpg
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
new new files/files2/plavaren_out.jpg
Normal file
After Width: | Height: | Size: 474 KiB |
BIN
new new files/files3/Cenník.pdf
Normal file
BIN
new new files/files3/Náhľad.pdf
Normal file
BIN
new new files/files3/muzeum_in.jpg
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
new new files/files3/muzeum_out.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
18
new new files/files4/Podrobnosti.txt
Normal file
@ -0,0 +1,18 @@
|
||||
Služby na stanici:
|
||||
|
||||
- Bezplatné parkovanie
|
||||
- Poistenie na počkanie
|
||||
- Predaj cestovných lístkov
|
||||
- Predaj miesteniek
|
||||
- Rezervácie
|
||||
- Predaj žrebov Niké
|
||||
|
||||
Kontakt
|
||||
|
||||
Adresa: Zámostie, 017 01 Považská Bystrica
|
||||
|
||||
Telefón
|
||||
Slovensko: 18 188
|
||||
Zo zahraničia: +421 24 28 54 182
|
||||
|
||||
info@slovakrail.sk
|
BIN
new new files/files4/Zľavy.pdf
Normal file
BIN
new new files/files4/zeleznicna_stanica_in.jpg
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
new new files/files4/zeleznicna_stanica_out.jpg
Normal file
After Width: | Height: | Size: 55 KiB |
24
new new files/filesystem.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ID": 0,
|
||||
"location": "49.14178021389778,18.353783098441415",
|
||||
"description": {
|
||||
"title": "Reštaurácia pod slivkou",
|
||||
"description_s": "Otvorené",
|
||||
"description_l": "Otváracie hodiny:\nPON-PIA: 09:00 - 22:00\nSOB: zatvorené\nNED: 14:00-21:00",
|
||||
"photo_s": "restaurant_out.jpg",
|
||||
"photo_b": "restaurant_in.jpg",
|
||||
"email": "restauracia.podslivkou@gmail.com",
|
||||
"phone_number": "0928229120"
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"name": "Podrobnosti",
|
||||
"format": ".txt",
|
||||
"description": "Vybavenie, služby a kontakt"
|
||||
}, {
|
||||
"name": "Jedálny lístok",
|
||||
"format": ".pdf",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
24
new new files/filesystem1.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ID": 1,
|
||||
"location": "49.095721799569304, 18.47399399775766",
|
||||
"description": {
|
||||
"title": "Slovenská pošta",
|
||||
"description_s": "Otvorené",
|
||||
"description_l": "Otváracie hodiny:\nPON-PIA: 09:00 - 17:00\nSOB: zatvorené\nNED: 10:00-16:00",
|
||||
"photo_s": "post_out.jpg",
|
||||
"photo_b": "post_in.jpg",
|
||||
"email": "slovenska.posta@gmail.com",
|
||||
"phone_number": "0918221189"
|
||||
},
|
||||
"files1": [
|
||||
{
|
||||
"name": "Podrobnosti",
|
||||
"format": ".txt",
|
||||
"description": ""
|
||||
}, {
|
||||
"name": "Cenník",
|
||||
"format": ".pdf",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
24
new new files/filesystem2.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ID": 2,
|
||||
"location": "49.14437583832675, 18.466946907073503",
|
||||
"description": {
|
||||
"title": "Mestská plaváreň",
|
||||
"description_s": "Otvorené",
|
||||
"description_l": "Otvorené nonstop\nOtváracie doby sa počas sviatkov môžu líšiť",
|
||||
"photo_s": "plavaren_out.jpg",
|
||||
"photo_b": "plavaren_in.jpg",
|
||||
"email": "",
|
||||
"phone_number": "0322215297"
|
||||
},
|
||||
"files2": [
|
||||
{
|
||||
"name": "Služby a kontakt",
|
||||
"format": ".txt",
|
||||
"description": ""
|
||||
}, {
|
||||
"name": "Fotogaléria a cenník",
|
||||
"format": ".pdf",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
24
new new files/filesystem3.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ID": 3,
|
||||
"location": "49.10101907820781, 18.440001048091226",
|
||||
"description": {
|
||||
"title": "Považsko Bystrické Múzeum",
|
||||
"description_s": "Otvorené",
|
||||
"description_l": "Otváracie hodiny:\nUT-PIA: 08:00 - 16:00",
|
||||
"photo_s": "muzeum_out.jpg",
|
||||
"photo_b": "muzeum_in.jpg",
|
||||
"email": "pbmuzeum@gmail.com",
|
||||
"phone_number": "0971294689"
|
||||
},
|
||||
"files3": [
|
||||
{
|
||||
"name": "Cenník",
|
||||
"format": ".pdf",
|
||||
"description": ""
|
||||
}, {
|
||||
"name": "Náhľad",
|
||||
"format": ".pdf",
|
||||
"description": "Nahľiadnite do expozície múzea"
|
||||
}
|
||||
]
|
||||
}
|
24
new new files/filesystem4.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ID": 4,
|
||||
"location": "49.12230758939453, 18.43195784744756",
|
||||
"description": {
|
||||
"title": "Železničná stanica",
|
||||
"description_s": "Otvorené",
|
||||
"description_l": "Otváracie hodiny:\nnonstop",
|
||||
"photo_s": "zeleznicna_stanica_out.jpg",
|
||||
"photo_b": "zeleznicna_stanica_in.jpg",
|
||||
"email": "info@slovakrail.sk",
|
||||
"phone_number": ""
|
||||
},
|
||||
"files4": [
|
||||
{
|
||||
"name": "Podrobnosti",
|
||||
"format": ".txt",
|
||||
"description": ""
|
||||
}, {
|
||||
"name": "Zľavy",
|
||||
"format": ".pdf",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import requests, json, uuid
|
||||
|
||||
|
||||
class Server:
|
||||
def __init__(self, server_ip="0.0.0.0"):
|
||||
self.device_id = None
|
||||
self.server = None
|
||||
self.client_id = uuid.uuid4().hex[24:]
|
||||
try:
|
||||
r = requests.get(f"http://{server_ip}:8000/discovery")
|
||||
if r.text.strip('"') == "Success":
|
||||
self.server = server_ip
|
||||
rr = requests.get(f"http://{server_ip}:8000/devices_list")
|
||||
self.device_id = dict(rr.json()[0])["connected_id"]
|
||||
except Exception as error:
|
||||
print(f"Program experienced a ERROR\nError: {error}")
|
||||
self.server = None
|
||||
|
||||
def get_sensors(self, server_id=None):
|
||||
if not server_id:
|
||||
cache = self.device_id
|
||||
else:
|
||||
cache = server_id
|
||||
if self.server:
|
||||
r = requests.get(f"http://{self.server}:8000/{cache}/sensors")
|
||||
return dict(r.json())
|
||||
else:
|
||||
raise Exception("Module was not inicialized/server was not found")
|
||||
|
||||
def update_sensors(self, name, value, ID=None):
|
||||
if not name and not value:
|
||||
raise Exception("Invalid values were passed")
|
||||
r = requests.post(f"http://{self.server}:8000/{ID if ID else self.device_id}/update_sensor")
|
||||
return r.text
|
||||
|
||||
def update_server(self, version, update_all=True):
|
||||
if update_all:
|
||||
r = requests.get(f"http://{self.server}:8000/admin/get/update-{version}")
|
||||
else:
|
||||
r = requests.get(f"http://{self.server}:8000/admin/get/update_one-{version}")
|
||||
return r.text
|
||||
|
||||
def get_versions(self):
|
||||
return requests.get(f"http://{self.server}:8000/admin/get/get_updates").text
|
||||
|
||||
def post_message(self, message):
|
||||
r = requests.post(f"http://{self.server}:8000/messages/post", json={"m_sender": self.client_id,
|
||||
"message": str(message)})
|
||||
return r.text
|
||||
|
||||
def get_messages(self, timestamp=""):
|
||||
r = requests.get(f"http://{self.server}:8000/messages/get", data={"timestamp": timestamp})
|
||||
return r.text
|
||||
|
||||
def upload_file(self, file_path, save_path):
|
||||
with open(file_path, "r") as cache:
|
||||
r = requests.get(f"http://{self.server}:8000/messages/get", files={"uploaded_file": cache, "patch": save_path})
|
||||
return r.text
|
BIN
server/cache/1/test.jpg
vendored
Normal file
After Width: | Height: | Size: 354 KiB |
BIN
server/files.zip
@ -1,198 +0,0 @@
|
||||
%PDF-1.3
|
||||
%âãÏÓ
|
||||
|
||||
1 0 obj
|
||||
<<
|
||||
/Type /Catalog
|
||||
/Outlines 2 0 R
|
||||
/Pages 3 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<<
|
||||
/Type /Outlines
|
||||
/Count 0
|
||||
>>
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<<
|
||||
/Type /Pages
|
||||
/Count 2
|
||||
/Kids [ 4 0 R 6 0 R ]
|
||||
>>
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<<
|
||||
/Type /Page
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
>>
|
||||
/ProcSet 8 0 R
|
||||
>>
|
||||
/MediaBox [0 0 612.0000 792.0000]
|
||||
/Contents 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Length 1074 >>
|
||||
stream
|
||||
2 J
|
||||
BT
|
||||
0 0 0 rg
|
||||
/F1 0027 Tf
|
||||
57.3750 722.2800 Td
|
||||
( A Simple PDF File ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 688.6080 Td
|
||||
( This is a small demonstration .pdf file - ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 664.7040 Td
|
||||
( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 652.7520 Td
|
||||
( text. And more text. And more text. And more text. ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 628.8480 Td
|
||||
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 616.8960 Td
|
||||
( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 604.9440 Td
|
||||
( more text. And more text. And more text. And more text. And more text. ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 592.9920 Td
|
||||
( And more text. And more text. ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 569.0880 Td
|
||||
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 557.1360 Td
|
||||
( text. And more text. And more text. Even more. Continued on page 2 ...) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<<
|
||||
/Type /Page
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
>>
|
||||
/ProcSet 8 0 R
|
||||
>>
|
||||
/MediaBox [0 0 612.0000 792.0000]
|
||||
/Contents 7 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
7 0 obj
|
||||
<< /Length 676 >>
|
||||
stream
|
||||
2 J
|
||||
BT
|
||||
0 0 0 rg
|
||||
/F1 0027 Tf
|
||||
57.3750 722.2800 Td
|
||||
( Simple PDF File 2 ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 688.6080 Td
|
||||
( ...continued from page 1. Yet more text. And more text. And more text. ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 676.6560 Td
|
||||
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 664.7040 Td
|
||||
( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 652.7520 Td
|
||||
( paint dry. And more text. And more text. And more text. And more text. ) Tj
|
||||
ET
|
||||
BT
|
||||
/F1 0010 Tf
|
||||
69.2500 640.8000 Td
|
||||
( Boring. More, a little more text. The end, and just as well. ) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
[/PDF /Text]
|
||||
endobj
|
||||
|
||||
9 0 obj
|
||||
<<
|
||||
/Type /Font
|
||||
/Subtype /Type1
|
||||
/Name /F1
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
>>
|
||||
endobj
|
||||
|
||||
10 0 obj
|
||||
<<
|
||||
/Creator (Rave \(http://www.nevrona.com/rave\))
|
||||
/Producer (Nevrona Designs)
|
||||
/CreationDate (D:20060301072826)
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0000000000 65535 f
|
||||
0000000019 00000 n
|
||||
0000000093 00000 n
|
||||
0000000147 00000 n
|
||||
0000000222 00000 n
|
||||
0000000390 00000 n
|
||||
0000001522 00000 n
|
||||
0000001690 00000 n
|
||||
0000002423 00000 n
|
||||
0000002456 00000 n
|
||||
0000002574 00000 n
|
||||
|
||||
trailer
|
||||
<<
|
||||
/Size 11
|
||||
/Root 1 0 R
|
||||
/Info 10 0 R
|
||||
>>
|
||||
|
||||
startxref
|
||||
2714
|
||||
%%EOF
|
Before Width: | Height: | Size: 76 KiB |
@ -1 +1 @@
|
||||
toto je test číslo 1 zo serveru s ID 2
|
||||
toto je test číslo 1
|
||||
|
@ -1 +0,0 @@
|
||||
toto je test n. 2 zo serveru ID2
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"ID": 0,
|
||||
"location": "49.14178021389778,18.353783098441415",
|
||||
"location": "25.997417761947318, -97.15738221291177",
|
||||
"description": {
|
||||
"title": "legionrpi",
|
||||
"description_s": "kr\u00e1tky popis, ktor\u00fd bude zobrazen\u00fd iba v n\u00e1hladovom okne",
|
||||
"description_l": "dlh\u0161\u00ed popis zariadenia, ktor\u00fd bude zobrazen\u00fd po otvoren\u00ed",
|
||||
"title": "WikiSpot-demo",
|
||||
"description_s": "Krátky popis",
|
||||
"description_l": "Dlhší popis",
|
||||
"photo_s": "test.jpg",
|
||||
"photo_b": "test.png"
|
||||
},
|
||||
@ -12,12 +12,12 @@
|
||||
{
|
||||
"name": "test",
|
||||
"format": ".jpg",
|
||||
"description": "toto je jpg test file"
|
||||
"description": "This is jpg test file"
|
||||
},
|
||||
{
|
||||
"name": "test2",
|
||||
"name": "test",
|
||||
"format": ".txt",
|
||||
"description": "toto je txt test file"
|
||||
"description": "This is txt test file"
|
||||
}
|
||||
]
|
||||
}
|
203
server/log.txt
@ -1,202 +1,3 @@
|
||||
|
||||
2021-03-21 12:33:11.947538 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-03-24 09:47:07.677185 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-03-24 10:51:12.802174 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-03-24 10:51:12.804164 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-03-24 12:20:17.717820 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-03-24 12:20:18.728113 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 17:47:36.579990 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 18:01:09.637683 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 18:06:27.367910 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:09:14.702582 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:09:44.558742 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:11:19.482976 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:21:00.445053 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: Internal Server Error
|
||||
2021-04-06 18:21:00.468768 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: Internal Server Error
|
||||
2021-04-06 18:26:26.230043 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:26:26.765624 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:26:46.326513 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:26:46.857832 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:27:17.853160 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:27:18.393648 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:28:32.760504 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:28:33.303332 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Version not found.\n"
|
||||
2021-04-06 18:28:47.795564 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 18:29:38.864951 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 18:30:21.991616 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Download succefull\nExtracting update\nupdate to 0.6 was succefull.\n"
|
||||
2021-04-06 18:30:22.828559 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "Download succefull\nExtracting update\nupdate to 0.6 was succefull.\n"
|
||||
2021-04-06 18:38:39.034010 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version {'version': '0.6', 'id': 4, 'url': 'https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json'} to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:38:39.846078 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version {'version': '0.6', 'id': 4, 'url': 'https://raw.githubusercontent.com/UntriexTv/test_directory/main/ver.json'} to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:38:43.579251 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-04-06 18:41:20.200515 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version {'0.1': {'change_list': 'this is only initial release for testing purpose', 'id': 2}, '0.5': {'change_list': 'fist working release', 'id': 3}, '0.6': {'change_list': 'normal update', 'id': 4}} to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:41:21.012333 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version {'0.1': {'change_list': 'this is only initial release for testing purpose', 'id': 2}, '0.5': {'change_list': 'fist working release', 'id': 3}, '0.6': {'change_list': 'normal update', 'id': 4}} to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:43:14.079603 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:43:14.908686 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:44:45.325212 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:44:45.334610 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:44:51.128403 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:44:51.135988 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: {"detail":"Not Found"}
|
||||
2021-04-06 18:45:13.073433 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:45:13.894493 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:46:42.900283 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:46:43.720053 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:47:20.543756 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:47:21.533385 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:48:44.524464 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:48:45.362610 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:49:28.460321 -> Warning: 192.168.1.232 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:49:29.387142 -> Warning: 192.168.1.231 failed to update. Manual update may be needed for proper working of network.
|
||||
Response from server: "SUCCESS\nUpdate from version 0.6 to 0.6 was sucesfull\n"
|
||||
2021-04-06 18:52:52.010837 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-04-06 18:53:06.029220 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-06 19:52:34.214066 -> Warning: Device Address(host='10.42.0.238', port=18381) is creating new sensor data.
|
||||
SENSOR: ['vlhkost', '40']
|
||||
2021-04-06 20:58:51.194511 -> Warning: Address(host='10.42.0.238', port=11244) created new sensor.
|
||||
SENSOR: name='Teplota' value='18'
|
||||
2021-04-06 20:58:52.311838 -> Warning: Address(host='10.42.0.238', port=8118) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='52'
|
||||
2021-04-06 21:00:22.844916 -> Warning: Address(host='10.42.0.238', port=9199) created new sensor.
|
||||
SENSOR: name='Teplota' value='27'
|
||||
2021-04-06 21:00:23.915833 -> Warning: Address(host='10.42.0.238', port=15482) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='95'
|
||||
2021-04-06 21:01:04.874694 -> Warning: Address(host='10.42.0.238', port=4606) created new sensor.
|
||||
SENSOR: name='Teplota' value='24'
|
||||
2021-04-06 21:01:06.020948 -> Warning: Address(host='10.42.0.238', port=16111) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='95'
|
||||
2021-04-06 21:02:56.676046 -> Warning: Address(host='10.42.0.238', port=1280) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-06 21:02:57.773619 -> Warning: Address(host='10.42.0.238', port=12034) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='91'
|
||||
2021-04-07 14:07:15.258217 -> Warning: Address(host='10.42.0.238', port=32353) created new sensor.
|
||||
SENSOR: name='Teplota' value='19'
|
||||
2021-04-07 14:07:16.454490 -> Warning: Address(host='10.42.0.238', port=19858) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 14:17:42.961164 -> Warning: Address(host='10.42.0.238', port=4696) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 14:17:44.114338 -> Warning: Address(host='10.42.0.238', port=4387) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='42'
|
||||
2021-04-07 14:18:25.886229 -> Warning: 192.168.1.232 disconnected/is not available
|
||||
2021-04-07 14:22:13.260725 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-07 14:22:42.995956 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-07 17:06:13.637610 -> ERROR: Sensor data download from 25 failed.
|
||||
ERROR: 25 is not in list
|
||||
2021-04-07 17:16:09.500542 -> Warning: test on server 192.168.1.231 is changed.
|
||||
2021-04-07 17:24:05.379288 -> Warning: Address(host='10.42.0.238', port=25175) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 17:24:06.475344 -> Warning: Address(host='10.42.0.238', port=5919) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 17:34:29.681729 -> Warning: Address(host='10.42.0.238', port=8767) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 17:34:30.857047 -> Warning: Address(host='10.42.0.238', port=19458) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 17:35:06.210117 -> Warning: Address(host='10.42.0.238', port=15677) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 17:35:07.332588 -> Warning: Address(host='10.42.0.238', port=27433) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 17:36:02.490752 -> Warning: Address(host='10.42.0.238', port=29010) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 17:36:03.561727 -> Warning: Address(host='10.42.0.238', port=26279) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 17:39:30.650731 -> Warning: Address(host='10.42.0.238', port=26716) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 17:39:31.746802 -> Warning: Address(host='10.42.0.238', port=11238) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 19:03:34.951363 -> Warning: Address(host='10.42.0.238', port=19388) created new sensor.
|
||||
SENSOR: name='Teplota' value='20'
|
||||
2021-04-07 19:03:36.076556 -> Warning: Address(host='10.42.0.238', port=24582) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-07 20:03:53.809025 -> Warning: Address(host='10.42.0.238', port=30182) created new sensor.
|
||||
SENSOR: name='Vlhkost' value='46'
|
||||
2021-04-14 12:55:05.505789 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-14 13:04:30.181791 -> Warning: Address(host='192.168.1.99', port=54888) created new sensor.
|
||||
SENSOR: name='sensor1' value='test'
|
||||
2021-04-14 13:04:36.780037 -> Warning: Address(host='192.168.1.99', port=54904) created new sensor.
|
||||
SENSOR: name='sensor2' value='1234'
|
||||
2021-04-14 13:06:59.405575 -> Warning: Address(host='192.168.1.99', port=54974) created new sensor.
|
||||
SENSOR: name='sensor2' value='1234'
|
||||
2021-04-14 14:09:58.696666 -> Warning: Address(host='192.168.1.99', port=58182) created new sensor.
|
||||
SENSOR: name='sensor1' value='test'
|
||||
2021-04-14 14:10:06.190377 -> Warning: Address(host='192.168.1.99', port=58192) created new sensor.
|
||||
SENSOR: name='sensor2' value='123456789'
|
||||
2021-04-22 10:15:53.540044 -> Warning: Address(host='192.168.1.99', port=43642) created new sensor.
|
||||
SENSOR: name='test1' value='juhuu'
|
||||
2021-04-22 10:16:02.865022 -> Warning: Address(host='192.168.1.99', port=43644) created new sensor.
|
||||
SENSOR: name='test2' value='eeeh'
|
||||
2021-04-23 11:22:54.684617 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-04-23 11:36:58.295015 -> Warning: 192.168.1.231 disconnected/is not available
|
||||
2021-04-23 18:13:09.497747 -> Warning: Address(host='192.168.1.28', port=45062) created new sensor.
|
||||
SENSOR: name='teplota' value='26°C'
|
||||
2021-04-23 20:25:12.224311 -> ERROR: Address(host='192.168.1.28', port=48898) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-23 20:25:14.287622 -> ERROR: Address(host='192.168.1.28', port=48898) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 11:54:17.948411 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-24 11:54:21.952522 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-24 18:38:26.095820 -> ERROR: Address(host='192.168.1.7', port=32928) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:38:28.128341 -> ERROR: Address(host='192.168.1.7', port=33038) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:41:06.944584 -> ERROR: Address(host='192.168.1.7', port=33612) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:41:08.942270 -> ERROR: Address(host='192.168.1.7', port=33612) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:41:08.961718 -> ERROR: Address(host='192.168.1.7', port=33612) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:41:11.001168 -> ERROR: Address(host='192.168.1.7', port=33996) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:46:18.062541 -> ERROR: Address(host='192.168.1.7', port=34856) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-24 18:46:20.103101 -> ERROR: Address(host='192.168.1.7', port=35128) tried to access file (_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_) on id 1 that does not exist.
|
||||
2021-04-26 14:51:30.981645 -> Warning: Address(host='192.168.1.99', port=41106) created new sensor.
|
||||
SENSOR: name='string' value='string'
|
||||
2021-04-27 11:03:50.711031 -> Warning: Address(host='192.168.1.99', port=38418) created new sensor.
|
||||
SENSOR: name='string' value='string'
|
||||
2021-04-27 11:04:00.123540 -> Warning: Address(host='192.168.1.99', port=38426) created new sensor.
|
||||
SENSOR: name='test' value='012'
|
||||
2021-04-27 11:04:13.492698 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-27 11:04:56.073021 -> ERROR: Sensor data download from 1 failed.
|
||||
ERROR: 1 is not in list
|
||||
2021-04-27 19:13:46.323037 -> Warning: Address(host='192.168.1.99', port=44312) created new sensor.
|
||||
SENSOR: name='string' value='string'
|
||||
2021-04-27 19:13:53.203502 -> Warning: Address(host='192.168.1.99', port=44322) created new sensor.
|
||||
SENSOR: name='test' value='0'
|
||||
2021-05-02 20:06:54.398494 -> Warning: Address(host='192.168.1.99', port=52808) created new sensor.
|
||||
SENSOR: name='test' value='0'
|
||||
2021-05-02 20:38:09.342482 -> Warning: Address(host='192.168.1.99', port=53404) created new sensor.
|
||||
SENSOR: name='[translate]-tempeature' value='16'
|
||||
2021-05-02 20:38:31.096100 -> Warning: Address(host='192.168.1.99', port=53422) created new sensor.
|
||||
SENSOR: name='tempeature' value='16'
|
||||
2021-05-04 16:11:47.026867 -> 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
|
@ -7,6 +7,9 @@ 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
|
||||
@ -24,8 +27,6 @@ devs = {
|
||||
"Samuel Šubika": {
|
||||
"git": "https://github.com/JustSteel", "mail": "SteelSamko2000@gmail.com"}
|
||||
}
|
||||
|
||||
|
||||
check = engine.Scan()
|
||||
check.check_to_go()
|
||||
if check.state_list["error"]:
|
||||
@ -39,11 +40,26 @@ with open("settings.json", "r", encoding='utf-8') 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"]
|
||||
time_to_save = settings["time_to_save"]
|
||||
|
||||
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 = ["*", ]
|
||||
@ -68,7 +84,7 @@ heartbeat_table = settings["heartbeat_table"]
|
||||
sensors = {}
|
||||
|
||||
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)
|
||||
@ -118,17 +134,19 @@ def heartbeat(s_table: ServerTable, request: Request):
|
||||
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}
|
||||
|
||||
@ -136,13 +154,13 @@ def heartbeat(s_table: ServerTable, 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}")
|
||||
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}")
|
||||
@ -157,9 +175,10 @@ def get_file(IDx: int, file: str, request: Request):
|
||||
if os.path.isfile(f"files/{file}"):
|
||||
return FileResponse(f"files/{file}")
|
||||
else:
|
||||
return f"File {file} does not exist."
|
||||
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.error(f"{request.client} tried to access id ({IDx}) that does not exist.")
|
||||
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}"):
|
||||
@ -174,17 +193,18 @@ def get_file(IDx: int, file: str, request: Request):
|
||||
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}")
|
||||
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.")
|
||||
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}")
|
||||
if ".txt" in file:
|
||||
with open(f"cache/{IDx}/{file}", "wb") as save:
|
||||
save.write(bytes(r.content))
|
||||
else:
|
||||
with open(f"cache/{IDx}/{file}", "wb") as save:
|
||||
save.write(bytes(r.content))
|
||||
return FileResponse(f"cache/{IDx}/{file}")
|
||||
@ -195,6 +215,10 @@ 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:
|
||||
@ -228,20 +252,20 @@ def get_devices_list():
|
||||
|
||||
|
||||
@app.get("/admin/get/{command}")
|
||||
def admin_get(command: str):
|
||||
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]
|
||||
return "success"
|
||||
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.
|
||||
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}""")
|
||||
@ -249,9 +273,8 @@ def admin_get(command: str):
|
||||
state.append({IP: "updated"})
|
||||
return state
|
||||
if "update_one-" in command:
|
||||
return "success"
|
||||
state = subprocess.check_output(["python3", "system.py", "update", "-version", f"""{command.split("-")[1]}"""])
|
||||
log.warning(state.decode("utf-8"))
|
||||
log.message(state.decode("utf-8"))
|
||||
return state.decode("utf-8")
|
||||
if command == "heartbeat_table":
|
||||
return heartbeat_table
|
||||
@ -262,7 +285,6 @@ def admin_get(command: str):
|
||||
@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}"
|
||||
print(f"file location: {file_location}")
|
||||
if id_server == ID:
|
||||
with open(file_location, "wb+") as file_object:
|
||||
file_object.write(uploaded_file.file.read())
|
||||
@ -316,7 +338,6 @@ def send_heartbeat(ip, id):
|
||||
global heartbeat_table
|
||||
log.message(f"""sending heartbeat to {ip}({"offline" if id in offline else "online"})""")
|
||||
cache_request = requests.post(f"http://{ip}:8000/heartbeat", data=json.dumps(heartbeat_table))
|
||||
print(cache_request.text)
|
||||
heartbeat_table = dict(cache_request.json()[0])
|
||||
log.debug(json.dumps(cache_request.json(), indent=4))
|
||||
|
||||
@ -326,7 +347,7 @@ def mainloop():
|
||||
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:
|
||||
@ -350,7 +371,7 @@ def mainloop():
|
||||
try:
|
||||
log.debug(
|
||||
f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
|
||||
heartbeat_table["last_heartbeat"][device_number] -= 1
|
||||
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"]:
|
||||
@ -363,12 +384,10 @@ def mainloop():
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
print(f"""Starting WikiSpot V{update.get_version()["version"]}""")
|
||||
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 settings for easy adding/editing files/id/text
|
||||
|
BIN
server/plugins/computer_vision/MobileNetSSD_deploy.caffemodel
Normal file
1912
server/plugins/computer_vision/MobileNetSSD_deploy.prototxt
Normal file
46
server/plugins/computer_vision/com_vision.py
Normal 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)
|
@ -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
|
@ -1,26 +1,25 @@
|
||||
{
|
||||
"ID": 0,
|
||||
"IP": "192.168.1.99",
|
||||
"location": "49.14178021389778,18.353783098441415",
|
||||
"time_to_heartbeat": 20,
|
||||
"time_to_heartbeat_offline": 25,
|
||||
"save_table": false,
|
||||
"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": false,
|
||||
"print_error": true,
|
||||
"save_warning": true,
|
||||
"print_warning": false,
|
||||
"print_warning": true,
|
||||
"save_message": false,
|
||||
"print_message": false,
|
||||
"print_message": true,
|
||||
"enable_debug": false
|
||||
},
|
||||
"heartbeat_table": {
|
||||
"ID": [1],
|
||||
"IP": ["10.61.42.92"],
|
||||
"location": [""],
|
||||
"file_system": [""],
|
||||
"last_heartbeat": [5]
|
||||
"ID": [],
|
||||
"IP": [],
|
||||
"location": [],
|
||||
"file_system": [],
|
||||
"last_heartbeat": []
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#! /usr/bin/python3
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
@ -1,8 +0,0 @@
|
||||
meno = input("zadajte meno: ")
|
||||
priezvisko = input("zadajte priezvisko: ")
|
||||
|
||||
print(f"Ahoj {meno} {priezvisko} vitaj v programe")
|
||||
print("-"*24)
|
||||
print("Ahoj " + meno + " " + priezvisko + " vitaj v programe")
|
||||
print("-"*24)
|
||||
print("Ahoj {} {} vitaj v programe".format(meno, priezvisko))
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"ID": 0,
|
||||
"location": "49.14178021389778,18.353783098441415",
|
||||
"description": {
|
||||
"title": "legionrpi",
|
||||
"description_s": "kr\u00e1tky popis, ktor\u00fd bude zobrazen\u00fd iba v n\u00e1hladovom okne",
|
||||
"description_l": "dlh\u0161\u00ed popis zariadenia, ktor\u00fd bude zobrazen\u00fd po otvoren\u00ed",
|
||||
"photo_s": "test.jpg",
|
||||
"photo_b": "test.png"
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"name": "test",
|
||||
"format": ".jpg",
|
||||
"description": "toto je jpg test file"
|
||||
},
|
||||
{
|
||||
"name": "test2",
|
||||
"format": ".txt",
|
||||
"description": "toto je txt test file"
|
||||
},
|
||||
{
|
||||
"name": "Wikispot",
|
||||
"format": "docx",
|
||||
"description": "Test"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
import socket
|
||||
import multiprocessing
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def pinger(job_q, results_q):
|
||||
"""
|
||||
Do Ping
|
||||
:param job_q:
|
||||
:param results_q:
|
||||
:return:
|
||||
"""
|
||||
DEVNULL = open(os.devnull, 'w')
|
||||
while True:
|
||||
|
||||
ip = job_q.get()
|
||||
|
||||
if ip is None:
|
||||
break
|
||||
|
||||
results_q.put(ip)
|
||||
|
||||
|
||||
def get_my_ip():
|
||||
"""
|
||||
Find my IP address
|
||||
:return:
|
||||
"""
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(("8.8.8.8", 80))
|
||||
ip = s.getsockname()[0]
|
||||
s.close()
|
||||
return ip
|
||||
|
||||
|
||||
def map_network(pool_size=255):
|
||||
"""
|
||||
Maps the network
|
||||
:param pool_size: amount of parallel ping processes
|
||||
:return: list of valid ip addresses
|
||||
"""
|
||||
|
||||
ip_list = list()
|
||||
my_ip = get_my_ip()
|
||||
|
||||
# get my IP and compose a base like 192.168.1.xxx
|
||||
ip_parts = get_my_ip().split('.')
|
||||
base_ip = ip_parts[0] + '.' + ip_parts[1] + '.' + ip_parts[2] + '.'
|
||||
|
||||
# prepare the jobs queue
|
||||
jobs = multiprocessing.Queue()
|
||||
results = multiprocessing.Queue()
|
||||
|
||||
pool = [multiprocessing.Process(target=pinger, args=(jobs, results)) for i in range(pool_size)]
|
||||
|
||||
for p in pool:
|
||||
p.start()
|
||||
|
||||
# cue hte ping processes
|
||||
for i in range(1, 255):
|
||||
jobs.put(base_ip + '{0}'.format(i))
|
||||
|
||||
for p in pool:
|
||||
jobs.put(None)
|
||||
|
||||
for p in pool:
|
||||
p.join()
|
||||
|
||||
# collect he results
|
||||
while not results.empty():
|
||||
ip = results.get()
|
||||
if ip != my_ip:
|
||||
ip_list.append(ip)
|
||||
|
||||
return ip_list
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
print('Mapping...')
|
||||
lst = map_network()
|
||||
print(lst)
|
@ -1,331 +0,0 @@
|
||||
import tkinter
|
||||
from tkinter.filedialog import askopenfilename
|
||||
import requests
|
||||
import json
|
||||
import tkinter.messagebox
|
||||
import os
|
||||
|
||||
window = tkinter.Tk()
|
||||
window.title("WikiSpot Editor")
|
||||
sellected = None
|
||||
sellected_index = None
|
||||
filename = None
|
||||
textn1 = None
|
||||
textn2 = None
|
||||
textn3 = None
|
||||
ip = "127.0.0.1"
|
||||
data = None
|
||||
rpi_active = []
|
||||
|
||||
|
||||
# commands
|
||||
|
||||
def save_changes():
|
||||
data[sellected_index]["description"]["title"] = text1.get()
|
||||
data[sellected_index]["location"] = text2.get()
|
||||
data[sellected_index]["description"]["description_s"]
|
||||
data[sellected_index]["description"]["description_l"]
|
||||
|
||||
|
||||
def update_server_refresh(text_window, description):
|
||||
text_window.configure(state="normal")
|
||||
text_window.delete('1.0', "end")
|
||||
text_window.insert("end", description)
|
||||
text_window.configure(state="disable")
|
||||
|
||||
|
||||
def update_server_func(version, servers_all=True):
|
||||
if servers_all:
|
||||
if tkinter.messagebox.askyesno(title="Warning", message=f"WikiSpot Network will update to\n V{version}"):
|
||||
r = requests.get(f"http://{ip}:8000/admin/get/update-{version}")
|
||||
tkinter.messagebox.showinfo(title="Done", message=r.text)
|
||||
|
||||
else:
|
||||
if tkinter.messagebox.askyesno(title="Warning", message=f"WikiSpot Server will update to\n V{version}"):
|
||||
r = requests.get(f"http://{ip}:8000/admin/get/update-one-{version}")
|
||||
tkinter.messagebox.showinfo(title="Done", message=r.text)
|
||||
|
||||
|
||||
def update_server():
|
||||
r = requests.get(f"http://{ip}:8000/admin/get/get_updates")
|
||||
versions = json.loads(r.text)
|
||||
versions_server = list(versions[1].keys())
|
||||
window_update_server = tkinter.Toplevel()
|
||||
window_update_server.title("server update")
|
||||
variable = tkinter.StringVar(window_update_server)
|
||||
variable.set(versions_server[-1]) # default value
|
||||
version_menu = tkinter.OptionMenu(window_update_server, variable, *versions_server)
|
||||
label1 = tkinter.Label(window_update_server, text="WikiSpot verison: ")
|
||||
label2 = tkinter.Label(window_update_server, text=versions[0]["version"])
|
||||
label3 = tkinter.Label(window_update_server, text="Versions")
|
||||
label4 = tkinter.Label(window_update_server, text="Release news")
|
||||
b1 = tkinter.Button(window_update_server, text="Update all", command=lambda: update_server_func(variable.get()))
|
||||
b2 = tkinter.Button(window_update_server, text="Update one", command=lambda: update_server_func(variable.get(), servers_all=False))
|
||||
b3 = tkinter.Button(window_update_server, text="Exit", command=lambda: window_update_server.destroy())
|
||||
text = tkinter.Text(window_update_server, width=50, height=10)
|
||||
text.insert("end", versions[1][variable.get()]["change_list"])
|
||||
variable.trace("w", lambda *args: update_server_refresh(text, versions[1][variable.get()]["change_list"]))
|
||||
label1.grid(row=0, column=0)
|
||||
label2.grid(row=0, column=1)
|
||||
label3.grid(row=1, column=0)
|
||||
label4.grid(row=2, column=0)
|
||||
version_menu.grid(row=1, column=1)
|
||||
text.grid(row=2, column=1)
|
||||
b1.grid(row=3, column=0)
|
||||
b2.grid(row=3, column=1)
|
||||
b3.grid(row=3, column=2)
|
||||
window_update_server.mainloop()
|
||||
|
||||
|
||||
|
||||
|
||||
def upload_new_file(name, window, file_format, description, *patch: str):
|
||||
global data
|
||||
if " " in name:
|
||||
tkinter.messagebox.showerror(title="Error", message="File name needs to be without spaces.\nApp on mobile will "
|
||||
"change `_` to space.")
|
||||
else:
|
||||
data[sellected_index]["files"].append({
|
||||
"name": name,
|
||||
"format": file_format,
|
||||
"description": description.get("1.0", "end").replace("\n", "")
|
||||
})
|
||||
print("saving")
|
||||
with open("./test.json", "w", encoding='utf-8') as fp:
|
||||
json.dump(dict(data[sellected_index]), fp, indent=2)
|
||||
with open("test.json", "rb") as fp:
|
||||
requests.post(f"http://{ip}:8000/admin/{sellected}/upload_file", files={"uploaded_file": fp})
|
||||
os.remove("test.json")
|
||||
if patch:
|
||||
with open(patch[0], "rb") as fp:
|
||||
requests.post(f"http://{ip}:8000/admin/{sellected}/upload_file", files={"uploaded_file": fp, "patch": "files/"}, params={"patch": "files/"})
|
||||
window.destroy()
|
||||
|
||||
|
||||
def new_file(*itnpu):
|
||||
global filename, sellected
|
||||
window_new = tkinter.Toplevel()
|
||||
window_new.title("New File")
|
||||
if sellected not in rpi_active:
|
||||
tkinter.messagebox.showerror(title="Error", message="Server is not selected!")
|
||||
window_new.destroy()
|
||||
else:
|
||||
filename = askopenfilename()
|
||||
while not filename:
|
||||
if not tkinter.messagebox.askretrycancel(title="Warning", message="File not selected."):
|
||||
window_new.destroy()
|
||||
break
|
||||
filename = askopenfilename()
|
||||
if filename:
|
||||
label1 = tkinter.Label(window_new, text="FileName")
|
||||
label2 = tkinter.Label(window_new, text="FileExtension")
|
||||
label3 = tkinter.Label(window_new, text="Description")
|
||||
label4 = tkinter.Label(window_new, text=str(filename.split("/")[-1].split(".")[0]))
|
||||
label5 = tkinter.Label(window_new, text=str(filename.split("/")[-1].split(".")[1]))
|
||||
in3 = tkinter.Text(window_new, height=8, width=40)
|
||||
b1 = tkinter.Button(window_new, text="UPLOAD", command=lambda: upload_new_file(
|
||||
str(filename.split("/")[-1].split(".")[0]), window_new,
|
||||
str(filename.split("/")[-1].split(".")[1]), in3, filename), width=40, height=2)
|
||||
b2 = tkinter.Button(window_new, text="EXIT", command=window_new.destroy, height=2)
|
||||
label1.grid(row=0, column=0)
|
||||
label2.grid(row=1, column=0)
|
||||
label3.grid(row=2, column=0)
|
||||
label4.grid(row=0, column=1)
|
||||
label5.grid(row=1, column=1)
|
||||
in3.grid(row=2, column=1)
|
||||
b1.grid(row=3, column=1)
|
||||
b2.grid(row=3, column=0)
|
||||
window_new.mainloop()
|
||||
|
||||
|
||||
def edit_file(file_name):
|
||||
window_edit = tkinter.Toplevel()
|
||||
window_edit.title("edit_file")
|
||||
try:
|
||||
for file in data[sellected_index]["files"]:
|
||||
if file["name"] == file_name:
|
||||
sellected_file_index = data[sellected_index]["files"].index(file)
|
||||
break
|
||||
else:
|
||||
sellected_file_index = None
|
||||
label1 = tkinter.Label(window_edit, text="Name\n(you can change name and\nformat only by uploading\nnew file)")
|
||||
label2 = tkinter.Label(window_edit, text="Format")
|
||||
label3 = tkinter.Label(window_edit, text="Description")
|
||||
label4 = tkinter.Label(window_edit, text=data[sellected_index]["files"][sellected_file_index]["name"])
|
||||
label5 = tkinter.Label(window_edit, text=data[sellected_index]["files"][sellected_file_index]["format"])
|
||||
text = tkinter.Text(window_edit, height=8, width=40)
|
||||
text.insert("end", data[sellected_index]["files"][sellected_file_index]["description"])
|
||||
button1 = tkinter.Button(window_edit, text="Exit", command=lambda: window_edit.destroy())
|
||||
button2 = tkinter.Button(window_edit, text="Save", command=lambda: upload_new_file(
|
||||
data[sellected_index]["files"][sellected_file_index]["name"], window_edit,
|
||||
data[sellected_index]["files"][sellected_file_index]["format"], text))
|
||||
button3 = tkinter.Button(window_edit, text="Remove", command=lambda: upload_new_file(
|
||||
data[sellected_index]["files"][sellected_file_index]["name"], window_edit, "_REMOVE_", text))
|
||||
label1.grid(row=0, column=0)
|
||||
label2.grid(row=1, column=0)
|
||||
label3.grid(row=2, column=0)
|
||||
label4.grid(row=0, column=1)
|
||||
label5.grid(row=1, column=1)
|
||||
text.grid(row=2, column=1)
|
||||
button1.grid(row=3, column=0)
|
||||
button2.grid(row=3, column=1)
|
||||
button3.grid(row=3, column=2)
|
||||
window_edit.mainloop()
|
||||
except TypeError:
|
||||
tkinter.messagebox.showerror(title="Error", message="No file sellected!\n"
|
||||
"Select server and then file you want to edit.")
|
||||
window_edit.destroy()
|
||||
|
||||
|
||||
|
||||
def update_inputs(self):
|
||||
global sellected, sellected_index, data
|
||||
try:
|
||||
if int(list_rpi.selection_get()) in rpi_active:
|
||||
sellected = int(list_rpi.selection_get())
|
||||
for rpi in data:
|
||||
if rpi["ID"] == sellected:
|
||||
sellected_index = data.index(rpi)
|
||||
text1.set(data[sellected_index]["ID"])
|
||||
text2.set(data[sellected_index]["location"])
|
||||
list2.clipboard_clear()
|
||||
list2.delete(0, "end")
|
||||
for file in data[sellected_index]["files"]:
|
||||
list2.insert("end", file["name"])
|
||||
except ValueError or tkinter.TclError:
|
||||
print(f"Exception: list_rpi sellection = {list_rpi.selection_get()}")
|
||||
|
||||
|
||||
def update_listbox():
|
||||
global data, rpi_active
|
||||
r = requests.get(f"http://{ip}:8000/devices_list")
|
||||
data = json.loads(r.text)
|
||||
del data[0]
|
||||
print(data)
|
||||
list_rpi.delete(0, "end")
|
||||
rpi_active.clear()
|
||||
for rpi in data:
|
||||
list_rpi.insert("end", rpi["ID"])
|
||||
rpi_active.append(rpi["ID"])
|
||||
# for rpi in zoznam:
|
||||
# list_rpi.insert("end", rpi)
|
||||
|
||||
|
||||
def clear_listbox():
|
||||
list_rpi.delete(0, "end")
|
||||
|
||||
|
||||
def cmd1():
|
||||
print(list_rpi.selection_get())
|
||||
|
||||
|
||||
# menu
|
||||
menu = tkinter.Menu(window)
|
||||
menu.master.config(menu=menu)
|
||||
|
||||
# file
|
||||
menu_submenu1 = tkinter.Menu(menu, tearoff=0)
|
||||
menu.add_cascade(label="File", menu=menu_submenu1)
|
||||
menu_submenu1.add_command(label="refresh", command=update_listbox)
|
||||
menu_submenu1.add_separator()
|
||||
menu_submenu1.add_command(label="exit", command=exit)
|
||||
|
||||
# about
|
||||
menu_submenu2 = tkinter.Menu(menu, tearoff=0)
|
||||
menu.add_cascade(label="About", menu=menu_submenu2)
|
||||
menu_submenu2.add_command(label="Check server updates", command=update_server)
|
||||
menu_submenu2.add_command(label="Check app updates", command=update_listbox)
|
||||
menu_submenu2.add_separator()
|
||||
menu_submenu2.add_command(label="About WikiSpot", command=exit)
|
||||
menu_submenu2.add_command(label="About Editor", command=exit)
|
||||
|
||||
|
||||
# labels
|
||||
|
||||
l1 = tkinter.Label(window, text='label1')
|
||||
l1.grid(row=0, column=0)
|
||||
|
||||
l2 = tkinter.Label(window, text='label2')
|
||||
l2.grid(row=0, column=2)
|
||||
|
||||
l3 = tkinter.Label(window, text='label3')
|
||||
l3.grid(row=1, column=0)
|
||||
|
||||
l4 = tkinter.Label(window, text='label4')
|
||||
l4.grid(row=1, column=2)
|
||||
|
||||
l5 = tkinter.Label(window, text='Servers:')
|
||||
l5.grid(row=2, column=0)
|
||||
|
||||
l6 = tkinter.Label(window, text='Files: ')
|
||||
l6.grid(row=2, column=5)
|
||||
|
||||
# entries
|
||||
|
||||
text1 = tkinter.StringVar()
|
||||
en1 = tkinter.Entry(window, textvariable=text1)
|
||||
en1.grid(row=0, column=1)
|
||||
|
||||
text2 = tkinter.StringVar()
|
||||
en2 = tkinter.Entry(window, textvariable=text2)
|
||||
en2.grid(row=0, column=3)
|
||||
|
||||
text3 = tkinter.StringVar()
|
||||
en3 = tkinter.Entry(window, textvariable=text3)
|
||||
en3.grid(row=1, column=1)
|
||||
|
||||
text4 = tkinter.StringVar()
|
||||
en4 = tkinter.Entry(window, textvariable=text4)
|
||||
en4.grid(row=1, column=3)
|
||||
|
||||
# listbox
|
||||
|
||||
list_rpi = tkinter.Listbox(window, height=6, width=35)
|
||||
list_rpi.grid(row=3, column=0, rowspan=6, columnspan=2)
|
||||
list_rpi.bind("<<ListboxSelect>>", update_inputs)
|
||||
|
||||
list2 = tkinter.Listbox(window, height=6, width=35)
|
||||
list2.grid(row=3, column=5, rowspan=6, columnspan=2)
|
||||
# list_rpi.bind("<<ListboxSelect>>", update_inputs)
|
||||
|
||||
# scrollbar
|
||||
|
||||
sb1 = tkinter.Scrollbar(window)
|
||||
sb1.grid(row=2, column=2, rowspan=6)
|
||||
|
||||
list_rpi.configure(yscrollcommand=sb1.set)
|
||||
sb1.configure(command=list_rpi.yview)
|
||||
|
||||
sb2 = tkinter.Scrollbar(window)
|
||||
sb2.grid(row=2, column=7, rowspan=6)
|
||||
|
||||
list2.configure(yscrollcommand=sb2.set)
|
||||
sb2.configure(command=list2.yview)
|
||||
|
||||
# buttons
|
||||
|
||||
btn1 = tkinter.Button(window, text="exit", width=12, command=update_listbox)
|
||||
btn1.grid(row=6, column=3)
|
||||
|
||||
btn2 = tkinter.Button(window, text="add server", width=12, command=clear_listbox)
|
||||
btn2.grid(row=3, column=3)
|
||||
|
||||
btn3 = tkinter.Button(window, text="place", width=12, command=new_file)
|
||||
btn3.grid(row=4, column=3)
|
||||
|
||||
btn4 = tkinter.Button(window, text="place", width=12, command=lambda: edit_file(list2.selection_get()))
|
||||
btn4.grid(row=5, column=3)
|
||||
|
||||
btn5 = tkinter.Button(window, text="save", width=12, command=update_listbox)
|
||||
btn5.grid(row=6, column=4)
|
||||
|
||||
btn5 = tkinter.Button(window, text="new file", width=12, command=new_file)
|
||||
btn5.grid(row=3, column=4)
|
||||
|
||||
btn5 = tkinter.Button(window, text="edit file", width=12, command=new_file)
|
||||
btn5.grid(row=4, column=4)
|
||||
|
||||
btn5 = tkinter.Button(window, text="place", width=12, command=lambda: window.destroy())
|
||||
btn5.grid(row=5, column=4)
|
||||
update_listbox()
|
||||
window.mainloop()
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "0.9",
|
||||
"id": 6
|
||||
"version": "1.0",
|
||||
"id": 7
|
||||
}
|
||||
|