mirror of
https://github.com/BOSWatch/BW3-Core.git
synced 2026-04-05 06:15:31 +00:00
Merge branch 'develop' into router
This commit is contained in:
commit
71d87b080f
23 changed files with 381 additions and 504 deletions
|
|
@ -1,131 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""!
|
||||
____ ____ ______ __ __ __ _____
|
||||
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
||||
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
||||
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
||||
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
||||
German BOS Information Script
|
||||
by Bastian Schroll
|
||||
|
||||
@file: config.py
|
||||
@date: 25.12.2017
|
||||
@author: Bastian Schroll
|
||||
@description: Module for the configuration
|
||||
"""
|
||||
import logging
|
||||
import configparser
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
||||
|
||||
class Config:
|
||||
|
||||
_sharePoints = {}
|
||||
|
||||
def __init__(self):
|
||||
"""!Create a new config object and load the ini file directly"""
|
||||
self._config = configparser.ConfigParser()
|
||||
|
||||
def loadConfigFile(self, configPath, sharePoint=""):
|
||||
"""!loads a given configuration in the class wide config variable
|
||||
|
||||
@param configPath: Path to the config file
|
||||
@param sharePoint: If you want to share the config set name here
|
||||
@return True or False"""
|
||||
logging.debug("load config file from: %s", configPath)
|
||||
try:
|
||||
self._config.read(configPath, "utf-8")
|
||||
if sharePoint:
|
||||
self._shareConfig(sharePoint)
|
||||
return True
|
||||
except: # pragma: no cover
|
||||
logging.exception("cannot load config file")
|
||||
return False
|
||||
|
||||
def _shareConfig(self, sharePoint):
|
||||
"""!Shares the configuration
|
||||
|
||||
Shares the local _config to the class wide global _sharedConfig
|
||||
@param sharePoint: Name of the global share point
|
||||
@return True or False"""
|
||||
if sharePoint in self._sharePoints:
|
||||
logging.error("cannot share config - name is always in use: %s", sharePoint)
|
||||
return False
|
||||
else:
|
||||
self._sharePoints[sharePoint] = self._config
|
||||
logging.debug("add config sharePoint: %s", sharePoint)
|
||||
return True
|
||||
|
||||
def getInt(self, section, key, sharePoint=""):
|
||||
"""!Method to read a single config entry as integer
|
||||
|
||||
@param section: Section to read from
|
||||
@param key: Value to read
|
||||
@param sharePoint: Name of the global config share (empty is only local)
|
||||
@return An Integer or None"""
|
||||
value = self._get(section, key, sharePoint)
|
||||
if value is None:
|
||||
return None
|
||||
return int(value)
|
||||
|
||||
def getBool(self, section, key, sharePoint=""):
|
||||
"""!Method to read a single config entry as boolean
|
||||
|
||||
@param section: Section to read from
|
||||
@param key: Value to read
|
||||
@param sharePoint: Name of the global config share (empty is only local)
|
||||
@return True or False"""
|
||||
if self._get(section, key, sharePoint).lower() in ["1", "true", "yes"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getStr(self, section, key, sharePoint=""):
|
||||
"""!Method to read a single config entry as string
|
||||
|
||||
@param section: Section to read from
|
||||
@param key: Value to read
|
||||
@param sharePoint: Name of the global config share (empty is only local)
|
||||
@return The value or None"""
|
||||
value = self._get(section, key, sharePoint)
|
||||
if value is None:
|
||||
return None
|
||||
return str(value)
|
||||
|
||||
def _get(self, section, key, sharePoint=""):
|
||||
"""!Method to read a single config entry
|
||||
|
||||
@param section: Section to read from
|
||||
@param key: Value to read
|
||||
@param sharePoint: Name of the global config share (empty is only local)
|
||||
@return The value or None"""
|
||||
if sharePoint:
|
||||
try:
|
||||
return self._sharePoints[sharePoint].get(section, key)
|
||||
except KeyError:
|
||||
logging.error("no sharePoint named: %s", sharePoint)
|
||||
except configparser.NoSectionError:
|
||||
logging.warning("no shared config section: %s", section)
|
||||
except configparser.NoOptionError:
|
||||
logging.warning("no shared config option: %s", key)
|
||||
except: # pragma: no cover
|
||||
logging.exception("error while reading shared config")
|
||||
return None
|
||||
|
||||
else:
|
||||
try:
|
||||
return self._config.get(section, key)
|
||||
except configparser.NoSectionError:
|
||||
logging.warning("no local config section: %s", section)
|
||||
except configparser.NoOptionError:
|
||||
logging.warning("no local config option: %s", key)
|
||||
except: # pragma: no cover
|
||||
logging.exception("error while reading local config")
|
||||
return None
|
||||
|
||||
def getAllSharepoints(self):
|
||||
"""!Return a python dict of all set sharepoints
|
||||
|
||||
@return Sharepoint dict"""
|
||||
return self._sharePoints
|
||||
79
boswatch/configYaml.py
Normal file
79
boswatch/configYaml.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""!
|
||||
____ ____ ______ __ __ __ _____
|
||||
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
||||
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
||||
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
||||
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
||||
German BOS Information Script
|
||||
by Bastian Schroll
|
||||
|
||||
@file: configYaml.py
|
||||
@date: 27.02.2019
|
||||
@author: Bastian Schroll
|
||||
@description: Module for the configuration in yaml format
|
||||
"""
|
||||
import logging
|
||||
import yaml
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
||||
__sharePoints = {}
|
||||
|
||||
|
||||
def loadConfigFile(configPath, sharePoint=""):
|
||||
"""!loads a given configuration
|
||||
|
||||
@param configPath: Path to the config file
|
||||
@param sharePoint: If you want to share the config set name here
|
||||
@return python dict of config or None"""
|
||||
logging.debug("load config file from: %s", configPath)
|
||||
try:
|
||||
|
||||
with open(configPath) as f:
|
||||
# use safe_load instead load
|
||||
config = yaml.safe_load(f)
|
||||
if sharePoint:
|
||||
_shareConfig(config, sharePoint)
|
||||
return config
|
||||
except: # pragma: no cover
|
||||
logging.exception("cannot load config file")
|
||||
return None
|
||||
|
||||
|
||||
def loadConfigSharepoint(sharePoint):
|
||||
"""!loads a given configuration from an sharepoint
|
||||
|
||||
@param sharePoint: Name of the sharepoint
|
||||
@return python dict of config or None"""
|
||||
try:
|
||||
return __sharePoints[sharePoint]
|
||||
except KeyError:
|
||||
logging.error("no sharePoint named: %s", sharePoint)
|
||||
except: # pragma: no cover
|
||||
logging.exception("error while reading shared config")
|
||||
return None
|
||||
|
||||
|
||||
def _shareConfig(config, sharePoint):
|
||||
"""!Shares the configuration
|
||||
|
||||
Shares the local _config to the class wide global _sharedConfig
|
||||
@param config: Python dict of the configuration
|
||||
@param sharePoint: Name of the global share point
|
||||
@return True or False"""
|
||||
if sharePoint in __sharePoints:
|
||||
logging.error("cannot share config - name is always in use: %s", sharePoint)
|
||||
return False
|
||||
else:
|
||||
__sharePoints[sharePoint] = config
|
||||
logging.debug("add config sharePoint: %s", sharePoint)
|
||||
return True
|
||||
|
||||
|
||||
def getAllSharepoints():
|
||||
"""!Return a python dict of all set sharepoints
|
||||
|
||||
@return Sharepoint dict"""
|
||||
return __sharePoints
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
from boswatch.config import Config
|
||||
from boswatch import configYaml
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ class DoubleFilter:
|
|||
|
||||
def __init__(self):
|
||||
"""!init"""
|
||||
self._config = Config()
|
||||
self._config = configYaml.loadConfigSharepoint("serverConfig")["filter"]["doubleFilter"]
|
||||
self._filterLists = {}
|
||||
|
||||
def filter(self, bwPacket):
|
||||
|
|
@ -57,14 +57,14 @@ class DoubleFilter:
|
|||
# delete entries that are to old
|
||||
counter = 0
|
||||
for listPacket in self._filterLists[bwPacket.get("mode")][1:]: # [1:] skip first entry, thats the new one
|
||||
if listPacket.get("timestamp") < (time.time() - self._config.getInt("doubleFilter", "IgnoreTime", "serverConfig")):
|
||||
if listPacket.get("timestamp") < (time.time() - self._config["ignoreTime"]):
|
||||
self._filterLists[bwPacket.get("mode")].remove(listPacket)
|
||||
counter += 1
|
||||
if counter:
|
||||
logging.debug("%d old entry(s) removed", counter)
|
||||
|
||||
# delete last entry if list is to big
|
||||
if len(self._filterLists[bwPacket.get("mode")]) > self._config.getInt("doubleFilter", "MaxEntry", "serverConfig"):
|
||||
if len(self._filterLists[bwPacket.get("mode")]) > self._config["maxEntry"]:
|
||||
logging.debug("MaxEntry reached - delete oldest")
|
||||
self._filterLists[bwPacket.get("mode")].pop()
|
||||
|
||||
|
|
|
|||
|
|
@ -101,12 +101,18 @@ class BroadcastServer:
|
|||
self._serverShutdown = False
|
||||
self._servePort = servePort
|
||||
|
||||
def __del__(self):
|
||||
if self.isRunning:
|
||||
self.stop()
|
||||
while self.isRunning:
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
"""!Start the broadcast server in a new thread
|
||||
|
||||
@return True or False"""
|
||||
try:
|
||||
if not self._serverThread:
|
||||
if not self.isRunning:
|
||||
logging.debug("start udp broadcast server")
|
||||
self._serverThread = threading.Thread(target=self._listen)
|
||||
self._serverThread.name = "BroadServ"
|
||||
|
|
@ -130,7 +136,7 @@ class BroadcastServer:
|
|||
|
||||
@return True or False"""
|
||||
try:
|
||||
if self._serverThread:
|
||||
if self.isRunning:
|
||||
logging.debug("stop udp broadcast server")
|
||||
self._serverShutdown = True
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -40,12 +40,15 @@ class TCPClient:
|
|||
@param port: Server Port (8080)
|
||||
@return True or False"""
|
||||
try:
|
||||
self._sock = socket
|
||||
self._sock.setdefaulttimeout(self._timeout)
|
||||
self._sock = socket.create_connection((host, port))
|
||||
|
||||
logging.debug("connected to %s:%s", host, port)
|
||||
return True
|
||||
if not self.isConnected:
|
||||
self._sock = socket
|
||||
self._sock.setdefaulttimeout(self._timeout)
|
||||
self._sock = socket.create_connection((host, port))
|
||||
logging.debug("connected to %s:%s", host, port)
|
||||
return True
|
||||
else:
|
||||
logging.warning("client always connected")
|
||||
return True
|
||||
except ConnectionRefusedError:
|
||||
logging.error("cannot connect to %s:%s - connection refused", host, port)
|
||||
return False
|
||||
|
|
@ -61,9 +64,14 @@ class TCPClient:
|
|||
|
||||
@return True or False"""
|
||||
try:
|
||||
self._sock.close()
|
||||
logging.debug("disconnected")
|
||||
return True
|
||||
if self.isConnected:
|
||||
self._sock.close()
|
||||
self._sock = None
|
||||
logging.debug("disconnected")
|
||||
return True
|
||||
else:
|
||||
logging.warning("client not connected")
|
||||
return True
|
||||
except AttributeError:
|
||||
logging.error("cannot disconnect - no connection established")
|
||||
return False
|
||||
|
|
@ -111,3 +119,10 @@ class TCPClient:
|
|||
except: # pragma: no cover
|
||||
logging.exception("error while receiving")
|
||||
return False
|
||||
|
||||
@property
|
||||
def isConnected(self):
|
||||
"""!Property of client connected state"""
|
||||
if self._sock:
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ class TCPServer:
|
|||
self._clientsConnectedLock = threading.Lock()
|
||||
self._clientsConnected = {}
|
||||
|
||||
def __del__(self):
|
||||
if self.isRunning:
|
||||
self.stop()
|
||||
|
||||
def start(self, port=8080):
|
||||
"""!Start a threaded TCP socket server
|
||||
|
||||
|
|
@ -93,21 +97,23 @@ class TCPServer:
|
|||
|
||||
@return True or False"""
|
||||
try:
|
||||
self._server = ThreadedTCPServer(("", port), ThreadedTCPRequestHandler)
|
||||
self._server.timeout = self._timeout
|
||||
self._server.alarmQueue = self._alarmQueue
|
||||
if not self.isRunning:
|
||||
self._server = ThreadedTCPServer(("", port), ThreadedTCPRequestHandler)
|
||||
self._server.timeout = self._timeout
|
||||
self._server.alarmQueue = self._alarmQueue
|
||||
|
||||
self._server.clientsConnctedLock = self._clientsConnectedLock
|
||||
self._server.clientsConnected = self._clientsConnected
|
||||
self._server.clientsConnctedLock = self._clientsConnectedLock
|
||||
self._server.clientsConnected = self._clientsConnected
|
||||
|
||||
self._server_thread = threading.Thread(target=self._server.serve_forever)
|
||||
self._server_thread.name = "Thread-BWServer"
|
||||
self._server_thread.daemon = True
|
||||
self._server_thread.start()
|
||||
logging.debug("TCPServer started in Thread: %s", self._server_thread.name)
|
||||
return True
|
||||
except OSError:
|
||||
logging.exception("server always running?")
|
||||
self._server_thread = threading.Thread(target=self._server.serve_forever)
|
||||
self._server_thread.name = "Thread-BWServer"
|
||||
self._server_thread.daemon = True
|
||||
self._server_thread.start()
|
||||
logging.debug("TCPServer started in Thread: %s", self._server_thread.name)
|
||||
return True
|
||||
else:
|
||||
logging.warning("server always started")
|
||||
return True
|
||||
except: # pragma: no cover
|
||||
logging.exception("cannot start the server")
|
||||
return False
|
||||
|
|
@ -117,16 +123,17 @@ class TCPServer:
|
|||
|
||||
@return True or False"""
|
||||
try:
|
||||
self._server.shutdown()
|
||||
self._server_thread.join()
|
||||
self._server_thread = None
|
||||
self._server.socket.close()
|
||||
self._server = None
|
||||
logging.debug("TCPServer stopped")
|
||||
return True
|
||||
except AttributeError:
|
||||
logging.exception("cannot stop - server not started?")
|
||||
return False
|
||||
if self.isRunning:
|
||||
self._server.shutdown()
|
||||
self._server_thread.join()
|
||||
self._server_thread = None
|
||||
self._server.socket.close()
|
||||
self._server = None
|
||||
logging.debug("TCPServer stopped")
|
||||
return True
|
||||
else:
|
||||
logging.warning("server always stopped")
|
||||
return True
|
||||
except: # pragma: no cover
|
||||
logging.exception("cannot stop the server")
|
||||
return False
|
||||
|
|
@ -147,3 +154,10 @@ class TCPServer:
|
|||
# todo return full list or write a print/debug method?
|
||||
with self._clientsConnectedLock: # because our list is not threadsafe
|
||||
return self._clientsConnected
|
||||
|
||||
@property
|
||||
def isRunning(self):
|
||||
"""!Property of server running state"""
|
||||
if self._server:
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"""
|
||||
import logging
|
||||
import time
|
||||
from boswatch.config import Config
|
||||
from boswatch import configYaml
|
||||
from boswatch import version
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
|
@ -73,14 +73,14 @@ class Packet:
|
|||
- clientBranch
|
||||
- inputSource
|
||||
- frequency"""
|
||||
config = Config()
|
||||
config = configYaml.loadConfigSharepoint("clientConfig")
|
||||
logging.debug("add client data to bwPacket")
|
||||
self.set("clientName", config.getStr("Client", "Name", "clientConfig"))
|
||||
self.set("clientName", config["client"]["name"])
|
||||
self.set("clientVersion", version.client)
|
||||
self.set("clientBuildDate", version.date)
|
||||
self.set("clientBranch", version.branch)
|
||||
self.set("inputSource", config.getStr("Client", "InputSource", "clientConfig"))
|
||||
self.set("frequency", config.getStr("Stick", "Frequency", "clientConfig"))
|
||||
self.set("inputSource", config["client"]["inputSource"])
|
||||
self.set("frequency", config["inputSource"]["sdr"]["frequency"])
|
||||
|
||||
def addServerData(self):
|
||||
"""!Add the server information to the decoded data
|
||||
|
|
@ -90,9 +90,9 @@ class Packet:
|
|||
- serverVersion
|
||||
- serverBuildDate
|
||||
- serverBranch"""
|
||||
config = Config()
|
||||
config = configYaml.loadConfigSharepoint("serverConfig")
|
||||
logging.debug("add server data to bwPacket")
|
||||
self.set("serverName", config.getStr("Server", "Name", "serverConfig"))
|
||||
self.set("serverName", config["server"]["name"])
|
||||
self.set("serverVersion", version.server)
|
||||
self.set("serverBuildDate", version.date)
|
||||
self.set("serverBranch", version.branch)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import logging
|
|||
import time
|
||||
|
||||
from boswatch.utils import paths
|
||||
from boswatch.config import Config
|
||||
from boswatch import configYaml
|
||||
from boswatch.utils import wildcard
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
|
@ -52,9 +52,8 @@ class Plugin:
|
|||
self._alarmErrorCount = 0
|
||||
self._teardownErrorCount = 0
|
||||
|
||||
if paths.fileExist(paths.PLUGIN_PATH + pluginName + "/" + pluginName + ".ini"):
|
||||
self.config = Config()
|
||||
self.config.loadConfigFile(paths.PLUGIN_PATH + pluginName + "/" + pluginName + ".ini")
|
||||
if paths.fileExist(paths.PLUGIN_PATH + pluginName + "/" + pluginName + ".yaml"):
|
||||
self.config = configYaml.loadConfigFile(paths.PLUGIN_PATH + pluginName + "/" + pluginName + ".yaml")
|
||||
else:
|
||||
logging.debug("no config for %s found", pluginName)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import os
|
|||
import time
|
||||
import importlib
|
||||
|
||||
from boswatch.config import Config
|
||||
from boswatch import configYaml
|
||||
from boswatch.utils import paths
|
||||
|
||||
logging.debug("- %s loaded", __name__)
|
||||
|
|
@ -33,7 +33,7 @@ class PluginManager:
|
|||
|
||||
def __init__(self):
|
||||
"""!init comment"""
|
||||
self._config = Config()
|
||||
self._config = configYaml.loadConfigSharepoint("serverConfig")
|
||||
self._pluginList = []
|
||||
|
||||
def searchPluginDir(self):
|
||||
|
|
@ -45,7 +45,7 @@ class PluginManager:
|
|||
if not os.path.isdir(location) or not name + ".py" in os.listdir(location):
|
||||
continue
|
||||
|
||||
pluginPriority = self._config.getInt("Plugins", name, "serverConfig")
|
||||
pluginPriority = self._config["plugins"][name]
|
||||
|
||||
if pluginPriority is None:
|
||||
logging.warning("no entry in server config for plugin: %s", name)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue