ProjectFlask/Project.py

branch
eric7
changeset 70
22e1d0f69668
parent 66
0d3168d0e310
child 72
4557829a4acf
--- a/ProjectFlask/Project.py	Thu Dec 30 12:13:22 2021 +0100
+++ b/ProjectFlask/Project.py	Wed Sep 21 16:30:15 2022 +0200
@@ -10,7 +10,12 @@
 import os
 
 from PyQt6.QtCore import (
-    pyqtSlot, QObject, QProcess, QProcessEnvironment, QTimer, QFileInfo
+    pyqtSlot,
+    QObject,
+    QProcess,
+    QProcessEnvironment,
+    QTimer,
+    QFileInfo,
 )
 from PyQt6.QtWidgets import QMenu, QDialog
 
@@ -31,10 +36,11 @@
     """
     Class implementing the Flask project support.
     """
+
     def __init__(self, plugin, iconSuffix, parent=None):
         """
         Constructor
-        
+
         @param plugin reference to the plugin object
         @type ProjectFlaskPlugin
         @param iconSuffix suffix for the icons
@@ -43,203 +49,238 @@
         @type QObject
         """
         super().__init__(parent)
-        
+
         self.__plugin = plugin
         self.__iconSuffix = iconSuffix
         self.__ui = parent
 
         self.__ericProject = ericApp().getObject("Project")
         self.__virtualEnvManager = ericApp().getObject("VirtualEnvManager")
-        
-        self.__menus = {}   # dictionary with references to menus
+
+        self.__menus = {}  # dictionary with references to menus
         self.__formsBrowser = None
         self.__hooksInstalled = False
-         
+
         self.__serverDialog = None
         self.__routesDialog = None
         self.__shellProcess = None
-        
+
         self.__projectData = {
             "flask": {},
             "flask-babel": {},
             "flask-migrate": {},
         }
-        
+
         self.__flaskVersions = {
             "python": "",
             "flask": "",
             "werkzeug": "",
         }
-        
+
         self.__capabilities = {}
-        
+
         self.__pybabelProject = PyBabelProject(self.__plugin, self, self)
         self.__migrateProject = MigrateProject(self.__plugin, self, self)
-    
+
     def initActions(self):
         """
         Public method to define the Flask actions.
         """
         self.actions = []
-        
+
         ##############################
         ## run actions below        ##
         ##############################
-        
+
         self.runServerAct = EricAction(
-            self.tr('Run Server'),
-            self.tr('Run &Server'),
-            0, 0,
-            self, 'flask_run_server')
-        self.runServerAct.setStatusTip(self.tr(
-            'Starts the Flask Web server'))
-        self.runServerAct.setWhatsThis(self.tr(
-            """<b>Run Server</b>"""
-            """<p>Starts the Flask Web server.</p>"""
-        ))
+            self.tr("Run Server"),
+            self.tr("Run &Server"),
+            0,
+            0,
+            self,
+            "flask_run_server",
+        )
+        self.runServerAct.setStatusTip(self.tr("Starts the Flask Web server"))
+        self.runServerAct.setWhatsThis(
+            self.tr("""<b>Run Server</b>""" """<p>Starts the Flask Web server.</p>""")
+        )
         self.runServerAct.triggered.connect(self.__runServer)
         self.actions.append(self.runServerAct)
-        
+
         self.runDevServerAct = EricAction(
-            self.tr('Run Development Server'),
-            self.tr('Run &Development Server'),
-            0, 0,
-            self, 'flask_run_dev_server')
-        self.runDevServerAct.setStatusTip(self.tr(
-            'Starts the Flask Web server in development mode'))
-        self.runDevServerAct.setWhatsThis(self.tr(
-            """<b>Run Development Server</b>"""
-            """<p>Starts the Flask Web server in development mode.</p>"""
-        ))
+            self.tr("Run Development Server"),
+            self.tr("Run &Development Server"),
+            0,
+            0,
+            self,
+            "flask_run_dev_server",
+        )
+        self.runDevServerAct.setStatusTip(
+            self.tr("Starts the Flask Web server in development mode")
+        )
+        self.runDevServerAct.setWhatsThis(
+            self.tr(
+                """<b>Run Development Server</b>"""
+                """<p>Starts the Flask Web server in development mode.</p>"""
+            )
+        )
         self.runDevServerAct.triggered.connect(self.__runDevelopmentServer)
         self.actions.append(self.runDevServerAct)
