From bb8e07abf4ab9eb6221a05af743bbd68187cbfc6 Mon Sep 17 00:00:00 2001 From: Capocchi L Date: Sun, 8 Nov 2020 15:10:17 +0100 Subject: [PATCH 1/3] bug fix for instanciation of model buld before the rename method implementation --- Mixins/Savable.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Mixins/Savable.py b/Mixins/Savable.py index d8bddebd..25f787d4 100644 --- a/Mixins/Savable.py +++ b/Mixins/Savable.py @@ -272,14 +272,6 @@ def Load(self, obj_loaded, fileName = None): import wx L.insert(6, [FONT_SIZE, 74, 93, 700, 'Arial']) - - ### label_pos checking - if len(obj_loaded.dump_attributes) != len(L): - - ### 'label_pos' attribut is on rank 6 and its defautl value is "middle" - j = 6 if fileName.endswith(DumpZipFile.ext[-1]) else 4 - L.insert(j, 'middle') - #======================================================================= ### abstraction hierarchy checking @@ -287,7 +279,19 @@ def Load(self, obj_loaded, fileName = None): obj_loaded.dump_attributes += Abstractable.DUMP_ATTR #======================================================================= - assert(len(L)==len(obj_loaded.dump_attributes)) + + ### for amd and cmd build after the implementation of the rename method of model in libratie + ### This may present an opportunity for the delete of the model_path and python_path of the .amd or .cmd compressed file. + if abs(len(L)-len(obj_loaded.dump_attributes))==2: + L=L[2:] + assert(len(L)==len(obj_loaded.dump_attributes)) + + ### for position_label checking (for very old version of .amd or .cmd model) + elif abs(len(obj_loaded.dump_attributes)-len(L)) == 1: + + ### 'label_pos' attribut is on rank 6 and its defautl value is "middle" + j = 6 if fileName.endswith(DumpZipFile.ext[-1]) else 4 + L.insert(j, 'middle') try: ### assign dumped attributs @@ -307,9 +311,12 @@ def Load(self, obj_loaded, fileName = None): sys.stderr.write(_("Problem loading (old model): %s -- %s \n")%(str(fileName), str(tb))) return info + obj_loaded.model_path = fileName + obj_loaded.python_path = os.path.join(fileName, os.path.basename(fileName).replace('.cmd','.py').replace('.amd','.py')) + ### if the model was made from another pc #if not os.path.exists(obj_loaded.model_path): - obj_loaded.model_path = fileName + # obj_loaded.model_path = fileName #with zipfile.ZipFile(fileName) as zf: # ### find all python files @@ -323,7 +330,7 @@ def Load(self, obj_loaded, fileName = None): ### ?: for exclude or non-capturing rule #obj_loaded.python_path = os.path.join(obj_loaded.model_path, re.findall(".*(?:.[a|c]md)+[/|\\\](.*.py)*", obj_loaded.python_path)[-1]) - obj_loaded.python_path = os.path.join(fileName,os.path.basename(fileName).replace('.cmd','.py').replace('.amd','.py')) + #obj_loaded.python_path = os.path.join(fileName,os.path.basename(fileName).replace('.cmd','.py').replace('.amd','.py')) return True From 4b1a66597804e7a8fbc857d94d597223daeb46fe Mon Sep 17 00:00:00 2001 From: Capocchi L Date: Sun, 8 Nov 2020 18:41:23 +0100 Subject: [PATCH 2/3] bug fix on LibraryTree for pyc and refactoring to reduce nesting --- Components.py | 26 ++--- LibraryTree.py | 267 ++++++++++++++++++++++++------------------------- 2 files changed, 146 insertions(+), 147 deletions(-) diff --git a/Components.py b/Components.py index 4bd0cf9f..9c0217d3 100644 --- a/Components.py +++ b/Components.py @@ -853,19 +853,19 @@ def GetModule(filename): module_name = os.path.basename(filename).split('.py')[0] # find and load module - #try: - name, ext = os.path.splitext(module_name) - pkg = '.'.join(module_name.split('.')[0:-1]) - module = importlib.import_module(name, package=pkg) - - #f, fn, description = imp.find_module(module_name, [dir_name]) - #module = imp.load_module(module_name, f, fn, description) - #f.close() - return module - - #except Exception as info: - # sys.stderr.write(_("Module %s not imported from %s!\n"%(module_name,dir_name))) - # return sys.exc_info() + try: + name, ext = os.path.splitext(module_name) + pkg = '.'.join(module_name.split('.')[0:-1]) + module = importlib.import_module(name, package=pkg) + + #f, fn, description = imp.find_module(module_name, [dir_name]) + #module = imp.load_module(module_name, f, fn, description) + #f.close() + return module + + except Exception as info: + sys.stderr.write(_("Module %s not imported from %s!\n"%(module_name,dir_name))) + return sys.exc_info() @staticmethod def GetBlock(filename, label): diff --git a/LibraryTree.py b/LibraryTree.py index a18416ff..cc34cd45 100644 --- a/LibraryTree.py +++ b/LibraryTree.py @@ -155,7 +155,7 @@ def Populate(self, chargedDomainList = []): #threading.Thread(target=self.InsertNewDomain, #args=(absdName, self.root, list(self.GetSubDomain(absdName, self.GetDomainList(absdName)).values())[0],) #).start() - + self.InsertNewDomain(absdName, self.root, list(self.GetSubDomain(absdName, self.GetDomainList(absdName)).values())[0]) wx.CallAfter(self.SortChildren,self.root) @@ -441,9 +441,19 @@ def GetPYFileList(dName, ext=".py"): try: name_list = getPYFileListFromInit(os.path.join(dName,'__init__.py'), ext) + except Exception as info: py_file_list = [] + # if dName contains a python file, __init__.py is forced + if os.path.isdir(dName): + for f in os.listdir(dName): + if f.endswith(ext): + sys.stderr.write(_("Exception, %s not imported: %s \n"%(dName,info))) + break + else: + + py_file_list = [] + for s in name_list: - for s in list(name_list): python_file = os.path.join(dName, s+ext) ### test if tmp is only composed by python file (case of the user write into the __init__.py file directory name is possible ! then we delete the directory names) @@ -464,15 +474,6 @@ def GetPYFileList(dName, ext=".py"): else: py_file_list.append(s) - except Exception as info: - py_file_list = [] - # if dName contains a python file, __init__.py is forced - if os.path.isdir(dName): - for f in os.listdir(dName): - if f.endswith(ext): - sys.stderr.write(_("Exception, %s not imported: %s \n"%(dName,info))) - break - return py_file_list ### @@ -574,7 +575,7 @@ def AddComponent(self, item, parentPath, parent, p=None): img = self.not_importedidx if error else self.pythoncfileidx if ispyc else self.pythonfileidx ### insert in the tree - id = self.InsertItemBefore(parent, 0, item, img, img) + id = self.InsertItemBefore(p if p else parent, 0, item, img, img) #mcc = float(subprocess.check_output('python {} {}'.format('Complexity.py', path), shell = True)) mcc = GetMacCabeMetric(path) @@ -603,118 +604,117 @@ def InsertNewDomain(self, dName, parent, L = []): self.SetPyData(id,dName) ### end - if L == []: - return - else: - item = L.pop(0) + if L == []: return + + item = L.pop(0) - isstr = isinstance(item, str) - isdict = isinstance(item, dict) + isstr = isinstance(item, str) + isdict = isinstance(item, dict) - ### element to insert in the list - D = [] + ### element to insert in the list + D = [] - ### if child is build from DEVSimPy - if isstr: - ### parent is retrieved from dict - parent = self.ItemDico[dName] - assert parent != None - - ### parent path - parentPath = self.GetPyData(parent) + ### if child is build from DEVSimPy + if isstr: + ### parent is retrieved from dict + parent = self.ItemDico[dName] + assert parent != None - ### comma replace - item = item.strip() + ### parent path + parentPath = self.GetPyData(parent) - ### only for atomic or coupled model (atomic model is readed from __init__, so no extention) - id, error = self.AddComponent(item, parentPath, parent) + ### comma replace + item = item.strip() - ### error info back propagation - if error: - while(parent): - self.SetItemImage(parent, self.not_importedidx, wx.TreeItemIcon_Normal) - ### next parent item - parent = self.GetItemParent(parent) + ### only for atomic or coupled model (atomic model is readed from __init__, so no extention) + id, error = self.AddComponent(item, parentPath, parent) - ### insertion des donnees dans l'item et gestion du ItemDico - self.ItemDico.update({os.path.join(parentPath,item):id}) + ### error info back propagation + if error: + while(parent): + self.SetItemImage(parent, self.not_importedidx, wx.TreeItemIcon_Normal) + ### next parent item + parent = self.GetItemParent(parent) - ### si le fils est un sous repertoire contenant au moins un fichier (all dans __init__.py different de []) - elif isdict and list(item.values()) != [[]]: + ### insertion des donnees dans l'item et gestion du ItemDico + self.ItemDico.update({os.path.join(parentPath,item):id}) - parentPath = list(item.keys())[0] + ### si le fils est un sous repertoire contenant au moins un fichier (all dans __init__.py different de []) + elif isdict and list(item.values()) != [[]]: - ### name to insert in the tree - dName = os.path.basename(parentPath) + parentPath = list(item.keys())[0] - ### new parent - parent = self.ItemDico[os.path.dirname(parentPath)] if not dName.startswith('http') else self.ItemDico[parentPath.replace('/'+dName,'')] + ### name to insert in the tree + dName = os.path.basename(parentPath) - assert(parent!=None) + ### new parent + parent = self.ItemDico[os.path.dirname(parentPath)] if not dName.startswith('http') else self.ItemDico[parentPath.replace('/'+dName,'')] - ### insert of the fName above the parent - id = self.InsertItemBefore(parent, 0, dName) - - self.SetItemBold(id) - self.SetItemImage(id, self.fldridx, wx.TreeItemIcon_Normal) - self.SetItemImage(id, self.fldropenidx, wx.TreeItemIcon_Expanded) - - ### stockage du parent avec pour cle le chemin complet avec extention (pour l'import du moule dans le Dnd) - self.ItemDico.update({parentPath:id}) - self.SetPyData(id,parentPath) - - self.MetricDico.update({id:{'mcc':0.0, 'parent':parent}}) - self.MetricDico.update({parent:{'mcc':0.0, 'parent':None}}) - - ### for the childrens of the sub-domain - for elem in list(item.values())[0]: - # if simple element (coupled or atomic model) - if isinstance(elem, str): - ### replace the spaces - elem = elem.strip() #replace(' ','') - - ### transiant parent - p = self.ItemDico[parentPath] - assert(p!=None) - - id, error = self.AddComponent(elem, parentPath, parent, p) - - ### error info back propagation - if error: - ### insert error to the doc field - while(p): - self.SetItemImage(p, self.not_importedidx, wx.TreeItemIcon_Normal) - ### next parent item - p = self.GetItemParent(p) - - self.ItemDico.update({os.path.join(parentPath, elem):id}) + assert(parent!=None) - else: - ### in order to go up the information in the list - D.append(elem) + ### insert of the fName above the parent + id = self.InsertItemBefore(parent, 0, dName) + + self.SetItemBold(id) + self.SetItemImage(id, self.fldridx, wx.TreeItemIcon_Normal) + self.SetItemImage(id, self.fldropenidx, wx.TreeItemIcon_Expanded) - ### update with whole name - dName = parentPath + ### stockage du parent avec pour cle le chemin complet avec extention (pour l'import du moule dans le Dnd) + self.ItemDico.update({parentPath:id}) + self.SetPyData(id,parentPath) - ### for spash screen - try: - ### format the string depending the nature of the item - info = " ".join([os.path.basename(parentPath), 'from', os.path.basename(os.path.dirname(parentPath))]) if isdict \ - else " ".join([item, 'from', os.path.basename(dName)]) - pub.sendMessage('object.added', message='Loading %s domain...'%info) - except: - pass + self.MetricDico.update({id:{'mcc':0.0, 'parent':parent}}) + self.MetricDico.update({parent:{'mcc':0.0, 'parent':None}}) - ### managment of the recursion - if D: - self.InsertNewDomain(dName, parent, D) - - try: - self.SortChildren(parent) - except: - pass + ### for the childrens of the sub-domain + for elem in list(item.values())[0]: + # if simple element (coupled or atomic model) + if isinstance(elem, str): + ### replace the spaces + elem = elem.strip() #replace(' ','') - return self.InsertNewDomain(dName, parent, L) + ### transiant parent + p = self.ItemDico[parentPath] + assert(p!=None) + + id, error = self.AddComponent(elem, parentPath, parent, p) + + ### error info back propagation + if error: + ### insert error to the doc field + while(p): + self.SetItemImage(p, self.not_importedidx, wx.TreeItemIcon_Normal) + ### next parent item + p = self.GetItemParent(p) + + self.ItemDico.update({os.path.join(parentPath, elem):id}) + + else: + ### in order to go up the information in the list + D.append(elem) + print(self.ItemDico) + ### update with whole name + dName = parentPath + + ### for spash screen + try: + ### format the string depending the nature of the item + info = " ".join([os.path.basename(parentPath), 'from', os.path.basename(os.path.dirname(parentPath))]) if isdict \ + else " ".join([item, 'from', os.path.basename(dName)]) + pub.sendMessage('object.added', message='Loading %s domain...'%info) + except: + pass + + ### managment of the recursion + if D: + self.InsertNewDomain(dName, parent, D) + + try: + self.SortChildren(parent) + except: + pass + + return self.InsertNewDomain(dName, parent, L) ### def GetSubDomain(self, dName, domainSubList = []): @@ -723,18 +723,17 @@ def GetSubDomain(self, dName, domainSubList = []): ) """ + ### on comptabilise les fichiers si il y en a dans le rep courant (la recusion s'occupe des sous domaines) + D = {dName: self.GetModelList(dName)} + if domainSubList == []: ### attention il faut que le fichier __init__.py respecte une certain ecriture - return {dName:self.GetModelList(dName)} - else: - - ### on comptabilise les fichiers si il y en a dans le rep courant (la recusion s'occupe des sous domaines) - D = {dName: self.GetModelList(dName)} - ### on lance la recursion sur les repertoires fils - for d in domainSubList: - p = os.path.join(dName, d) - D[dName].append(self.GetSubDomain(p, self.GetDomainList(p))) return D + + ### on lance la recursion sur les repertoires fils + D[dName].extend([self.GetSubDomain(os.path.join(dName, d), self.GetDomainList(os.path.join(dName, d))) for d in domainSubList]) + + return D ### def GetChildRoot(self): @@ -809,27 +808,28 @@ def CheckItem(self, path): ### def UpdateDomain(self, path): - """ Update the Tree Library with new path of the corresponding domain + """ Update the Tree Library with new path of the corresponding domain. """ + bn = os.path.basename(path) + dl = self.GetDomainList(path) + ### only of the path is in the tree - if self.HasString(os.path.basename(path)): - dName = path + if self.HasString(bn): ### try to find focused item from dName try: - item = self.ItemDico[dName] + item = self.ItemDico[path] ### if dName is not present in ItemDico but exist and represent the same directory, we find the path strored in ItemDico except KeyError: - for p in self.ItemDico: - if p.endswith(os.path.basename(dName)): - item = self.ItemDico[p] + for p in [a for a in self.ItemDico if a.endswith(bn)]: + item = self.ItemDico[p] ### save parent before deleting item parent = self.GetItemParent(item) ### save expanded info before deleting item - L = [dName] if self.IsExpanded(item) else [] + L = [path] if self.IsExpanded(item) else [] for k,v in list(self.ItemDico.items()): if self.IsExpanded(v): L.append(k) @@ -837,18 +837,17 @@ def UpdateDomain(self, path): ### remove for create udpated new item self.RemoveItem(item) + LL = list(self.GetSubDomain(path, dl).values())[0] + ### insertion du nouveau domain - self.InsertNewDomain(dName, parent, list(self.GetSubDomain(dName, self.GetDomainList(dName)).values())[0]) + self.InsertNewDomain(path, parent, LL) ### module checking - for d in list(self.GetSubDomain(dName, self.GetDomainList(dName)).values())[0]: - if isinstance(d, dict): - name_list = list(d.values())[0] - if name_list: - for name in [a for a in name_list if not isinstance(a, dict)]: - path = list(d.keys())[0] - if not name.endswith(('.cmd','.amd')): - self.CheckItem(os.path.join(path, name)) + for d in [ a for a in LL if isinstance(a, dict)]: + name_list = list(d.values())[0] + if name_list: + for name in [a for a in name_list if not isinstance(a, dict) and not a.endswith(('.cmd','.amd'))]: + self.CheckItem(os.path.join(list(d.keys())[0], name)) ### restor expanded item for item in [self.ItemDico[name] for name in L]: @@ -913,7 +912,7 @@ def UpdateAll(self): # return thread.finish() def OnCompareItems(self, item1, item2): - """ overriden method OnCompareItems used by sortChildren + """ Overriden method OnCompareItems used by sortChildren. """ if LibraryTree.COMPARE_BY_MACABE_METRIC: @@ -933,7 +932,7 @@ def OnCompareItems(self, item1, item2): ### def RemoveItem(self, item): - """ Remove item from Tree and also the corresponding elements of ItemDico + """ Remove item from Tree and also the corresponding elements of ItemDico. """ ### delete all references from the ItemDico From 1725aca80097f811e8c6b67282c67c2ccc66471b Mon Sep 17 00:00:00 2001 From: Capocchi L Date: Sun, 8 Nov 2020 21:33:41 +0100 Subject: [PATCH 3/3] some docstrings --- Container.py | 12 ++- DetachedFrame.py | 16 +++- DiagramConstantsDialog.py | 52 +++++++++--- ImportLibrary.py | 166 ++++++++++++++++++++------------------ LibraryTree.py | 44 +++++++--- Menu.py | 53 ++++++++++-- Mixins/Savable.py | 44 ++++++---- ZipManager.py | 48 +++++++---- 8 files changed, 294 insertions(+), 141 deletions(-) diff --git a/Container.py b/Container.py index b1a30384..34410adc 100644 --- a/Container.py +++ b/Container.py @@ -20,8 +20,6 @@ # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## - - import builtins if builtins.__dict__.get('GUI_FLAG',True): @@ -58,6 +56,7 @@ import types import array +from abc import ABC from tempfile import gettempdir from traceback import format_exception from math import * ### for eval @@ -123,7 +122,6 @@ # # ############################################################## - def MsgBoxError(event, parent, msg): """ Pop-up alert for error in the .py file of a model """ @@ -579,13 +577,19 @@ def makeDEVSInstance(diagram = None): return diagram.getDEVSModel() def SetParent(self, parent): + """ + """ assert isinstance(parent, ShapeCanvas) self.parent = parent def GetParent(self): + """ + """ return self.parent def GetGrandParent(self): + """ + """ return self.GetParent().GetParent() @BuzyCursorNotification @@ -1144,7 +1148,7 @@ def GetName(self): return os.path.basename(self.last_name_saved) # Generic Shape Event Handler--------------------------------------------------- -class ShapeEvtHandler: +class ShapeEvtHandler(ABC): """ Handler class """ diff --git a/DetachedFrame.py b/DetachedFrame.py index e8e4d399..660de9ad 100644 --- a/DetachedFrame.py +++ b/DetachedFrame.py @@ -38,9 +38,14 @@ import Container import Menu - import PrintOut +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class DetachedFrame(wx.Frame, PrintOut.Printable): """ Detached Frame including a diagram. """ @@ -288,12 +293,19 @@ def OnClose(self, event): event.Skip() -### ------------------------------------------------------------ +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# MAIN PROGRAM +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class TestApp(wx.App): """ Testing application """ def OnInit(self): + """ Init the user interface. + """ import gettext diff --git a/DiagramConstantsDialog.py b/DiagramConstantsDialog.py index 39663c04..1ba84b42 100644 --- a/DiagramConstantsDialog.py +++ b/DiagramConstantsDialog.py @@ -1,11 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# DiagramConstantsDialog.py --- Dialog to define constantes in a diagram. +# -------------------------------- +# Copyright (c) 2020 +# L. CAPOCCHI (capocchi@univ-corse.fr) +# SPE Lab - SISU Group - University of Corsica +# -------------------------------- +# Version 1.0 last modified: 08/11/20 +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GENERAL NOTES AND REMARKS: +# +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + import wx import os import builtins import csv import DSV +import gettext ID_IMPORT = wx.NewIdRef() ID_EXPORT = wx.NewIdRef() @@ -13,12 +29,20 @@ ID_REMOVE = wx.NewIdRef() ID_HELP = wx.NewIdRef() -import gettext _ = gettext.gettext -class DiagramConstantsDialog(wx.Dialog): +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +class DiagramConstantsDialog(wx.Dialog): + """ Dialogue to define constantes in a diagram. + """ def __init__(self, *args, **kw): + """ Constructor. + """ super(DiagramConstantsDialog, self).__init__(*args, **kw) ### local copy @@ -30,7 +54,7 @@ def __init__(self, *args, **kw): self.InitUI() def InitUI(self): - """ Init the user interface + """ Init the user interface. """ self.SetTitle(_("%s - Constants Manager")%(self.label)) @@ -115,7 +139,7 @@ def __set_events(self): self.Bind(wx.EVT_BUTTON, self.OnCancel, self._button_cancel) def Populate(self, data): - """ Populate the grid from a dictionary data + """ Populate the grid from a dictionary data. """ ### populate the grid @@ -127,12 +151,12 @@ def Populate(self, data): self._grid.SetCellValue(i, 1, str(data[key])) def OnAdd(self,evt): - """ Add line + """ Add line. """ self._grid.AppendRows() def OnRemove(self, evt): - """ Delete selected lines + """ Delete selected lines. """ ### only if the grid has rows @@ -153,7 +177,7 @@ def OnRemove(self, evt): self._grid.DeleteRows(row) def OnImport(self, event): - """ csv file importing + """ csv file importing. """ dlg = wx.FileDialog(self, _("Choose a file"), os.getenv('USERPROFILE') or os.getenv('HOME') or HOME_PATH, "", @@ -197,7 +221,7 @@ def logErrors(oldrow, newrow, expectedColumns, maxColumns, file = errorLog): dlg.Destroy() def OnExport(self,evt): - """ csv file exporting + """ csv file exporting. """ wcd = _("CSV files (*.csv)|*.csv|Text files (*.txt)|*.txt|All files (*.*)|*.*") @@ -241,19 +265,27 @@ def OnOk(self,evt): evt.Skip() def GetData(self): - """ Return the constants stored in the grid as a dictionnary + """ Return the constants stored in the grid as a dictionnary. """ return self.data def OnCancel(self,evt): - """ Close dialog + """ Close dialog. """ self.Destroy() def OnHelp(self, event): + """ Help message dialogue. + """ dial = wx.MessageDialog(self, _("In order to use constante:\n\nCall constante by using \"Name of Diagram\"[\'Name of constante\']\n"), _('Help Manager'), wx.OK|wx.ICON_INFORMATION) dial.ShowModal() +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# MAIN PROGRAM +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + ### ------------------------------------------------------------ class TestApp(wx.App): """ Testing application diff --git a/ImportLibrary.py b/ImportLibrary.py index a66ce55e..957a0a9b 100644 --- a/ImportLibrary.py +++ b/ImportLibrary.py @@ -15,15 +15,8 @@ # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## -## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## -# -# GLOBAL VARIABLES AND FUNCTIONS -# -## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## - ### at the beginning to prevent with statement for python vetrsion <=2.5 - import os import sys import shutil @@ -35,11 +28,27 @@ import wx.lib.dialogs from concurrent.futures import ThreadPoolExecutor -from Utilities import checkURL, getDirectorySize, RecurseSubDirs, getPYFileListFromInit +from Utilities import checkURL, getDirectorySize, RecurseSubDirs, getPYFileListFromInit, NotificationMessage from Decorators import BuzyCursorNotification +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GLOBAL VARIABLES AND FUNCTIONS +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): + """ + """ def __init__(self, *args, **kw): + """ Constructor. + """ wx.ListCtrl.__init__(self, *args, **kw) ListCtrlAutoWidthMixin.__init__(self) @@ -80,7 +89,7 @@ def __init__(self, *args, **kw): # self.CheckItem(index, False) def AddItem(self, path, dName, check=False): - """ Add item to the list + """ Add item to the list. """ index = self.InsertStringItem(100000000, dName) @@ -89,7 +98,6 @@ def AddItem(self, path, dName, check=False): self.SetStringItem(index, 3, "..%s%s"%(os.sep,os.path.basename(DOMAIN_PATH) if path.startswith(DOMAIN_PATH) else path)) self.CheckItem(index, check) - self.SetData(index, path) self.SetItemData(index, index) @@ -101,7 +109,7 @@ def SetData(self, id, data): @BuzyCursorNotification def Populate(self, D={}): - """ Populate the list + """ Populate the list. """ for path, dName in D.items(): self.AddItem(path, dName) @@ -109,6 +117,7 @@ def Populate(self, D={}): class DeleteBox(wx.Dialog): """ Delete box for libraries manager. """ + def __init__(self, *args, **kwargs): """ Constructor. """ @@ -118,6 +127,8 @@ def __init__(self, *args, **kwargs): self.SetSize((250, 200)) def InitUI(self): + """ Init the user interface. + """ pnl = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) @@ -172,7 +183,11 @@ def InitUI(self): #------------------------------------------------------------------- class ImportLibrary(wx.Dialog): + """ + """ def __init__(self, *args, **kwargs): + """ Constructor. + """ super(ImportLibrary, self).__init__(*args, **kwargs) ### local copy @@ -248,15 +263,13 @@ def __init__(self, *args, **kwargs): ### Buttons new = wx.Button(leftPanel, id = wx.ID_NEW, size=(120, -1)) - imp = wx.Button(leftPanel, wx.NewIdRef(), _('Import'), size=(120, -1)) sel = wx.Button(leftPanel, id = wx.ID_SELECTALL, size=(120, -1)) des = wx.Button(leftPanel, wx.NewIdRef(), _('Deselect All'), size=(120, -1)) apply = wx.Button(rightPanel, id=wx.ID_OK, size=(100, -1)) cancel = wx.Button(rightPanel, id=wx.ID_CANCEL, size=(100, -1)) vbox2.Add(new, 0, wx.TOP|wx.LEFT, 6) - vbox2.Add(imp, 0, wx.TOP|wx.LEFT, 6) - #vbox2.Add((-1, 5)) + vbox2.Add((-1, 5)) vbox2.Add(sel, 0, wx.TOP|wx.LEFT, 6) vbox2.Add(des, 0, wx.TOP|wx.LEFT, 6) @@ -279,7 +292,6 @@ def __init__(self, *args, **kwargs): ##Binding Events self.Bind(wx.EVT_BUTTON, self.OnNew, id = new.GetId()) - self.Bind(wx.EVT_BUTTON, self.OnAdd, id = imp.GetId()) self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id = sel.GetId()) self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id = des.GetId()) self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnItemRightClick) @@ -293,18 +305,25 @@ def __init__(self, *args, **kwargs): self.ProcessEvent(e) def CheckDomainPath(self): + """ + """ ABS_HOME_PATH = os.path.abspath(os.path.dirname(sys.argv[0])) if os.path.join(ABS_HOME_PATH, "Domain") != DOMAIN_PATH: - dlg = wx.MessageDialog(self, _("Local domain path is different from the .devsimpy.\nGo to options and preferences to change the domain path."), _('Import Manager'), wx.OK|wx.ICON_INFORMATION) + dlg = wx.MessageDialog(self, _("Local domain path is different from the .devsimpy.\n\ + Go to options and preferences to change the domain path."), _('Import Manager'), wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def OnSelectAll(self, event): + """ + """ num = self._cb.GetItemCount() for i in range(num): self._cb.CheckItem(i,True) def OnDeselectAll(self, event): + """ + """ num = self._cb.GetItemCount() for i in range(num): self._cb.CheckItem(i, False) @@ -377,7 +396,7 @@ def DocDirectory(self, path): return doc def OnDoc(self, evt): - """ documentation of item has been invocked + """ Documentation of item has been invocked. """ index = self._cb.GetFocusedItem() label = self._cb.GetItemText(index) @@ -432,6 +451,8 @@ def OnDelete(self, evt): self._cb.DeleteItem(index) def EvtCheckListBox(self, evt): + """ + """ index = self._cb.GetFocusedItem() label = self._cb.GetItemText(index) @@ -443,23 +464,17 @@ def EvtCheckListBox(self, evt): @staticmethod def CreateInitFile(path): - """ Static method to create the __init_.py file which contain the name of accessing models + """ Static method to create the __init_.py file which contain the name of accessing models. """ dial = wx.MessageDialog(None, _('If %s contain python files, do you want to insert it in __all__ variable of __init__.py file?')%os.path.basename(path), _('New file Manager'), wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION) - if dial.ShowModal() == wx.ID_YES: - ### if there is python file in the importing directory - L = [f for f in os.listdir(path) if f.endswith(".py")] - else: - L = [] + ### if there is python file in the importing directory + L = [f for f in os.listdir(path) if f.endswith(".py")] if dial.ShowModal() == wx.ID_YES else [] ### how many python file to insert on __init__.py file if L: dlg = wx.lib.dialogs.MultipleChoiceDialog(None, _('List of python file in %s')%(os.path.dirname(path)), _('Select the python files to insert in the __init__.py file'), L) - if dlg.ShowModal() == wx.ID_OK: - select = dlg.GetValueString() - else: - select = [] + select = dlg.GetValueString() if dlg.ShowModal() == wx.ID_OK else [] dlg.Destroy() else: select = [] @@ -474,24 +489,47 @@ def CreateInitFile(path): f.write('\t\t ]') def OnNew(self, event): - dlg1 = wx.TextEntryDialog(self, _('Enter new directory name'), _('New Library'), _("New_lib")) - if dlg1.ShowModal() == wx.ID_OK: - dName = dlg1.GetValue() - path = os.path.join(DOMAIN_PATH, dName) - if not os.path.exists(path): - os.makedirs(path) - f = open(os.path.join(path,'__init__.py'),'w') - f.write("__all__=[\n]") - f.close() - self.DoAdd(path, dName) + """ + """ + #dlg1 = wx.TextEntryDialog(self, _('Enter new directory name'), _('New Library'), _("New_lib")) + ### Get path to add + dialog = wx.DirDialog(self, _("Choose a new directory:"), DOMAIN_PATH, style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) + path = dialog.GetPath() if dialog.ShowModal() == wx.ID_OK else None + dialog.Destroy() + if path: + # Getting the list of directories + dir = os.listdir(path) + + # Checking if the list is empty or not + if len(dir) == 0: + if not '__init__.py' in dir: + self.CreateInitFile(path) + + self.DoAdd(path, os.path.basename(path)) + + ### selected directory exist, we import it else: - wx.MessageBox(_('Directory already exist.\nChoose another name.'), _('Information'), wx.OK | wx.ICON_INFORMATION) + dName = os.path.basename(path) if not path.startswith('http') else [a for a in path.split('/') if a!=''][-1] - dlg1.Destroy() + # si la lib n'est pas deja importee + #if (not self.parent.tree.IsChildRoot(dName), (dName not in self._d or (dName in self._d and self._d[dName] != path))) + if dName not in self._d or (dName in self._d and self._d[dName] != path): + ### import form local or web + if os.path.isdir(path) or checkURL(path): + self.DoAdd(path, dName) + ### error + else: + msg = _('%s is an invalid url')%path if path.startswith('http') else _('%s directory does not exist')%dName + dial = wx.MessageDialog(self, msg, _('New librarie manager'), wx.OK | wx.ICON_ERROR) + dial.ShowModal() + else: + dial = wx.MessageDialog(self, _('%s is already imported!')%dName, _('New librarie manager'), wx.OK|wx.ICON_INFORMATION) + dial.ShowModal() def DoAdd(self, path, dName): - + """ + """ ### ajout dans la liste box self._cb.AddItem(path, dName, True) @@ -504,56 +542,30 @@ def DoAdd(self, path, dName): self._d.update({dName:path}) ### create the __init__.py file if doesn't exist - if not path.startswith('http') and not os.path.exists(os.path.join(path,'__init__.py')): + if not path.startswith('http') and (not os.path.exists(os.path.join(path,'__init__.py') and len(os.listdir(path)) == 0)): dial = wx.MessageDialog(self, _('%s directory has no __init__.py file.\nDo you want to create it?')%path, _('New librarie Manager'), wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION) if dial.ShowModal() == wx.ID_YES: self.CreateInitFile(path) dial.Destroy() + + NotificationMessage(_('Information'), _("Librarie %s has been succeffully added!")%dName, self, timeout=5) + def OnAdd(self, evt): """ """ - - ### Get path to add - dialog = wx.DirDialog(self, "Choose a directory:",style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) - if dialog.ShowModal() == wx.ID_OK: - path = dialog.GetPath() - else: - path = None - dialog.Destroy() - - if path: - dName = os.path.basename(path) if not path.startswith('http') else [a for a in path.split('/') if a!=''][-1] - - # si la lib n'est pas deja importee - if not self.parent.tree.IsChildRoot(dName): - if dName not in self._d or (dName in self._d and self._d[dName] != path): - ### si importation a partir du local - if os.path.isdir(path): - self.DoAdd(path, dName) - ### si importation à partir du web - elif checkURL(path): - self.DoAdd(path, dName) - ### gestion de l'erreur - else: - if path.startswith('http'): - msg = _('%s is an invalid url')%path - else: - msg = _('%s directory does not exist')%dName - dial = wx.MessageDialog(self, msg, _('New librarie manager'), wx.OK | wx.ICON_ERROR) - dial.ShowModal() - else: - dial = wx.MessageDialog(self, _('%s is already imported!')%dName, _('New librarie manager'), wx.OK|wx.ICON_INFORMATION) - dial.ShowModal() - else: - dial = wx.MessageDialog(self, _('%s is already imported!')%dName, _('New librarie manager'), wx.OK|wx.ICON_INFORMATION) - dial.ShowModal() + self.OnNew(evt) def OnCloseWindow(self, event): self.Destroy() event.Skip() -### ------------------------------------------------------------ +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# MAIN PROGRAM +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class TestApp(wx.App): """ Testing application """ diff --git a/LibraryTree.py b/LibraryTree.py index cc34cd45..373a2091 100644 --- a/LibraryTree.py +++ b/LibraryTree.py @@ -14,12 +14,6 @@ # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## -## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## -# -# GLOBAL VARIABLES AND FUNCTIONS -# -## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## - import wx import os import sys @@ -47,7 +41,18 @@ _ = wx.GetTranslation -#---------------------------------------------------------------------------------------------------- +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GLOBAL VARIABLES AND FUNCTIONS +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class LibraryTree(wx.TreeCtrl): """ Class of libraries tree of DEVSimPy model and Python files. @@ -692,7 +697,7 @@ def InsertNewDomain(self, dName, parent, L = []): else: ### in order to go up the information in the list D.append(elem) - print(self.ItemDico) + ### update with whole name dName = parentPath @@ -934,10 +939,11 @@ def OnCompareItems(self, item1, item2): def RemoveItem(self, item): """ Remove item from Tree and also the corresponding elements of ItemDico. """ + bn = os.path.basename(self.GetPyData(item)) ### delete all references from the ItemDico for key in copy.copy(self.ItemDico): - if os.path.basename(self.GetPyData(item)) in key.split(os.sep): + if bn in key.split(os.sep): del self.ItemDico[key] self.Delete(item) @@ -1093,7 +1099,25 @@ def OnItemDocumentation(self, evt): dlg.CenterOnParent(wx.BOTH) dlg.ShowModal() else: - wx.MessageBox(_("No documentation! \n Please define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) + wx.MessageBox(_("No documentation!\n Please define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) + + ### + def OnLibDocumentation(self, evt): + """ Display the lib's documentation on miniFrame. + """ + + item = self.GetSelection() + path = self.GetItemPyData(item) + name = self.GetItemText(item) + + doc = "Path of lib: %s\n"%path + + if doc: + dlg = wx.lib.dialogs.ScrolledMessageDialog(self, doc, _("%s Documentation")%name, style=wx.OK|wx.ICON_EXCLAMATION|wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) + dlg.CenterOnParent(wx.BOTH) + dlg.ShowModal() + else: + wx.MessageBox(_("No documentation!\n Please define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) ### def OnInfo(self, event): diff --git a/Menu.py b/Menu.py index 57c7b36a..6a7c37f6 100644 --- a/Menu.py +++ b/Menu.py @@ -172,11 +172,17 @@ def AppendMenu(menu, ID, label, submenu): else: return menu.AppendSubMenu(submenu, label) +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFINITION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class TaskBarMenu(wx.Menu): """ """ def __init__(self, parent): - """ Constructor + """ Constructor. """ wx.Menu.__init__(self) @@ -187,6 +193,8 @@ class FileMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) openModel=wx.MenuItem(self, ID_OPEN, _('&Open\tCtrl+O'),_('Open an existing diagram')) @@ -249,6 +257,8 @@ class ProfileFileMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -271,6 +281,8 @@ class RecentFileMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -299,6 +311,8 @@ class ShowMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -329,7 +343,11 @@ def __init__(self, parent): parent.Bind(wx.EVT_MENU, parent.OnShowToolBar, id = ID_SHOW_TOOLBAR) class PerspectiveMenu(wx.Menu): + """ + """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -368,6 +386,8 @@ class DiagramMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -440,6 +460,8 @@ class SettingsMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constrcutor. + """ wx.Menu.__init__(self) languagesSubmenu = wx.Menu() @@ -481,6 +503,8 @@ class HelpMenu(wx.Menu): """ """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) parent = parent.GetParent() @@ -526,7 +550,11 @@ def __init__(self, parent): parent.Bind(wx.EVT_MENU, parent.OnContact, id=ID_CONTACT) class MainMenuBar(wx.MenuBar): + """ + """ def __init__(self, parent): + """ Constructor. + """ wx.MenuBar.__init__(self) self.parent = parent @@ -670,7 +698,7 @@ def __init__(self, parent): ### Bind is not necessary because ID_EXIT_DAIGRAM and ID_DETACH_DIAGRAM are already binded class PropertiesCtrlPopupMenu(wx.Menu): - """ PropertiesCtrl popup menu + """ PropertiesCtrl popup menu. """ def __init__(self, parent, row, col): @@ -685,6 +713,7 @@ def __init__(self, parent, row, col): edit = wx.MenuItem(self, ID_EDIT_ATTR, _('Edit'), _('Edit attribute')) insert = wx.MenuItem(self, ID_INSERT_ATTR, _('Insert'), _('Insert attribute')) clear = wx.MenuItem(self, ID_CLEAR_ATTR, _('Clear'), _('Clear value')) + edit.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16,'edit.png'))) insert.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16,'insert.png'))) clear.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16,'edit-clear.png'))) @@ -736,10 +765,15 @@ def __init__(self, parent): update_lib = wx.MenuItem(self, ID_UPDATE_SUBLIB, _('Update'), _('Update all models of the selected library')) update_lib.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16, 'db_refresh2.png'))) InsertItem(3, update_lib) + doc = wx.MenuItem(self, wx.NewIdRef(), _('Documentation'), _('Documentation of selected library')) + doc.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16,'doc.png'))) + InsertItem(4, doc) + self.Bind(wx.EVT_MENU, parent.OnNewModel, id=ID_NEW_MODEL_LIB) self.Bind(wx.EVT_MENU, parent.OnDirRename, id=ID_RENAME_DIR_LIB) self.Bind(wx.EVT_MENU, parent.OnNewDir, id=ID_NEW_DIR_LIB) self.Bind(wx.EVT_MENU, parent.OnUpdateSubLib, id=ID_UPDATE_SUBLIB) + self.Bind(wx.EVT_MENU, parent.OnLibDocumentation, id = doc.GetId()) # put before the popUpMenu else: @@ -776,8 +810,12 @@ def __init__(self, parent): class LibraryPopupMenu(wx.Menu): + """ Popup menu for panel library. + """ def __init__(self, parent): + """ Constructor. + """ wx.Menu.__init__(self) new = wx.MenuItem(self, ID_NEW_LIB, _('New/Import'), _('Create or import library')) @@ -805,12 +843,11 @@ def __init__(self, parent): self.Bind(wx.EVT_MENU, parent.OnUpdateAll, id=ID_REFRESH_LIB) class ShapeCanvasPopupMenu(wx.Menu): - """ ShapeCanvas menu class + """ ShapeCanvas menu class. """ def __init__(self, parent): """ Constructor. """ - wx.Menu.__init__(self) ### local copy @@ -865,6 +902,7 @@ def __init__(self, parent): parent.Bind(wx.EVT_MENU, parent.diagram.OnAddConstants, id=ID_ADD_CONSTANTS) parent.Bind(wx.EVT_MENU, parent.parent.PrintPreview, id=ID_PREVIEW_PRINT) parent.Bind(wx.EVT_MENU, ExperimentGenerator(os.path.join(HOME_PATH,'out')).OnExperiment, id=ID_GEN_EXPERIMENT) + class ShapePopupMenu(wx.Menu): """ Shape menu class """ @@ -996,10 +1034,10 @@ def __init__(self, shape, event): rotate_output_subMenu.AppendItem = rotate_output_subMenu.Append ### for port, just right of left rotation - if isinstance(shape, Container.Port): - + if isinstance(shape, Container.Port): Rotate_SubMenu1 = rotate_subMenu.AppendItem(rotateR) Rotate_SubMenu2 = rotate_subMenu.AppendItem(rotateL) + else: Rotate_SubMenu11 = rotate_all_subMenu.AppendItem(rotateR) Rotate_SubMenu12 = rotate_all_subMenu.AppendItem(rotateL) @@ -1023,6 +1061,7 @@ def __init__(self, shape, event): new_item = wx.MenuItem(connectable_subMenu, wx.NewIdRef(), item.label) connectable_subMenu.Append(new_item) self.__canvas.Bind(wx.EVT_MENU, self.__canvas.OnConnectTo,id = new_item.GetId()) + AppendMenu(self,-1, _('Connect to'), connectable_subMenu) if isinstance(shape, Container.CodeBlock): @@ -1112,4 +1151,6 @@ def __init__(self, shape, event): shape.OnDeleteNode(event) def GetParent(self): + """ Return the parent. + """ return self.__canvas \ No newline at end of file diff --git a/Mixins/Savable.py b/Mixins/Savable.py index 25f787d4..6c6174b2 100644 --- a/Mixins/Savable.py +++ b/Mixins/Savable.py @@ -1,15 +1,19 @@ # -*- coding: utf-8 -*- -""" -Name: Savable.py -Brief descritpion: -Author(s): L. Capocchi , A-T. Luciani -Version: 1.0 -Last modified: 2012.04.04 -GENERAL NOTES AND REMARKS: - -GLOBAL VARIABLES AND FUNCTIONS: -""" +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# Savable.py --- Class based on pickle module and dedicated to save and load components. +# -------------------------------- +# Copyright (c) 2020 +# L. CAPOCCHI (capocchi@univ-corse.fr) +# SPE Lab - SISU Group - University of Corsica +# -------------------------------- +# Version 1.0 last modified: 08/11/20 +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GENERAL NOTES AND REMARKS: +# +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## import os import sys @@ -61,6 +65,12 @@ import Components import ZipManager +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class PickledCollection(list): """ Custom list class for dsp attributes dumping. """ @@ -86,7 +96,7 @@ def __iter__(self): yield from self.pickled_obj class DumpBase(object): - """ DumpBase class + """ DumpBase class. """ ### list of available extension @@ -223,7 +233,7 @@ def Save(self, obj_dumped, fileName = None)->bool: return True def Load(self, obj_loaded, fileName = None): - """ Load codeblock (obj_loaded) from fileName + """ Load codeblock (obj_loaded) from fileName. """ # get zip file object @@ -513,7 +523,8 @@ class DumpJSFile(DumpBase): ext = [".js"] def Save(self, obj_dumped, fileName = None): - + """ + """ assert(fileName.endswith(tuple(DumpJSFile.ext))) diagram = obj_dumped @@ -536,7 +547,8 @@ class DumpXMLFile(DumpBase): ext = [".xml"] def Save(self, obj_dumped, fileName = None): - + """ + """ assert(fileName.endswith(tuple(DumpXMLFile.ext))) diagram = obj_dumped @@ -559,7 +571,7 @@ class Savable(object): @cond_decorator(builtins.__dict__.get('GUI_FLAG',True), BuzyCursorNotification) @cond_decorator(builtins.__dict__.get('GUI_FLAG',True), StatusBarNotification('Sav')) def SaveFile(self, fileName = None): - """ Save object in fileName + """ Save object in fileName. """ if fileName is None: return False @@ -581,7 +593,7 @@ def SaveFile(self, fileName = None): @cond_decorator(builtins.__dict__.get('GUI_FLAG',True), StatusBarNotification('Load')) def LoadFile(self, fileName = None): - """ Load object from fileName + """ Load object from fileName. """ if fileName is None: diff --git a/ZipManager.py b/ZipManager.py index d90c5faf..9b5e8a2e 100644 --- a/ZipManager.py +++ b/ZipManager.py @@ -1,15 +1,19 @@ # -*- coding: utf-8 -*- -""" -Name: ZipManager.py -Brief descritpion: Static class dedicated to the zip file managment -Author(s): L. Capocchi -Version: 1.0 -Last modified: 2012.12.16 -GENERAL NOTES AND REMARKS: - -GLOBAL VARIABLES AND FUNCTIONS: -""" +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# ZipManager.py --- Python class dedicated to the zip file managment +# -------------------------------- +# Copyright (c) 2020 +# L. CAPOCCHI (capocchi@univ-corse.fr) +# SPE Lab - SISU Group - University of Corsica +# -------------------------------- +# Version 1.0 last modified: 08/11/20 +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GENERAL NOTES AND REMARKS: +# +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## import os import sys @@ -30,8 +34,11 @@ from traceback import format_exception from Utilities import listf, path_to_module,install_and_import -#global Cmtp -#Cmtp=0 +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# GLOBAL VARIABLES AND FUNCTIONS +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## def get_from_modules(name:str)->types.ModuleType: """ get module with the correct name from the name that come from dir(). @@ -45,8 +52,6 @@ def getPythonModelFileName(fn:str)->str: """ Get filename of zipped python file. """ - #global Cmtp - assert zipfile.is_zipfile(fn), fn zf = zipfile.ZipFile(fn,'r') @@ -86,10 +91,18 @@ def getPythonModelFileName(fn:str)->str: else: return "" +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFIINTION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class Zip: + """ Zip class. + """ def __init__(self, fn:str, files:[str]=[]): - """ Constructor + """ Constructor. """ ### local copy self.fn = fn @@ -98,6 +111,9 @@ def __init__(self, fn:str, files:[str]=[]): self.Create(files) def Create(self, add_files:[str]=[])->None: + """ Create the Zip with files. + """ + dir_name, base_name = os.path.split(self.fn) name, ext = os.path.splitext(base_name) @@ -124,7 +140,7 @@ def Create(self, add_files:[str]=[])->None: zout.close() def Update(self, replace_files:[str]=[])->None: - """ Update zip archive with the new replace file names + """ Update zip archive with the new replace file names. """ ### delete empty fileName