mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-05-26 23:19:33 +00:00
WIP 3
This commit is contained in:
@@ -224,7 +224,7 @@ class Client(object):
|
||||
@messaging.message_callback("config_write")
|
||||
def _command_config_write(*args, **kwargs):
|
||||
options = [ConfigOption(**raw_option) for raw_option in kwargs["options"]]
|
||||
logger.info("Writing config options: {}".format(options))
|
||||
logger.info("Writing config_attrs options: {}".format(options))
|
||||
active_client.write_config(kwargs["reload"], *options)
|
||||
|
||||
|
||||
|
||||
19
Drone/config/client.ini
Normal file
19
Drone/config/client.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
# This is generated config_attrs with defaults
|
||||
# Modify to configure
|
||||
[SERVER]
|
||||
port = 25000
|
||||
host = 192.168.1.101
|
||||
buffer_size = 1024
|
||||
|
||||
[BROADCAST]
|
||||
use = True
|
||||
port = 8181
|
||||
|
||||
[NTP]
|
||||
use = False
|
||||
host = ntp1.stratum2.ru
|
||||
port = 123n
|
||||
|
||||
[PRIVATE]
|
||||
# avialiable options: /hostname ; /default ; /ip ; any string 63 characters lengh
|
||||
#id = /hostname
|
||||
@@ -13,4 +13,5 @@ host = string(default=ntp1.stratum2.ru)
|
||||
port = integer(default=123)
|
||||
|
||||
[PRIVATE]
|
||||
id = string(default=/hostname, max=63)
|
||||
# avialiable options: /hostname ; /default ; /ip ; any string 63 characters lengh
|
||||
id = string(default=/hostname, max=63)
|
||||
@@ -4,10 +4,12 @@ from PyQt5.QtCore import Qt as Qt
|
||||
|
||||
|
||||
class ConfigModelItem:
|
||||
def __init__(self, label, value="", parent=None):
|
||||
self.parentItem = parent
|
||||
def __init__(self, label, value="", is_section=False, parent=None):
|
||||
self.itemData = [label, value]
|
||||
|
||||
self.is_section=is_section
|
||||
self.childItems = []
|
||||
self.parentItem = parent
|
||||
|
||||
if self.parentItem is not None:
|
||||
self.parentItem.appendChild(self)
|
||||
@@ -64,12 +66,6 @@ class ConfigModel(QtCore.QAbstractItemModel):
|
||||
self.rootItem = ConfigModelItem("Option", "Value")
|
||||
self.setup(data)
|
||||
|
||||
#i = ConfigModelItem("1314", "")
|
||||
#self.rootItem.appendChild(i)
|
||||
#i.appendChild(ConfigModelItem("36hhj", "34566"))
|
||||
#i.appendChild(ConfigModelItem("36hhj", "34566"))
|
||||
|
||||
|
||||
def headerData(self, section, orientation, role):
|
||||
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
|
||||
return self.rootItem.data(section)
|
||||
@@ -143,12 +139,11 @@ class ConfigModel(QtCore.QAbstractItemModel):
|
||||
def flags(self, index):
|
||||
if not index.isValid():
|
||||
return Qt.NoItemFlags
|
||||
childItem = index.internalPointer()
|
||||
parentItem = childItem.parent()
|
||||
item = index.internalPointer()
|
||||
|
||||
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
||||
|
||||
if index.column() == 1 and parentItem != self.rootItem:
|
||||
if index.column() == 1 and not item.is_section:
|
||||
flags |= Qt.ItemIsEditable
|
||||
|
||||
return flags
|
||||
@@ -168,13 +163,18 @@ class ConfigModel(QtCore.QAbstractItemModel):
|
||||
self.endRemoveRows()
|
||||
return True
|
||||
|
||||
def setup(self, d: dict):
|
||||
for section, options in d.items():
|
||||
section_item = ConfigModelItem(section, parent=self.rootItem)
|
||||
for option, value in options.items():
|
||||
section_item.appendChild(ConfigModelItem(option, value))
|
||||
def setup(self, data: dict, parent=None):
|
||||
if parent is None:
|
||||
parent = self.rootItem
|
||||
|
||||
def to_dict(self):
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
item = ConfigModelItem(key, parent=parent, is_section=True)
|
||||
self.setup(value, parent=item)
|
||||
else:
|
||||
parent.appendChild(ConfigModelItem(key, value))
|
||||
|
||||
def to_dict(self): # TODO recursive
|
||||
d = {}
|
||||
for section in self.rootItem.childItems:
|
||||
section_d = {}
|
||||
@@ -221,8 +221,8 @@ if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
Dialog = QtWidgets.QDialog()
|
||||
|
||||
data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": ""},
|
||||
"section 2": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": ""}}
|
||||
data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": {'subopt': 'bal'}},
|
||||
"section 2": {"opt1": "str", "opt2": [1.1, 2.3, 34], "opt3": 1.23, "opt4": False, "...": ""}}
|
||||
|
||||
ui = ConfigDialog(data)
|
||||
ui.setupUi(Dialog)
|
||||
@@ -230,4 +230,8 @@ if __name__ == '__main__':
|
||||
|
||||
Dialog.show()
|
||||
print(app.exec_())
|
||||
|
||||
print(Dialog.result())
|
||||
print(ui.model.to_dict())
|
||||
|
||||
sys.exit()
|
||||
|
||||
137
config.py
137
config.py
@@ -1,64 +1,109 @@
|
||||
import collections
|
||||
import os
|
||||
from configobj import ConfigObj
|
||||
|
||||
from functools import partial
|
||||
from configobj import ConfigObj, Section
|
||||
from validate import Validator
|
||||
|
||||
ConfigOption = collections.namedtuple("ConfigOption", ["section", "option", "value"])
|
||||
|
||||
def modify_filename(path, pattern):
|
||||
old_path, filename = os.path.split(path)
|
||||
filename = os.path.splitext(filename)[0]
|
||||
newfilename = pattern.format(filename)
|
||||
return os.path.join(old_path, newfilename)
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
def __init__(self):
|
||||
self.configs = {}
|
||||
self.config = ConfigObj()
|
||||
|
||||
@staticmethod
|
||||
def _get_default_path(path):
|
||||
old_path, filename = os.path.split(path)
|
||||
filename = os.path.splitext(filename)[0]
|
||||
newfilename = "default_{}.ini".format(filename)
|
||||
print(os.path.join(old_path, newfilename))
|
||||
return os.path.join(old_path, newfilename)
|
||||
def load_config(self, path):
|
||||
self.generate_default_config(path)
|
||||
|
||||
def load_config(self, path): # todo maybe automatic config path
|
||||
vdt = Validator()
|
||||
config = ConfigObj(infile=path, raise_errors=True,
|
||||
configspec=modify_filename(path, 'spec/configspec_{}.ini'))
|
||||
test = config.validate(vdt)
|
||||
print(test)
|
||||
print(config)
|
||||
self.config = config
|
||||
|
||||
default_config = ConfigObj(
|
||||
infile=self._get_default_path(path), configspec="Drone/configs/configspec_client.ini")
|
||||
default_config.validate(vdt)
|
||||
print(default_config)
|
||||
default_config.walk(self.transform)
|
||||
print(default_config.dict())
|
||||
#default_config = configparser.ConfigParser(co)
|
||||
#default_config.read(default_path)
|
||||
def get(self, section, option):
|
||||
return self.config[section][option]
|
||||
|
||||
def set(self, section, option, value, write=False):
|
||||
self.config[section][option] = value
|
||||
if write:
|
||||
self.write()
|
||||
|
||||
|
||||
def create_empty_config(self, path):
|
||||
with open(path, 'w') as f:
|
||||
f.write("# Write here any configurations to replace default values \n\n")
|
||||
|
||||
@staticmethod
|
||||
def getvalue(section, key):
|
||||
try:
|
||||
return section.as_int(key)
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return section.as_float(key)
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return section.as_bool(key)
|
||||
except ValueError:
|
||||
pass
|
||||
return section.get(key)
|
||||
def write(self):
|
||||
self.config.write()
|
||||
|
||||
@classmethod
|
||||
def transform(cls, section, key):
|
||||
value = cls.getvalue(section, key)
|
||||
print(value)
|
||||
section[key] = value
|
||||
def _get_defaults(cls, item, unchanged_only=False):
|
||||
if isinstance(item, Section):
|
||||
default_values = item.default_values.copy()
|
||||
|
||||
if unchanged_only:
|
||||
default_list = item.defaults.copy()
|
||||
defaults = {key: default_values[key] for key in default_list if key in default_values}
|
||||
else:
|
||||
defaults = default_values
|
||||
|
||||
for key, value in item.items():
|
||||
result = cls._get_defaults(value, unchanged_only=unchanged_only)
|
||||
if result is not None:
|
||||
defaults[key] = result
|
||||
|
||||
return defaults if defaults else None
|
||||
|
||||
@property
|
||||
def default_values(self):
|
||||
return self._get_defaults(self.config) or {}
|
||||
|
||||
@property
|
||||
def unchanged_defaults(self):
|
||||
return self._get_defaults(self.config, unchanged_only=True) or {}
|
||||
|
||||
@staticmethod
|
||||
def generate_default_config(path):
|
||||
if os.path.isfile(path):
|
||||
return
|
||||
|
||||
vdt = Validator()
|
||||
config = ConfigObj(configspec=modify_filename(path, 'spec/configspec_{}.ini'))
|
||||
config.filename = path
|
||||
config.validate(vdt, copy=True)
|
||||
config.initial_comment = ('This is generated config_attrs with defaults',
|
||||
'Modify to configure')
|
||||
config.write()
|
||||
|
||||
def __getattr__(self, item):
|
||||
try:
|
||||
section, option = item.split('_', 1)
|
||||
return self.config[section.upper()][option.lower()]
|
||||
except (ValueError, KeyError):
|
||||
return self.__dict__[item]
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
try:
|
||||
section, option = key.split('_', 1)
|
||||
self.config[section.upper()][option.lower()] = value
|
||||
except (ValueError, KeyError):
|
||||
self.__dict__[key] = value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cfg = ConfigManager()
|
||||
#open('Drone/default_clinet_config.ini')
|
||||
cfg.load_config('Drone/configs/clinet_config.ini')
|
||||
cfg.load_config('Drone/config/client.ini')
|
||||
|
||||
print(cfg.server_host)
|
||||
cfg.server_host = '192.168.1.103'
|
||||
|
||||
print(cfg.get('SERVER', 'host'))
|
||||
cfg.set('SERVER', 'host', '192.168.1.103')
|
||||
|
||||
print(cfg.config)
|
||||
print(cfg.default_values)
|
||||
print(cfg.unchanged_defaults)
|
||||
#print(cfg.con)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user