From c365df69e84528d1ff2f91064bd6ca38056483f2 Mon Sep 17 00:00:00 2001 From: Artem30801 Date: Thu, 5 Dec 2019 08:49:44 +0300 Subject: [PATCH] WIP 5 (config broken) --- Drone/config/client.ini | 2 +- Server/config_editor_models.py | 48 +++++++++----- config.py | 118 +++++++++++++++++++++++---------- 3 files changed, 117 insertions(+), 51 deletions(-) diff --git a/Drone/config/client.ini b/Drone/config/client.ini index 801fde4..29978d6 100644 --- a/Drone/config/client.ini +++ b/Drone/config/client.ini @@ -20,6 +20,6 @@ port = 123 [PRIVATE] # avialiable options: /hostname ; /spec_default ; /ip ; any string 63 characters lengh id = /hostname -# Drone's individual offset +# Drone's individual offset (X, Y, Z) # __list__ X Y Z offset = 0.0, 0.0, 0.0 diff --git a/Server/config_editor_models.py b/Server/config_editor_models.py index 198b59a..fe09581 100644 --- a/Server/config_editor_models.py +++ b/Server/config_editor_models.py @@ -5,11 +5,20 @@ from copy import deepcopy from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt as Qt -from PyQt5.QtGui import QCursor, QStandardItemModel -from PyQt5.QtWidgets import QAbstractItemView, QTreeView, QMenu, QAction, QMessageBox, QInputDialog +from PyQt5.QtGui import QCursor +from PyQt5.QtWidgets import QAbstractItemView, QTreeView, QMenu, QAction, QMessageBox, QInputDialog, QFileDialog import config_editor +import sys +import os, inspect # Add parent dir to PATH to import messaging_lib + +current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parent_dir = os.path.dirname(current_dir) +sys.path.insert(0, parent_dir) + +import config + def dict_walk(d: dict, keys): current = d @@ -563,6 +572,27 @@ class ConfigDialog(QtWidgets.QDialog): ) return reply == QMessageBox.Yes + def call_standalone_dialog(self): + path = QFileDialog.getOpenFileName(self, "Select configuration or specification file", + filter="Config and spec files (*.ini)")[0] + print(path) + if not path: + return + + cfg = config.ConfigManager() + cfg.load_from_file(path) + + self.setupModel(cfg.full_dict) + + self.show() + self.exec() + + print(ui.result()) + print(ui.model.to_dict()) + print(ui.model.to_config_dict()) + + + class ConfigTreeWidget(QTreeView): def __init__(self): @@ -726,21 +756,9 @@ class ConfigTreeWidget(QTreeView): self.reset_item(child, reset_type) -def call_standalone_dialog(): - pass + if __name__ == '__main__': - import os, inspect # Add parent dir to PATH to import messaging_lib - - current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) - parent_dir = os.path.dirname(current_dir) - - import config - - import sys - sys.path.insert(0, parent_dir) - - def except_hook(cls, exception, traceback): print(cls, exception, traceback) sys.__excepthook__(cls, exception, traceback) diff --git a/config.py b/config.py index de83b5c..6c6e873 100644 --- a/config.py +++ b/config.py @@ -4,7 +4,11 @@ from configobj import ConfigObj, Section from validate import Validator +from pathlib import Path + + def modify_filename(path, pattern): + # name = pattern.format(Path(path).stem) old_path, filename = os.path.split(path) filename = os.path.splitext(filename)[0] newfilename = pattern.format(filename) @@ -52,29 +56,71 @@ class ConfigManager: config = ConfigObj(infile=self._extract_values(d), indent_type='', configspec=modify_filename(path, 'spec/configspec_{}.ini')) - self._load_validate(config) - self.config.filename = path - self.config.initial_comment = initial_comment - self.config.final_comment = final_comment + config.filename = path + config.initial_comment = initial_comment + config.final_comment = final_comment + self._load_validate(config) self._load_comments(d, self.config) - def load_from_file(self, path): - self.generate_default_config(path) + @staticmethod + def _config_exists(path): + return not((not path.is_file()) or path.suffix != '.ini') - config = ConfigObj(infile=path, raise_errors=True, - configspec=modify_filename(path, 'spec/configspec_{}.ini')) + @staticmethod + def _get_spec_path(path): + return modify_filename(path, 'spec/configspec_{}.ini') + + def load_from_file(self, path): + p = Path(path) + if not self._config_exists(p): + raise ValueError('Config file do not exist!') + + if p.name.startswith('configspec_'): + config_path = p.parents[1].joinpath(p.name.replace('configspec_', '')) + if self._config_exists(config_path): + return self.load_config_and_spec(config_path) + + if p.parent.name == 'spec': + self.generate_default_config(config_path) + + return self.load_only_spec(p) + + else: + spec_path = Path(self._get_spec_path(p)) + if self._config_exists(spec_path): + return self.load_config_and_spec(p) + + return self.load_only_config(p) + + def load_config_and_spec(self, path): + path = str(path) + self.generate_default_config(path) + config = ConfigObj(infile=path, + configspec=self._get_spec_path(path)) self._load_validate(config) - def _load_validate(self, config): + def load_only_config(self, path: Path): + path = str(path) + config = ConfigObj(infile=path) + self.set_config(config) + + def load_only_spec(self, path: Path): + path = str(path) + config = ConfigObj(configspec=path) + config.filename = path.parent.joinpath(path.name.replace('configspec_', '')) + + self._load_validate(config, True) + + def _load_validate(self, config, copy=False): vdt = Validator() - test = config.validate(vdt) + test = config.validate(vdt, copy=copy) if test != True: # Important syntax, do no change raise ValueError('Some values are wrong: {}'.format(test)) - self.config = config + self.set_config(config) def get(self, section, option): return self.config[section][option] @@ -121,7 +167,7 @@ class ConfigManager: if not isinstance(result, dict): item_d = {'__option__': True, 'value': value, - 'default': default_values[key], + 'default': default_values.get(key, None), 'unchanged': key in defaults, 'comments': comments[key], 'inline_comment': inline_comments[key], @@ -148,13 +194,12 @@ class ConfigManager: d['final_comment'] = self.config.final_comment return d - @staticmethod - def generate_default_config(path): - if os.path.isfile(path): + @classmethod + def generate_default_config(cls, path): + if cls._config_exists(path): return - vdt = Validator() - config = ConfigObj(configspec=modify_filename(path, 'spec/configspec_{}.ini')) + config = ConfigObj(configspec=cls._get_spec_path(path)) config.filename = path config.validate(vdt, copy=True) config.initial_comment = ('This is generated config_attrs with defaults', @@ -179,26 +224,29 @@ class ConfigManager: if __name__ == '__main__': cfg = ConfigManager() cfg.load_from_file('Drone/config/client.ini') - #print(cfg.config.comments) - #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.initial_comment, cfg.config.final_comment) - - # print(cfg.config) - # print(cfg.default_values) - # print(cfg.unchanged_defaults) - - # print(11111) + # cfg.load_config_and_spec('Drone/config/client.ini') + # #print(cfg.config.comments) + # #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.initial_comment, cfg.config.final_comment) + # + # # print(cfg.config) + # # print(cfg.default_values) + # # print(cfg.unchanged_defaults) + # + # # print(11111) import pprint pprint.pprint(cfg.full_dict) - #print(cfg.full_dict) - - #cfg.load_from_dict(cfg.full_dict, 'Drone/config/client.ini') - #print(cfg.config.initial_comment, cfg.config.final_comment) - #cfg.write() - + # #print(cfg.full_dict) + # + # #cfg.load_from_dict(cfg.full_dict, 'Drone/config/client.ini') + # #print(cfg.config.initial_comment, cfg.config.final_comment) + # #cfg.write() + #