-        
+
         self.askForServerOptionsAct = EricAction(
-            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.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 = EricAction(
-            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.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 = EricAction(
-            self.tr('Show Routes'),
-            self.tr('Show &Routes'),
-            0, 0,
-            self, 'flask_show_routes')
-        self.showRoutesAct.setStatusTip(self.tr(
-            'Shows a dialog with the routes of the flask app'))
-        self.showRoutesAct.setWhatsThis(self.tr(
-            """<b>Show Routes</b>"""
-            """<p>Shows a dialog with the routes of the flask app.</p>"""
-        ))
+            self.tr("Show Routes"),
+            self.tr("Show &Routes"),
+            0,
+            0,
+            self,
+            "flask_show_routes",
+        )
+        self.showRoutesAct.setStatusTip(
+            self.tr("Shows a dialog with the routes of the flask app")
+        )
+        self.showRoutesAct.setWhatsThis(
+            self.tr(
+                """<b>Show Routes</b>"""
+                """<p>Shows a dialog with the routes of the flask app.</p>"""
+            )
+        )
         self.showRoutesAct.triggered.connect(self.__showRoutes)
         self.actions.append(self.showRoutesAct)
-        
+
         ##################################
         ## documentation action below   ##
         ##################################
-        
+
         self.documentationAct = EricAction(
-            self.tr('Documentation'),
-            self.tr('D&ocumentation'),
-            0, 0,
-            self, 'flask_documentation')
-        self.documentationAct.setStatusTip(self.tr(
-            'Shows the help viewer with the Flask documentation'))
-        self.documentationAct.setWhatsThis(self.tr(
-            """<b>Documentation</b>"""
-            """<p>Shows the help viewer with the Flask documentation.</p>"""
-        ))
+            self.tr("Documentation"),
+            self.tr("D&ocumentation"),
+            0,
+            0,
+            self,
+            "flask_documentation",
+        )
+        self.documentationAct.setStatusTip(
+            self.tr("Shows the help viewer with the Flask documentation")
+        )
+        self.documentationAct.setWhatsThis(
+            self.tr(
+                """<b>Documentation</b>"""
+                """<p>Shows the help viewer with the Flask documentation.</p>"""
+            )
+        )
         self.documentationAct.triggered.connect(self.__showDocumentation)
         self.actions.append(self.documentationAct)
-    
+
         ##############################
         ## about action below       ##
         ##############################
-        
+
         self.aboutFlaskAct = EricAction(
-            self.tr('About Flask'),
-            self.tr('About &Flask'),
-            0, 0,
-            self, 'flask_about')
-        self.aboutFlaskAct.setStatusTip(self.tr(
-            'Shows some information about Flask'))
-        self.aboutFlaskAct.setWhatsThis(self.tr(
-            """<b>About Flask</b>"""
-            """<p>Shows some information about Flask.</p>"""
-        ))
+            self.tr("About Flask"), self.tr("About &Flask"), 0, 0, self, "flask_about"
+        )
+        self.aboutFlaskAct.setStatusTip(self.tr("Shows some information about Flask"))
+        self.aboutFlaskAct.setWhatsThis(
+            self.tr(
+                """<b>About Flask</b>"""
+                """<p>Shows some information about Flask.</p>"""
+            )
+        )
         self.aboutFlaskAct.triggered.connect(self.__flaskInfo)
         self.actions.append(self.aboutFlaskAct)
-        
+
         self.__pybabelProject.initActions()
         self.__migrateProject.initActions()
-    
+
         ######################################
         ## configuration action below       ##
         ######################################
