def test_load_ports(self): block = self.create_block() # if it is not a dictionary block.ports.append("x") # if "type" not in port: block.ports.append({ "label": "Output", "conn_type": "Output", "name": "output" }) # if "conn_type" not in port block.ports.append({ "type": "Output", "label": "Output", "name": "output" }) # Port ok block.ports.append({ "type": "Output", "label": "Output", "conn_type": "Output", "name": "output" }) BlockControl.load_ports(block, System.get_ports())
def create_block(self, diagram_control=None): if diagram_control is None: diagram_control = self.create_diagram_control() block_model = BlockModel() block_model.maxIO = 2 block = Block(diagram_control.diagram, block_model) block.language = "language" block.properties = [{"name": "test", "label": "Test", "type": "Test"}] block.ports = [{ "type": "Test", "label": "Input", "conn_type": "Input", "name": "input" }, { "type": "Test", "label": "Output", "conn_type": "Outpu", "name": "output" }] BlockControl.load_ports(block, System.get_ports()) DiagramControl.add_block(diagram_control.diagram, block) return block
def __load_libs(self): # Create user directory if does not exist if not os.path.isdir(System.get_user_dir() + "/extensions/"): try: os.makedirs(System.get_user_dir() + "/extensions/") except: pass # Load CodeTemplates, Blocks and Ports self.__code_templates.clear() self.__ports.clear() self.__blocks.clear() # First load ports on python classes. # They are installed with mosaicode as root def walk_lib_packages(path=None, name_par=""): for importer, name, ispkg in pkgutil.iter_modules(path, name_par + "."): if path is None and name.startswith("." + System.APP): name = name.replace('.', '', 1) if not name.startswith(System.APP+"_lib") and not name_par.startswith(System.APP+"_lib"): continue if ispkg: if name_par is not "" and not name.startswith(System.APP): name = name_par + "." + name __import__(name) path = getattr(sys.modules[name], '__path__', None) or [] walk_lib_packages(path, name) else: module = __import__(name, fromlist="dummy") for class_name, obj in inspect.getmembers(module): if not inspect.isclass(obj): continue modname = inspect.getmodule(obj).__name__ if not modname.startswith(System.APP+"_lib"): continue instance = obj() if isinstance(instance, CodeTemplate): self.__code_templates[instance.type] = instance if isinstance(instance, Port): self.__ports[instance.type] = instance if isinstance(instance, BlockModel): if instance.label != "": self.__blocks[instance.type] = instance walk_lib_packages(None, "") # Load XML files in application space self.__load_xml(System.DATA_DIR + "extensions") # Load XML files in user space self.__load_xml(System.get_user_dir() + "/extensions") for key in self.__blocks: try: block = self.__blocks[key] BlockControl.load_ports(block, self.__ports) except: print("Error in loading plugin " + key)
def add_extension(self, element): if isinstance(element, Port): PortControl.add_port(element) elif isinstance(element, CodeTemplate): CodeTemplateControl.add_code_template(element) elif isinstance(element, BlockModel): BlockControl.add_new_block(element) self.update_blocks() System.reload()
def test_load(self): file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets", "block.xml") block = BlockControl.load(file_name) assert isinstance(block, BlockModel) file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets", "block_error.xml") block = BlockControl.load(file_name) assert not isinstance(block, BlockModel)
def test_load_ports(self): block = self.create_block() block.ports.append("x") block.ports.append({ "type": "ERRO!", "label": "Output", "conn_type": "Output", "name": "output" }) block.ports.append({ "label": "Output", "conn_type": "Output", "name": "output" }) BlockControl.load_ports(block, System.get_ports())
def test_delete_block(self): block = self.create_block() file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_file") f = open(file_name, 'w') f.close() block.file = file_name ok = BlockControl.delete_block(block) assert ok block = self.create_block() block.file = None ok = BlockControl.delete_block(self.create_block()) assert not ok
def delete_extension(self, element, element_type): if isinstance(element_type, Port): if not PortControl.delete_port(element): message = "This port is a python file installed in the System.\n" message = message + "Sorry, you can't remove it" MessageDialog("Error", message, self.main_window).run() return False System.reload() elif isinstance(element_type, CodeTemplate): filename = CodeTemplateControl.delete_code_template(element) if not filename: message = "This code template does not exist." MessageDialog("Error", message, self.main_window).run() return False if filename is None: message = "This code template is a python file installed in the System.\n" message = message + "Sorry, you can't remove it" MessageDialog("Error", message, self.main_window).run() return False System.reload() return True elif isinstance(element_type, BlockModel): if not BlockControl.delete_block(element): message = "This block is a python file installed in the System.\n" message = message + "Sorry, you can't remove it" MessageDialog("Error", message, self.main_window).run() return False self.update_blocks() MessageDialog("Info", str(element) + " deleted.", self.main_window).run() return True
def __load_xml(self, data_dir): if not os.path.exists(data_dir): return for file_name in os.listdir(data_dir): full_file_path = data_dir + "/" + file_name # Recursion to make it more interesting... if os.path.isdir(full_file_path): self.__load_xml(full_file_path) if not file_name.endswith(".xml"): continue code_template = CodeTemplateControl.load(full_file_path) if code_template is not None: code_template.source = "xml" self.code_templates[code_template.type] = code_template port = PortControl.load(full_file_path) if port is not None: port.source = "xml" self.ports[port.type] = port plugin = BlockControl.load(full_file_path) if plugin is not None: plugin.source = "xml" self.plugins[plugin.type] = plugin
def __get_extensions_xml(self, data_dir): if not os.path.exists(data_dir): return for file_name in os.listdir(data_dir): full_file_path = data_dir + "/" + file_name # Recursion to make it more interesting... if os.path.isdir(full_file_path): self.__get_extensions_xml(full_file_path) if not file_name.endswith(".xml"): continue code_template = CodeTemplateControl.load(full_file_path) if code_template is not None: code_template.file = full_file_path self.__code_templates[code_template.type] = code_template port = PortControl.load(full_file_path) if port is not None: port.file = full_file_path self.__ports[port.type] = port block = BlockControl.load(full_file_path) if block is not None: block.file = full_file_path self.__blocks[block.type] = block
def delete_block(self, block): result = BlockControl.delete_block(block) if not result[0]: self.message_dialog = MessageDialog("Error", result[1], self.main_window) self.message_dialog.run() self.update_blocks()
def create_block(self, diagram_control=None): if diagram_control is None: diagram_control = self.create_diagram_control() System() block_model = BlockModel() System.add_port(self.create_port()) block_model.ports = [{ "type": "Test", "label": "Click", "conn_type": "Input", "name": "0" }, { "type": "Test", "label": "Click", "conn_type": "Output", "name": "1" }, { "type": "Test", "label": "Click", "conn_type": "Input", "name": "2" }, { "type": "Test", "label": "Click", "conn_type": "Output", "name": "3" }] block_model.help = "Test" block_model.label = "Test" block_model.color = "200:200:25:150" block_model.group = "Test" block_model.codes = {"code0": "Test", "Code1": "Test", "Code2": "Test"} block_model.type = "Test" block_model.language = "Test" block_model.properties = [{ "name": "test", "label": "Test", "value": "0", "type": MOSAICODE_FLOAT }] block_model.extension = "Test" block_model.file = None result = BlockControl.load_ports(block_model, System.get_ports()) System.add_block(block_model) self.assertEquals(result[1], "Success") self.assertEquals(result[0], True) self.assertEquals(len(block_model.ports), 4) block = Block(diagram_control.diagram, block_model) self.assertEquals(len(block.ports), 4) return block
def test_init(self): BlockControl()
def add_new_block(self, block): BlockControl.add_new_block(block) self.main_window.block_notebook.update()
def test_add_new_block(self): BlockControl.add_new_block(self.create_block())
def print_blocks(cls): for block in System.blocks: print "--------------------- " BlockControl.print_block(System.blocks[block])
def add_plugin(self, plugin): BlockControl.add_plugin(plugin) self.main_window.block_notebook.update()
def export_python(cls): System() BlockControl.export_python() PortControl.export_python() CodeTemplateControl.export_python()
def setUp(self): """Do the test basic setup.""" #data = {"label": ("Type"), "name":"type", "value": "text"} self.blockmodel = BlockModel() self.blockmodel.id = 1 self.blockmodel.x = 2 self.blockmodel.y = 2 self.blockmodel.language = "c" self.blockmodel.framework = "opencv" self.blockmodel.help = "Adiciona bordas na imagem." self.blockmodel.label = "Teste BlockModel" self.blockmodel.color = "0:180:210:150" self.blockmodel.in_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "input_image", "label": "Input Image" }, { "type": "mosaicode_c_opencv.extensions.ports.int", "name": "border_size", "label": "Border Size" }] self.blockmodel.out_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "output_image", "label": "Output Image" }] self.blockmodel.group = "Experimental" self.blockmodel.properties = [{ "label": "Color", "name": "color", "type": MOSAICODE_COLOR, "value": "#FF0000" }, { "name": "type", "label": "Type", "type": MOSAICODE_COMBO, "value": "IPL_BORDER_CONSTANT", "values": [ "IPL_BORDER_CONSTANT", "IPL_BORDER_REPLICATE", "IPL_BORDER_REFLECT", "IPL_BORDER_WRAP" ] }, { "label": "Border Size", "name": "border_size", "type": MOSAICODE_INT, "value": "50" }] self.blockmodel.codes[0] = \ "CvScalar get_scalar_color(const char * rgbColor){\n" + \ " if (strlen(rgbColor) < 13 || rgbColor[0] != '#')\n" + \ " return cvScalar(0,0,0,0);\n" + \ " char r[4], g[4], b[4];\n" + \ " strncpy(r, rgbColor+1, 4);\n" + \ " strncpy(g, rgbColor+5, 4);\n" + \ " strncpy(b, rgbColor+9, 4);\n" + \ "\n" + \ " int ri, gi, bi = 0;\n" + \ " ri = (int)strtol(r, NULL, 16);\n" + \ " gi = (int)strtol(g, NULL, 16);\n" + \ " bi = (int)strtol(b, NULL, 16);\n" + \ "\n" + \ " ri /= 257;\n" + \ " gi /= 257;\n" + \ " bi /= 257;\n" + \ " \n" + \ " return cvScalar(bi, gi, ri, 0);\n" + \ "}\n" self.blockmodel.codes[1] = \ "IplImage * block$id$_img_i0 = NULL;\n" + \ "int block$id$_int_i1 = $prop[border_size]$;\n" + \ "IplImage * block$id$_img_o0 = NULL;\n" self.blockmodel.codes[2] = \ 'if(block$id$_img_i0){\n' + \ '\tCvSize size$id$ = cvSize(block$id$_img_i0->width +' + \ ' block$id$_int_i1 * 2, block$id$_img_i0->height' + \ ' + block$id$_int_i1 * 2);\n' + \ '\tblock$id$_img_o0 = cvCreateImage(size$id$,' + \ ' block$id$_img_i0->depth,block$id$_img_i0->nChannels);\n' + \ '\tCvPoint point$id$ = cvPoint' + \ '(block$id$_int_i1, block$id$_int_i1);\n' + \ '\tCvScalar color = get_scalar_color("$prop[color]$");\n' + \ '\tcvCopyMakeBorder(block$id$_img_i0, block$id$_img_o0,' + \ ' point$id$, $prop[type]$, color);\n' + \ '}\n' self.blockcontrol = BlockControl()
def delete_block(self, block): if not BlockControl.delete_block(block): message = "This block is a python file installed in the System.\n" message = message + "Sorry, you can't remove it" Dialog().message_dialog("Error", message, self.main_window) self.update_blocks()
def test_export_xml(self): System() System.reload() BlockControl.export_xml() BlockControl.add_new_block(self.create_block()) BlockControl.print_block(self.create_block())
def delete_plugin(self, plugin): if not BlockControl.delete_plugin(plugin): message = "This plugin is a python file installed in the System.\n" message = message + "Sorry, you can't remove it" Dialog().message_dialog("Error", message, self.main_window) self.main_window.block_notebook.update()
def export_xml(cls): System() BlockControl.export_xml() PortControl.export_xml() CodeTemplateControl.export_xml()
def test_print_block(self): BlockControl.print_block(self.create_block())
class TestBlockControl(TestCase): def setUp(self): """Do the test basic setup.""" #data = {"label": ("Type"), "name":"type", "value": "text"} self.blockmodel = BlockModel() self.blockmodel.id = 1 self.blockmodel.x = 2 self.blockmodel.y = 2 self.blockmodel.language = "c" self.blockmodel.framework = "opencv" self.blockmodel.help = "Adiciona bordas na imagem." self.blockmodel.label = "Teste BlockModel" self.blockmodel.color = "0:180:210:150" self.blockmodel.in_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "input_image", "label": "Input Image" }, { "type": "mosaicode_c_opencv.extensions.ports.int", "name": "border_size", "label": "Border Size" }] self.blockmodel.out_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "output_image", "label": "Output Image" }] self.blockmodel.group = "Experimental" self.blockmodel.properties = [{ "label": "Color", "name": "color", "type": MOSAICODE_COLOR, "value": "#FF0000" }, { "name": "type", "label": "Type", "type": MOSAICODE_COMBO, "value": "IPL_BORDER_CONSTANT", "values": [ "IPL_BORDER_CONSTANT", "IPL_BORDER_REPLICATE", "IPL_BORDER_REFLECT", "IPL_BORDER_WRAP" ] }, { "label": "Border Size", "name": "border_size", "type": MOSAICODE_INT, "value": "50" }] self.blockmodel.codes[0] = \ "CvScalar get_scalar_color(const char * rgbColor){\n" + \ " if (strlen(rgbColor) < 13 || rgbColor[0] != '#')\n" + \ " return cvScalar(0,0,0,0);\n" + \ " char r[4], g[4], b[4];\n" + \ " strncpy(r, rgbColor+1, 4);\n" + \ " strncpy(g, rgbColor+5, 4);\n" + \ " strncpy(b, rgbColor+9, 4);\n" + \ "\n" + \ " int ri, gi, bi = 0;\n" + \ " ri = (int)strtol(r, NULL, 16);\n" + \ " gi = (int)strtol(g, NULL, 16);\n" + \ " bi = (int)strtol(b, NULL, 16);\n" + \ "\n" + \ " ri /= 257;\n" + \ " gi /= 257;\n" + \ " bi /= 257;\n" + \ " \n" + \ " return cvScalar(bi, gi, ri, 0);\n" + \ "}\n" self.blockmodel.codes[1] = \ "IplImage * block$id$_img_i0 = NULL;\n" + \ "int block$id$_int_i1 = $prop[border_size]$;\n" + \ "IplImage * block$id$_img_o0 = NULL;\n" self.blockmodel.codes[2] = \ 'if(block$id$_img_i0){\n' + \ '\tCvSize size$id$ = cvSize(block$id$_img_i0->width +' + \ ' block$id$_int_i1 * 2, block$id$_img_i0->height' + \ ' + block$id$_int_i1 * 2);\n' + \ '\tblock$id$_img_o0 = cvCreateImage(size$id$,' + \ ' block$id$_img_i0->depth,block$id$_img_i0->nChannels);\n' + \ '\tCvPoint point$id$ = cvPoint' + \ '(block$id$_int_i1, block$id$_int_i1);\n' + \ '\tCvScalar color = get_scalar_color("$prop[color]$");\n' + \ '\tcvCopyMakeBorder(block$id$_img_i0, block$id$_img_o0,' + \ ' point$id$, $prop[type]$, color);\n' + \ '}\n' self.blockcontrol = BlockControl() # ---------------------------------------------------------------------- def test_export_xml(self): self.assertIsNone(self.blockcontrol.export_xml()) # ---------------------------------------------------------------------- def test_export_python(self): self.assertIsNone(self.blockcontrol.export_python()) # ---------------------------------------------------------------------- def test_load(self): file_name = "Aa" self.assertIsNone(self.blockcontrol.load(file_name)) file_name = "" self.assertIsNone(self.blockcontrol.load(file_name)) file_name = "Teste.xml" self.assertIsNone(self.blockcontrol.load(file_name)) file_name = "Teste.py" self.assertIsNone(self.blockcontrol.load(file_name)) # file_name = None # self.assertIsNone(self.blockcontrol.load(file_name)) # ---------------------------------------------------------------------- def test_add_new_block(self): self.assertIsNone(self.blockcontrol.add_new_block(self.blockmodel)) # NÃO TRATA None # self.assertIsNone(self.blockcontrol.add_new_block(None)) # ---------------------------------------------------------------------- def test_delete_block(self): #self.assertFalse(self.blockcontrol.delete_block("test_codegenerator.py")) #self.assertFalse(self.blockcontrol.delete_block("test_codegenerator.py")) #Apresenta um erro de System nao tem blockmodels: #self.assertFalse(self.blockcontrol.delete_block(self.blockmodel)) #self.assertTrue(self.blockcontrol.delete_block(self.blockmodel)) self.assertIsNotNone(self.blockcontrol.delete_block(self.blockmodel)) self.blockmodel.id = 1 self.blockmodel.x = 2 self.blockmodel.y = 2 self.blockmodel.type = "c" self.blockmodel.source = "/home/lucas/mosaicode/extensions/c/opencv/mosaicode.model.blockmodel" self.blockmodel.language = "c" self.blockmodel.framework = "opencv" self.blockmodel.help = "Adiciona bordas na imagem." self.blockmodel.label = "Testing A" self.blockmodel.color = "0:180:210:150" self.blockmodel.in_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "input_image", "label": "Input Image" }, { "type": "mosaicode_c_opencv.extensions.ports.int", "name": "border_size", "label": "Border Size" }] self.blockmodel.out_ports = [{ "type": "mosaicode_c_opencv.extensions.ports.image", "name": "output_image", "label": "Output Image" }] self.blockmodel.group = "Experimental" self.blockmodel.properties = [{ "label": "Color", "name": "color", "type": MOSAICODE_COLOR, "value": "#FF0000" }, { "name": "type", "label": "Type", "type": MOSAICODE_COMBO, "value": "IPL_BORDER_CONSTANT", "values": [ "IPL_BORDER_CONSTANT", "IPL_BORDER_REPLICATE", "IPL_BORDER_REFLECT", "IPL_BORDER_WRAP" ] }, { "label": "Border Size", "name": "border_size", "type": MOSAICODE_INT, "value": "50" }] self.blockmodel.codes[0] = \ "CvScalar get_scalar_color(const char * rgbColor){\n" + \ " if (strlen(rgbColor) < 13 || rgbColor[0] != '#')\n" + \ " return cvScalar(0,0,0,0);\n" + \ " char r[4], g[4], b[4];\n" + \ " strncpy(r, rgbColor+1, 4);\n" + \ " strncpy(g, rgbColor+5, 4);\n" + \ " strncpy(b, rgbColor+9, 4);\n" + \ "\n" + \ " int ri, gi, bi = 0;\n" + \ " ri = (int)strtol(r, NULL, 16);\n" + \ " gi = (int)strtol(g, NULL, 16);\n" + \ " bi = (int)strtol(b, NULL, 16);\n" + \ "\n" + \ " ri /= 257;\n" + \ " gi /= 257;\n" + \ " bi /= 257;\n" + \ " \n" + \ " return cvScalar(bi, gi, ri, 0);\n" + \ "}\n" self.blockmodel.codes[1] = \ "IplImage * block$id$_img_i0 = NULL;\n" + \ "int block$id$_int_i1 = $prop[border_size]$;\n" + \ "IplImage * block$id$_img_o0 = NULL;\n" self.blockmodel.codes[2] = \ 'if(block$id$_img_i0){\n' + \ '\tCvSize size$id$ = cvSize(block$id$_img_i0->width +' + \ ' block$id$_int_i1 * 2, block$id$_img_i0->height' + \ ' + block$id$_int_i1 * 2);\n' + \ '\tblock$id$_img_o0 = cvCreateImage(size$id$,' + \ ' block$id$_img_i0->depth,block$id$_img_i0->nChannels);\n' + \ '\tCvPoint point$id$ = cvPoint' + \ '(block$id$_int_i1, block$id$_int_i1);\n' + \ '\tCvScalar color = get_scalar_color("$prop[color]$");\n' + \ '\tcvCopyMakeBorder(block$id$_img_i0, block$id$_img_o0,' + \ ' point$id$, $prop[type]$, color);\n' + \ '}\n' #self.assertFalse(self.blockcontrol.delete_block(self.blockmodel)) #self.assertTrue(self.blockcontrol.delete_block(self.blockmodel)) self.assertIsNotNone(self.blockcontrol.delete_block(self.blockmodel)) # PARA QUE O TESTE ABAIXO SEJA EXECUTADO, # DEVE-SE CRIAR UM ARQUIVO c.xml DENTRO # DA PASTA mosaicode/extensions, QUE SE # ENCONTRA NA home do usuário. ASSIM, # O TESTE IRÁ ABRANGER 100% DA CLASSE. # LEMBRANDO QUE, ISTO É ERRADO, POIS NÃO # EXCLUIRÁ O PLUGIN EM SI, MAS, UM ARQUIVO # QUALQUER XML. CASO NÃO SE DELETE, NÃO APRESENTA # NENHUMA MENSAGEM DE ERRO. self.blockmodel.type = "c" self.blockmodel.source = "xml" #self.assertFalse(self.blockcontrol.delete_block(self.blockmodel)) #self.assertFalse(self.blockcontrol.delete_block(self.blockmodel)) self.assertIsNotNone(self.blockcontrol.delete_block(self.blockmodel)) # ---------------------------------------------------------------------- def test_print_block(self): #self.assertIsNone(self.blockcontrol.print_block("test_codegenerator.py")) self.assertIsNone(self.blockcontrol.print_block(self.blockmodel))
def print_blockmodels(cls): # This method is used by the launcher class blocks = System.get_blocks() for block in blocks: print "--------------------- " BlockControl.print_block(blocks[block])
def test_export_xml(self): System() System.reload() BlockControl.export_xml()
def print_plugins(cls): for plugin in System.plugins: print "--------------------- " BlockControl.print_plugin(System.plugins[plugin])
def add_new_block(self, block): BlockControl.add_new_block(block) self.update_blocks()
def __load_extensions(self): # Load CodeTemplates, Blocks and Ports self.__code_templates.clear() self.__ports.clear() self.__blocks.clear() # First load ports on python classes. # They are installed with mosaicode as root def walk_lib_packages(path=None, name_par=""): for importer, name, ispkg in pkgutil.iter_modules( path, name_par + "."): if path is None and name.startswith("." + System.APP): name = name.replace('.', '', 1) if not name.startswith(System.APP + "_lib") and not name_par.startswith( System.APP + "_lib"): continue if ispkg: if name_par != "" and not name.startswith(System.APP): name = name_par + "." + name __import__(name) path = getattr(sys.modules[name], '__path__', None) or [] walk_lib_packages(path, name) else: module = __import__(name, fromlist="dummy") for class_name, obj in inspect.getmembers(module): if not inspect.isclass(obj): continue modname = inspect.getmodule(obj).__name__ if not modname.startswith(System.APP + "_lib"): continue try: instance = obj() except Exception as error: continue if isinstance(instance, BlockModel): if instance.label != "": self.__blocks[instance.type] = instance continue elif isinstance(instance, Port): self.__ports[instance.type] = instance continue elif isinstance(instance, CodeTemplate): self.__code_templates[instance.type] = instance continue walk_lib_packages(None, "") # Load XML files in user space data_dir = System.get_user_dir() + "/extensions" if not os.path.exists(data_dir): return # List of languages for languages in os.listdir(data_dir): lang_path = os.path.join(data_dir, languages) # Load Code Templates for file_name in os.listdir( os.path.join(lang_path, "codetemplates")): if not file_name.endswith(".json"): continue file_path = os.path.join(lang_path, "codetemplates") file_path = os.path.join(file_path, file_name) code_template = CodeTemplateControl.load(file_path) if code_template is not None: code_template.file = file_path self.__code_templates[ code_template.type] = code_template # Load Ports for file_name in os.listdir(os.path.join(lang_path, "ports")): if not file_name.endswith(".json"): continue file_path = os.path.join(lang_path, "ports") file_path = os.path.join(file_path, file_name) port = PortControl.load(file_path) if port is not None: port.file = file_path self.__ports[port.type] = port # Load Blocks for extension_name in os.listdir( os.path.join(lang_path, "blocks")): extension_path = os.path.join(lang_path, "blocks") extension_path = os.path.join(extension_path, extension_name) for group_name in os.listdir(extension_path): group_path = os.path.join(extension_path, group_name) for file_name in os.listdir(group_path): if not file_name.endswith(".json"): continue file_path = os.path.join(group_path, file_name) block = BlockControl.load(file_path) if block is not None: block.file = file_path self.__blocks[block.type] = block for key in self.__blocks: try: block = self.__blocks[key] BlockControl.load_ports(block, self.__ports) except: print("Error in loading block " + key)