NEW server app as API module

This commit is contained in:
Artem30801
2019-03-23 21:58:45 +03:00
parent 67f83797c5
commit da7d972e10
3 changed files with 223 additions and 522 deletions

View File

@@ -1,63 +1,151 @@
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import ttkwidgets
import os
import sys
import glob
import math
import time
import json
import struct
import socket
import random
import threading
import collections
import configparser
# All imports sorted in pyramid
random.seed()
def get_ip_address():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
BUFFER_SIZE = 1024
def auto_connect():
while True:
ServerSocket.listen(1)
c, addr = ServerSocket.accept()
print("Got connection from:", str(addr))
if not any(client_addr == addr[0] for client_addr in Client.clients.keys()):
client = Client(addr[0])
print("New client")
class ConfigOption:
def __init__(self, section, option, value):
self.section = section
self.option = option
self.value = value
class Server:
def __init__(self, server_id=None, config_path="server_config.ini"):
self.id = server_id if server_id else str(random.randint(0, 9999)).zfill(4)
# Init socket
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host = socket.gethostname()
self.ip = Server.get_ip_address()
# Init configs
self.config_path = config_path
self.config = configparser.ConfigParser()
self.config.read(self.config_path)
self.load_config()
# Init threads
self.autoconnect_thread = threading.Thread(target=self._auto_connect, daemon=True,
name='Client auto-connect thread')
self.autoconnect_thread_running = threading.Event() # Can be used for manual thread killing
self.broadcast_thread = threading.Thread(target=self._ip_broadcast, daemon=True,
name='IP message broadcast sender thread')
self.broadcast_thread_running = threading.Event()
self.listener_thread = threading.Thread(target=self._broadcast_listen, daemon=True,
name='IP message broadcast listener thread')
self.listener_thread_running = threading.Event()
def load_config(self):
self.port = int(self.config['SERVER']['port'])
self.broadcast_port = int(self.config['SERVER']['broadcast_port'])
self.BUFFER_SIZE = int(self.config['SERVER']['buffer_size'])
self.USE_NTP = self.config.getboolean('NTP', 'use_ntp')
self.NTP_HOST = self.config['NTP']['host']
self.NTP_PORT = int(self.config['NTP']['port'])
def start(self): # do_auto_connect=True, do_ip_broadcast=True, do_listen_broadcast=False
print("Starting server!")
self.server_socket.bind((self.ip, self.port))
self.autoconnect_thread_running.set()
self.autoconnect_thread.start()
self.broadcast_thread_running.set()
self.broadcast_thread.start()
self.listener_thread_running.set()
# listener_thread.start()
def stop(self):
self.autoconnect_thread_running.clear()
self.broadcast_thread_running.clear()
self.listener_thread_running.clear()
self.server_socket.close()
@staticmethod
def get_ip_address():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as ip_socket:
ip_socket.connect(("8.8.8.8", 80))
return ip_socket.getsockname()[0]
@staticmethod
def get_ntp_time(ntp_host, ntp_port):
NTP_DELTA = 2208988800 # 1970-01-01 00:00:00
NTP_QUERY = b'\x1b' + bytes(47)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as ntp_socket:
ntp_socket.sendto(NTP_QUERY, (ntp_host, ntp_port))
msg, _ = ntp_socket.recvfrom(1024)
return int.from_bytes(msg[-8:], 'big') / 2 ** 32 - NTP_DELTA
def _auto_connect(self):
while self.autoconnect_thread_running.is_set():
self.server_socket.listen(1)
c, addr = self.server_socket.accept()
print("Got connection from:", str(addr))
if not any(client_addr == addr[0] for client_addr in Client.clients.keys()):
client = Client(addr[0])
print("New client")
else:
print("Reconnected client")
Client.clients[addr[0]].connect(c, addr)
def _ip_broadcast(self):
msg = bytes(Client.form_message(
"server_ip", {"host": self.ip, "port": str(self.port), "id": self.id}
), "UTF-8")
broadcast_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
while self.broadcast_thread_running.is_set():
time.sleep(10)
broadcast_sock.sendto(msg, ('255.255.255.255', self.broadcast_port))
print("Broadcast sent")
broadcast_sock.close()
def _broadcast_listen(self):
broadcast_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcast_client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
try:
broadcast_client.bind(("", self.broadcast_port))
except OSError:
print("Another server is running on this computer, shutting down!")
sys.exit()
while self.listener_thread_running.is_set():
data, addr = broadcast_client.recvfrom(1024)
command, args = Client.parse_message(data.decode("UTF-8"))
if command == "server_ip":
if args["id"] != self.id:
print("Another server detected on network, shutting down")
sys.exit()
def send_starttime(self, dt=0):
if self.USE_NTP:
timenow = Server.get_ntp_time(self.NTP_HOST, self.NTP_PORT)
else:
print("Reconnected client")
Client.clients[addr[0]].connect(c, addr)
def ip_broadcast(ip, port):
ip = ip
broadcast_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
while True:
msg = bytes(Client.form_command("server_ip ", ip, ), "UTF-8")
broadcast_sock.sendto(msg, ('255.255.255.255', 8181)) #TODO to config
print("Broadcast sent")
time.sleep(5)
NTP_DELTA = 2208988800 # 1970-01-01 00:00:00
NTP_QUERY = b'\x1b' + bytes(47)
def get_ntp_time(ntp_host, ntp_port):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.sendto(NTP_QUERY, (ntp_host, ntp_port))
msg, _ = s.recvfrom(1024)
return int.from_bytes(msg[-8:], 'big') / 2 ** 32 - NTP_DELTA
timenow = time.time()
print('Now:', time.ctime(timenow), "+ dt =", dt)
Client.send_to_selected(Client.form_message("starttime", {"time": str(timenow + dt)}))
def requires_connect(f):
@@ -69,8 +157,20 @@ def requires_connect(f):
return wrapper
def requires_any_connected(f):
def wrapper(*args, **kwargs):
if Client.clients:
return f(*args, **kwargs)
else:
print("No clients were connected!")
return wrapper
class Client:
resume_quee = True
clients = {}
on_connect = None # Use as callback functions
on_disconnect = None
def __init__(self, ip):
self.socket = None
@@ -81,7 +181,7 @@ class Client:
self._request_queue = collections.OrderedDict()
self.copter_id = None
self.malfunction = False
self.selected = False # Use to select copters for certain purposes
Client.clients[ip] = self
@@ -89,7 +189,8 @@ class Client:
def connect(self, client_socket, client_addr):
print("Client connected")
# self._send_queue = collections.deque() # comment for resuming queue after reconnection
if not Client.resume_quee:
self._send_queue = collections.deque() # comment for resuming queue after reconnection
self.socket = client_socket
self.addr = client_addr
@@ -101,7 +202,6 @@ class Client:
if self.copter_id is None:
self.copter_id = self.get_response("id")
print("Got copter id:", self.copter_id)
drone_list.insert("", "end", self.addr[0], text=self.copter_id)
def _send_all(self, msg):
self.socket.sendall(struct.pack('>I', len(msg)) + msg)
@@ -135,9 +235,6 @@ class Client:
print("Attempt to send failed")
self._send_queue.appendleft(msg)
raise e
else:
msg = "ping"
# self._send_all(msg)
try: # check if data in buffer
check = self.socket.recv(BUFFER_SIZE, socket.MSG_PEEK)
@@ -145,12 +242,12 @@ class Client:
received = self._receive_message()
if received:
received = received.decode("UTF-8")
print("Recived", received, "from", self.addr)
command, args = Client.parse_command(received)
print("Received", received, "from", self.addr)
command, args = Client.parse_message(received)
if command == "response":
for key, value in self._request_queue.items():
if not value:
self._request_queue[key] = args[0]
self._request_queue[key] = args['value']
print("Request successfully closed")
break
else:
@@ -166,174 +263,86 @@ class Client:
# time.sleep(0.05)
@staticmethod
def form_command(command: str, args=()): # Change for different protocol
return " ".join([command, *args])
def form_message(command: str, dict_arguments: dict = None):
if dict_arguments is None:
dict_arguments = {}
msg_dict = {command: str(dict_arguments).replace(",", '').replace("'", '')[1:-1]}
msg = json.dumps(msg_dict)
return msg
@staticmethod
def parse_command(command_input):
args = command_input.split()
command = args.pop(0)
return command, args
def parse_message(msg):
try:
j_message = json.loads(msg)
except json.decoder.JSONDecodeError:
print("Json string not in correct format")
return None
str_command = list(j_message.keys())[0]
arguments = list(j_message.values())[0].replace(":", '').split()
dict_arguments = collections.OrderedDict(zip(arguments[::2], arguments[1::2]))
return str_command, dict_arguments
@requires_connect
def send(self, *messages):
for message in messages:
self._send_queue.append(bytes(message, "UTF-8"))
@staticmethod
def broadcast(message, force_all=False):
if Client.clients:
for client in Client.clients.values():
if (not client.malfunction) or force_all:
client.send(message)
else:
print("No clients were connected!")
@requires_connect
def send_file(self, filepath, dest_filename):
print("Sending file ", dest_filename)
self.send(Client.form_command("writefile", (dest_filename,)))
file = open(filepath, 'rb')
chunk = file.read(BUFFER_SIZE)
while chunk:
self._send_queue.append(chunk)
chunk = file.read(BUFFER_SIZE)
file.close()
self.send(Client.form_command("/endoffile"))
print("File sent")
@requires_connect
def get_response(self, requested_value):
self._request_queue[requested_value] = ""
self.send(Client.form_command("request", (requested_value, )))
self.send(Client.form_message("request", {"value": requested_value}))
while not self._request_queue[requested_value]:
pass
return self._request_queue.pop(requested_value)
@requires_connect
def send_file(self, filepath, dest_filename):
print("Sending file ", dest_filename)
chunk_count = math.ceil(os.path.getsize(filepath) / BUFFER_SIZE)
self.send(Client.form_message("writefile", {"filesize": chunk_count, "filename": dest_filename}))
with open(filepath, 'rb') as file:
chunk = file.read(BUFFER_SIZE)
while chunk:
self._send_queue.append(chunk) # TODO lock!!!!!
chunk = file.read(BUFFER_SIZE)
# UI functions
def stop_swarm():
Client.broadcast("stop") # для тестирования
self.send(Client.form_message("/endoffile")) # TODO mb remove
print("File sent")
@staticmethod
@requires_any_connected
def send_to_selected(message):
for client in Client.clients.values():
if client.connected and client.selected:
client.send(message)
def land_all():
Client.broadcast("land")
@staticmethod
@requires_any_connected
def request_to_selected(requested_value):
for client in Client.clients.values(): # TODO change to selected
if client.connected and client.selected:
client.get_response(requested_value)
@staticmethod
@requires_any_connected
def broadcast(message, force_all=False):
for client in Client.clients.values():
if client.connected or force_all:
client.send(message)
def disarm_all():
Client.broadcast("disarm")
@staticmethod
def send_config_options(*options: ConfigOption):
for option in options:
Client.send_to_selected(
Client.form_message('config_write',
{'section': option.section, 'option': option.option, 'value': option.value}))
Client.send_to_selected(Client.form_message("config_reload"))
def takeoff_all():
Client.broadcast("takeoff")
def send_animations():
path = filedialog.askdirectory(title="Animation directory")
if path:
print("Selected directory:", path)
files = [file for file in glob.glob(path+'/*.csv')]
names = [os.path.basename(file).split(".")[0] for file in files]
print(files)
for file, name in zip(files, names):
for copter in Client.clients.values():
if name == copter.copter_id:
copter.send_file(file, "animation.csv") # TODO config
else:
print("Filename not matches with any drone connected")
# dr = next(iter(Client.clients.values())) # костыль для тестирования
# ANS = dr.get_response("someshit")
# print(ANS)
def send_starttime(dt=15):
timenow = time.time()
print('Now:', time.ctime(timenow), "+ dt =", dt)
Client.broadcast(Client.form_command("starttime", (str(timenow+dt), )))
# UI build here
root = Tk()
root.wm_title("Drone swarm operation server")
root.style = ttk.Style()
root.style.theme_use("default")
leftFrame = Frame(root)
leftFrame.grid(row=0, column=0, padx=10, pady=10)
rightFrame = Frame(root)
rightFrame.grid(row=0, column=1, padx=10, pady=10)
drone_list = ttkwidgets.CheckboxTreeview(leftFrame, columns=("addr", "connected"))
# drone_list["columns"] = ("addr")
# drone_list.column("name") #width=100
# drone_list.column("addr")
drone_list.heading("#0", text="Drone name")
drone_list.heading("#1", text="Connection adress")
drone_list.heading("#2", text="Connection status")
drone_list.pack()
button_frame = Frame(leftFrame, borderwidth=1, relief="solid")
button_frame.pack(fill=BOTH, expand=True)
land_all_btn = ttk.Button(button_frame, text="Disarm all", command=disarm_all)
land_all_btn.pack(side=RIGHT, padx=5, pady=5)
land_all_btn = ttk.Button(button_frame, text="Land all", command=land_all)
land_all_btn.pack(side=RIGHT, padx=5, pady=5)
stop_all_btn = ttk.Button(button_frame, text="Stop swarm", command=stop_swarm)
stop_all_btn.pack(side=RIGHT, padx=5, pady=5)
send_animation_btn = ttk.Button(button_frame, text="Send animations", command=send_animations)
send_animation_btn.pack(side=LEFT, padx=5, pady=5)
send_starttime_btn = Button(button_frame, bg='red', text="Takeoff all", command=takeoff_all)
send_starttime_btn.pack(side=LEFT, padx=5, pady=5)
send_starttime_btn = ttk.Button(button_frame, text="Start animation after...", command=send_starttime)
send_starttime_btn.pack(side=LEFT, padx=5, pady=5)
def gui_update():
time.sleep(0.1)
# reading config
config = configparser.ConfigParser()
config.read("server_config.ini")
port = int(config['SERVER']['port'])
BUFFER_SIZE = int(config['SERVER']['buffer_size'])
NTP_HOST = config['NTP']['host']
NTP_PORT = int(config['NTP']['port'])
ServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = socket.gethostname()
ip = get_ip_address()
print('Server started on', host, ip, ":", port)
# print('Now:', time.ctime(get_ntp_time(NTP_HOST, NTP_PORT)))
print('Waiting for clients...')
ServerSocket.bind((ip, port))
autoconnect_thread = threading.Thread(target=auto_connect)
autoconnect_thread.daemon = True
autoconnect_thread.start()
broadcast_thread = threading.Thread(target=ip_broadcast, args=(ip, port, ))
broadcast_thread.daemon = True
broadcast_thread.start()
if __name__ == '__main__':
try:
mainloop()
except KeyboardInterrupt:
print("Stopping server by keyboard interrupt")
finally:
ServerSocket.close()
print("Server shutdown")
server = Server()
server.start()