-        
+
         self.flaskConfigAct = EricAction(
-            self.tr('Configure Flask for Project'),
-            self.tr('Configure Flask for &Project'),
-            0, 0,
-            self, 'flask_config_for_project')
-        self.flaskConfigAct.setStatusTip(self.tr(
-            'Shows a dialog to edit the project specific flask configuration'))
-        self.flaskConfigAct.setWhatsThis(self.tr(
-            """<b>Configure Flask for Project</b>"""
-            """<p>Shows a dialog to edit the project specific flask"""
-            """ configuration.</p>"""
-        ))
-        self.flaskConfigAct.triggered.connect(
-            self.__configureFlaskForProject)
+            self.tr("Configure Flask for Project"),
+            self.tr("Configure Flask for &Project"),
+            0,
+            0,
+            self,
+            "flask_config_for_project",
+        )
+        self.flaskConfigAct.setStatusTip(
+            self.tr("Shows a dialog to edit the project specific flask configuration")
+        )
+        self.flaskConfigAct.setWhatsThis(
+            self.tr(
+                """<b>Configure Flask for Project</b>"""
+                """<p>Shows a dialog to edit the project specific flask"""
+                """ configuration.</p>"""
+            )
+        )
+        self.flaskConfigAct.triggered.connect(self.__configureFlaskForProject)
         self.actions.append(self.flaskConfigAct)
-    
+
     def initMenu(self):
         """
         Public method to initialize the Flask menu.
-        
+
         @return the menu generated
         @rtype QMenu
         """
-        self.__menus = {}   # clear menus references
-        
+        self.__menus = {}  # clear menus references
+
         self.__menus["flask-babel"] = self.__pybabelProject.initMenu()
         self.__menus["flask-migrate"] = self.__migrateProject.initMenu()
-        
-        menu = QMenu(self.tr('&Flask'), self.__ui)
+
+        menu = QMenu(self.tr("&Flask"), self.__ui)
         menu.setTearOffEnabled(True)
-        
+
         menu.addAction(self.flaskConfigAct)
         menu.addSeparator()
         menu.addAction(self.runServerAct)
@@ -257,15 +298,15 @@
         menu.addAction(self.documentationAct)
         menu.addSeparator()
         menu.addAction(self.aboutFlaskAct)
-        
+
         self.__menus["main"] = menu
-        
+
         return menu
-    
+
     def getMenu(self, name):
         """
         Public method to get a reference to the requested menu.
-        
+
         @param name name of the menu
         @type str
         @return reference to the menu or None, if no menu with the given
@@ -276,88 +317,89 @@
             return self.__menus[name]
         else:
             return None
-    
+
     def getMenuNames(self):
         """
         Public method to get the names of all menus.
-        
+
         @return menu names
         @rtype list of str
         """
         return list(self.__menus.keys())
-    
+
     def projectOpenedHooks(self):
         """
         Public method to add our hook methods.
         """
         if self.__ericProject.getProjectType() == "Flask":
             self.__formsBrowser = (
-                ericApp().getObject("ProjectBrowser")
-                .getProjectBrowser("forms"))
+                ericApp().getObject("ProjectBrowser").getProjectBrowser("forms")
+            )
             self.__formsBrowser.addHookMethodAndMenuEntry(
-                "newForm", self.newForm, self.tr("New template..."))
-            
+                "newForm", self.newForm, self.tr("New template...")
+            )
+
             self.__determineCapabilities()
             self.__setDebugEnvironment()
-            
+
             self.__pybabelProject.projectOpenedHooks()
-            
+
             self.__hooksInstalled = True
-    
+
     def projectClosedHooks(self):
         """
         Public method to remove our hook methods.
         """
         self.__pybabelProject.projectClosedHooks()
-        
+
         if self.__hooksInstalled:
             self.__formsBrowser.removeHookMethod("newForm")
             self.__formsBrowser = None
-        
+
         self.__hooksInstalled = False
-    
+
     def newForm(self, dirPath):
         """
         Public method to create a new form.
