--- a/ProjectFlask/Project.py Fri Nov 13 19:51:28 2020 +0100 +++ b/ProjectFlask/Project.py Sat Nov 14 19:56:06 2020 +0100 @@ -10,7 +10,7 @@ import os from PyQt5.QtCore import ( - pyqtSlot, QObject, QProcess, QProcessEnvironment + pyqtSlot, QObject, QProcess, QProcessEnvironment, QTimer ) from PyQt5.QtWidgets import QMenu @@ -25,6 +25,7 @@ from .RunServerDialog import RunServerDialog from .RoutesDialog import RoutesDialog +from .FlaskCommandDialog import FlaskCommandDialog class Project(QObject): @@ -53,10 +54,10 @@ self.__menus = {} # dictionary with references to menus -## self.__serverProc = None self.__serverDialog = None self.__routesDialog = None - + self.__shellProcess = None + self.__flaskVersions = { "python": "", "flask": "", @@ -101,9 +102,43 @@ self.runDevServerAct.triggered.connect(self.__runDevelopmentServer) self.actions.append(self.runDevServerAct) - ############################## + self.askForServerOptionsAct = E5Action( + self.tr('Ask for Server Start Options'), + self.tr('Ask for Server Start Options'), + 0, 0, + self, 'flask_ask_server_options') + self.askForServerOptionsAct.setStatusTip(self.tr( + 'Ask for server start options')) + self.askForServerOptionsAct.setWhatsThis(self.tr( + """<b>Ask for Server Start Options</b>""" + """<p>Asks for server start options before the Flask Web server""" + """ is started. If this is unchecked, the server is started with""" + """ default parameters.</p>""" + )) + self.askForServerOptionsAct.setCheckable(True) + self.actions.append(self.askForServerOptionsAct) + + ############################### + ## shell action below ## + ############################### + + self.runPythonShellAct = E5Action( + self.tr('Start Flask Python Console'), + self.tr('Start Flask &Python Console'), + 0, 0, + self, 'flask_python_console') + self.runPythonShellAct.setStatusTip(self.tr( + 'Starts an interactive Python interpreter')) + self.runPythonShellAct.setWhatsThis(self.tr( + """<b>Start Flask Python Console</b>""" + """<p>Starts an interactive Python interpreter.</p>""" + )) + self.runPythonShellAct.triggered.connect(self.__runPythonShell) + self.actions.append(self.runPythonShellAct) + + ################################ ## routes action below ## - ############################## + ################################ self.showRoutesAct = E5Action( self.tr('Show Routes'), @@ -120,6 +155,25 @@ self.actions.append(self.showRoutesAct) ################################## + ## database action below ## + ################################## + + self.initDatabaseAct = E5Action( + self.tr('Initialize Database'), + self.tr('&Initialize Database'), + 0, 0, + self, 'flask_init_database') + self.initDatabaseAct.setStatusTip(self.tr( + 'Shows a dialog with the result of the database creation')) + self.initDatabaseAct.setWhatsThis(self.tr( + """<b>Initialize Database</b>""" + """<p>Shows a dialog with the result of the database""" + """ creation.</p>""" + )) + self.initDatabaseAct.triggered.connect(self.__initDatabase) + self.actions.append(self.initDatabaseAct) + + ################################## ## documentation action below ## ################################## @@ -167,11 +221,17 @@ menu = QMenu(self.tr('&Flask'), self.__ui) menu.setTearOffEnabled(True) + menu.addSection("flask run") menu.addAction(self.runServerAct) menu.addAction(self.runDevServerAct) - menu.addSeparator() + menu.addAction(self.askForServerOptionsAct) + menu.addSection("flask shell") + menu.addAction(self.runPythonShellAct) + menu.addSection("flask routes") menu.addAction(self.showRoutesAct) - menu.addSeparator() + menu.addSection("flask init-db") + menu.addAction(self.initDatabaseAct) + menu.addSection(self.tr("Various")) menu.addAction(self.documentationAct) menu.addSeparator() menu.addAction(self.aboutFlaskAct) @@ -421,7 +481,7 @@ self.__ui.launchHelpViewer(page) ################################################################## - ## slots below implement run functions + ## slots below implement run functions for the server ################################################################## @pyqtSlot() @@ -435,8 +495,10 @@ if self.__serverDialog is not None: self.__serverDialog.close() - dlg = RunServerDialog(self.__plugin) - if dlg.startServer(self, development=development): + askForOptions = self.askForServerOptionsAct.isChecked() + dlg = RunServerDialog(self.__plugin, self) + if dlg.startServer(development=development, + askForOptions=askForOptions): dlg.show() self.__serverDialog = dlg @@ -447,31 +509,60 @@ """ self.__runServer(development=True) - # TODO: add method to start a server with parameters + ################################################################## + ## slots below implement functions for the flask console + ################################################################## -## def __serverProcFinished(self): -## """ -## Private slot connected to the finished signal. -## """ -## if ( -## self.__serverProc is not None and -## self.__serverProc.state() != QProcess.NotRunning -## ): -## self.__serverProc.terminate() -## QTimer.singleShot(2000, self.__serverProc.kill) -## self.__serverProc.waitForFinished(3000) -## self.__serverProc = None - + @pyqtSlot() def __runPythonShell(self): """ Private slot to start a Python console in the app context. """ - # TODO: implement this (flask shell) + workdir, env = self.prepareRuntimeEnvironment() + if env is not None: + command = self.getFlaskCommand() + + consoleCmd = self.__plugin.getPreferences("ConsoleCommand") + if consoleCmd: + self.__terminatePythonShell() + + args = Utilities.parseOptionString(consoleCmd) + args[0] = Utilities.getExecutablePath(args[0]) + args += [command, "shell"] + + self.__shellProcess = QProcess() + self.__shellProcess.setProcessEnvironment(env) + self.__shellProcess.setWorkingDirectory(workdir) + self.__shellProcess.finished.connect( + self.__shellProcessFinished) + + self.__shellProcess.start(args[0], args[1:]) + self.__shellProcess.waitForStarted(10000) + + @pyqtSlot() + def __shellProcessFinished(self): + """ + Private slot connected to the finished signal. + """ + self.__shellProcess = None + + def __terminatePythonShell(self): + """ + Private method to terminate the current Python console. + """ + if ( + self.__shellProcess is not None and + self.__shellProcess.state() != QProcess.NotRunning + ): + self.__shellProcess.terminate() + QTimer.singleShot(2000, self.__shellProcess.kill) + self.__shellProcess.waitForFinished(3000) ################################################################## ## slots below implement various debugging functions ################################################################## + @pyqtSlot() def __showRoutes(self): """ Private slot showing all URL dispatch routes. @@ -483,3 +574,12 @@ if dlg.showRoutes(): dlg.show() self.__routesDialog = dlg + + @pyqtSlot() + def __initDatabase(self): + """ + Private slot showing the result of the database creation. + """ + dlg = FlaskCommandDialog(self) + if dlg.startCommand("init-db"): + dlg.exec()