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. |
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 |
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 """ |