ProjectFlask/Project.py

changeset 4
e164b9ad3819
parent 3
265c3c2914e2
child 6
d491ccab7343
equal deleted inserted replaced
3:265c3c2914e2 4:e164b9ad3819
7 Module implementing the Flask project support. 7 Module implementing the Flask project support.
8 """ 8 """
9 9
10 import os 10 import os
11 11
12 from PyQt5.QtCore import pyqtSlot, QObject, QProcess, QTimer 12 from PyQt5.QtCore import (
13 pyqtSlot, QObject, QProcess, QProcessEnvironment, QTimer
14 )
13 from PyQt5.QtWidgets import QMenu 15 from PyQt5.QtWidgets import QMenu
14 16
15 from E5Gui import E5MessageBox 17 from E5Gui import E5MessageBox
16 from E5Gui.E5Action import E5Action 18 from E5Gui.E5Action import E5Action
17 from E5Gui.E5Application import e5App 19 from E5Gui.E5Application import e5App
18 20
19 from Globals import isWindowsPlatform 21 from Globals import isWindowsPlatform
20 22
21 import UI.PixmapCache 23 import UI.PixmapCache
22 import Utilities 24 import Utilities
25
26 from .RunServerDialog import RunServerDialog
23 27
24 28
25 class Project(QObject): 29 class Project(QObject):
26 """ 30 """
27 Class implementing the Flask project support. 31 Class implementing the Flask project support.
46 self.__e5project = e5App().getObject("Project") 50 self.__e5project = e5App().getObject("Project")
47 self.__virtualEnvManager = e5App().getObject("VirtualEnvManager") 51 self.__virtualEnvManager = e5App().getObject("VirtualEnvManager")
48 52
49 self.__menus = {} # dictionary with references to menus 53 self.__menus = {} # dictionary with references to menus
50 54
51 self.__serverProc = None 55 ## self.__serverProc = None
56 self.__serverDialog = None
52 57
53 self.__flaskVersions = { 58 self.__flaskVersions = {
54 "python": "", 59 "python": "",
55 "flask": "", 60 "flask": "",
56 "werkzeug": "", 61 "werkzeug": "",
59 def initActions(self): 64 def initActions(self):
60 """ 65 """
61 Public method to define the Flask actions. 66 Public method to define the Flask actions.
62 """ 67 """
63 self.actions = [] 68 self.actions = []
69
70 ##############################
71 ## run actions below ##
72 ##############################
73
74 self.runServerAct = E5Action(
75 self.tr('Run Server'),
76 self.tr('Run &Server'),
77 0, 0,
78 self, 'flask_run_server')
79 self.runServerAct.setStatusTip(self.tr(
80 'Starts the Flask Web server'))
81 self.runServerAct.setWhatsThis(self.tr(
82 """<b>Run Server</b>"""
83 """<p>Starts the Flask Web server.</p>"""
84 ))
85 self.runServerAct.triggered.connect(self.__runServer)
86 self.actions.append(self.runServerAct)
87
88 ##################################
89 ## documentation action below ##
90 ##################################
91
92 self.documentationAct = E5Action(
93 self.tr('Documentation'),
94 self.tr('D&ocumentation'),
95 0, 0,
96 self, 'flask_documentation')
97 self.documentationAct.setStatusTip(self.tr(
98 'Shows the help viewer with the Flask documentation'))
99 self.documentationAct.setWhatsThis(self.tr(
100 """<b>Documentation</b>"""
101 """<p>Shows the help viewer with the Flask documentation.</p>"""
102 ))
103 self.documentationAct.triggered.connect(self.__showDocumentation)
104 self.actions.append(self.documentationAct)
64 105
65 ############################## 106 ##############################
66 ## about action below ## 107 ## about action below ##
67 ############################## 108 ##############################
68 109
90 self.__menus = {} # clear menus references 131 self.__menus = {} # clear menus references
91 132
92 menu = QMenu(self.tr('&Flask'), self.__ui) 133 menu = QMenu(self.tr('&Flask'), self.__ui)
93 menu.setTearOffEnabled(True) 134 menu.setTearOffEnabled(True)
94 135
136 menu.addAction(self.runServerAct)
137 menu.addSeparator()
138 menu.addAction(self.documentationAct)
139 menu.addSeparator()
95 menu.addAction(self.aboutFlaskAct) 140 menu.addAction(self.aboutFlaskAct)
96 141
97 self.__menus["main"] = menu 142 self.__menus["main"] = menu
98 143
99 return menu 144 return menu
128 173
129 def projectClosed(self): 174 def projectClosed(self):
130 """ 175 """
131 Public method to handle the closing of a project. 176 Public method to handle the closing of a project.
132 """ 177 """
133 if self.__serverProc is not None: 178 ## if self.__serverProc is not None:
134 self.__serverProcFinished() 179 ## self.__serverProcFinished()
135 180
136 def supportedPythonVariants(self): 181 def supportedPythonVariants(self):
137 """ 182 """
138 Public method to get the supported Python variants. 183 Public method to get the supported Python variants.
139 184
244 def __flaskInfo(self): 289 def __flaskInfo(self):
245 """ 290 """
246 Private slot to show some info about Flask. 291 Private slot to show some info about Flask.
247 """ 292 """
248 versions = self.getFlaskVersionStrings() 293 versions = self.getFlaskVersionStrings()
249 url = "https://flask.palletsprojects.com" 294 url = "https://palletsprojects.com/p/flask/"
250 295
251 msgBox = E5MessageBox.E5MessageBox( 296 msgBox = E5MessageBox.E5MessageBox(
252 E5MessageBox.Question, 297 E5MessageBox.Question,
253 self.tr("About Flask"), 298 self.tr("About Flask"),
254 self.tr( 299 self.tr(
258 "<p><table>" 303 "<p><table>"
259 "<tr><td>Flask Version:</td><td>{0}</td></tr>" 304 "<tr><td>Flask Version:</td><td>{0}</td></tr>"
260 "<tr><td>Werkzeug Version:</td><td>{1}</td></tr>" 305 "<tr><td>Werkzeug Version:</td><td>{1}</td></tr>"
261 "<tr><td>Python Version:</td><td>{2}</td></tr>" 306 "<tr><td>Python Version:</td><td>{2}</td></tr>"
262 "<tr><td>Flask URL:</td><td><a href=\"{3}\">" 307 "<tr><td>Flask URL:</td><td><a href=\"{3}\">"
263 "{3}</a></td></tr>" 308 "The Pallets Projects - Flask</a></td></tr>"
264 "</table></p>" 309 "</table></p>"
265 ).format(versions["flask"], versions["werkzeug"], 310 ).format(versions["flask"], versions["werkzeug"],
266 versions["python"], url), 311 versions["python"], url),
267 modal=True, 312 modal=True,
268 buttons=E5MessageBox.Ok) 313 buttons=E5MessageBox.Ok)
289 key, version = line.strip().split(None, 1) 334 key, version = line.strip().split(None, 1)
290 self.__flaskVersions[key] = version 335 self.__flaskVersions[key] = version
291 336
292 return self.__flaskVersions 337 return self.__flaskVersions
293 338
339 def prepareRuntimeEnvironment(self, development=False):
340 """
341 Public method to prepare a QProcessEnvironment object and determine
342 the appropriate working directory.
343
344 @param development flag indicating development mode
345 @type bool
346 @return tuple containing the working directory and a prepared
347 environment object to be used with QProcess
348 @rtype tuple of (str, QProcessEnvironment)
349 """
350 mainScript = self.__e5project.getMainScript(normalized=True)
351 if not mainScript:
352 E5MessageBox.critical(
353 self.__ui,
354 self.tr("Prepare Environment"),
355 self.tr("""The project has no configured main script"""
356 """ (= Flask application). Aborting..."""))
357 return "", None
358
359 scriptPath, scriptName = os.path.split(mainScript)
360 if scriptName == "__init__.py":
361 workdir, app = os.path.split(scriptPath)
362 else:
363 workdir, app = scriptPath, scriptName
364
365 env = QProcessEnvironment.systemEnvironment()
366 env.insert("FLASK_APP", app)
367 if development:
368 env.insert("FLASK_ENV", "development")
369
370 return workdir, env
371
372 ##################################################################
373 ## slots below implement documentation functions
374 ##################################################################
375
376 def __showDocumentation(self):
377 """
378 Private slot to show the helpviewer with the Flask documentation.
379 """
380 page = self.__plugin.getPreferences("FlaskDocUrl")
381 self.__ui.launchHelpViewer(page)
382
294 ################################################################## 383 ##################################################################
295 ## slots below implement run functions 384 ## slots below implement run functions
296 ################################################################## 385 ##################################################################
297 386
387 # TODO: does the flask server support logging?
298 def __runServer(self, logging=False): 388 def __runServer(self, logging=False):
299 """ 389 """
300 Private slot to start the Pyramid Web server. 390 Private slot to start the Flask Web server.
301 391
302 @param logging flag indicating to enable logging 392 @param logging flag indicating to enable logging
303 @type bool 393 @type bool
304 """ 394 """
305 # TODO: implement this (flask run) 395 # TODO: implement this (flask run)
306 396 workdir, env = self.prepareRuntimeEnvironment()
307 def __serverProcFinished(self): 397 if env is not None:
308 """ 398 cmd = self.getFlaskCommand()
309 Private slot connected to the finished signal. 399
310 """ 400 dlg = RunServerDialog()
311 if ( 401 if dlg.startServer(cmd, workdir, env):
312 self.__serverProc is not None and 402 dlg.show()
313 self.__serverProc.state() != QProcess.NotRunning 403 self.__serverDialog = dlg
314 ): 404
315 self.__serverProc.terminate() 405 def __runDevelopmentServer(self, logging=False):
316 QTimer.singleShot(2000, self.__serverProc.kill) 406 """
317 self.__serverProc.waitForFinished(3000) 407 Private slot to start the Flask Web server in development mode.
318 self.__serverProc = None 408
409 @param logging flag indicating to enable logging
410 @type bool
411 """
412 # TODO: implement this (flask run with FLASK_ENV=development)
413
414 ## def __serverProcFinished(self):
415 ## """
416 ## Private slot connected to the finished signal.
417 ## """
418 ## if (
419 ## self.__serverProc is not None and
420 ## self.__serverProc.state() != QProcess.NotRunning
421 ## ):
422 ## self.__serverProc.terminate()
423 ## QTimer.singleShot(2000, self.__serverProc.kill)
424 ## self.__serverProc.waitForFinished(3000)
425 ## self.__serverProc = None
319 426
320 def __runPythonShell(self): 427 def __runPythonShell(self):
321 """ 428 """
322 Private slot to start a Python console in the app context. 429 Private slot to start a Python console in the app context.
323 """ 430 """

eric ide

mercurial