def _load(self): """ Load the treeview with database information """ self.commands_node = self.insert("", "end", "commands", text="Commands", image=CommandView.getClassIcon()) commands = Command.fetchObjects({}) for command in commands: command_vw = CommandView(self, self.appli.commandsViewFrame, self.appli, CommandController(command)) command_vw.addInTreeview() self.group_command_node = self.insert( "", "end", str("command_groups"), text="Command Groups", image=CommandGroupView.getClassIcon()) command_groups = CommandGroup.fetchObjects({}) for command_group in command_groups: command_group_vw = CommandGroupView( self, self.appli.commandsViewFrame, self.appli, CommandGroupController(command_group)) command_group_vw.addInTreeview()
def notify(self, db, collection, iid, action, parent): """ Callback for the observer pattern implemented in mongo.py. Args: collection: the collection that has been modified iid: the mongo ObjectId _id that was modified/inserted/deleted action: update/insert/delete. It was the action performed on the iid parent: the mongo ObjectId of the parent. Only if action in an insert. """ if db != "pollenisator": return # Delete mongoInstance = MongoCalendar.getInstance() if action == "delete": try: self.delete(ObjectId(iid)) except tk.TclError: pass # item was not inserted in the treeview # Insert if action == "insert": res = mongoInstance.findInDb(db, collection, {"_id": ObjectId(iid)}, False) if collection == "commands": view = CommandView(self, self.appli.commandsViewFrame, self.appli, CommandController(Command(res))) parent = None elif collection == "group_commands": view = CommandGroupView( self, self.appli.commandsViewFrame, self.appli, CommandGroupController(CommandGroup(res))) parent = None try: view.addInTreeview(parent) if view is not None: view.insertReceived() except tk.TclError: pass if action == "update": try: view = self.getViewFromId(str(iid)) if view is not None: self.item(str(iid), text=str(view.controller.getModelRepr()), image=view.getIcon()) except tk.TclError: if view is not None: view.addInTreeview() if str(self.appli.openedViewFrameId) == str(iid): for widget in self.appli.viewframe.winfo_children(): widget.destroy() view.openModifyWindow() if view is not None: view.controller.actualize() view.updateReceived()
def prepareCalendar(self, dbName, pentest_type, start_date, end_date, scope, settings, pentesters): """ Initiate a pentest database with wizard info Args: dbName: the database name pentest_type: a pentest type choosen from settings pentest_types. Used to select commands that will be launched by default start_date: a begining date and time for the pentest end_date: ending date and time for the pentest scope: a list of scope valid string (IP, network IP or host name) settings: a dict of settings with keys: * "Add domains whose IP are in scope": if 1, will do a dns lookup on new domains and check if found IP is in scope * "Add domains who have a parent domain in scope": if 1, will add a new domain if a parent domain is in scope * "Add all domains found": Unsafe. if 1, all new domains found by tools will be considered in scope. """ commands = Command.getList({"$or":[{"types":{"$elemMatch":{"$eq":pentest_type}}}, {"types":{"$elemMatch":{"$eq":"Commun"}}}]}) if not commands: commandslist = Command.getList() if not commandslist: dialog = ChildDialogQuestion(self.parent, "No command found", "There is no registered command in the database. Would you like to import the default set?") self.parent.wait_window(dialog.app) if dialog.rvalue != "Yes": return default = os.path.join(Utils.getMainDir(), "exports/pollenisator_commands.gzip") res = self.importCommands(default) if res: default = os.path.join(Utils.getMainDir(), "exports/pollenisator_group_commands.gzip") res = self.importCommands(default) commands = Command.getList({"$or":[{"types":{"$elemMatch":{"$eq":pentest_type}}}, {"types":{"$elemMatch":{"$eq":"Commun"}}}]}) #Duplicate commands in local database allcommands = Command.fetchObjects({}) for command in allcommands: command.indb = MongoCalendar.getInstance().calendarName command.addInDb() Wave().initialize(dbName, commands).addInDb() Interval().initialize(dbName, start_date, end_date).addInDb() values = {"wave":dbName, "Scopes":scope, "Settings":False} ScopeController(Scope()).doInsert(values) self.settings.reloadSettings() self.settings.db_settings["pentest_type"] = pentest_type self.settings.db_settings["include_domains_with_ip_in_scope"] = settings['Add domains whose IP are in scope'] == 1 self.settings.db_settings["include_domains_with_topdomain_in_scope"] = settings["Add domains who have a parent domain in scope"] == 1 self.settings.db_settings["include_all_domains"] = settings["Add all domains found"] == 1 self.settings.db_settings["pentesters"] = list(map(lambda x: x.strip(), pentesters.split("\n"))) self.settings.save()
def openInsertWindow(self): """ Creates a tkinter form using Forms classes. This form aims to insert a new Wave """ top_panel = self.form.addFormPanel(grid=True) top_panel.addFormLabel("Wave") top_panel.addFormStr("Wave", r".+", "", column=1) self.form.addFormHelper("Only selected commands will be launchable.") self.form.addFormChecklist("Commands", Command.getList(), []) self.completeInsertWindow()
def onTreeviewSelect(self, event=None): """Called when a line is selected on the treeview Open the selected object view on the view frame. Args: _event: not used but mandatory """ selection = self.selection() if len(selection) == 1: item = super().onTreeviewSelect(event) if isinstance(item, str): mongoInstance = MongoCalendar.getInstance() self.saveState(mongoInstance.calendarName) if str(item) == "waves": objView = WaveView(self, self.appli.viewframe, self.appli, WaveController(Wave())) objView.openInsertWindow() elif str(item) == "commands": objView = CommandView( self, self.appli.viewframe, self.appli, CommandController( Command({"indb": mongoInstance.calendarName}))) objView.openInsertWindow() elif str(item) == "ips": objView = MultipleIpView(self, self.appli.viewframe, self.appli, IpController(Ip())) objView.openInsertWindow() elif "intervals" in str(item): wave = Wave.fetchObject({ "_id": ObjectId(IntervalView.treeviewListIdToDb(item)) }) objView = IntervalView( self, self.appli.viewframe, self.appli, IntervalController(Interval().initialize(wave.wave))) objView.openInsertWindow() elif "scopes" in str(item): wave = Wave.fetchObject( {"_id": ObjectId(ScopeView.treeviewListIdToDb(item))}) objView = MultipleScopeView( self, self.appli.viewframe, self.appli, ScopeController(Scope().initialize(wave.wave))) objView.openInsertWindow() else: self.openModifyWindowOf(item) elif len(selection) > 1: # Multi select: multiView = MultiSelectionView(self, self.appli.viewframe, self.appli) for widget in self.appli.viewframe.winfo_children(): widget.destroy() multiView.form.clear() multiView.openModifyWindow()
def openModifyWindow(self): """ Creates a tkinter form using Forms classes. This form aims to update or delete an existing Wave """ modelData = self.controller.getData() top_panel = self.form.addFormPanel(grid=True) top_panel.addFormLabel("Wave", modelData["wave"]) self.form.addFormHelper( "If you select a previously unselected command,\n it will be added to every object of its level.\nIf you unselect a previously selected command,\n it will remove only tools that are not already done." ) self.form.addFormChecklist("Commands", Command.getList(), modelData["wave_commands"]) self.completeModifyWindow()
def refreshUI(self): """Reload informations and renew widgets""" mongoInstance = MongoCalendar.getInstance() workernames = self.monitor.getWorkerList() running_scans = Tool.fetchObjects({"status":"running"}) for children in self.scanTv.get_children(): self.scanTv.delete(children) for running_scan in running_scans: self.scanTv.insert('','end', running_scan.getId(), text=running_scan.name, values=(running_scan.dated), image=self.running_icon) for children in self.workerTv.get_children(): self.workerTv.delete(children) registeredCommands = set() for workername in workernames: try: worker_node = self.workerTv.insert( '', 'end', workername, text=workername, image=self.ok_icon) except tk.TclError: worker_node = self.workerTv.item(workername) worker_registered = mongoInstance.findInDb("pollenisator", "workers", {"name":workername}, False) commands_registered = worker_registered["registeredCommands"] for command in commands_registered: try: self.workerTv.insert( worker_node, 'end', command, text=command, image=self.ok_icon) except tk.TclError: pass registeredCommands.add(str(command)) allCommands = Command.getList(None, mongoInstance.calendarName) for command in allCommands: if command not in registeredCommands: try: self.workerTv.insert( worker_node, '0', 'notRegistered|'+command, text=command, image=self.nok_icon) except tk.TclError: pass else: try: self.workerTv.delete('notRegistered|'+command) except tk.TclError: pass if len(registeredCommands) > 0 and self.btn_autoscan is None: if self.running_auto_scans: self.btn_autoscan = ttk.Button( self.parent, text="Stop Scanning", command=self.stopAutoscan) self.btn_autoscan.pack() else: self.btn_autoscan = ttk.Button( self.parent, text="Start Scanning", command=self.startAutoscan) self.btn_autoscan.pack()
def openModifyWindow(self): """ Creates a tkinter form using Forms classes. This form aims to update or delete an existing Port """ modelData = self.controller.getData() top_panel = self.form.addFormPanel(grid=True) top_panel.addFormLabel("IP", row=0, column=0) top_panel.addFormStr( "IP", '', modelData["ip"], None, column=1, row=0, state="readonly") top_panel.addFormLabel("Number", column=0, row=1) top_panel.addFormStr( "Number", '', modelData["port"], None, column=1, row=1, state="readonly") top_panel.addFormLabel("Proto", row=2, column=0) top_panel.addFormStr( "Proto", '', modelData["proto"], None, column=1, row=2, state="readonly") top_panel.addFormLabel("Service", row=3) top_panel.addFormStr( "Service", r"", modelData["service"], column=1, row=3) if "http" in modelData["service"]: top_panel.addFormButton( "Open in browser", self.openInBrowser, column=2, row=3) top_panel.addFormLabel("Product", row=4) top_panel.addFormStr("Product", r"", modelData["product"], width=40, row=4, column=1) top_panel = self.form.addFormPanel() top_panel.addFormLabel("Notes", side="top") top_panel.addFormText( "Notes", r"", modelData["notes"], None, side="top", height=10) top_panel.addFormLabel("Infos", side="left") top_panel.addFormTreevw("Infos", ("Infos", "Values"), modelData["infos"], side="left", width=300, fill="both", height=8, binds={"<Enter>": self.mainApp.unboundToMousewheelMain, "<Leave>": self.mainApp.boundToMousewheelMain}) command_list = Command.fetchObjects({"lvl": "port"}) command_names = ["None"] for command_doc in command_list: command_names.append(command_doc.name) self.tool_panel = self.form.addFormPanel(grid=True) self.tool_panel.addFormLabel("Tool to add") self.tool_panel.addFormCombo( "Tool to add", command_names, "None", column=1) self.tool_panel.addFormButton("Add tool", self._addTool, column=2) top_panel = self.form.addFormPanel(grid=True) top_panel.addFormButton("Add a security defect", self.addDefectCallback) self.form.addFormHidden("ip", modelData["ip"]) self.completeModifyWindow()
def onTreeviewSelect(self, event=None): """Called when a line is selected on the treeview Open the selected object view on the view frame. IF it's a parent commands or command_groups node, opens Insert ELSE open a modify window Args: event: filled with the callback, contains data about line clicked """ item = super().onTreeviewSelect(event) if isinstance(item, str): if str(item) == "commands": objView = CommandView(self, self.appli.commandsViewFrame, self.appli, CommandController(Command())) objView.openInsertWindow() elif str(item) == "command_groups": objView = CommandGroupView( self, self.appli.commandsViewFrame, self.appli, CommandGroupController(CommandGroup())) objView.openInsertWindow() else: self.openModifyWindowOf(item)
def hasSpaceFor(self, launchableTool, calendarName): """ Check if this worker has space for the given tool. (this checks the command and every group of commands max_thred settings) Args: launchableTool: a tool documents fetched from database that has to be launched Returns: Return True if a command of the tool's type can be launched on this worker, False otherwise. """ # 1. Find command with command id command = Command.fetchObject({"name": launchableTool.name}, calendarName) if command.safe == "False": return False # 2. Calculate individual command limit for the server nb = self.getNbOfLaunchedCommand(command.name) + 1 if nb > int(command.max_thread): #print("Can't launch "+command.name+" on worker cause command max_trhad "+str(nb)+" > "+str(int(command.max_thread))) return False # 3. Get groups of command incorporation command id command_groups = CommandGroup.fetchObjects( {"commands": { "$elemMatch": { "$eq": command.name } }}) # 4. Calculate limites for the group for group in command_groups: tots = 0 for commandName in group.commands: tots += self.getNbOfLaunchedCommand(commandName) if tots + 1 > int(group.max_thread): #print("Can't launch "+command.name+" on worker cause group_max_thread "+str(tots + 1)+" > "+str(int(group.max_thread))) return False return True
def initUI(self, parent): """Create widgets and initialize them Args: parent: the parent tkinter widget container.""" if self.workerTv is not None: self.refreshUI() return mongoInstance = MongoCalendar.getInstance() self.parent = parent ### WORKER TREEVIEW : Which worker knows which commands lblworker = ttk.Label(self.parent, text="Workers:") lblworker.pack(side=tk.TOP, padx=10, pady=5, fill=tk.X) self.workerTv = ttk.Treeview(self.parent) self.workerTv['columns'] = ('workers') self.workerTv.heading("#0", text='Workers', anchor=tk.W) self.workerTv.column("#0", anchor=tk.W) self.workerTv.pack(side=tk.TOP, padx=10, pady=10, fill=tk.X) registeredCommands = set() workernames = self.monitor.getWorkerList() for workername in workernames: worker_node = self.workerTv.insert('', 'end', workername, text=workername, image=self.ok_icon) commands_registered = mongoInstance.getRegisteredCommands( workername) for command in commands_registered: self.workerTv.insert(worker_node, 'end', None, text=command, image=self.ok_icon) registeredCommands.add(str(command)) allCommands = Command.getList() for command in allCommands: if command not in registeredCommands: try: self.workerTv.insert('', 'end', 'notRegistered', text='Laking commands', image=self.nok_icon) except tk.TclError: self.workerTv.item('notRegistered') try: self.workerTv.insert('notRegistered', 'end', 'notRegistered|' + str(command), text=str(command), image=self.nok_icon) except tk.TclError: pass #### TREEVIEW SCANS : overview of ongoing auto scan#### lblscan = ttk.Label(self.parent, text="Scan overview:") lblscan.pack(side=tk.TOP, padx=10, pady=5, fill=tk.X) self.scanTv = ttk.Treeview(self.parent) self.scanTv['columns'] = ('Started at') self.scanTv.heading("#0", text='Scans', anchor=tk.W) self.scanTv.column("#0", anchor=tk.W) self.scanTv.pack(side=tk.TOP, padx=10, pady=10, fill=tk.X) self.scanTv.bind("<Double-Button-1>", self.OnDoubleClick) running_scans = Tool.fetchObjects({"status": "running"}) for running_scan in running_scans: self.scanTv.insert('', 'end', running_scan.getId(), text=running_scan.name, values=(running_scan.dated), image=self.running_icon) #### BUTTONS FOR AUTO SCANNING #### if len(registeredCommands) > 0: if self.running_auto_scans: self.btn_autoscan = ttk.Button(self.parent, text="Stop Scanning", command=self.stopAutoscan) self.btn_autoscan.pack() else: self.btn_autoscan = ttk.Button(self.parent, text="Start Scanning", command=self.startAutoscan) self.btn_autoscan.pack() btn_parse_scans = ttk.Button(self.parent, text="Parse existing files", command=self.parseFiles) btn_parse_scans.pack()
def executeCommand(calendarName, toolId, parser=""): """ CELERY remote task Execute the tool with the given toolId on the given calendar name. Then execute the plugin corresponding. Any unhandled exception will result in a task-failed event in the Monitor class. Args: calendarName: The calendar to search the given tool id for. toolId: the mongo Object id corresponding to the tool to execute. parser: plugin name to execute. If empty, the plugin specified in tools.d will be feteched. Raises: Terminated: if the task gets terminated OSError: if the output directory cannot be created (not if it already exists) Exception: if an exception unhandled occurs during the bash command execution. Exception: if a plugin considered a failure. """ # Connect to given calendar mongoInstance = MongoCalendar.getInstance() mongoInstance.connectToDb(calendarName) msg = "" # retrieve tool from tool sid toolModel = Tool.fetchObject({"_id": ObjectId(toolId)}) if toolModel is None: raise Exception("Tool does not exist : " + str(toolId)) command = Command.fetchObject({"name": toolModel.name}, calendarName) # Get time limit and output directory if toolModel.wave == "Custom commands": timeLimit = None else: timeLimit = getWaveTimeLimit(toolModel.wave) if command is not None: timeLimit = min(datetime.now() + timedelta(0, int(command.timeout)), timeLimit) outputRelDir = toolModel.getOutputDir(calendarName) abs_path = os.path.dirname(os.path.abspath(__file__)) outputDir = os.path.join(abs_path, "./results", outputRelDir) # Create the output directory try: os.makedirs(outputDir) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(outputDir): pass else: raise exc # Read Tool config file tools_infos = Utils.loadToolsConfig() comm = toolModel.getCommandToExecute(outputDir) if parser.strip() == "": if toolModel.name not in list(tools_infos.keys()): msg = "TASK FAILED Received tool that was not registered : " + \ str(toolModel.name)+" not in "+str(list(tools_infos.keys())) raise Exception(msg) # Fetch the command to execute if tools_infos.get(toolModel.name, None) is None: bin_path = "" else: bin_path = tools_infos[toolModel.name].get("bin") if bin_path is not None: if not bin_path.endswith(" "): bin_path = bin_path + " " comm = bin_path + comm if comm != "": try: # Load the plugin if parser.strip() == "": mod = Utils.loadPlugin(tools_infos[toolModel.name]["plugin"]) elif parser.strip() == "auto-detect": mod = Utils.loadPluginByBin(toolModel.name.split("::")[0]) else: mod = Utils.loadPlugin(parser) # Complete command with file output toolFileName = toolModel.name+"_" + \ str(time.time())+mod.getFileOutputExt() comm = mod.changeCommand(comm, outputDir, toolFileName) print(('TASK STARTED:' + toolModel.name)) print("Will timeout at " + str(timeLimit)) # Execute the command with a timeout returncode = Utils.execute(comm, timeLimit, True) except Exception as e: raise e # Execute found plugin if there is one if mod is not None: filepath = mod.getFileOutputPath(comm) try: # Open generated file as utf8 with io.open(filepath, "r", encoding="utf-8", errors='ignore') as file_opened: # Check return code by plugin (can be always true if the return code is inconsistent) if mod.checkReturnCode(returncode): notes, tags, _, _ = mod.Parse(file_opened) if notes is None: notes = "No results found by plugin." if tags is None: tags = [] if isinstance(tags, str): tags = [tags] # Success could be change to False by the plugin function (evaluating the return code for exemple) # if the success is validated, mark tool as done toolModel.markAsDone( os.path.join(outputRelDir, os.path.basename(filepath))) # And update the tool in database toolModel.notes = notes toolModel.tags = tags toolModel.update() # Upload file to SFTP mod.centralizeFile(filepath, outputDir) msg = "TASK SUCCESS : " + toolModel.name else: # BAS RESULT OF PLUGIN msg = "TASK FAILED (says the mod) : " + toolModel.name msg += "The return code was not the expected one. (" + str( returncode) + ")." toolModel.markAsError() raise Exception(msg) except IOError as e: toolModel.tags = ["todo"] toolModel.notes = "Failed to read results file" toolModel.markAsDone() else: msg = "TASK FAILED (no plugin found) : " + toolModel.name toolModel.markAsNotDone() raise Exception(msg) # Delay if command is not None: if float(command.sleep_between) > 0.0: msg += " (will sleep for " + \ str(float(command.sleep_between))+")" print(msg) time.sleep(float(command.sleep_between)) return
def _load(self): """ Load the treeview with database information """ mongoInstance = MongoCalendar.getInstance() dialog = ChildDialogProgress(self.appli, "Loading "+str( mongoInstance.calendarName), "Opening "+str(mongoInstance.calendarName) + ". Please wait for a few seconds.", 200, "determinate") step = 0 dialog.show(100) nbObjects = mongoInstance.find("waves").count() nbObjects += mongoInstance.find("scopes").count() nbObjects += mongoInstance.find("intervals").count() nbObjects += mongoInstance.find("scopes").count() nbObjects += mongoInstance.find("ips").count() nbObjects += mongoInstance.find("ports").count() nbObjects += mongoInstance.find("tools").count() nbObjects += mongoInstance.find("commands").count() onePercentNbObject = nbObjects//100 if nbObjects > 100 else 1 nbObjectTreated = 0 for child in self.get_children(): self.delete(child) self._hidden = [] self._detached = [] self.waves_node = self.insert("", "end", str( "waves"), text="Waves", image=WaveView.getClassIcon()) # Loading every category separatly is faster than recursivly. # This is due to cursor.next function calls in pymongo # Adding wave objects self.commands_node = self.insert( "", "end", "commands", text="Commands", image=CommandView.getClassIcon()) commands = Command.fetchObjects({}, mongoInstance.calendarName) for command in commands: command_vw = CommandView( self, self.appli.viewframe, self.appli, CommandController(command)) command_vw.addInTreeview() waves = Wave.fetchObjects({}) for wave in waves: wave_o = WaveController(wave) wave_vw = WaveView(self, self.appli.viewframe, self.appli, wave_o) wave_vw.addInTreeview(self.waves_node, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) scopes = Scope.fetchObjects({}) for scope in scopes: scope_o = ScopeController(scope) scope_vw = ScopeView(self, self.appli.viewframe, self.appli, scope_o) scope_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) intervals = Interval.fetchObjects({}) for interval in intervals: interval_o = IntervalController(interval) interval_vw = IntervalView(self, self.appli.viewframe, self.appli, interval_o) interval_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding ip objects self.ips_node = self.insert("", "end", str( "ips"), text="IPs", image=IpView.getClassIcon()) ips = Ip.fetchObjects({}) for ip in ips: ip_o = IpController(ip) ip_vw = IpView(self, self.appli.viewframe, self.appli, ip_o) ip_vw.addInTreeview(None, False) self.appli.statusbar.notify(ip_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding port objects ports = Port.fetchObjects({}) for port in ports: port_o = PortController(port) port_vw = PortView(self, self.appli.viewframe, self.appli, port_o) port_vw.addInTreeview(None, False) self.appli.statusbar.notify(port_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding defect objects defects = Defect.fetchObjects({"ip":{"$ne":""}}) for defect in defects: defect_o = DefectController(defect) defect_vw = DefectView( self, self.appli.viewframe, self.appli, defect_o) defect_vw.addInTreeview(None) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding tool objects tools = Tool.fetchObjects({}) for tool in tools: tool_o = ToolController(tool) tool_vw = ToolView(self, self.appli.viewframe, self.appli, tool_o) tool_vw.addInTreeview(None, False) self.appli.statusbar.notify(tool_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) self.sort(self.ips_node) self.appli.statusbar.update() dialog.destroy()
def notify(self, db, collection, iid, action, _parent): """ Callback for the observer implemented in mongo.py. Each time an object is inserted, updated or deleted the standard way, this function will be called. Args: collection: the collection that has been modified iid: the mongo ObjectId _id that was modified/inserted/deleted action: string "update" or "insert" or "delete". It was the action performed on the iid _parent: Not used. the mongo ObjectId of the parent. Only if action in an insert. Not used anymore """ mongoInstance = MongoCalendar.getInstance() if not mongoInstance.hasACalendarOpen(): return if mongoInstance.calendarName != db: return # Delete if action == "delete": if collection == "defects": view = self.getViewFromId(str(iid)) if view is not None: view.beforeDelete() self.appli.statusbar.notify([],view.controller.getTags()) try: self.delete(ObjectId(iid)) except tk.TclError: pass # item was not inserted in the treeview # Insert if action == "insert": view = None res = mongoInstance.find(collection, {"_id": ObjectId(iid)}, False) if collection == "tools": view = ToolView(self, self.appli.viewframe, self.appli, ToolController(Tool(res))) elif collection == "waves": view = WaveView(self, self.appli.viewframe, self.appli, WaveController(Wave(res))) elif collection == "scopes": view = ScopeView(self, self.appli.viewframe, self.appli, ScopeController(Scope(res))) elif collection == "ports": view = PortView(self, self.appli.viewframe, self.appli, PortController(Port(res))) elif collection == "ips": view = IpView(self, self.appli.viewframe, self.appli, IpController(Ip(res))) elif collection == "intervals": view = IntervalView(self, self.appli.viewframe, self.appli, IntervalController(Interval(res))) elif collection == "defects": view = DefectView(self, self.appli.viewframe, self.appli, DefectController(Defect(res))) elif collection == "commands": view = CommandView(self, self.appli.viewframe, self.appli, CommandController(Command(res))) try: if view is not None: view.addInTreeview() view.insertReceived() self.appli.statusbar.notify(view.controller.getTags()) except tk.TclError: pass if action == "update": try: view = self.getViewFromId(str(iid)) if view is not None: oldTags = self.item(str(iid))["tags"] view.controller.actualize() self.appli.statusbar.notify(view.controller.getTags(), oldTags) self.item(str(iid), text=str( view.controller.getModelRepr()), image=view.getIcon()) except tk.TclError: if view is not None: view.addInTreeview() if str(self.appli.openedViewFrameId) == str(iid): for widget in self.appli.viewframe.winfo_children(): widget.destroy() view.openModifyWindow() if view is not None: view.updateReceived() self.appli.statusbar.update()