コード例 #1
0
ファイル: mainwindow.py プロジェクト: m0sth8/faraday
class MainWindow(qt.QMainWindow):

    def __init__(self, title, main_app, model_controller, plugin_manager):
        qt.QMainWindow.__init__(self, None, title, qt.Qt.WDestructiveClose)
        self.setWindowState(qt.Qt.WindowMaximized)
        self.setCaption(title)

        self.setIcon(qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                'faraday_icon.png')))

        self._main_app = main_app
        self._model_controller = model_controller

        self._mainArea = qt.QHBox(self)
        self.setCentralWidget(self._mainArea)
        self._vb_splitter = qt.QSplitter(self._mainArea)
        self._vb_splitter.setOrientation(qt.QSplitter.Vertical)
        self._hb_splitter = qt.QSplitter(self._vb_splitter)
        self._hb_splitter.setOrientation(qt.QSplitter.Horizontal)

        self.statusBar().setSizeGripEnabled(False)

        self._shell_widgets = []
        self._notifications = []
        self._tab_manager = TabManager(self._hb_splitter)
        self._perspective_manager = PerspectiveManager(self._hb_splitter,
                                                       self._main_app)

        self._hosts_treeview = HostsBrowser(self._perspective_manager,
                                            self._model_controller,
                                            'Hosts')
        notifier.registerWidget(self._hosts_treeview)

        self._perspective_manager.registerPerspective(self._hosts_treeview,
                                                      default=True)

        wtw = WorkspaceTreeWindow(self._perspective_manager, 'Workspaces',
                                  self._main_app.getWorkspaceManager())
        self._perspective_manager.registerPerspective(wtw)
        self._workspaces_treeview = wtw

        self._log_console = LogConsole(self._vb_splitter, 'Console')

        self._actions = dict()
        self._setupActions()

        self._menues = {}
        self._setupMenues()

        self.main_toolbar = qt.QToolBar(self, 'main toolbar')
        self._setupMainToolbar()

        self.location_toolbar = LocationToolbar(self, 'location toolbar')
        self.location_toolbar.setOffset(1500)

        self._status_bar_widgets = dict()
        self._setupStatusBar()

        self._is_shell_maximized = False

        self.shell_font = qt.QFont()
        self.shell_font.setRawName(CONF.getFont())
        self.setSizeFont()

    def setSizeFont(self):
        if re.search("fixed",str(self.shell_font.family()),re.IGNORECASE) is None:
            self.shell_font=qt.QFont()
            CONF.setFont("-Misc-Fixed-medium-r-normal-*-12-100-100-100-c-70-iso8859-1")
            CONF.saveConfig()
            self.shell_font.setRawName(CONF.getFont())

        self._sizes = [6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36]
        i=0
        self._size=6
        for f_i in self._sizes:
            if f_i == self.shell_font.pixelSize():
                self._size=i
            i+=1


    def setMainApp(self, mainapp):
       self._main_app = mainapp


    def _setupActions(self):
        """
        creates some actions needed on some menues and toolbars
        Actions are later added to different toolbars, for example in
        method _setupMainToolbar
        """


        a = self._actions["new_shell"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"newshell.png"))), "&New Shell", qt.Qt.CTRL + qt.Qt.SHIFT + qt.Qt.Key_T, self, "New Shell" )
        self.connect(a, qt.SIGNAL('activated()'), self.createShellTab)


        a = self._actions["close_shell"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"exit.png"))), "&Close Shell", qt.Qt.CTRL + qt.Qt.SHIFT +qt.Qt.Key_W, self, "New Shell" )
        self.connect(a, qt.SIGNAL('activated()'), self.destroyShellTab)


        a = self._actions["toggle-hosttree"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"HostTreeView.png"))), "Toggle Host Tree", 0, self, "Toggle Log Console" )
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.togglePerspectives)


        a = self._actions["toggle-logconsole"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"LogConsole.png"))), "Toggle Log Console", 0, self, "Toggle Log Console" )
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.toggleLogConsole)


        a = self._actions["maximize-shell"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"maximize.png"))), "Maximize Shell", 0, self, "Maximize Shell" )
        a.setToggleAction(True)

        self.connect(a, qt.SIGNAL('activated()'), self.maximizeShell)
        self._tab_manager.tabBar().addAction("maximize", self.maximizeShell)









        #a = self._actions["test"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"donotpresstheredbutton.png"))), "Test", qt.Qt.CTRL + qt.Qt.Key_H, self, "Test" )

        #self.connect(a, qt.SIGNAL('activated()'), self.test)

        a = self._actions["screenshot"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"Screenshot.png"))), "Take Screenshot", 0, self, "Take Screenshot" )
        self.connect(a, qt.SIGNAL('activated()'), self.takeScreenshot)


        a = self._actions["clear-hosttree"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"clear.png"))), "Clear Host Tree", qt.Qt.CTRL + qt.Qt.Key_R, self, "Clear Host Tree" )
        self.connect(a, qt.SIGNAL('activated()'), self._hosts_treeview.clearTree)



        a = self._actions["repo-config"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"connect.png"))), "Server Connection", 0, self, "Server Connection" )
        self.connect(a, qt.SIGNAL('activated()'), self._showRepositoryConfigDialog)


        a = self._actions["visualization"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"visualize.png"))), "Visualize", 0, self, "Visualize" )
        self.connect(a, qt.SIGNAL('activated()'), self.runVisualization)

        a = self._actions["plugin"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"config.png"))), "Plugin", 0, self, "Plugin" )
        self.connect(a, qt.SIGNAL('activated()'), self.showPluginSettingsDialog)


        a = self._actions["documentation"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"Documentation.png"))), "Documentation", 0, self, "Documentation" )
        self.connect(a, qt.SIGNAL('activated()'), self.go2Website)


        a = self._actions["exit-faraday"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"exit.png"))), "Exit Faraday", 0, self, "Exit Faraday" )
        self.connect(a, qt.SIGNAL('activated()'), self.exitFaraday)






        a = self._actions["create-workspace"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"sync.png"))), "Create", 0, self, "Create" )
        self.connect(a, qt.SIGNAL('activated()'), self.createWorkspace)






        # a = self._actions["open-workspace"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"sync.png"))), "Open", 0, self, "Open" )
        # self.connect(a, qt.SIGNAL('activated()'), self.openWorkspace)

        a = self._actions["bfont"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"fontb.png"))), "Big Font", 0, self, "Big Font" )
        self.connect(a, qt.SIGNAL('activated()'), self.setBfont)

        a = self._actions["sfont"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"fonts.png"))), "Small Font", 0, self, "Small Font" )
        self.connect(a, qt.SIGNAL('activated()'), self.setSfont)

        if CONF.getDebugStatus():
            a = self._actions["debug"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"debug.png"))), "Debug", 0, self, "Debug" )
            self.connect(a, qt.SIGNAL('activated()'), self.doDebug)

    def _setupStatusBar(self):
        label_order = ["username", "userLevel", "space", "status"]
        for lname in label_order:
            l = qt.QLabel("", self)
            l.setFrameStyle(qt.QFrame.MenuBarPanel | qt.QFrame.Plain)
            self._status_bar_widgets[lname] = l
            self.statusBar().addWidget(l, 0, True)

        notification_button = qt.QPushButton("0", self)
        notification_button.setSizePolicy(qt.QSizePolicy(
            qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum))
        self.connect(notification_button, qt.SIGNAL('clicked()'),
                     self.showNotifications)
        self._status_bar_widgets["notifications"] = notification_button
        self.statusBar().addWidget(notification_button, 0, True)

        w = qt.QWidget(self)
        self.statusBar().addWidget(w, 1, True)

    def _setupMenues(self):
        """
        Configures all the main windows menues
        """


        self._menues["file"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&File',self._menues["file"])







        self._actions["exit-faraday"].addTo(self._menues["file"]);
        self.menuBar().insertSeparator()


        self._menues["shell"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Shell',self._menues["shell"])
        self._actions["new_shell"].addTo(self._menues["shell"]);
        self._actions["close_shell"].addTo(self._menues["shell"]);
        self._actions["maximize-shell"].addTo(self._menues["shell"]);

        self.menuBar().insertSeparator()

        self._menues["edit"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Edit',self._menues["edit"])
        self._menues["edit"].insertItem('&Copy', self._copy)
        self._menues["edit"].insertItem('&Paste', self._paste)

        self._actions["repo-config"].addTo(self._menues["edit"]);

        self.menuBar().insertSeparator()


        self._menues["workspace"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Workspace',self._menues["workspace"])
        # self._actions["open-workspace"].addTo(self._menues["workspace"])
        self._actions["create-workspace"].addTo(self._menues["workspace"])



        self.menuBar().insertSeparator()


        self._menues["tools"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Tools',self._menues["tools"])
        self._actions["visualization"].addTo(self._menues["tools"]);

        self._actions["plugin"].addTo(self._menues["tools"]);
        self._actions["screenshot"].addTo(self._menues["tools"]);

        self.menuBar().insertSeparator()


        self._menues["view"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&View',self._menues["view"])
        self._actions["toggle-hosttree"].addTo(self._menues["view"]);
        self._actions["toggle-logconsole"].addTo(self._menues["view"]);
        self._actions["maximize-shell"].addTo(self._menues["view"]);

        self.menuBar().insertSeparator()


        self._menues["help"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Help',self._menues["help"])
        self._menues["help"].insertItem('&About', self._showAboutDialog)
        self._actions["documentation"].addTo(self._menues["help"]);




    def _setupMainToolbar(self):
        """
        Sets up the main toolbar
        """
        self._actions["new_shell"].addTo(self.main_toolbar)
        self._actions["toggle-hosttree"].addTo(self.main_toolbar)
        self._actions["toggle-logconsole"].addTo(self.main_toolbar)
        self._actions["maximize-shell"].addTo(self.main_toolbar)

        self._actions["clear-hosttree"].addTo(self.main_toolbar)
        self._actions["repo-config"].addTo(self.main_toolbar)
        self._actions["visualization"].addTo(self.main_toolbar)
        self._actions["plugin"].addTo(self.main_toolbar)
        self._actions["screenshot"].addTo(self.main_toolbar)
        self._actions["sfont"].addTo(self.main_toolbar)
        self._actions["bfont"].addTo(self.main_toolbar)
        if CONF.getDebugStatus():
            self._actions["debug"].addTo(self.main_toolbar)

    def setFilter(self):
        value = self.location_toolbar.getSelectedValue()
        self._hosts_treeview.filterTree(value)
        self.location_toolbar.addFilter(value)

    def showAll(self):

        self.show()

        self.main_toolbar.show()
        self.location_toolbar.show()

        self._tab_manager.show()

        self._perspective_manager.show()


        self._hosts_treeview.show()

        self._log_console.show()

        for shell_widget in self._shell_widgets:
            shell_widget.show()

    def addShell(self, shell_widget):
        self._shell_widgets.append(shell_widget)


        self._tab_manager.addView(shell_widget)
        shell_widget.show()
        shell_widget.setFocus()

    def createShellTab(self):

        tab_name = "Shell-%d" % self._tab_manager.getNextId()
        self._main_app.createShellEnvironment(tab_name)

    def destroyShellTab(self):


        tabmanager = self.getTabManager()
        if tabmanager.count() == 1:
            self.exitFaraday()
        else:
            index = tabmanager.currentPageIndex()
            name = tabmanager.label(index)
            self._main_app.deleteShellEnvironment(str(name))


    def imIncomplete(self):
        model.api.log("This function is not implemented yet")










    def _copy(self):
        None

    def _paste(self):


        text = qt.QApplication.clipboard().text()
        if not text.isEmpty():
            text.replace(qt.QRegExp("\n"), "\r")
        ev = qt.QKeyEvent(qt.QEvent.KeyPress, 0, -1, 0, text)
        shell = self.getShellWithFocus()
        if shell:
            shell.myemit('keyPressedSignal', (ev,))
            shell.myemit('clearSelectionSignal')
        qt.QApplication.clipboard().setSelectionMode(False)

    def _importWorkspace(self):
        model.api.showPopup("Be careful that importing could overwrite existing files", level="Warning")
        wm = self._main_app.getWorkspaceManager()
        mwin = self._main_app.getMainWindow()

        filename =  QFileDialog.getOpenFileName(
                    "$HOME/.faraday",
                    "Faraday export file  (*.faraday)",
                    None,
                    "import file dialog",
                    "Choose a file to import" );
        if filename and filename is not None:
            model.api.log("Import function %s/ %s" % (CONF.getPersistencePath(),filename))



            api.importWorskpace("%s/" % CONF.getPersistencePath(), filename)

            wm.loadWorkspaces()
            w = wm.getActiveWorkspace()
            wm.setActiveWorkspace(w)


            mwin.getWorkspaceTreeView().loadAllWorkspaces()

    def _exportWorkspace(self):
        filename =  QFileDialog.getSaveFileName(
                    "/tmp",
                    "Faraday export file  (*.faraday)",
                    None,
                    "save file dialog",
                    "Choose a file to save the export" );
        if filename and filename is not None:
            model.api.log("Export function %s" % filename)
            api.exportWorskpace("%s/" % CONF.getPersistencePath(), "%s.faraday" % filename)


    def getTabManager(self):
        return self._tab_manager

    def getLogConsole(self):
        return self._log_console

    def getHostTreeView(self):
        return self._hosts_treeview

    def getWorkspaceTreeView(self):
        return self._workspaces_treeview

    def refreshWorkspaceTreeView(self):
        self._workspaces_treeview.loadAllWorkspaces()

    def _showAboutDialog(self):
        about = AboutDialog(self)
        about.exec_loop()

    def _showConfigDialog(self):
        config_dialog = ConfigDialog(self)
        config_dialog.exec_loop()






    def showExceptionDialog(self, text="", callback=None , excection_objects=None):
        exc_dialog = ExceptionDialog(self, text, callback, excection_objects)
        return exc_dialog.exec_loop()

    def showSimpleDialog(self, text, type="Information"):
        dialog = SimpleDialog(self, text, type)
        return dialog.exec_loop()

    def showPluginSettingsDialog(self, type="Information"):
        dialog = PluginSettingsDialog(self, self._main_app.plugin_manager)
        return dialog.exec_loop()

    def showDebugPersistenceDialog(self, text, type="Information"):
        dialog = DebugPersistenceDialog(self)
        return dialog.exec_loop()

    def showPopup(self, text, type="Information"):
        message = "<b>%s:</b>\n%s" % (type, text)
        notification = NotificationWidget(self, message)
        notification.show()
        qt.QTimer.singleShot(4000, notification.closeNotification)

    def doLogin(self, callback=None):


        login_dialog = LoginDialog(self, callback)
        result_code = login_dialog.exec_loop()


        if result_code == qt.QDialog.Rejected:
            return None,None
        else:
            return login_dialog.getData()

    def showLoggedUser(self, username):
        self._status_bar_widgets["username"].setText("Logged user: %s" % username)

    def _showRepositoryConfigDialog(self):

        repoconfig_dialog = RepositoryConfigDialog(self, CONF.getCouchURI(),
                                                   CONF.getCouchIsReplicated(),
                                                   CONF.getCouchReplics(),
                                                   callback=None)
        result = repoconfig_dialog.exec_loop()
        if result == qt.QDialog.Accepted:
            repourl, isReplicated, replics = repoconfig_dialog.getData()
            api.devlog("repourl = %s" % repourl)
            wm = self._main_app.getWorkspaceManager()
            if not CouchDbManager.testCouch(repourl):
                self.showPopup("""
                Repository URL Not valid, check if
                service is available and that connection string is from
                the form: http[s]://hostname:port""")
                return

            CONF.setCouchUri(repourl)
            CONF.setCouchIsReplicated(isReplicated)
            CONF.setCouchReplics(replics)
            CONF.saveConfig()

            wm.closeWorkspace()
            wm.resource()
            wm.openWorkspace('untitled')

            mwin = self._main_app.getMainWindow()
            mwin.getWorkspaceTreeView().loadAllWorkspaces()
            mwin.getWorkspaceTreeView().setDefaultWorkspace()

    def showConflictsDialog(self, local):
        dialog = ResolveConflictsDialog(self, local=local)
        result = dialog.exec_loop()
        return result

    def customEvent(self, event):
        """
        This method is to be able to handle custom events in order
        to show custom dialogs or pop ups
        """
        if event.type() ==  EXCEPTION_ID:
            self.showExceptionDialog(event.text, event.callback, event.exception_objects)
        elif event.type() ==  SHOWDIALOG_ID:
            self.showSimpleDialog(event.text, event.level)
        elif event.type() ==  SHOWPOPUP_ID:
            self.showPopup(event.text, event.level)
        elif event.type() == CONFLICTS_ID:
            self.showConflictsDialog(event.local)
        elif event.type() == CHANGEFROMINSTANCE:
            self.newNotification(event.change)

    def update(self, event):
        if event.type() ==  EXCEPTION_ID:
            self.showExceptionDialog(event.text, event.callback, event.exception_objects)
        elif event.type() ==  SHOWDIALOG_ID:
            self.showSimpleDialog(event.text, event.level)
        elif event.type() ==  SHOWPOPUP_ID:
            self.showPopup(event.text, event.level)
        elif event.type() == CONFLICTS_ID:
            self.showConflictsDialog(event.local)

    def newNotification(self, change):
        button = self._status_bar_widgets["notifications"]
        button.setText(str(int(button.text()) + 1))
        button.setPaletteBackgroundColor(qt.QColor(180, 0, 0))
        self._notifications.append(change)

    def showNotifications(self):
        button = self._status_bar_widgets["notifications"]
        button.setText("0")
        button.setPaletteBackgroundColor(self.paletteBackgroundColor())
        dialog = NotificationsDialog(self, self._notifications)
        dialog.exec_loop()
        self._notifications[:] = []

    def toggleLogConsole(self):
        if self._log_console.isVisible():
            self._log_console.hide()
        else:
            self._log_console.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def togglePerspectives(self):
        if self._perspective_manager.isVisible():
            self._perspective_manager.hide()
        else:
            self._perspective_manager.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def maximizeShell(self):



        if self._is_shell_maximized:
            self._is_shell_maximized = False
            if not self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()
            if not self._perspective_manager.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()
        else:
            self._is_shell_maximized = True
            if self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()

            if self._hosts_treeview.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()

    def changeShellFont(self):
        preferences_dialog = PreferencesDialog(self)
        if preferences_dialog.exec_loop():
            self.setShellFont()
            CONF.setFont(self.shell_font.rawName())
            CONF.saveConfig()

    def setBfont(self):
        if (self._size+1) < len(self._sizes):
            self._size=self._size+1
            self.setShellFont()

    def setSfont(self):
        if (self._size-1) > -1:
            self._size=self._size-1
            self.setShellFont()

    def getShellWithFocus(self):
        for shell in self._shell_widgets:
            if shell.hasFocus():
                return shell
        return None

    def setShellFont(self):
        self.shell_font=qt.QFont()
        CONF.setFont("-Misc-Fixed-medium-r-normal-*-"+str(self._sizes[self._size])+"-100-100-100-c-70-iso8859-1")
        CONF.saveConfig()
        self.shell_font.setRawName(CONF.getFont())

        for shell in self._shell_widgets:
            shell.setVTFont(self.shell_font)

    def runVisualization(self):
        """
        runs script that builds the html for visutalizacion and opens a browser
        """
        base_uri = str(CONF.getCouchURI())
        uri = base_uri + "/reports/_design/reports/index.html"
        import requests
        try:
            response = requests.head(uri)
            res = response.ok
        except:
            res = False
            return notification_center.showDialog(
                    "Error trying to connect couchdb.\nIn order to see the visualizations you should have couchdb started.",
                    level="ERROR")
        if res:
            webbrowser.open_new(uri)

    def go2Website(self):

        webbrowser.open_new("https://www.faradaysec.com")
        model.api.log("Opening faraday's website")

    def closeEvent(self, e):
        result = self.exitFaraday()
        if result == qt.QDialog.Accepted:
            e.accept()

    def exitFaraday(self):
        exit_dialog = ExitDialog(self, self._main_app.quit)
        return exit_dialog.exec_loop()

    def doDebug(self):
        exit_dialog = MessageDialog(self, self.__debug,"Debug", "Faraday use IPython for debuging, please switch to terminal\n where do you execute the framework, use Ctrl+D to exit debug.\nDo you want to continue?" )
        return exit_dialog.exec_loop()

    def __debug(self, item=False):
        from utils import ipython_shell
        ipython_shell.embedd(locals(), globals())

    def takeScreenshot(self):
        view = self._tab_manager.activeWindow()
        ts = datetime.datetime.now().strftime("%Y%m%d%H%M%s")
        pixmap = qt.QPixmap.grabWidget(view)
        pixmap.save(os.path.join(CONF.getDefaultTempPath(), "shell_capture_%s.png" % ts), "PNG")
        pixmap = qt.QPixmap.grabWidget(self)
        pixmap.save(os.path.join(CONF.getDefaultTempPath(), "fullscreen_capture_%s.png" % ts), "PNG")
        model.api.log("Screenshots taken")

    def createWorkspace(self):

        wdialog = WorkspaceCreationDialog(self, callback=self._main_app.createWorkspace, workspace_manager=self._main_app.getWorkspaceManager())

        wdialog.exec_loop()


    def openWorkspace(self):


        name = "Untitled"
        self._main_app.openWorkspace(name)

    """
コード例 #2
0
class MainWindow(qt.QMainWindow):
    def __init__(self, title, main_app, model_controller, plugin_manager):
        qt.QMainWindow.__init__(self, None, title, qt.Qt.WDestructiveClose)
        self.setWindowState(qt.Qt.WindowMaximized)
        self.setCaption(title)

        self.setIcon(
            qt.QPixmap(os.path.join(CONF.getIconsPath(), 'faraday_icon.png')))

        self._main_app = main_app
        self._model_controller = model_controller

        self._mainArea = qt.QHBox(self)
        self.setCentralWidget(self._mainArea)
        self._vb_splitter = qt.QSplitter(self._mainArea)
        self._vb_splitter.setOrientation(qt.QSplitter.Vertical)
        self._hb_splitter = qt.QSplitter(self._vb_splitter)
        self._hb_splitter.setOrientation(qt.QSplitter.Horizontal)

        self.statusBar().setSizeGripEnabled(False)

        self._shell_widgets = []
        self._notifications = []
        self._tab_manager = TabManager(self._hb_splitter)
        self._perspective_manager = PerspectiveManager(self._hb_splitter,
                                                       self._main_app)

        self._hosts_treeview = HostsBrowser(self._perspective_manager,
                                            self._model_controller, 'Hosts')
        notifier.registerWidget(self._hosts_treeview)

        self._perspective_manager.registerPerspective(self._hosts_treeview,
                                                      default=True)

        wtw = WorkspaceTreeWindow(self._perspective_manager, 'Workspaces',
                                  self._main_app.getWorkspaceManager())
        self._perspective_manager.registerPerspective(wtw)
        self._workspaces_treeview = wtw

        self._log_console = LogConsole(self._vb_splitter, 'Console')

        self._actions = dict()
        self._setupActions()

        self._menues = {}
        self._setupMenues()

        self.main_toolbar = qt.QToolBar(self, 'main toolbar')
        self._setupMainToolbar()

        self.location_toolbar = LocationToolbar(self, 'location toolbar')
        self.location_toolbar.setOffset(1500)

        self._status_bar_widgets = dict()
        self._setupStatusBar()

        self._is_shell_maximized = False

        self.shell_font = qt.QFont()
        self.shell_font.setRawName(CONF.getFont())
        self.setSizeFont()

    def setSizeFont(self):
        if re.search("fixed", str(self.shell_font.family()),
                     re.IGNORECASE) is None:
            self.shell_font = qt.QFont()
            CONF.setFont(
                "-Misc-Fixed-medium-r-normal-*-12-100-100-100-c-70-iso8859-1")
            CONF.saveConfig()
            self.shell_font.setRawName(CONF.getFont())

        self._sizes = [
            6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36
        ]
        i = 0
        self._size = 6
        for f_i in self._sizes:
            if f_i == self.shell_font.pixelSize():
                self._size = i
            i += 1

    def setMainApp(self, mainapp):
        self._main_app = mainapp

    def _setupActions(self):
        """
        creates some actions needed on some menues and toolbars
        Actions are later added to different toolbars, for example in
        method _setupMainToolbar
        """

        a = self._actions["new_shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "newshell.png"))), "&New Shell",
            qt.Qt.CTRL + qt.Qt.SHIFT + qt.Qt.Key_T, self, "New Shell")
        self.connect(a, qt.SIGNAL('activated()'), self.createShellTab)

        a = self._actions["close_shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "exit.png"))), "&Close Shell",
            qt.Qt.CTRL + qt.Qt.SHIFT + qt.Qt.Key_W, self, "New Shell")
        self.connect(a, qt.SIGNAL('activated()'), self.destroyShellTab)

        a = self._actions["toggle-hosttree"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(
                    os.path.join(CONF.getIconsPath(), "HostTreeView.png"))),
            "Toggle Host Tree", 0, self, "Toggle Log Console")
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.togglePerspectives)

        a = self._actions["toggle-logconsole"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "LogConsole.png"))),
            "Toggle Log Console", 0, self, "Toggle Log Console")
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.toggleLogConsole)

        a = self._actions["maximize-shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "maximize.png"))),
            "Maximize Shell", 0, self, "Maximize Shell")
        a.setToggleAction(True)

        self.connect(a, qt.SIGNAL('activated()'), self.maximizeShell)
        self._tab_manager.tabBar().addAction("maximize", self.maximizeShell)

        #a = self._actions["test"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"donotpresstheredbutton.png"))), "Test", qt.Qt.CTRL + qt.Qt.Key_H, self, "Test" )

        #self.connect(a, qt.SIGNAL('activated()'), self.test)

        a = self._actions["screenshot"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "Screenshot.png"))), "Take Screenshot",
            0, self, "Take Screenshot")
        self.connect(a, qt.SIGNAL('activated()'), self.takeScreenshot)

        a = self._actions["clear-hosttree"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "clear.png"))), "Clear Host Tree",
            qt.Qt.CTRL + qt.Qt.Key_R, self, "Clear Host Tree")
        self.connect(a, qt.SIGNAL('activated()'),
                     self._hosts_treeview.clearTree)

        a = self._actions["repo-config"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "connect.png"))),
            "Server Connection", 0, self, "Server Connection")
        self.connect(a, qt.SIGNAL('activated()'),
                     self._showRepositoryConfigDialog)

        a = self._actions["visualization"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "visualize.png"))), "Visualize", 0,
            self, "Visualize")
        self.connect(a, qt.SIGNAL('activated()'), self.runVisualization)

        a = self._actions["plugin"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "config.png"))),
            "Plugin", 0, self, "Plugin")
        self.connect(a, qt.SIGNAL('activated()'),
                     self.showPluginSettingsDialog)

        a = self._actions["documentation"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(
                    os.path.join(CONF.getIconsPath(), "Documentation.png"))),
            "Documentation", 0, self, "Documentation")
        self.connect(a, qt.SIGNAL('activated()'), self.go2Website)

        a = self._actions["exit-faraday"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "exit.png"))),
            "Exit Faraday", 0, self, "Exit Faraday")
        self.connect(a, qt.SIGNAL('activated()'), self.exitFaraday)

        a = self._actions["create-workspace"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "sync.png"))),
            "Create", 0, self, "Create")
        self.connect(a, qt.SIGNAL('activated()'), self.createWorkspace)

        # a = self._actions["open-workspace"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"sync.png"))), "Open", 0, self, "Open" )
        # self.connect(a, qt.SIGNAL('activated()'), self.openWorkspace)

        a = self._actions["bfont"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "fontb.png"))),
            "Big Font", 0, self, "Big Font")
        self.connect(a, qt.SIGNAL('activated()'), self.setBfont)

        a = self._actions["sfont"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "fonts.png"))),
            "Small Font", 0, self, "Small Font")
        self.connect(a, qt.SIGNAL('activated()'), self.setSfont)

        if CONF.getDebugStatus():
            a = self._actions["debug"] = qt.QAction(
                qt.QIconSet(
                    qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                            "debug.png"))), "Debug", 0, self,
                "Debug")
            self.connect(a, qt.SIGNAL('activated()'), self.doDebug)

    def _setupStatusBar(self):
        label_order = ["username", "userLevel", "space", "status"]
        for lname in label_order:
            l = qt.QLabel("", self)
            l.setFrameStyle(qt.QFrame.MenuBarPanel | qt.QFrame.Plain)
            self._status_bar_widgets[lname] = l
            self.statusBar().addWidget(l, 0, True)

        notification_button = qt.QPushButton("0", self)
        notification_button.setSizePolicy(
            qt.QSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum))
        self.connect(notification_button, qt.SIGNAL('clicked()'),
                     self.showNotifications)
        self._status_bar_widgets["notifications"] = notification_button
        self.statusBar().addWidget(notification_button, 0, True)

        w = qt.QWidget(self)
        self.statusBar().addWidget(w, 1, True)

    def _setupMenues(self):
        """
        Configures all the main windows menues
        """

        self._menues["file"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&File', self._menues["file"])

        self._actions["exit-faraday"].addTo(self._menues["file"])
        self.menuBar().insertSeparator()

        self._menues["shell"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Shell', self._menues["shell"])
        self._actions["new_shell"].addTo(self._menues["shell"])
        self._actions["close_shell"].addTo(self._menues["shell"])
        self._actions["maximize-shell"].addTo(self._menues["shell"])

        self.menuBar().insertSeparator()

        self._menues["edit"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Edit', self._menues["edit"])
        self._menues["edit"].insertItem('&Copy', self._copy)
        self._menues["edit"].insertItem('&Paste', self._paste)

        self._actions["repo-config"].addTo(self._menues["edit"])

        self.menuBar().insertSeparator()

        self._menues["workspace"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Workspace', self._menues["workspace"])
        # self._actions["open-workspace"].addTo(self._menues["workspace"])
        self._actions["create-workspace"].addTo(self._menues["workspace"])

        self.menuBar().insertSeparator()

        self._menues["tools"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Tools', self._menues["tools"])
        self._actions["visualization"].addTo(self._menues["tools"])

        self._actions["plugin"].addTo(self._menues["tools"])
        self._actions["screenshot"].addTo(self._menues["tools"])

        self.menuBar().insertSeparator()

        self._menues["view"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&View', self._menues["view"])
        self._actions["toggle-hosttree"].addTo(self._menues["view"])
        self._actions["toggle-logconsole"].addTo(self._menues["view"])
        self._actions["maximize-shell"].addTo(self._menues["view"])

        self.menuBar().insertSeparator()

        self._menues["help"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Help', self._menues["help"])
        self._menues["help"].insertItem('&About', self._showAboutDialog)
        self._actions["documentation"].addTo(self._menues["help"])

    def _setupMainToolbar(self):
        """
        Sets up the main toolbar
        """
        self._actions["new_shell"].addTo(self.main_toolbar)
        self._actions["toggle-hosttree"].addTo(self.main_toolbar)
        self._actions["toggle-logconsole"].addTo(self.main_toolbar)
        self._actions["maximize-shell"].addTo(self.main_toolbar)

        self._actions["clear-hosttree"].addTo(self.main_toolbar)
        self._actions["repo-config"].addTo(self.main_toolbar)
        self._actions["visualization"].addTo(self.main_toolbar)
        self._actions["plugin"].addTo(self.main_toolbar)
        self._actions["screenshot"].addTo(self.main_toolbar)
        self._actions["sfont"].addTo(self.main_toolbar)
        self._actions["bfont"].addTo(self.main_toolbar)
        if CONF.getDebugStatus():
            self._actions["debug"].addTo(self.main_toolbar)

    def setFilter(self):
        value = self.location_toolbar.getSelectedValue()
        self._hosts_treeview.filterTree(value)
        self.location_toolbar.addFilter(value)

    def showAll(self):

        self.show()

        self.main_toolbar.show()
        self.location_toolbar.show()

        self._tab_manager.show()

        self._perspective_manager.show()

        self._hosts_treeview.show()

        self._log_console.show()

        self.timer = qt.QTimer(self)
        self.connect(self.timer, qt.SIGNAL('timeout()'), self.createShellTab)
        self.timer.start(1000, True)

        for shell_widget in self._shell_widgets:
            shell_widget.show()

    def addShell(self, shell_widget):
        self._shell_widgets.append(shell_widget)

        self._tab_manager.addView(shell_widget)
        shell_widget.show()
        shell_widget.setFocus()

    def createShellTab(self):
        tab_name = "Shell-%d" % self._tab_manager.getNextId()
        self._main_app.createShellEnvironment(tab_name)

    def destroyShellTab(self):

        tabmanager = self.getTabManager()
        if tabmanager.count() == 1:
            self.exitFaraday()
        else:
            index = tabmanager.currentPageIndex()
            name = tabmanager.label(index)
            self._main_app.deleteShellEnvironment(str(name))

    def imIncomplete(self):
        model.api.log("This function is not implemented yet")

    def _copy(self):
        None

    def _paste(self):

        text = qt.QApplication.clipboard().text()
        if not text.isEmpty():
            text.replace(qt.QRegExp("\n"), "\r")
        ev = qt.QKeyEvent(qt.QEvent.KeyPress, 0, -1, 0, text)
        shell = self.getShellWithFocus()
        if shell:
            shell.myemit('keyPressedSignal', (ev, ))
            shell.myemit('clearSelectionSignal')
        qt.QApplication.clipboard().setSelectionMode(False)

    def _importWorkspace(self):
        model.api.showPopup(
            "Be careful that importing could overwrite existing files",
            level="Warning")
        wm = self._main_app.getWorkspaceManager()
        mwin = self._main_app.getMainWindow()

        filename = QFileDialog.getOpenFileName(
            "$HOME/.faraday", "Faraday export file  (*.faraday)", None,
            "import file dialog", "Choose a file to import")
        if filename and filename is not None:
            model.api.log("Import function %s/ %s" %
                          (CONF.getPersistencePath(), filename))

            api.importWorskpace("%s/" % CONF.getPersistencePath(), filename)

            wm.loadWorkspaces()
            w = wm.getActiveWorkspace()
            wm.setActiveWorkspace(w)

            mwin.getWorkspaceTreeView().loadAllWorkspaces()

    def _exportWorkspace(self):
        filename = QFileDialog.getSaveFileName(
            "/tmp", "Faraday export file  (*.faraday)", None,
            "save file dialog", "Choose a file to save the export")
        if filename and filename is not None:
            model.api.log("Export function %s" % filename)
            api.exportWorskpace("%s/" % CONF.getPersistencePath(),
                                "%s.faraday" % filename)

    def getTabManager(self):
        return self._tab_manager

    def getLogConsole(self):
        return self._log_console

    def getHostTreeView(self):
        return self._hosts_treeview

    def getWorkspaceTreeView(self):
        return self._workspaces_treeview

    def refreshWorkspaceTreeView(self):
        self._workspaces_treeview.loadAllWorkspaces()

    def _showAboutDialog(self):
        about = AboutDialog(self)
        about.exec_loop()

    def _showConfigDialog(self):
        config_dialog = ConfigDialog(self)
        config_dialog.exec_loop()

    def showExceptionDialog(self,
                            text="",
                            callback=None,
                            excection_objects=None):
        exc_dialog = ExceptionDialog(self, text, callback, excection_objects)
        return exc_dialog.exec_loop()

    def showSimpleDialog(self, text, type="Information"):
        dialog = SimpleDialog(self, text, type)
        return dialog.exec_loop()

    def showPluginSettingsDialog(self, type="Information"):
        dialog = PluginSettingsDialog(self, self._main_app.plugin_manager)
        return dialog.exec_loop()

    def showDebugPersistenceDialog(self, text, type="Information"):
        dialog = DebugPersistenceDialog(self)
        return dialog.exec_loop()

    def showPopup(self, text, type="Information"):
        message = "<b>%s:</b>\n%s" % (type, text)
        notification = NotificationWidget(self, message)
        notification.show()
        qt.QTimer.singleShot(4000, notification.closeNotification)

    def doLogin(self, callback=None):

        login_dialog = LoginDialog(self, callback)
        result_code = login_dialog.exec_loop()

        if result_code == qt.QDialog.Rejected:
            return None, None
        else:
            return login_dialog.getData()

    def showLoggedUser(self, username):
        self._status_bar_widgets["username"].setText("Logged user: %s" %
                                                     username)

    def _showRepositoryConfigDialog(self):

        repoconfig_dialog = RepositoryConfigDialog(self,
                                                   CONF.getCouchURI(),
                                                   CONF.getCouchIsReplicated(),
                                                   CONF.getCouchReplics(),
                                                   callback=None)
        result = repoconfig_dialog.exec_loop()
        if result == qt.QDialog.Accepted:
            repourl, isReplicated, replics = repoconfig_dialog.getData()
            api.devlog("repourl = %s" % repourl)
            wm = self._main_app.getWorkspaceManager()
            if not CouchDbManager.testCouch(repourl):
                self.showPopup("""
                Repository URL Not valid, check if
                service is available and that connection string is from
                the form: http[s]://hostname:port""")
                return
            if repourl.startswith("https://"):
                if not checkSSL(repourl):
                    self.showPopup("""
                        SSL certificate validation failed.
                        You can use the --cert option in Faraday
                        to set the path of the cert
                        """)
                    return

            CONF.setCouchUri(repourl)
            CONF.setCouchIsReplicated(isReplicated)
            CONF.setCouchReplics(replics)
            CONF.saveConfig()

            wm.closeWorkspace()
            wm.resource()
            wm.openWorkspace('untitled')

            mwin = self._main_app.getMainWindow()
            mwin.getWorkspaceTreeView().loadAllWorkspaces()
            mwin.getWorkspaceTreeView().setDefaultWorkspace()

    def showConflictsDialog(self, local):
        dialog = ResolveConflictsDialog(self, local=local)
        result = dialog.exec_loop()
        return result

    def customEvent(self, event):
        """
        This method is to be able to handle custom events in order
        to show custom dialogs or pop ups
        """
        if event.type() == EXCEPTION_ID:
            self.showExceptionDialog(event.text, event.callback,
                                     event.exception_objects)
        elif event.type() == SHOWDIALOG_ID:
            self.showSimpleDialog(event.text, event.level)
        elif event.type() == SHOWPOPUP_ID:
            self.showPopup(event.text, event.level)
        elif event.type() == CONFLICTS_ID:
            self.showConflictsDialog(event.local)
        elif event.type() == CHANGEFROMINSTANCE:
            self.newNotification(event.change)

    def update(self, event):
        if event.type() == EXCEPTION_ID:
            self.showExceptionDialog(event.text, event.callback,
                                     event.exception_objects)
        elif event.type() == SHOWDIALOG_ID:
            self.showSimpleDialog(event.text, event.level)
        elif event.type() == SHOWPOPUP_ID:
            self.showPopup(event.text, event.level)
        elif event.type() == CONFLICTS_ID:
            self.showConflictsDialog(event.local)

    def newNotification(self, change):
        button = self._status_bar_widgets["notifications"]
        button.setText(str(int(button.text()) + 1))
        button.setPaletteBackgroundColor(qt.QColor(180, 0, 0))
        self._notifications.append(change)

    def showNotifications(self):
        button = self._status_bar_widgets["notifications"]
        button.setText("0")
        button.setPaletteBackgroundColor(self.paletteBackgroundColor())
        dialog = NotificationsDialog(self, self._notifications)
        dialog.exec_loop()
        self._notifications[:] = []

    def toggleLogConsole(self):
        if self._log_console.isVisible():
            self._log_console.hide()
        else:
            self._log_console.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def togglePerspectives(self):
        if self._perspective_manager.isVisible():
            self._perspective_manager.hide()
        else:
            self._perspective_manager.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def maximizeShell(self):

        if self._is_shell_maximized:
            self._is_shell_maximized = False
            if not self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()
            if not self._perspective_manager.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()
        else:
            self._is_shell_maximized = True
            if self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()

            if self._hosts_treeview.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()

    def changeShellFont(self):
        preferences_dialog = PreferencesDialog(self)
        if preferences_dialog.exec_loop():
            self.setShellFont()
            CONF.setFont(self.shell_font.rawName())
            CONF.saveConfig()

    def setBfont(self):
        if (self._size + 1) < len(self._sizes):
            self._size = self._size + 1
            self.setShellFont()

    def setSfont(self):
        if (self._size - 1) > -1:
            self._size = self._size - 1
            self.setShellFont()

    def getShellWithFocus(self):
        for shell in self._shell_widgets:
            if shell.hasFocus():
                return shell
        return None

    def setShellFont(self):
        self.shell_font = qt.QFont()
        CONF.setFont("-Misc-Fixed-medium-r-normal-*-" +
                     str(self._sizes[self._size]) +
                     "-100-100-100-c-70-iso8859-1")
        CONF.saveConfig()
        self.shell_font.setRawName(CONF.getFont())

        for shell in self._shell_widgets:
            shell.setVTFont(self.shell_font)

    def runVisualization(self):
        """
        runs script that builds the html for visutalizacion and opens a browser
        """
        base_uri = str(CONF.getCouchURI())
        current_workspace = str(CONF.getLastWorkspace())
        uri = base_uri + "/reports/_design/reports/index.html#/dashboard/ws/" + current_workspace
        import requests
        try:
            response = requests.head(uri)
            res = response.ok
        except:
            res = False
            return notification_center.showDialog(
                "Error trying to connect couchdb.\nIn order to see the visualizations you should have couchdb started.",
                level="ERROR")
        if res:
            webbrowser.open_new(uri)

    def go2Website(self):

        webbrowser.open_new("https://www.faradaysec.com")
        model.api.log("Opening faraday's website")

    def closeEvent(self, e):
        result = self.exitFaraday()
        if result == qt.QDialog.Accepted:
            e.accept()

    def exitFaraday(self):
        result = model.api.getConflicts()
        msg = "Are you sure?"
        if result:
            msg = "You have pending conflicts\nAre you sure you want to exit and discard them ?"

        exit_dialog = ExitDialog(self, self._main_app.quit, msg=msg)
        return exit_dialog.exec_loop()

    def doDebug(self):
        exit_dialog = MessageDialog(
            self, self.__debug, "Debug",
            "Faraday use IPython for debuging, please switch to terminal\n where do you execute the framework, use Ctrl+D to exit debug.\nDo you want to continue?"
        )
        return exit_dialog.exec_loop()

    def __debug(self, item=False):
        from utils import ipython_shell
        ipython_shell.embedd(locals(), globals())

    def takeScreenshot(self):
        view = self._tab_manager.activeWindow()
        ts = datetime.datetime.now().strftime("%Y%m%d%H%M%s")
        pixmap = qt.QPixmap.grabWidget(view)
        pixmap.save(
            os.path.join(CONF.getDefaultTempPath(),
                         "shell_capture_%s.png" % ts), "PNG")
        pixmap = qt.QPixmap.grabWidget(self)
        pixmap.save(
            os.path.join(CONF.getDefaultTempPath(),
                         "fullscreen_capture_%s.png" % ts), "PNG")
        model.api.log("Screenshots taken")

    def createWorkspace(self):

        wdialog = WorkspaceCreationDialog(
            self,
            callback=self._main_app.createWorkspace,
            workspace_manager=self._main_app.getWorkspaceManager())

        wdialog.exec_loop()

    def openWorkspace(self):

        name = "Untitled"
        self._main_app.openWorkspace(name)

    """
コード例 #3
0
ファイル: mainwindow.py プロジェクト: andy737/faraday
class MainWindow(qt.QMainWindow):
    def __init__(self, title, main_app, model_controller):
        qt.QMainWindow.__init__(self, None, title, qt.Qt.WDestructiveClose)
        self.setWindowState(qt.Qt.WindowMaximized)
        self.setCaption(title)

        self.setIcon(
            qt.QPixmap(os.path.join(CONF.getIconsPath(), "faraday_icon.png")))

        self._main_app = main_app
        self._model_controller = model_controller

        self._mainArea = qt.QHBox(self)
        self.setCentralWidget(self._mainArea)
        self._vb_splitter = qt.QSplitter(self._mainArea)
        self._vb_splitter.setOrientation(qt.QSplitter.Vertical)

        self._hb_splitter = qt.QSplitter(self._vb_splitter)
        self._hb_splitter.setOrientation(qt.QSplitter.Horizontal)

        self.statusBar().setSizeGripEnabled(False)

        self._shell_widgets = []

        self._tab_manager = TabManager(self._hb_splitter)
        self._perspective_manager = PerspectiveManager(self._hb_splitter,
                                                       self._main_app)

        self._hosts_treeview = HostsBrowser(self._perspective_manager, "Hosts")
        self._model_controller.registerWidget(self._hosts_treeview)
        self._perspective_manager.registerPerspective(self._hosts_treeview,
                                                      default=True)

        wtw = WorkspaceTreeWindow(self._perspective_manager, "Workspaces",
                                  self._main_app.getWorkspaceManager())
        self._perspective_manager.registerPerspective(wtw)
        self._workspaces_treeview = wtw

        self._log_console = LogConsole(self._vb_splitter, "Console")

        self._actions = dict()
        self._setupActions()

        self._menues = {}
        self._setupMenues()

        self.main_toolbar = qt.QToolBar(self, 'main toolbar')
        self._setupMainToolbar()

        self.location_toolbar = LocationToolbar(self, 'location toolbar')
        self.location_toolbar.setOffset(1500)

        self._status_bar_widgets = dict()
        self._setupStatusBar()

        self._is_shell_maximized = False

        self.shell_font = qt.QFont()
        self.shell_font.setRawName(CONF.getFont())
        self.setSizeFont()

    def setSizeFont(self):
        if re.search("fixed", str(self.shell_font.family()),
                     re.IGNORECASE) is None:
            self.shell_font = qt.QFont()
            CONF.setFont(
                "-Misc-Fixed-medium-r-normal-*-12-100-100-100-c-70-iso8859-1")
            CONF.saveConfig()
            self.shell_font.setRawName(CONF.getFont())

        self._sizes = [
            6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36
        ]
        i = 0
        self._size = 6
        for f_i in self._sizes:
            if f_i == self.shell_font.pixelSize():
                self._size = i
            i += 1

    def setMainApp(self, mainapp):
        self._main_app = mainapp

    def _setupActions(self):
        """
        creates some actions needed on some menues and toolbars
        Actions are later added to different toolbars, for example in
        method _setupMainToolbar
        """

        a = self._actions["new_shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "newshell.png"))), "&New Shell",
            qt.Qt.CTRL + qt.Qt.SHIFT + qt.Qt.Key_T, self, "New Shell")
        self.connect(a, qt.SIGNAL('activated()'), self.createShellTab)

        a = self._actions["close_shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "exit.png"))), "&Close Shell",
            qt.Qt.CTRL + qt.Qt.SHIFT + qt.Qt.Key_W, self, "New Shell")
        self.connect(a, qt.SIGNAL('activated()'), self.destroyShellTab)

        a = self._actions["toggle-hosttree"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(
                    os.path.join(CONF.getIconsPath(), "HostTreeView.png"))),
            "Toggle Host Tree", 0, self, "Toggle Log Console")
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.togglePerspectives)

        a = self._actions["toggle-logconsole"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "LogConsole.png"))),
            "Toggle Log Console", 0, self, "Toggle Log Console")
        a.setToggleAction(True)
        a.toggle()
        self.connect(a, qt.SIGNAL('activated()'), self.toggleLogConsole)

        a = self._actions["maximize-shell"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "maximize.png"))),
            "Maximize Shell", 0, self, "Maximize Shell")
        a.setToggleAction(True)

        self.connect(a, qt.SIGNAL('activated()'), self.maximizeShell)
        self._tab_manager.tabBar().addAction("maximize", self.maximizeShell)

        a = self._actions["test"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(
                    os.path.join(CONF.getIconsPath(),
                                 "donotpresstheredbutton.png"))), "Test",
            qt.Qt.CTRL + qt.Qt.Key_H, self, "Test")

        self.connect(a, qt.SIGNAL('activated()'), self.test)

        a = self._actions["screenshot"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "Screenshot.png"))), "Take Screenshot",
            0, self, "Take Screenshot")
        self.connect(a, qt.SIGNAL('activated()'), self.takeScreenshot)

        a = self._actions["clear-hosttree"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "clear.png"))), "Clear Host Tree",
            qt.Qt.CTRL + qt.Qt.Key_R, self, "Clear Host Tree")
        self.connect(a, qt.SIGNAL('activated()'),
                     self._hosts_treeview.clearTree)

        a = self._actions["repo-config"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "connect.png"))),
            "Server Connection", 0, self, "Server Connection")
        self.connect(a, qt.SIGNAL('activated()'),
                     self._showRepositoryConfigDialog)

        a = self._actions["visualization"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                        "visualize.png"))), "Visualize", 0,
            self, "Visualize")
        self.connect(a, qt.SIGNAL('activated()'), self.runVisualization)

        a = self._actions["plugin"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "config.png"))),
            "Plugin", 0, self, "Plugin")
        self.connect(a, qt.SIGNAL('activated()'),
                     self.showPluginSettingsDialog)

        a = self._actions["documentation"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(
                    os.path.join(CONF.getIconsPath(), "Documentation.png"))),
            "Documentation", 0, self, "Documentation")
        self.connect(a, qt.SIGNAL('activated()'), self.go2Website)

        a = self._actions["exit-faraday"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "exit.png"))),
            "Exit Faraday", 0, self, "Exit Faraday")
        self.connect(a, qt.SIGNAL('activated()'), self.exitFaraday)

        a = self._actions["create-workspace"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "sync.png"))),
            "Create", 0, self, "Create")
        self.connect(a, qt.SIGNAL('activated()'), self.createWorkspace)

        # a = self._actions["open-workspace"] = qt.QAction( qt.QIconSet(qt.QPixmap(os.path.join(CONF.getIconsPath(),"sync.png"))), "Open", 0, self, "Open" )
        # self.connect(a, qt.SIGNAL('activated()'), self.openWorkspace)

        a = self._actions["reconnect"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "sync.png"))),
            "Reconnect", 0, self, "Reconnect")

        self.connect(a, qt.SIGNAL('activated()'), self.reconnect)

        a = self._actions["bfont"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "fontb.png"))),
            "Big Font", 0, self, "Big Font")
        self.connect(a, qt.SIGNAL('activated()'), self.setBfont)

        a = self._actions["sfont"] = qt.QAction(
            qt.QIconSet(
                qt.QPixmap(os.path.join(CONF.getIconsPath(), "fonts.png"))),
            "Small Font", 0, self, "Small Font")
        self.connect(a, qt.SIGNAL('activated()'), self.setSfont)

        if CONF.getDebugStatus():
            a = self._actions["debug"] = qt.QAction(
                qt.QIconSet(
                    qt.QPixmap(os.path.join(CONF.getIconsPath(),
                                            "debug.png"))), "Debug", 0, self,
                "Debug")
            self.connect(a, qt.SIGNAL('activated()'), self.doDebug)

    def _setupStatusBar(self):
        label_order = ["username", "userLevel", "space", "status"]
        for lname in label_order:
            l = qt.QLabel("", self)
            l.setFrameStyle(qt.QFrame.MenuBarPanel | qt.QFrame.Plain)
            self._status_bar_widgets[lname] = l
            self.statusBar().addWidget(l, 0, True)

        w = qt.QWidget(self)
        self.statusBar().addWidget(w, 1, True)

    def _setupMenues(self):
        """
        Configures all the main windows menues
        """

        self._menues["file"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&File', self._menues["file"])

        self._actions["exit-faraday"].addTo(self._menues["file"])
        self.menuBar().insertSeparator()

        self._menues["shell"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Shell', self._menues["shell"])
        self._actions["new_shell"].addTo(self._menues["shell"])
        self._actions["close_shell"].addTo(self._menues["shell"])
        self._actions["maximize-shell"].addTo(self._menues["shell"])

        self.menuBar().insertSeparator()

        self._menues["edit"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Edit', self._menues["edit"])
        self._menues["edit"].insertItem('&Copy', self._copy)
        self._menues["edit"].insertItem('&Paste', self._paste)

        self._actions["repo-config"].addTo(self._menues["edit"])

        self.menuBar().insertSeparator()

        self._menues["workspace"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Workspace', self._menues["workspace"])
        # self._actions["open-workspace"].addTo(self._menues["workspace"])
        self._actions["create-workspace"].addTo(self._menues["workspace"])

        self.menuBar().insertSeparator()

        self._menues["tools"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Tools', self._menues["tools"])
        self._actions["visualization"].addTo(self._menues["tools"])

        self._actions["plugin"].addTo(self._menues["tools"])
        self._actions["screenshot"].addTo(self._menues["tools"])

        self.menuBar().insertSeparator()

        self._menues["view"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&View', self._menues["view"])
        self._actions["toggle-hosttree"].addTo(self._menues["view"])
        self._actions["toggle-logconsole"].addTo(self._menues["view"])
        self._actions["maximize-shell"].addTo(self._menues["view"])

        self.menuBar().insertSeparator()

        self._menues["help"] = qt.QPopupMenu(self)
        self.menuBar().insertItem('&Help', self._menues["help"])
        self._menues["help"].insertItem('&About', self._showAboutDialog)
        self._actions["documentation"].addTo(self._menues["help"])

    def _setupMainToolbar(self):
        """
        Sets up the main toolbar
        """
        self._actions["new_shell"].addTo(self.main_toolbar)
        self._actions["toggle-hosttree"].addTo(self.main_toolbar)
        self._actions["toggle-logconsole"].addTo(self.main_toolbar)
        self._actions["maximize-shell"].addTo(self.main_toolbar)

        self._actions["clear-hosttree"].addTo(self.main_toolbar)
        self._actions["repo-config"].addTo(self.main_toolbar)
        self._actions["visualization"].addTo(self.main_toolbar)
        self._actions["plugin"].addTo(self.main_toolbar)
        self._actions["screenshot"].addTo(self.main_toolbar)
        self._actions["reconnect"].addTo(self.main_toolbar)
        self._actions["sfont"].addTo(self.main_toolbar)
        self._actions["bfont"].addTo(self.main_toolbar)
        if CONF.getDebugStatus():
            self._actions["debug"].addTo(self.main_toolbar)

    def setFilter(self):
        value = self.location_toolbar.getSelectedValue()
        self._hosts_treeview.filterTree(value)
        self.location_toolbar.addFilter(value)

    def showAll(self):

        self.show()

        self.main_toolbar.show()
        self.location_toolbar.show()

        self._tab_manager.show()

        self._perspective_manager.show()

        self._hosts_treeview.show()

        self._log_console.show()

        for shell_widget in self._shell_widgets:
            shell_widget.show()

    def addShell(self, shell_widget):
        self._shell_widgets.append(shell_widget)

        self._tab_manager.addView(shell_widget)
        shell_widget.show()
        shell_widget.setFocus()

    def createShellTab(self):

        tab_name = "Shell-%d" % self._tab_manager.getNextId()
        self._main_app.createShellEnvironment(tab_name)

    def destroyShellTab(self):

        tabmanager = self.getTabManager()
        if tabmanager.count() == 1:
            self.exitFaraday()
        else:
            index = tabmanager.currentPageIndex()
            name = tabmanager.label(index)
            self._main_app.deleteShellEnvironment(str(name))

    def imIncomplete(self):
        model.api.log("This function is not implemented yet")

    def _copy(self):
        None

    def _paste(self):

        text = qt.QApplication.clipboard().text()
        if not text.isEmpty():
            text.replace(qt.QRegExp("\n"), "\r")
        ev = qt.QKeyEvent(qt.QEvent.KeyPress, 0, -1, 0, text)
        shell = self.getShellWithFocus()
        if shell:
            shell.myemit('keyPressedSignal', (ev, ))
            shell.myemit('clearSelectionSignal')
        qt.QApplication.clipboard().setSelectionMode(False)

    def _importWorkspace(self):
        model.api.showPopup(
            "Be careful that importing could overwrite existing files",
            level="Warning")
        wm = self._main_app.getWorkspaceManager()
        mwin = self._main_app.getMainWindow()

        filename = QFileDialog.getOpenFileName(
            "$HOME/.faraday", "Faraday export file  (*.faraday)", None,
            "import file dialog", "Choose a file to import")
        if filename and filename is not None:
            model.api.log("Import function %s/ %s" %
                          (CONF.getPersistencePath(), filename))

            api.importWorskpace("%s/" % CONF.getPersistencePath(), filename)

            wm.loadWorkspaces()
            w = wm.getActiveWorkspace()
            wm.setActiveWorkspace(w)

            mwin.getWorkspaceTreeView().loadAllWorkspaces()

    def _exportWorkspace(self):
        filename = QFileDialog.getSaveFileName(
            "/tmp", "Faraday export file  (*.faraday)", None,
            "save file dialog", "Choose a file to save the export")
        if filename and filename is not None:
            model.api.log("Export function %s" % filename)
            api.exportWorskpace("%s/" % CONF.getPersistencePath(),
                                "%s.faraday" % filename)

    def getTabManager(self):
        return self._tab_manager

    def getLogConsole(self):
        return self._log_console

    def getHostTreeView(self):
        return self._hosts_treeview

    def getWorkspaceTreeView(self):
        return self._workspaces_treeview

    def refreshWorkspaceTreeView(self):
        self._workspaces_treeview.loadAllWorkspaces()

    def _showAboutDialog(self):
        about = AboutDialog(self)
        about.exec_loop()

    def _showConfigDialog(self):
        config_dialog = ConfigDialog(self)
        config_dialog.exec_loop()

    def showExceptionDialog(self,
                            text="",
                            callback=None,
                            excection_objects=None):
        exc_dialog = ExceptionDialog(self, text, callback, excection_objects)
        return exc_dialog.exec_loop()

    def showSimpleDialog(self, text, type="Information"):
        dialog = SimpleDialog(self, text, type)
        return dialog.exec_loop()

    def showPluginSettingsDialog(self, type="Information"):
        dialog = PluginSettingsDialog(self, self._main_app.plugin_manager)
        return dialog.exec_loop()

    def showDebugPersistenceDialog(self, text, type="Information"):
        dialog = DebugPersistenceDialog(self)
        return dialog.exec_loop()

    def showPopup(self, text, type="Information"):
        message = "<b>%s:</b>\n%s" % (type, text)
        notification = NotificationWidget(self, message)
        notification.show()
        qt.QTimer.singleShot(4000, notification.closeNotification)

    def doLogin(self, callback=None):

        login_dialog = LoginDialog(self, callback)
        result_code = login_dialog.exec_loop()

        if result_code == qt.QDialog.Rejected:
            return None, None
        else:
            return login_dialog.getData()

    def showLoggedUser(self, username):
        self._status_bar_widgets["username"].setText("Logged user: %s" %
                                                     username)

    def _showRepositoryConfigDialog(self):

        repoconfig_dialog = RepositoryConfigDialog(self,
                                                   CONF.getCouchURI(),
                                                   CONF.getCouchIsReplicated(),
                                                   CONF.getCouchReplics(),
                                                   callback=None)
        result = repoconfig_dialog.exec_loop()
        if result == qt.QDialog.Accepted:
            repourl, isReplicated, replics = repoconfig_dialog.getData()
            api.devlog("repourl = %s" % repourl)
            wm = self._main_app.getWorkspaceManager()
            if not CouchdbManager.testCouch(repourl):
                self.showPopup("""
                Repository URL Not valid, check if
                service is available and that connection string is from
                the form: http[s]://hostname:port""")
                repourl, isReplicated, replics = "", False, ""

            CONF.setCouchUri(repourl)
            CONF.setCouchIsReplicated(isReplicated)
            CONF.setCouchReplics(replics)
            CONF.saveConfig()

            couchdbmanager = CouchdbManager(repourl)
            wm.setCouchManager(couchdbmanager)

            wm.loadWorkspaces()
            mwin = self._main_app.getMainWindow()
            mwin.getWorkspaceTreeView().loadAllWorkspaces()
            mwin.getWorkspaceTreeView().setDefaultWorkspace()

    def showConflictsDialog(self, local):
        dialog = ResolveConflictsDialog(self, local=local)
        result = dialog.exec_loop()
        return result

    def customEvent(self, event):
        """
        This method is to be able to handle custom events in order
        to show custom dialogs or pop ups
        """
        if event.type() == EXCEPTION_ID:
            self.showExceptionDialog(event.text, event.callback,
                                     event.exception_objects)
        elif event.type() == SHOWDIALOG_ID:
            self.showSimpleDialog(event.text, event.level)
        elif event.type() == SHOWPOPUP_ID:
            self.showPopup(event.text, event.level)
        elif event.type() == CONFLICTS_ID:

            self.showConflictsDialog(event.local)

    def toggleLogConsole(self):
        if self._log_console.isVisible():
            self._log_console.hide()
        else:
            self._log_console.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def togglePerspectives(self):
        if self._perspective_manager.isVisible():
            self._perspective_manager.hide()
        else:
            self._perspective_manager.show()
            if self._is_shell_maximized:
                self._actions["maximize-shell"].toggle()
                self._is_shell_maximized = False

    def maximizeShell(self):

        if self._is_shell_maximized:
            self._is_shell_maximized = False
            if not self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()
            if not self._perspective_manager.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()
        else:
            self._is_shell_maximized = True
            if self._log_console.isVisible():
                self.toggleLogConsole()
                self._actions["toggle-logconsole"].toggle()

            if self._hosts_treeview.isVisible():
                self.togglePerspectives()
                self._actions["toggle-hosttree"].toggle()

    def changeShellFont(self):
        preferences_dialog = PreferencesDialog(self)
        if preferences_dialog.exec_loop():
            self.setShellFont()
            CONF.setFont(self.shell_font.rawName())
            CONF.saveConfig()

    def setBfont(self):
        if (self._size + 1) < len(self._sizes):
            self._size = self._size + 1
            self.setShellFont()

    def setSfont(self):
        if (self._size - 1) > -1:
            self._size = self._size - 1
            self.setShellFont()

    def getShellWithFocus(self):
        for shell in self._shell_widgets:
            if shell.hasFocus():
                return shell
        return None

    def setShellFont(self):
        self.shell_font = qt.QFont()
        CONF.setFont("-Misc-Fixed-medium-r-normal-*-" +
                     str(self._sizes[self._size]) +
                     "-100-100-100-c-70-iso8859-1")
        CONF.saveConfig()
        self.shell_font.setRawName(CONF.getFont())

        for shell in self._shell_widgets:
            shell.setVTFont(self.shell_font)

    def runVisualization(self):
        """
        runs script that builds the html for visutalizacion and opens a browser
        """

        ret, url = self._main_app.getWorkspaceManager().createVisualizations()
        if ret:
            webbrowser.open_new(url)

    def go2Website(self):

        webbrowser.open_new("https://www.faradaysec.com")
        model.api.log("Opening faraday's website")

    def closeEvent(self, e):
        result = self.exitFaraday()
        if result == qt.QDialog.Accepted:
            e.accept()

    def exitFaraday(self):
        exit_dialog = ExitDialog(self, self._main_app.quit)
        return exit_dialog.exec_loop()

    def doDebug(self):
        exit_dialog = MessageDialog(
            self, self.__debug, "Debug",
            "Faraday use IPython for debuging, please switch to terminal\n where do you execute the framework, use Ctrl+D to exit debug.\nDo you want to continue?"
        )
        return exit_dialog.exec_loop()

    def __debug(self, item=False):
        from utils import ipython_shell
        ipython_shell.embedd(locals(), globals())

    def takeScreenshot(self):
        view = self._tab_manager.activeWindow()
        ts = datetime.datetime.now().strftime("%Y%m%d%H%M%s")
        pixmap = qt.QPixmap.grabWidget(view)
        pixmap.save(
            os.path.join(CONF.getDefaultTempPath(),
                         "shell_capture_%s.png" % ts), "PNG")
        pixmap = qt.QPixmap.grabWidget(self)
        pixmap.save(
            os.path.join(CONF.getDefaultTempPath(),
                         "fullscreen_capture_%s.png" % ts), "PNG")
        model.api.log("Screenshots taken")

    def syncWorkspaces(self):

        self._model_controller.syncActiveWorkspace()

    def saveWorkspaces(self):
        """
        Saves workspaces and it is done syncronically so GUI won't respond
        until it finishes saving everything
        """

        model.api.log("Saving workspaces...")
        self._main_app.saveWorkspaces()
        model.api.log("Workspaces saved!")

    def createWorkspace(self):

        wdialog = WorkspaceCreationDialog(
            self, callback=self._main_app.createWorkspace)
        wdialog.exec_loop()

    def openWorkspace(self):

        name = "Untitled"
        self._main_app.openWorkspace(name)

    def reconnect(self):
        wm = self._main_app.getWorkspaceManager()
        wm.reconnect()

    """
    #XXX: test ALT+r on console to delete line
    def test2(self):
        for env in self._main_app._shell_envs.itervalues():
            env.session.em.sendString("\033r")
    """

    def testAPI(self):
        import model.api
        model.api.createAndAddHost("prueba-host", "Windows 7")
        model.api.createAndAddInterface("eth0",
                                        mac="00:00:00:00:00:00",
                                        ipv4_address="10.1.1.1",
                                        ipv4_mask="255.255.0.0",
                                        ipv4_gateway="10.1.1.2",
                                        hostname_resolution="TestHost",
                                        hostname="prueba-host")

        h = model.api.newHost("127.0.0.1", "Windows 2003")
        h = model.api.getHost("prueba-host")
        model.api.addHost(h)
        h.name = "Nuevo Nombre"
        model.api.addHost(h, update=True, old_hostname="prueba-host")

    def test(self):
        """
        DELETE THIS BEFORE RELEASE
        used for internal testing (not correct way but we need to use it like
        this for now)
        """

        global test_count
        test_count += 1
        model.api.showPopup("Creating test host %d" % test_count)

        from utils.error_report import exception_handler

        def raiser():
            sys.excepthook = exception_handler
            time.sleep(3)
            raise Exception("Exception from a secondary thread...")

        from model.hosts import Host
        from model.hosts import Interface
        from model.hosts import Service
        from model.hosts import HostApplication

        self._main_app.getLogger().log("testing..")
        self._main_app.getLogger().log("creating test host %d" % test_count)
        host = Host("TestHost-%d" % test_count, "Windows 2003")
        service = Service("TestService-%d" % test_count, "TCP", [80, 8080],
                          "running")
        interface = Interface("eth%d" % test_count,
                              mac="00:00:00:00:00:00",
                              ipv4_address="10.1.1.%d" % test_count,
                              ipv4_mask="255.255.0.0",
                              ipv4_gateway="10.1.1.%d" % (test_count + 1),
                              hostname_resolution="TestHost-%d" % test_count)
        app = HostApplication("AppTest-%d" % test_count, "running", "1.0 beta")

        host.addInterface(interface)
        host.addService(service)
        host.addApplication(app)
        interface.addService(service)
        app.addService(service)
        service.addInterface(interface)
        self._model_controller.addHostASYNC(host)