-        
+
         @param dirPath full directory path for the new form file
         @type str
         """
         from .FormSelectionDialog import FormSelectionDialog
-        
+
         dlg = FormSelectionDialog()
         if dlg.exec() == QDialog.DialogCode.Accepted:
             template = dlg.getTemplateText()
-            
+
             fileFilters = self.tr(
-                "HTML Files (*.html);;"
-                "HTML Files (*.htm);;"
-                "All Files (*)")
+                "HTML Files (*.html);;" "HTML Files (*.htm);;" "All Files (*)"
+            )
             fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
                 self.__ui,
                 self.tr("New Form"),
                 dirPath,
                 fileFilters,
                 None,
-                EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite))
+                EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite),
+            )
             if fname:
                 ext = QFileInfo(fname).suffix()
                 if not ext:
                     ex = selectedFilter.split("(*")[1].split(")")[0]
                     if ex:
                         fname += ex
-                
+
                 if os.path.exists(fname):
                     res = EricMessageBox.yesNo(
                         self.__ui,
                         self.tr("New Form"),
-                        self.tr("""The file already exists! Overwrite"""
-                                """ it?"""),
-                        icon=EricMessageBox.Warning)
+                        self.tr("""The file already exists! Overwrite""" """ it?"""),
+                        icon=EricMessageBox.Warning,
+                    )
                     if not res:
                         # user selected to not overwrite
                         return
-                
+
                 try:
                     with open(fname, "w", encoding="utf-8") as f:
                         f.write(template)
@@ -365,22 +407,24 @@
                     EricMessageBox.critical(
                         self.__ui,
                         self.tr("New Form"),
-                        self.tr("<p>The new form file <b>{0}</b> could"
-                                " not be created.</p><p>Problem: {1}</p>")
-                        .format(fname, str(err)))
+                        self.tr(
+                            "<p>The new form file <b>{0}</b> could"
+                            " not be created.</p><p>Problem: {1}</p>"
+                        ).format(fname, str(err)),
+                    )
                     return
-                
+
                 self.__ericProject.appendFile(fname)
                 self.__formsBrowser.sourceFile.emit(fname)
-    
+
     ##################################################################
     ## methods below implement virtual environment handling
     ##################################################################
-    
+
     def getVirtualEnvironment(self):
         """
         Public method to get the path of the virtual environment.
-        
+
         @return path of the virtual environment
         @rtype str
         """
@@ -389,35 +433,34 @@
             # get project specific virtual environment name
             venvName = self.getData("flask", "virtual_environment_name")
             if not venvName:
-                venvName = self.__plugin.getPreferences(
-                    "VirtualEnvironmentNamePy3")
+                venvName = self.__plugin.getPreferences("VirtualEnvironmentNamePy3")
         else:
             venvName = ""
         virtEnv = (
             self.__virtualEnvManager.getVirtualenvDirectory(venvName)
-            if venvName else
-            ""
+            if venvName
+            else ""
         )
-        
+
         if virtEnv and not os.path.exists(virtEnv):
             virtEnv = ""
-        
-        return virtEnv      # __IGNORE_WARNING_M834__
-    
+
+        return virtEnv  # __IGNORE_WARNING_M834__
+
     def getVirtualenvInterpreter(self):
         """
         Public method to get the path of the Python interpreter to be used
         with the current project.
-        
+
         @return path of the Python interpreter
         @rtype str
         """
         return self.getFullCommand("python")
-    
+
     def getFullCommand(self, command, virtualEnvPath=None):
         """
         Public method to get the full command for a given command name.
-        
+
         @param command command name
         @type str
         @param virtualEnvPath path of the virtual environment
@@ -427,24 +470,28 @@
         """
         virtualEnv = virtualEnvPath or self.getVirtualEnvironment()
         fullCmds = (
-            [os.path.join(virtualEnv, "Scripts", command + '.exe'),
-             os.path.join(virtualEnv, "bin", command + '.exe'),
-             command]     # fall back to just cmd
-            if isWindowsPlatform() else
-            [os.path.join(virtualEnv, "bin", command),
-             os.path.join(virtualEnv, "local", "bin", command),
-             Utilities.getExecutablePath(command),
-             command]     # fall back to just cmd
+            [
+                os.path.join(virtualEnv, "Scripts", command + ".exe"),
+                os.path.join(virtualEnv, "bin", command + ".exe"),
+                command,
+            ]  # fall back to just cmd
+            if isWindowsPlatform()
+            else [
+                os.path.join(virtualEnv, "bin", command),
+                os.path.join(virtualEnv, "local", "bin", command),
+                Utilities.getExecutablePath(command),
+                command,
+            ]  # fall back to just cmd
         )
         for command in fullCmds:
             if os.path.exists(command):
                 break
         return command
-    
+
     ##################################################################
     ## methods below implement general functionality
     ##################################################################
-    
+
     def projectClosed(self):
         """
         Public method to handle the closing of a project.
