ProjectFlask/Project.py

changeset 9
79094fb72c18
parent 8
cfbd3a2757fd
child 11
da6ef8ab8268
equal deleted inserted replaced
8:cfbd3a2757fd 9:79094fb72c18
8 """ 8 """
9 9
10 import os 10 import os
11 11
12 from PyQt5.QtCore import ( 12 from PyQt5.QtCore import (
13 pyqtSlot, QObject, QProcess, QProcessEnvironment 13 pyqtSlot, QObject, QProcess, QProcessEnvironment, QTimer
14 ) 14 )
15 from PyQt5.QtWidgets import QMenu 15 from PyQt5.QtWidgets import QMenu
16 16
17 from E5Gui import E5MessageBox 17 from E5Gui import E5MessageBox
18 from E5Gui.E5Action import E5Action 18 from E5Gui.E5Action import E5Action
23 import UI.PixmapCache 23 import UI.PixmapCache
24 import Utilities 24 import Utilities
25 25
26 from .RunServerDialog import RunServerDialog 26 from .RunServerDialog import RunServerDialog
27 from .RoutesDialog import RoutesDialog 27 from .RoutesDialog import RoutesDialog
28 from .FlaskCommandDialog import FlaskCommandDialog
28 29
29 30
30 class Project(QObject): 31 class Project(QObject):
31 """ 32 """
32 Class implementing the Flask project support. 33 Class implementing the Flask project support.
51 self.__e5project = e5App().getObject("Project") 52 self.__e5project = e5App().getObject("Project")
52 self.__virtualEnvManager = e5App().getObject("VirtualEnvManager") 53 self.__virtualEnvManager = e5App().getObject("VirtualEnvManager")
53 54
54 self.__menus = {} # dictionary with references to menus 55 self.__menus = {} # dictionary with references to menus
55 56
56 ## self.__serverProc = None
57 self.__serverDialog = None 57 self.__serverDialog = None
58 self.__routesDialog = None 58 self.__routesDialog = None
59 59 self.__shellProcess = None
60
60 self.__flaskVersions = { 61 self.__flaskVersions = {
61 "python": "", 62 "python": "",
62 "flask": "", 63 "flask": "",
63 "werkzeug": "", 64 "werkzeug": "",
64 } 65 }
99 """<p>Starts the Flask Web server in development mode.</p>""" 100 """<p>Starts the Flask Web server in development mode.</p>"""
100 )) 101 ))
101 self.runDevServerAct.triggered.connect(self.__runDevelopmentServer) 102 self.runDevServerAct.triggered.connect(self.__runDevelopmentServer)
102 self.actions.append(self.runDevServerAct) 103 self.actions.append(self.runDevServerAct)
103 104
104 ############################## 105 self.askForServerOptionsAct = E5Action(
106 self.tr('Ask for Server Start Options'),
107 self.tr('Ask for Server Start Options'),
108 0, 0,
109 self, 'flask_ask_server_options')
110 self.askForServerOptionsAct.setStatusTip(self.tr(
111 'Ask for server start options'))
112 self.askForServerOptionsAct.setWhatsThis(self.tr(
113 """<b>Ask for Server Start Options</b>"""
114 """<p>Asks for server start options before the Flask Web server"""
115 """ is started. If this is unchecked, the server is started with"""
116 """ default parameters.</p>"""
117 ))
118 self.askForServerOptionsAct.setCheckable(True)
119 self.actions.append(self.askForServerOptionsAct)
120
121 ###############################
122 ## shell action below ##
123 ###############################
124
125 self.runPythonShellAct = E5Action(
126 self.tr('Start Flask Python Console'),
127 self.tr('Start Flask &Python Console'),
128 0, 0,
129 self, 'flask_python_console')
130 self.runPythonShellAct.setStatusTip(self.tr(
131 'Starts an interactive Python interpreter'))
132 self.runPythonShellAct.setWhatsThis(self.tr(
133 """<b>Start Flask Python Console</b>"""
134 """<p>Starts an interactive Python interpreter.</p>"""
135 ))
136 self.runPythonShellAct.triggered.connect(self.__runPythonShell)
137 self.actions.append(self.runPythonShellAct)
138
139 ################################
105 ## routes action below ## 140 ## routes action below ##
106 ############################## 141 ################################
107 142
108 self.showRoutesAct = E5Action( 143 self.showRoutesAct = E5Action(
109 self.tr('Show Routes'), 144 self.tr('Show Routes'),
110 self.tr('Show &Routes'), 145 self.tr('Show &Routes'),
111 0, 0, 146 0, 0,
118 )) 153 ))
119 self.showRoutesAct.triggered.connect(self.__showRoutes) 154 self.showRoutesAct.triggered.connect(self.__showRoutes)
120 self.actions.append(self.showRoutesAct) 155 self.actions.append(self.showRoutesAct)
121 156
122 ################################## 157 ##################################
158 ## database action below ##
159 ##################################
160
161 self.initDatabaseAct = E5Action(
162 self.tr('Initialize Database'),
163 self.tr('&Initialize Database'),
164 0, 0,
165 self, 'flask_init_database')
166 self.initDatabaseAct.setStatusTip(self.tr(
167 'Shows a dialog with the result of the database creation'))
168 self.initDatabaseAct.setWhatsThis(self.tr(
169 """<b>Initialize Database</b>"""
170 """<p>Shows a dialog with the result of the database"""
171 """ creation.</p>"""
172 ))
173 self.initDatabaseAct.triggered.connect(self.__initDatabase)
174 self.actions.append(self.initDatabaseAct)
175
176 ##################################
123 ## documentation action below ## 177 ## documentation action below ##
124 ################################## 178 ##################################
125 179
126 self.documentationAct = E5Action( 180 self.documentationAct = E5Action(
127 self.tr('Documentation'), 181 self.tr('Documentation'),
165 self.__menus = {} # clear menus references 219 self.__menus = {} # clear menus references
166 220
167 menu = QMenu(self.tr('&Flask'), self.__ui) 221 menu = QMenu(self.tr('&Flask'), self.__ui)
168 menu.setTearOffEnabled(True) 222 menu.setTearOffEnabled(True)
169 223
224 menu.addSection("flask run")
170 menu.addAction(self.runServerAct) 225 menu.addAction(self.runServerAct)
171 menu.addAction(self.runDevServerAct) 226 menu.addAction(self.runDevServerAct)
172 menu.addSeparator() 227 menu.addAction(self.askForServerOptionsAct)
228 menu.addSection("flask shell")
229 menu.addAction(self.runPythonShellAct)
230 menu.addSection("flask routes")
173 menu.addAction(self.showRoutesAct) 231 menu.addAction(self.showRoutesAct)
174 menu.addSeparator() 232 menu.addSection("flask init-db")
233 menu.addAction(self.initDatabaseAct)
234 menu.addSection(self.tr("Various"))
175 menu.addAction(self.documentationAct) 235 menu.addAction(self.documentationAct)
176 menu.addSeparator() 236 menu.addSeparator()
177 menu.addAction(self.aboutFlaskAct) 237 menu.addAction(self.aboutFlaskAct)
178 238
179 self.__menus["main"] = menu 239 self.__menus["main"] = menu
419 """ 479 """
420 page = self.__plugin.getPreferences("FlaskDocUrl") 480 page = self.__plugin.getPreferences("FlaskDocUrl")
421 self.__ui.launchHelpViewer(page) 481 self.__ui.launchHelpViewer(page)
422 482
423 ################################################################## 483 ##################################################################
424 ## slots below implement run functions 484 ## slots below implement run functions for the server
425 ################################################################## 485 ##################################################################
426 486
427 @pyqtSlot() 487 @pyqtSlot()
428 def __runServer(self, development=False): 488 def __runServer(self, development=False):
429 """ 489 """
433 @type bool 493 @type bool
434 """ 494 """
435 if self.__serverDialog is not None: 495 if self.__serverDialog is not None:
436 self.__serverDialog.close() 496 self.__serverDialog.close()
437 497
438 dlg = RunServerDialog(self.__plugin) 498 askForOptions = self.askForServerOptionsAct.isChecked()
439 if dlg.startServer(self, development=development): 499 dlg = RunServerDialog(self.__plugin, self)
500 if dlg.startServer(development=development,
501 askForOptions=askForOptions):
440 dlg.show() 502 dlg.show()
441 self.__serverDialog = dlg 503 self.__serverDialog = dlg
442 504
443 @pyqtSlot() 505 @pyqtSlot()
444 def __runDevelopmentServer(self): 506 def __runDevelopmentServer(self):
445 """ 507 """
446 Private slot to start the Flask Web server in development mode. 508 Private slot to start the Flask Web server in development mode.
447 """ 509 """
448 self.__runServer(development=True) 510 self.__runServer(development=True)
449 511
450 # TODO: add method to start a server with parameters 512 ##################################################################
451 513 ## slots below implement functions for the flask console
452 ## def __serverProcFinished(self): 514 ##################################################################
453 ## """ 515
454 ## Private slot connected to the finished signal. 516 @pyqtSlot()
455 ## """
456 ## if (
457 ## self.__serverProc is not None and
458 ## self.__serverProc.state() != QProcess.NotRunning
459 ## ):
460 ## self.__serverProc.terminate()
461 ## QTimer.singleShot(2000, self.__serverProc.kill)
462 ## self.__serverProc.waitForFinished(3000)
463 ## self.__serverProc = None
464
465 def __runPythonShell(self): 517 def __runPythonShell(self):
466 """ 518 """
467 Private slot to start a Python console in the app context. 519 Private slot to start a Python console in the app context.
468 """ 520 """
469 # TODO: implement this (flask shell) 521 workdir, env = self.prepareRuntimeEnvironment()
522 if env is not None:
523 command = self.getFlaskCommand()
524
525 consoleCmd = self.__plugin.getPreferences("ConsoleCommand")
526 if consoleCmd:
527 self.__terminatePythonShell()
528
529 args = Utilities.parseOptionString(consoleCmd)
530 args[0] = Utilities.getExecutablePath(args[0])
531 args += [command, "shell"]
532
533 self.__shellProcess = QProcess()
534 self.__shellProcess.setProcessEnvironment(env)
535 self.__shellProcess.setWorkingDirectory(workdir)
536 self.__shellProcess.finished.connect(
537 self.__shellProcessFinished)
538
539 self.__shellProcess.start(args[0], args[1:])
540 self.__shellProcess.waitForStarted(10000)
541
542 @pyqtSlot()
543 def __shellProcessFinished(self):
544 """
545 Private slot connected to the finished signal.
546 """
547 self.__shellProcess = None
548
549 def __terminatePythonShell(self):
550 """
551 Private method to terminate the current Python console.
552 """
553 if (
554 self.__shellProcess is not None and
555 self.__shellProcess.state() != QProcess.NotRunning
556 ):
557 self.__shellProcess.terminate()
558 QTimer.singleShot(2000, self.__shellProcess.kill)
559 self.__shellProcess.waitForFinished(3000)
470 560
471 ################################################################## 561 ##################################################################
472 ## slots below implement various debugging functions 562 ## slots below implement various debugging functions
473 ################################################################## 563 ##################################################################
474 564
565 @pyqtSlot()
475 def __showRoutes(self): 566 def __showRoutes(self):
476 """ 567 """
477 Private slot showing all URL dispatch routes. 568 Private slot showing all URL dispatch routes.
478 """ 569 """
479 if self.__routesDialog is not None: 570 if self.__routesDialog is not None:
481 572
482 dlg = RoutesDialog(self) 573 dlg = RoutesDialog(self)
483 if dlg.showRoutes(): 574 if dlg.showRoutes():
484 dlg.show() 575 dlg.show()
485 self.__routesDialog = dlg 576 self.__routesDialog = dlg
577
578 @pyqtSlot()
579 def __initDatabase(self):
580 """
581 Private slot showing the result of the database creation.
582 """
583 dlg = FlaskCommandDialog(self)
584 if dlg.startCommand("init-db"):
585 dlg.exec()

eric ide

mercurial