ProjectFlask/RunServerDialog.py

changeset 9
79094fb72c18
parent 6
d491ccab7343
child 10
506c78268b18
equal deleted inserted replaced
8:cfbd3a2757fd 9:79094fb72c18
9 9
10 import re 10 import re
11 11
12 from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer 12 from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer
13 from PyQt5.QtGui import QTextCharFormat 13 from PyQt5.QtGui import QTextCharFormat
14 from PyQt5.QtWidgets import QDialog, QDialogButtonBox 14 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMenu
15 15
16 from E5Gui import E5MessageBox 16 from E5Gui import E5MessageBox
17 from E5Gui.E5Application import e5App 17 from E5Gui.E5Application import e5App
18 18
19 from .Ui_RunServerDialog import Ui_RunServerDialog 19 from .Ui_RunServerDialog import Ui_RunServerDialog
20 20
21 from . import AnsiTools 21 from . import AnsiTools
22 from .ServerStartOptionsDialog import ServerStartOptionsDialog
23
24 import UI.PixmapCache
22 25
23 26
24 # TODO: should this be placed into the sidebar as a sidebar widget? 27 # TODO: should this be placed into the sidebar as a sidebar widget?
25 class RunServerDialog(QDialog, Ui_RunServerDialog): 28 class RunServerDialog(QDialog, Ui_RunServerDialog):
26 """ 29 """
27 Class implementing a dialog to run the Flask server. 30 Class implementing a dialog to run the Flask server.
28 """ 31 """
29 def __init__(self, plugin, parent=None): 32 def __init__(self, plugin, project, parent=None):
30 """ 33 """
31 Constructor 34 Constructor
32 35
33 @param plugin reference to the plug-in object 36 @param plugin reference to the plug-in object
34 @type PluginProjectFlask 37 @type PluginProjectFlask
38 @param project reference to the project object
39 @type Project
35 @param parent reference to the parent widget 40 @param parent reference to the parent widget
36 @type QWidget 41 @type QWidget
37 """ 42 """
38 super(RunServerDialog, self).__init__(parent) 43 super(RunServerDialog, self).__init__(parent)
39 self.setupUi(self) 44 self.setupUi(self)
40 45
41 self.__plugin = plugin 46 self.__plugin = plugin
47 self.__project = project
48
49 self.__serverOptions = {
50 "development": False
51 }
42 52
43 self.__process = None 53 self.__process = None
44 self.__serverUrl = "" 54 self.__serverUrl = ""
45 55
46 self.__ansiRe = re.compile(r"""(\\x1b\[\d+m)""") 56 self.__ansiRe = re.compile("(\\x1b\[\d+m)")
47 57
48 self.__urlRe = re.compile(r""" * Running on ([^(]+) \(.*""") 58 self.__urlRe = re.compile(r""" * Running on ([^(]+) \(.*""")
49 59
50 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 60 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
51 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 61 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
52 62
53 self.__defaultTextFormat = self.outputEdit.currentCharFormat() 63 self.__defaultTextFormat = self.outputEdit.currentCharFormat()
54 64
55 def startServer(self, project, development=False): 65 self.__initActionsMenu()
66
67 def __initActionsMenu(self):
68 """
69 Private method to populate the actions button menu.
70 """
71 self.__actionsMenu = QMenu()
72 self.__actionsMenu.setTearOffEnabled(True)
73 self.__actionsMenu.setToolTipsVisible(True)
74 self.__actionsMenu.aboutToShow.connect(self.__showActionsMenu)
75
76 # re-start server
77 self.__actionsMenu.addAction(
78 self.tr("Re-start Server"), self.__restartServer)
79 self.__restartModeAct = self.__actionsMenu.addAction(
80 self.tr("Re-start Server"), self.__restartServerDifferentMode)
81 self.__actionsMenu.addSeparator()
82 self.__actionsMenu.addAction(
83 self.tr("Re-start Server with Options"),
84 self.__restartServerWithOptions)
85 # start server with options
86
87 self.menuButton.setIcon(UI.PixmapCache.getIcon("actionsToolButton"))
88 self.menuButton.setMenu(self.__actionsMenu)
89
90 @pyqtSlot()
91 def __showActionsMenu(self):
92 """
93 Private slot handling the actions menu about to be shown.
94 """
95 if self.__serverOptions["development"]:
96 self.__restartModeAct.setText(
97 self.tr("Re-start Server (Production Mode)"))
98 else:
99 self.__restartModeAct.setText(
100 self.tr("Re-start Server (Development Mode)"))
101
102 def startServer(self, development=False, restart=False,
103 askForOptions=False):
56 """ 104 """
57 Public method to start the Flask server process. 105 Public method to start the Flask server process.
58 106
59 @param project reference to the project object
60 @type Project
61 @param development flag indicating development mode 107 @param development flag indicating development mode
62 @type bool 108 @type bool
63 @return flag indicating success 109 @return flag indicating success
64 @rtype bool 110 @rtype bool
65 """ 111 """
66 workdir, env = project.prepareRuntimeEnvironment( 112 self.__serverOptions["development"] = development
67 development=development) 113
114 if askForOptions:
115 dlg = ServerStartOptionsDialog(self.__serverOptions)
116 if dlg.exec() != QDialog.Accepted:
117 return False
118
119 self.__serverOptions.update(dlg.getDataDict())
120
121 workdir, env = self.__project.prepareRuntimeEnvironment(
122 development=self.__serverOptions["development"])
68 if env is not None: 123 if env is not None:
69 command = project.getFlaskCommand() 124 command = self.__project.getFlaskCommand()
70 125
71 self.__process = QProcess() 126 self.__process = QProcess()
72 self.__process.setProcessEnvironment(env) 127 self.__process.setProcessEnvironment(env)
73 self.__process.setWorkingDirectory(workdir) 128 self.__process.setWorkingDirectory(workdir)
74 self.__process.setProcessChannelMode(QProcess.MergedChannels) 129 self.__process.setProcessChannelMode(QProcess.MergedChannels)
75 130
76 self.__process.readyReadStandardOutput.connect(self.__readStdOut) 131 self.__process.readyReadStandardOutput.connect(self.__readStdOut)
77 self.__process.finished.connect(self.__processFinished) 132 self.__process.finished.connect(self.__processFinished)
78 133
134 self.outputEdit.clear()
135
79 args = ["run"] 136 args = ["run"]
80 # if host: 137 if "host" in self.__serverOptions and self.__serverOptions["host"]:
81 # args += ["--host", host] 138 args += ["--host", self.__serverOptions["host"]]
82 # if port: 139 if "port" in self.__serverOptions and self.__serverOptions["port"]:
83 # args += ["--port", str(port)] 140 args += ["--port", self.__serverOptions["port"]]
84 141
85 self.__process.start(command, args) 142 self.__process.start(command, args)
86 ok = self.__process.waitForStarted(10000) 143 ok = self.__process.waitForStarted(10000)
87 if not ok: 144 if not ok:
88 E5MessageBox.critical( 145 E5MessageBox.critical(
92 """ started.""")) 149 """ started."""))
93 else: 150 else:
94 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 151 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
95 self.stopServerButton.setEnabled(True) 152 self.stopServerButton.setEnabled(True)
96 self.stopServerButton.setDefault(True) 153 self.stopServerButton.setDefault(True)
154 self.startBrowserButton.setEnabled(True)
97 else: 155 else:
98 ok = False 156 ok = False
99 157
100 return ok 158 return ok
101 159
118 out = str(self.__process.readAllStandardOutput(), "utf-8") 176 out = str(self.__process.readAllStandardOutput(), "utf-8")
119 if not self.__serverUrl: 177 if not self.__serverUrl:
120 urlMatch = self.__urlRe.search(out) 178 urlMatch = self.__urlRe.search(out)
121 if urlMatch: 179 if urlMatch:
122 self.__serverUrl = urlMatch.group(1) 180 self.__serverUrl = urlMatch.group(1)
123 self.startBrowserButton.setEnabled(True)
124 181
125 for txt in self.__ansiRe.split(out): 182 for txt in self.__ansiRe.split(out):
126 if txt.startswith("\x1b["): 183 if txt.startswith("\x1b["):
127 color = int(txt[2:-1]) # strip off ANSI command parts 184 color = int(txt[2:-1]) # strip off ANSI command parts
128 if color == 0: 185 if color == 0:
178 import webbrowser 235 import webbrowser
179 webbrowser.open(self.__serverUrl) 236 webbrowser.open(self.__serverUrl)
180 else: 237 else:
181 e5App().getObject("UserInterface").launchHelpViewer( 238 e5App().getObject("UserInterface").launchHelpViewer(
182 self.__serverUrl) 239 self.__serverUrl)
240
241 @pyqtSlot()
242 def __restartServer(self):
243 """
244 Private slot to restart the server process.
245 """
246 # step 1: stop the current server
247 self.on_stopServerButton_clicked()
248
249 # step 2: start a new server
250 self.startServer(development=self.__serverOptions["development"])
251
252 @pyqtSlot()
253 def __restartServerDifferentMode(self):
254 """
255 Private slot to restart the server process with the opposite mode.
256 """
257 # step 1: stop the current server
258 self.on_stopServerButton_clicked()
259
260 # step 2: start a new server
261 self.startServer(development=not self.__serverOptions["development"])
262 @pyqtSlot()
263 def __restartServerWithOptions(self):
264 """
265 Private slot to restart the server asking for start options.
266 """
267 # step 1: stop the current server
268 self.on_stopServerButton_clicked()
269
270 # step 2: start a new server
271 self.startServer(development=self.__serverOptions["development"],
272 askForOptions=True)

eric ide

mercurial