@@ -452,18 +499,18 @@
         for dlg in (self.__serverDialog, self.__routesDialog):
             if dlg is not None:
                 dlg.close()
-        
+
         self.__migrateProject.projectClosed()
-    
+
     def supportedPythonVariants(self):
         """
         Public method to get the supported Python variants.
-        
+
         @return list of supported Python variants
         @rtype list of str
         """
         variants = []
-        
+
         virtEnv = self.getVirtualEnvironment()
         if virtEnv:
             fullCmd = self.getFlaskCommand()
@@ -478,21 +525,21 @@
                 fullCmds = Utilities.getExecutablePaths("flask")
                 for fullCmd in fullCmds:
                     try:
-                        with open(fullCmd, 'r', encoding='utf-8') as f:
+                        with open(fullCmd, "r", encoding="utf-8") as f:
                             l0 = f.readline()
                     except OSError:
                         l0 = ""
                     if self.__isSuitableForVariant("Python3", l0):
                         variants.append("Python3")
                         break
-        
+
         return variants
-    
+
     def __isSuitableForVariant(self, variant, line0):
         """
         Private method to test, if a detected command file is suitable for the
         given Python variant.
-        
+
         @param variant Python variant to test for
         @type str
         @param line0 first line of the executable
@@ -501,21 +548,20 @@
         @rtype bool
         """
         l0 = line0.lower()
-        ok = (variant.lower() in l0 or
-              "{0}.".format(variant[-1]) in l0)
+        ok = variant.lower() in l0 or "{0}.".format(variant[-1]) in l0
         ok |= "pypy3" in l0
-        
+
         return ok
-    
+
     def getFlaskCommand(self):
         """
         Public method to build the Flask command.
-        
+
         @return full flask command
         @rtype str
         """
         return self.getFullCommand("flask")
-    
+
     @pyqtSlot()
     def __flaskInfo(self):
         """
@@ -523,7 +569,7 @@
         """
         versions = self.getFlaskVersionStrings()
         url = "https://palletsprojects.com/p/flask/"
-        
+
         msgBox = EricMessageBox.EricMessageBox(
             EricMessageBox.Question,
             self.tr("About Flask"),
@@ -535,24 +581,28 @@
                 "<tr><td>Flask Version:</td><td>{0}</td></tr>"
                 "<tr><td>Werkzeug Version:</td><td>{1}</td></tr>"
                 "<tr><td>Python Version:</td><td>{2}</td></tr>"
-                "<tr><td>Flask URL:</td><td><a href=\"{3}\">"
+                '<tr><td>Flask URL:</td><td><a href="{3}">'
                 "The Pallets Projects - Flask</a></td></tr>"
                 "</table></p>",
-                "Do not translate the program names."
-            ).format(versions["flask"], versions["werkzeug"],
-                     versions["python"], url),
+                "Do not translate the program names.",
+            ).format(versions["flask"], versions["werkzeug"], versions["python"], url),
             modal=True,
-            buttons=EricMessageBox.Ok)
-        msgBox.setIconPixmap(UI.PixmapCache.getPixmap(
-            os.path.join("ProjectFlask", "icons",
-                         "flask64-{0}".format(self.__iconSuffix))))
+            buttons=EricMessageBox.Ok,
+        )
+        msgBox.setIconPixmap(
+            UI.PixmapCache.getPixmap(
+                os.path.join(
+                    "ProjectFlask", "icons", "flask64-{0}".format(self.__iconSuffix)
+                )
+            )
+        )
         msgBox.exec()