View File

@@ -1,6 +1,7 @@
[SERVER]
port = 25000
broadcast_port = 8181
broadcast_delay = 10
buffer_size = 1024
[NTP]

View File

@@ -1,3 +1,5 @@
import glob
from PyQt5 import QtWidgets
from PyQt5.QtGui import QStandardItem
from PyQt5.QtGui import QStandardItemModel
@@ -10,274 +12,7 @@ from PyQt5.QtWidgets import QFileDialog
# Importing gui form
from server_gui import Ui_MainWindow
import os
import sys
import glob
import time
import json
import struct
import socket
import random
import threading
import collections
import configparser
# All imports sorted in pyramid
# Functions
def get_ip_address():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
my_ip = s.getsockname()[0]
s.close()
return my_ip
def auto_connect():
while True:
ServerSocket.listen(1)
c, addr = ServerSocket.accept()
print("Got connection from:", str(addr))
if not any(client_addr == addr[0] for client_addr in Client.clients.keys()):
client = Client(addr[0])
print("New client")
else:
print("Reconnected client")
Client.clients[addr[0]].connect(c, addr)
def ip_broadcast(server_ip, server_port):
msg = bytes(Client.form_message(
"server_ip", {"host": server_ip, "port": str(server_port), "id": SERVER_TID}
), "UTF-8")
broadcast_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadcast_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
while True:
time.sleep(10)
broadcast_sock.sendto(msg, ('255.255.255.255', broadcast_port))
print("Broadcast sent")
def broadcast_listener():
broadcast_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcast_client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
try:
broadcast_client.bind(("", broadcast_port))
except OSError:
print("Another server is running on this computer, shutting down!")
# error_dialog = QtWidgets.QErrorMessage()
# error_dialog.setModal(True)
# error_dialog.showMessage('Another server detected on network, shutting down!')
# error_dialog.exec_()
sys.exit()
while True:
data, addr = broadcast_client.recvfrom(1024)
command, args = Client.parse_message(data.decode("UTF-8"))
if command == "server_ip":
if args["id"] != SERVER_TID:
print("Another server detected on network, shutting down")
# error_dialog = QtWidgets.QErrorMessage()
# error_dialog.setModal(True)
# error_dialog.showMessage('Another server detected on network, shutting down!')
# error_dialog.exec_()
sys.exit()
NTP_DELTA = 2208988800 # 1970-01-01 00:00:00
NTP_QUERY = b'\x1b' + bytes(47)
def get_ntp_time(ntp_host, ntp_port):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.sendto(NTP_QUERY, (ntp_host, ntp_port))
msg, _ = s.recvfrom(1024)
return int.from_bytes(msg[-8:], 'big') / 2 ** 32 - NTP_DELTA
def requires_connect(f):
def wrapper(*args, **kwargs):
if args[0].connected:
return f(*args, **kwargs)
else:
print("Function requires client to be connected!")
return wrapper
class Client:
clients = {}
def __init__(self, ip):
self.socket = None
self.addr = None
self._send_queue = collections.deque()
self._received_queue = collections.deque()
self._request_queue = collections.OrderedDict()
self.copter_id = None
self.malfunction = False
Client.clients[ip] = self
self.connected = False
def connect(self, client_socket, client_addr):
print("Client connected")
# self._send_queue = collections.deque() # comment for resuming queue after reconnection
self.socket = client_socket
self.addr = client_addr
self.socket.setblocking(0)
self.connected = True
client_thread = threading.Thread(target=self._run, args=())
client_thread.start()
if self.copter_id is None:
self.copter_id = self.get_response("id")
print("Got copter id:", self.copter_id)
model.appendRow((QStandardItem(self.copter_id), )) # TODO: get responses for another columns
def _send_all(self, msg):
self.socket.sendall(struct.pack('>I', len(msg)) + msg)
def _receive_all(self, n):
data = b''
while len(data) < n:
packet = self.socket.recv(min(n - len(data), BUFFER_SIZE))
if not packet:
return None
data += packet
return data
def _receive_message(self):
raw_msglen = self._receive_all(4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
msg = self._receive_all(msglen)
return msg
def _run(self):
while self.connected:
try:
if self._send_queue:
msg = self._send_queue.popleft()
print("Send", msg, "to", self.addr)
try:
self._send_all(msg)
except socket.error as e:
print("Attempt to send failed")
self._send_queue.appendleft(msg)
raise e
else:
msg = "ping"
# self._send_all(msg)
try: # check if data in buffer
check = self.socket.recv(BUFFER_SIZE, socket.MSG_PEEK)
if check:
received = self._receive_message()
if received:
received = received.decode("UTF-8")
print("Received", received, "from", self.addr)
command, args = Client.parse_message(received)
if command == "response":
for key, value in self._request_queue.items():
if not value:
self._request_queue[key] = args['value']
print("Request successfully closed")
break
else:
self._received_queue.appendleft(received)
except socket.error:
pass
except socket.error as e:
print("Client error: {}, disconnected".format(e))
self.connected = False
self.socket.close()
break
# time.sleep(0.05)
@staticmethod
def form_message(command: str, dict_arguments: dict = None):
if dict_arguments is None:
dict_arguments = {}
msg_dict = {command: str(dict_arguments).replace(",", '').replace("'", '')[1:-1]}
msg = json.dumps(msg_dict)
return msg
@staticmethod
def parse_message(msg):
try:
j_message = json.loads(msg)
except json.decoder.JSONDecodeError:
print("Json string not in correct format")
return None
str_command = list(j_message.keys())[0]
arguments = list(j_message.values())[0].replace(":", '').split()
dict_arguments = collections.OrderedDict(zip(arguments[::2], arguments[1::2]))
return str_command, dict_arguments
@requires_connect
def send(self, *messages):
for message in messages:
self._send_queue.append(bytes(message, "UTF-8"))
@requires_connect
def get_response(self, requested_value):
self._request_queue[requested_value] = ""
self.send(Client.form_message("request", {"value": requested_value}))
while not self._request_queue[requested_value]:
pass
return self._request_queue.pop(requested_value)
@staticmethod
def send_to_selected(*messages):
if Client.clients:
for client in Client.clients.values(): # TODO change to selected
client.send(*messages)
else:
print("No clients were connected!")
@staticmethod
def request_to_selected(requested_value):
if Client.clients:
for client in Client.clients.values(): # TODO change to selected
client.get_response(requested_value)
else:
print("No clients were connected!")
@staticmethod
def broadcast(message, force_all=False):
if Client.clients:
for client in Client.clients.values():
if (not client.malfunction) or force_all:
client.send(message)
else:
print("No clients were connected!")
@requires_connect
def send_file(self, filepath, dest_filename):
print("Sending file ", dest_filename)
self.send(Client.form_message("writefile", {"filename": dest_filename}))
file = open(filepath, 'rb')
chunk = file.read(BUFFER_SIZE)
while chunk:
self._send_queue.append(chunk) # TODO os.sendfile
chunk = file.read(BUFFER_SIZE)
file.close()
self.send(Client.form_message("/endoffile"))
print("File sent")
from server import *
class MainWindow(QtWidgets.QMainWindow):
@@ -315,12 +50,7 @@ class MainWindow(QtWidgets.QMainWindow):
@pyqtSlot()
def send_starttime(self):
dt = self.ui.start_delay_spin.value()
if USE_NTP:
timenow = get_ntp_time(NTP_HOST, NTP_PORT)
else:
timenow = time.time()
print('Now:', time.ctime(timenow), "+ dt =", dt)
Client.send_to_selected(Client.form_message("starttime", {"time": str(timenow + dt)}))
server.send_starttime(dt)
@pyqtSlot()
def stop_all(self):
@@ -369,14 +99,13 @@ class MainWindow(QtWidgets.QMainWindow):
print("Selected file:", path)
sendable_config = configparser.ConfigParser()
sendable_config.read(path)
options = []
for section in sendable_config.sections():
for option in dict(sendable_config.items(section)):
value = sendable_config[section][option]
print("Got item from config:", section, option, value)
Client.send_to_selected(
Client.form_message('config_write', {'section': section, 'option': option, 'value': value})
)
Client.send_to_selected(Client.form_message("config_reload"))
options.append(ConfigOption(section, option, value))
Client.send_config_options(*options)
model = QStandardItemModel()
@@ -385,54 +114,16 @@ model.setHorizontalHeaderLabels(
)
model.setColumnCount(6)
model.setRowCount(0)
# Pre-initialization
# reading config
config = configparser.ConfigParser()
config.read("server_config.ini")
port = int(config['SERVER']['port'])
broadcast_port = int(config['SERVER']['broadcast_port'])
BUFFER_SIZE = int(config['SERVER']['buffer_size'])
USE_NTP = config.getboolean('NTP', 'use_ntp')
NTP_HOST = config['NTP']['host']
NTP_PORT = int(config['NTP']['port'])
random.seed()
SERVER_TID = str(random.randint(0, 9999)).zfill(4)
ServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = socket.gethostname()
ip = get_ip_address()
# Client.on_connect = model.appendRow((QStandardItem(self.copter_id), )) # TODO: get responses for another columns
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
print('Server started on', host, ip, ":", port)
server = Server()
server.start()
if USE_NTP:
print("Using NTP time:")
now = get_ntp_time(NTP_HOST, NTP_PORT)
else:
now = time.time()
print('Now:', time.ctime(now))
print('Waiting for clients...')
ServerSocket.bind((ip, port))
autoconnect_thread = threading.Thread(target=auto_connect)
autoconnect_thread.daemon = True
autoconnect_thread.start()
broadcast_thread = threading.Thread(target=ip_broadcast, args=(ip, port,))
broadcast_thread.daemon = True
broadcast_thread.start()
listener_thread = threading.Thread(target=broadcast_listener)
listener_thread.daemon = True
#listener_thread.start()
sys.exit(app.exec_())
app.exec_()
server.stop()
sys.exit()