From b527faf0864abc26c0ad16686dd53485f72f9af7 Mon Sep 17 00:00:00 2001 From: mistangl Date: Mon, 12 Feb 2024 17:19:42 +0100 Subject: [PATCH] =?UTF-8?q?Schalter=20-use=5Flocal=20dazu.=20Keine=20Daten?= =?UTF-8?q?bankabfrage=20vom=20Server,=20wenn=20die=20Dateien=20schon=20da?= =?UTF-8?q?=20sind.=20EInige=20Attribute=20im=20config=20manager=20privati?= =?UTF-8?q?siert.=20In=20die=20Logik=20auch=20die=20Abh=C3=A4ngigkeit=20de?= =?UTF-8?q?r=20comboboxen=20definiert.=20Controller=20ist=20jetzt=20ein=20?= =?UTF-8?q?Observer=20(der=20einzige)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 3 +- lib/CreoMigrateGui.py | 5 ++- lib/caditem.py | 71 +++++++++++++++++++++++++++++++++++- lib/controller.py | 26 ++++++++----- lib/get_teilestamm.py | 18 ++++++++- lib/manage_configs.py | 85 ++++++++++++++++++++++++------------------- 6 files changed, 157 insertions(+), 51 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a900aee..e8ba384 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -68,7 +68,8 @@ "console": "integratedTerminal", "justMyCode": true, "args": [ - "-s 400102196" + "-s 400102196", + "--uselocal", ], } ] diff --git a/lib/CreoMigrateGui.py b/lib/CreoMigrateGui.py index 60d1a9e..1743fa0 100644 --- a/lib/CreoMigrateGui.py +++ b/lib/CreoMigrateGui.py @@ -103,8 +103,9 @@ def build_gui(model, configs): if __name__ == '__main__': parser = argparse.ArgumentParser(description='Das Programm ermöglicht einw graphisch unterstützte Migration eines Teiles oder Assemblies von Creo nach SolidEdge. Erzeugt eine korrekte Impfdatei.', prog='CreoMigrateGui') - parser.add_argument('-s', '--sivasid', action='store', help='Eingabe der SIVAS-Teilenummer, für die der Migrationsstatus angezeigt werden soll', metavar="id") + parser.add_argument('-s', '--sivasid', action='store', help='Eingabe der SIVAS-Teilenummer, für die der Migrationsstatus angezeigt werden soll') parser.add_argument('-d', '--demo', action='store_true', help='arbeitet ohne Server. Lädt Testdaten ein um nur eine Oberfläche darzustellen') + parser.add_argument('-l', '--uselocal', action='store_true', help='Verbinde dich nicht zur Datenbank. Benutzer alle lokalen Dateien (falls vorhanden) für die gegebene asm-id') args = parser.parse_args() @@ -130,6 +131,8 @@ if __name__ == '__main__': else: # ansonsten sich die Einzelteile als .csv und den Aufbau des Assemblies als .json holen sivas_teilestamm = FetchSivasTeilestamm(sivasid, data_dir) + + sivas_teilestamm.fetch_from_db(args.uselocal) sivas_teilestamm.get_unmigrated_teilstamm_csvs() redids = sivas_teilestamm.get_red_ids() sad = SivasAssemblyData(data_dir, filename) diff --git a/lib/caditem.py b/lib/caditem.py index cf35063..6236d89 100644 --- a/lib/caditem.py +++ b/lib/caditem.py @@ -352,6 +352,12 @@ class CadItem(DataModel): else: self._logic.callback(key, value) + def get_dependent(self, key): + if self._logic == None: + raise Exception("no logic set") + else: + self._logic.get_dependent(key) + def set_gui_defaults(self): self._logic.set_gui_defaults() class CadItemRepository: @@ -473,7 +479,70 @@ class GuiLogic(): else: raise Exception("this callback does not exist "+key) return ret - + + def get_dependent(self, key): + """gibt die Namen der Callbacks zurück, welche nach dem Aufruf der ursprünglichen Methode wegen der Abhängigkeiten der Comboboxen anschliessend folgen sollen""" + + if key == 'cb_pdm_kategorie_neu': + ret = ['cb_neuaufbau', 'cb_aus_halbzeug_neu'] + elif key == 'cb_neuaufbau': + ret = [] + elif key == 'cb_aus_halbzeug_neu': + ret = [] + elif key == "cb_halbzeugoberflaeche": + ret = [] + elif key == "cb_halbzeugfarbe": + ret = [] + elif key == 'cb_lebenszyklus_status_neu': + ret = [] + elif key == 'cb_3Dmodel_neu': + ret = [] + elif key == 'cb_halbzeugOhneSaege_neu': + ret = [] + elif key == 'cb_ruestcode_neu': + ret = [] + elif key == 'cb_fertigungsart_neu': + ret = [] + elif key == 'cb_allgemeintoleranz_neu': + ret = [] + elif key == 'cb_fosGruppe_neu': + ret = [] + elif key == 'cb_kalkulationsart_neu': + ret = [] + elif key == 'cb_beschaffungsart_neu': + ret = [] + elif key == 'cb_mengeneinheit_neu': + ret = [] + elif key == 'cb_halbzeug_neu': + ret = [] + elif key == 'cb_dispogruppe_neu': + ret = [] + elif key == 'cb_dispolaufgruppe_neu': + ret = [] + elif key == 'cb_hersteller_neu': + ret = [] + elif key == 'cb_werkstoffdiskrepanz': + ret = [] + elif key == 'cb_werkstofftyp_neu': + ret = [] + elif key == 'cb_material_neu': + ret = [] + elif key == 'cb_oberflaeche_neu': + ret = [] + elif key == 'cb_farbe_neu': + ret = [] + elif key == 'cb_speichern': + ret = [] + elif key == 'cb_migrieren': + ret = [] + elif key == 'cb_zurücksetzen': + ret = [] + elif key == 'cb_suche_asm': + ret = [] + else: + raise Exception("this callback does not exist "+key) + return ret + def cb_pdm_kategorie_neu(self, selected): """setzt die Dropdownliste mit , Baugruppe, Einzelteil, Kaufteil, Schweissbaugruppe diff --git a/lib/controller.py b/lib/controller.py index 54f608c..e444e4e 100644 --- a/lib/controller.py +++ b/lib/controller.py @@ -32,20 +32,29 @@ messages = { # Der Beobachter class Observer: - def __init__(self, observable): + def __init__(self): + pass + + def attach(self, observable): observable.subscribe(self) def notify(self, observable, *args, **kwargs): print(f"Got {args} {kwargs} from {observable}") + dependent_cbs = self._model.get_dependent(args[0]) + for cb in dependent_cbs: + model_values = self._model.callback(cb, None) + if model_values: + self.set_gui_dict(model_values) + self.refresh_gui() -class Controller(): + +class Controller(Observer): """ Class for manipulating the model and returning data for the view """ def __init__(self, model, view): self._environment = None - self._observer = None self.set_model(model) self.set_view(view) @@ -69,8 +78,8 @@ class Controller(): def set_model(self, model): self._model = model - if self._observer == None: - self._observer = Observer(model) + self.attach(model) + def set_view(self, view): self._view = view @@ -157,15 +166,14 @@ class Controller(): if not self._model: raise Exception("no model yet added") - # gib dem observer Bescheid, was aufgerufen wurde - if self._observer: - self._observer.notify(key,value) - # Logik um neue Werte in Oberfläche oder Modell zu füllen model_values = self._model.callback(key, value) if model_values: self.set_gui_dict(model_values) self.refresh_gui() + + # gib dem observer Bescheid, was aufgerufen wurde + self.notify(self._model, key,value) # reine Aktionen if key == 'cb_speichern': diff --git a/lib/get_teilestamm.py b/lib/get_teilestamm.py index 42688e9..ddc3c3a 100644 --- a/lib/get_teilestamm.py +++ b/lib/get_teilestamm.py @@ -5,21 +5,34 @@ import update_database class FetchSivasTeilestamm: def __init__(self, assembly_json_name, assembly_json_out_dir=os.environ.get('CREMIG_DATA'), csv_out_dir=os.environ.get('CREMIG_DATA')): - self.migration = MigrationStatus(assembly_json_out_dir, str(assembly_json_name).replace('.json', "") + ".json") + self.assembly_json_out_dir = assembly_json_out_dir + self.assembly_json_name = str(assembly_json_name).replace('.json', "") + ".json" self.csv_out_dir = csv_out_dir + self.migration = None + + def fetch_from_db(self, use_local=False): + self.migration = MigrationStatus(self.assembly_json_out_dir, self.assembly_json_name) + if use_local: + self.migration.use_local() def get_unmigrated_teilstamm_csvs(self): """Generiert CSV-Dateien für alle noch nicht migrierten Stücklistenteile der angegebenen Baugruppennummer""" + if self.migration == None: + raise Exception("not yet connected to local data or database") unmigrated_ids = self.migration.get_unmigrated_ids() update_database.get_sivas_teilestamm(unmigrated_ids, self.csv_out_dir) def get_red_ids(self): + if self.migration == None: + raise Exception("not yet connected to local data or database") return self.migration.get_unmigrated_ids() if __name__ == '__main__': parser = argparse.ArgumentParser(description='fetches data from sivas or ruledesigner fusion', prog='update_database') parser.add_argument('-s', '--sivasid', action='store', help='fetch teilestamm-data for all unmigrated parts in the bom of a given asm-id. Specifiy multiple ids as comma separated values without space, e.g. 200000089,200000090', metavar='id(s)') + parser.add_argument('-l', '--uselocal', action='store_true', help='Do not connect to database. Use local files (if already existing) for the given asm-id') + args = parser.parse_args() out_dir = os.environ.get('CREMIG_DATA') @@ -27,6 +40,9 @@ if __name__ == '__main__': if args.sivasid: sivas_asm_id = args.sivasid.strip().replace(".json","") sivas_teilestamm = FetchSivasTeilestamm(sivas_asm_id, out_dir) + if args.uselocal: + sivas_teilestamm.use_local(args.uselocal) + sivas_teilestamm.fetch_from_db() sivas_teilestamm.get_unmigrated_teilstamm_csvs() else: diff --git a/lib/manage_configs.py b/lib/manage_configs.py index 37c7ee5..a824c0a 100644 --- a/lib/manage_configs.py +++ b/lib/manage_configs.py @@ -12,11 +12,11 @@ class JsonBasedConfig: """Klasse mit generellen Methoden für alle Config Objekte mit json files""" def __init__(self, config_dir, config_file): """merke dir den Pfad zu den Configdateien""" - self.config_path = os.path.join(config_dir, config_file) + self._config_path = os.path.join(config_dir, config_file) def load_json_from_file(self): """lade das json file vom gegeben Pfad in ein json Objekt""" - with open(self.config_path, 'r', encoding='utf-8') as fh: + with open(self._config_path, 'r', encoding='utf-8') as fh: return json.loads(fh.read()) def from_json(self, json_str): @@ -28,11 +28,11 @@ class CSVBasedConfig: def __init__(self, config_dir, config_file): """merke dir den Pfad zu den Configdateien""" - self.config_path = os.path.join(config_dir, config_file) + self._config_path = os.path.join(config_dir, config_file) def load_csv_from_file(self): """lade die csv aus dem angegebenen Dateipfad in ein Dataframe""" - return pd.read_csv(self.config_path, sep=";", dtype="object") + return pd.read_csv(self._config_path, sep=";", dtype="object") class SivasAssemblyData(JsonBasedConfig): @@ -135,16 +135,25 @@ class RuleDesignerDatabaseConfig(CSVBasedConfig): class MigrationStatus: def __init__(self, file_dir, assembly_json): - self.file_dir = file_dir - self.assembly_json = assembly_json.replace(".json", "") - self.sivas_assembly_data = SivasAssemblyData(file_dir, assembly_json) - self.ruledesigner_data = RuleDesignerDatabaseConfig(file_dir) + self._file_dir = file_dir + self._assembly_json = assembly_json + self._uselocal = False + def use_local(self): + self._uselocal = True + def get_migration_status(self) -> dict: """Gibt zurück, ob die Teilenummern der Baugruppe bereits migriert wurden, oder nicht""" - update_database.get_sivas_dbase(sivas_id=self.assembly_json, out_dir=self.file_dir) - update_database.get_rd_dbase() + out_dir = self._file_dir + if self._uselocal == False: + update_database.get_sivas_dbase(self._assembly_json, out_dir) + update_database.get_rd_dbase() + else: + if not os.path.exists(os.path.join(out_dir, self._assembly_json)): + raise Exception("no local file exists "+ self._assembly_json) + self.sivas_assembly_data = SivasAssemblyData(out_dir, self._assembly_json) sivas_assembly_ids = self.sivas_assembly_data.get_assembly_ids() + self.ruledesigner_data = RuleDesignerDatabaseConfig(out_dir) ruledesigner_ids = self.ruledesigner_data.get_ruledesigner_ids() migration_status = {} @@ -219,28 +228,28 @@ class MaterialTransConfig(JsonBasedConfig): """Auslesen der Config zu allen Materialangaben""" def __init__(self, config_dir='.', config_file='Materialübersetzung.json'): - self.materials = None + self._materials = None super().__init__(config_dir, config_file) def from_json(self, json_str): """lade den Json String zur Initialisierung des Objektes""" - self.materials = super().from_json(json_str) + self._materials = super().from_json(json_str) def get_all_materials(self): """hole alle Materialien, welche in der config Datei definiert sind""" - if not self.materials: - self.materials = super().load_json_from_file() + if not self._materials: + self._materials = super().load_json_from_file() ret = list() - for k in self.materials.keys(): + for k in self._materials.keys(): ret.append(k) return ret def get_material_of_type(self, mat): """hole alle Materialien, welche in der config Datei definiert sind""" - if not self.materials: + if not self._materials: self.load_materials() - return self.materials[mat] + return self._materials[mat] @@ -251,39 +260,39 @@ class IniBasedConfig: self.config_path = os.path.join(config_dir, config_file) if not os.path.exists(self.config_path): raise Exception("path does not exist") - self.isInitalized = False - self.config = ConfigParser(allow_no_value=True) - self.config.optionxform = lambda option: option # preserve case for letters + self._isInitalized = False + self._config = ConfigParser(allow_no_value=True) + self._config.optionxform = lambda option: option # preserve case for letters def from_cfg_str(self, cfg_str): """nimm den config String zur Initialisierung des Objektes""" - self.config.read_string(cfg_str) - self.isInitalized = True + self._config.read_string(cfg_str) + self._isInitalized = True def load_cfg_from_file(self): """lade das config file vom gegeben Pfad""" - self.config.read(self.config_path, encoding='utf-8') - self.isInitalized = True + self._config.read(self.config_path, encoding='utf-8') + self._isInitalized = True def get_section_options(self, section_name): - if not self.isInitalized: + if not self._isInitalized: self.load_cfg_from_file() - return self.config.options(section_name) + return self._config.options(section_name) def sections(self): - if not self.isInitalized: + if not self._isInitalized: self.load_cfg_from_file() - return self.config.sections() + return self._config.sections() def get_int(self, section_name, option): - if not self.isInitalized: + if not self._isInitalized: self.load_cfg_from_file() - return self.config.getint(section_name, option) + return self._config.getint(section_name, option) def get_dict(self, section_name): - if not self.isInitalized: + if not self._isInitalized: self.load_cfg_from_file() - return dict(self.config.items(section_name)) + return dict(self._config.items(section_name)) class AllgemeinConfig(IniBasedConfig): """Auslesen der Config für alle allgemeinen Angaben""" @@ -429,7 +438,7 @@ class PfadConfig(IniBasedConfig): class Configs: """Sammlung aller Configdateien """ def __init__(self, cfg_dir): - self.cfg_dir = cfg_dir + self._cfg_dir = cfg_dir self.Allgemein = AllgemeinConfig(cfg_dir) self.Bezeichner = BezeichnerConfig(cfg_dir) self.Farben = FarbenConfig(cfg_dir) @@ -442,16 +451,16 @@ class Configs: self.TOSGruppen = TOSGroupsConfig(cfg_dir) self.Materialien = MaterialTransConfig(cfg_dir) - self.env = None + self._env = None def get_cfg_path(self): - return self.cfg_dir + return self._cfg_dir def set_env(self, env): - self.env = env + self._env = env def get_env(self): - if self.env: - return self.env + if self._env: + return self._env return None