-    
+
     def getFlaskVersionStrings(self):
         """
         Public method to get the Flask, Werkzeug and Python versions as a
         string.
-        
+
         @return dictionary containing the Flask, Werkzeug and Python versions
         @rtype dict
         """
@@ -565,14 +615,14 @@
                 for line in output.lower().splitlines():
                     key, version = line.strip().split(None, 1)
                     self.__flaskVersions[key] = version
-        
+
         return self.__flaskVersions
-    
+
     def prepareRuntimeEnvironment(self, development=False):
         """
         Public method to prepare a QProcessEnvironment object and determine
         the appropriate working directory.
-        
+
         @param development flag indicating development mode
         @type bool
         @return tuple containing the working directory and a prepared
@@ -584,14 +634,14 @@
         env.insert("FLASK_APP", app)
         if development:
             env.insert("FLASK_ENV", "development")
-        
+
         return workdir, env
-    
+
     def getApplication(self):
         """
         Public method to determine the application name and the respective
         working directory.
-        
+
         @return tuple containing the working directory and the application name
         @rtype tuple of (str, str)
         """
@@ -600,21 +650,24 @@
             EricMessageBox.critical(
                 self.__ui,
                 self.tr("Prepare Environment"),
-                self.tr("""The project has no configured main script"""
-                        """ (= Flask application). Aborting..."""))
+                self.tr(
+                    """The project has no configured main script"""
+                    """ (= Flask application). Aborting..."""
+                ),
+            )
             return "", None
-        
+
         scriptPath, scriptName = os.path.split(mainScript)
         if scriptName == "__init__.py":
             workdir, app = os.path.split(scriptPath)
         else:
             workdir, app = scriptPath, scriptName
         return workdir, app
-    
+
     def getData(self, category, key):
         """
         Public method to get data stored in the project store.
-        
+
         @param category data category
         @type str
         @param key data key
@@ -624,13 +677,12 @@
         """
         if category not in self.__projectData:
             self.__projectData[category] = {}
-        
+
         if not self.__projectData[category]:
-            data = self.__ericProject.getData(
-                "PROJECTTYPESPECIFICDATA", category)
+            data = self.__ericProject.getData("PROJECTTYPESPECIFICDATA", category)
             if data is not None:
                 self.__projectData[category] = data
-        
+
         data = self.__projectData[category]
         if not key:
             # return complete category dictionary
@@ -641,11 +693,11 @@
         else:
             # failure
             return None
-    
+
     def setData(self, category, key, value):
         """
         Public method to store data in the project store.
-        
+
         @param category data category
         @type str
         @param key data key
@@ -655,23 +707,23 @@
         """
         if category not in self.__projectData:
             self.__projectData[category] = {}
-        
+
         if not self.__projectData[category]:
-            data = self.__ericProject.getData(
-                "PROJECTTYPESPECIFICDATA", category)
+            data = self.__ericProject.getData("PROJECTTYPESPECIFICDATA", category)
             if data is not None:
                 self.__projectData[category] = data
-        
+
         if not key:
             # update the complete category
             self.__projectData[category] = value
         else:
             # update individual entry
             self.__projectData[category][key] = value
-        
+
         self.__ericProject.setData(
-            "PROJECTTYPESPECIFICDATA", category, self.__projectData[category])
-    
+            "PROJECTTYPESPECIFICDATA", category, self.__projectData[category]
+        )
+
     def __determineCapabilities(self):
         """
         Private method to determine capabilities provided by supported
@@ -679,14 +731,14 @@
         """
         # 1. support for flask-babel (i.e. pybabel)
         self.__pybabelProject.determineCapability()
-        
+
         # 2. support for flask-migrate
         self.__migrateProject.determineCapability()
-    
+
     def hasCapability(self, key):
         """
         Public method to check, if a capability is available.
-        
+
         @param key key of the capability to check
         @type str
         @return flag indicating the availability of the capability
@@ -696,29 +748,29 @@
             return self.__capabilities[key]
         except KeyError:
             return False
-    
+
     def setCapability(self, key, available):
         """
         Public method to set the availability status of a capability.
-        
+
         @param key key of the capability to set
         @type str
         @param available flag indicating the availability of the capability
         @type bool
         """
         self.__capabilities[key] = available
