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( |