-    
+
     ##################################################################
     ## slots below implements project specific flask configuration
     ##################################################################
-    
+
     @pyqtSlot()
     def __configureFlaskForProject(self):
         """
         Private slot to configure the project specific flask parameters.
         """
         from .FlaskConfigDialog import FlaskConfigDialog
-        
+
         config = self.getData("flask", "")
         dlg = FlaskConfigDialog(config, self)
         if dlg.exec() == QDialog.DialogCode.Accepted:
@@ -726,13 +778,13 @@
             self.setData("flask", "", config)
             self.__setIgnoreVirtualEnvironment()
             self.__setDebugEnvironment()
-            
+
             self.__migrateProject.determineCapability()
-            
+
             self.__pybabelProject.determineCapability()
             self.projectClosedHooks()
             self.projectOpenedHooks()
-    
+
     def __setIgnoreVirtualEnvironment(self):
         """
         Private method to add an embedded project specific virtual environment
@@ -743,13 +795,12 @@
             virtenvPath = self.getVirtualEnvironment()
             if self.__ericProject.startswithProjectPath(virtenvPath):
                 relVirtenvPath = self.__ericProject.getRelativeUniversalPath(
-                    virtenvPath)
+                    virtenvPath
+                )
                 if relVirtenvPath not in self.__ericProject.pdata["FILETYPES"]:
-                    self.__ericProject.pdata["FILETYPES"][relVirtenvPath] = (
-                        "__IGNORE__"
-                    )
+                    self.__ericProject.pdata["FILETYPES"][relVirtenvPath] = "__IGNORE__"
                     self.__ericProject.setDirty(True)
-    
+
     def __setDebugEnvironment(self):
         """
         Private method to set the virtual environment as the selected debug
@@ -760,57 +811,55 @@
             # get project specific virtual environment name
             venvName = self.getData("flask", "virtual_environment_name")
             if not venvName:
-                venvName = self.__plugin.getPreferences(
-                    "VirtualEnvironmentNamePy3")
+                venvName = self.__plugin.getPreferences("VirtualEnvironmentNamePy3")
             if venvName:
                 self.__ericProject.debugProperties["VIRTUALENV"] = venvName
-    
+
     ##################################################################
     ## slot below implements documentation function
     ##################################################################
-    
+
     def __showDocumentation(self):
         """
         Private slot to show the helpviewer with the Flask documentation.
         """
         page = self.__plugin.getPreferences("FlaskDocUrl")
         self.__ui.launchHelpViewer(page)
-    
+
     ##################################################################
     ## slots below implement run functions for the server
     ##################################################################
-    
+
     @pyqtSlot()
     def __runServer(self, development=False):
         """
         Private slot to start the Flask Web server.
-        
+
         @param development flag indicating development mode
         @type bool
         """
         from .RunServerDialog import RunServerDialog
-        
+
         if self.__serverDialog is not None:
             self.__serverDialog.close()
-        
+
         askForOptions = self.askForServerOptionsAct.isChecked()
         dlg = RunServerDialog(self.__plugin, self)
-        if dlg.startServer(development=development,
-                           askForOptions=askForOptions):
+        if dlg.startServer(development=development, askForOptions=askForOptions):
             dlg.show()
             self.__serverDialog = dlg
-    
+
     @pyqtSlot()
     def __runDevelopmentServer(self):
         """
         Private slot to start the Flask Web server in development mode.
         """
         self.__runServer(development=True)
-    
+
     ##################################################################
     ## slots below implement functions for the flask console
     ##################################################################
-    
+
     @pyqtSlot()
     def __runPythonShell(self):
         """
@@ -819,57 +868,56 @@
         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.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.ProcessState.NotRunning
+            self.__shellProcess is not None
+            and self.__shellProcess.state() != QProcess.ProcessState.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.
         """
         from .RoutesDialog import RoutesDialog
-        
+
         if self.__routesDialog is not None:
             self.__routesDialog.close()
-        
+
         dlg = RoutesDialog(self)
         if dlg.showRoutes():
             dlg.show()

eric ide

mercurial