Skip to content

Commit ccce399

Browse files
authored
v1.6.0
version 1.6.0
2 parents b57a10b + fda0a03 commit ccce399

File tree

3 files changed

+24
-124
lines changed

3 files changed

+24
-124
lines changed

pyobs_gui/shellwidget.py

Lines changed: 7 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pyobs.comm import Comm, Proxy
1414
from pyobs.events import ModuleOpenedEvent, Event, ModuleClosedEvent
1515
from pyobs.utils import exceptions as exc
16+
from pyobs.utils.shellcommand import ShellCommand
1617
from pyobs.vfs import VirtualFileSystem
1718
from .base import BaseWidget
1819
from .qt.shellwidget_ui import Ui_ShellWidget
@@ -172,133 +173,23 @@ def _add_command_log(self, msg: str, color: str | None = None) -> None:
172173
msg = '<span style="color:%s;">%s</span>' % (color, msg)
173174
self.add_command_log.emit(msg)
174175

175-
def _parse_command(self, cmd: str) -> tuple[str, str, list[Any]]:
176-
# tokenize command
177-
tokens = tokenize.tokenize(BytesIO(cmd.encode("utf-8")).readline)
178-
179-
# init values
180-
module: str | None = None
181-
command: str | None = None
182-
params: list[Any] = []
183-
sign = 1
184-
185-
# we start here
186-
state = ParserState.START
187-
188-
# loop tokens
189-
for t in tokens:
190-
if state == ParserState.START:
191-
# first token is always ENCODING
192-
if t.type != tokenize.ENCODING:
193-
raise ValueError("Invalid command.")
194-
state = ParserState.MODULE
195-
196-
elif state == ParserState.MODULE:
197-
# 2nd token is always a NAME with the command
198-
if t.type != tokenize.NAME:
199-
raise ValueError("Invalid command.")
200-
module = t.string
201-
state = ParserState.MODSEP
202-
203-
elif state == ParserState.MODSEP:
204-
# 3rd token is always a point
205-
if t.type != tokenize.OP or t.string != ".":
206-
raise ValueError("Invalid command.")
207-
state = ParserState.COMMAND
208-
209-
elif state == ParserState.COMMAND:
210-
# 4th token is always a NAME with the command
211-
if t.type != tokenize.NAME:
212-
raise ValueError("Invalid command.")
213-
command = t.string
214-
state = ParserState.OPEN
215-
216-
elif state == ParserState.OPEN:
217-
# 5th token is always an OP with an opening bracket
218-
if t.type != tokenize.OP or t.string != "(":
219-
raise ValueError("Invalid parameters.")
220-
state = ParserState.PARAM
221-
222-
elif state == ParserState.PARAM:
223-
# if params list is empty, we accept an OP with a closing bracket, otherwise it must be
224-
# a NUMBER or STRING
225-
if len(params) == 0 and t.type == tokenize.OP and t.string == ")":
226-
state = ParserState.CLOSE
227-
elif t.type == tokenize.OP and t.string == "-":
228-
sign = -1
229-
elif t.type == tokenize.NUMBER or t.type == tokenize.STRING:
230-
if t.type == tokenize.STRING:
231-
if t.string[0] == t.string[-1] and t.string[0] in ['"', '"']:
232-
params.append(t.string[1:-1])
233-
else:
234-
params.append(t.string)
235-
else:
236-
params.append(sign * float(t.string))
237-
sign = 1
238-
state = ParserState.PARAMSEP
239-
else:
240-
raise ValueError("Invalid parameters.")
241-
242-
elif state == ParserState.PARAMSEP:
243-
# following a PARAM, there must be an OP, either a comma, or a closing bracket
244-
if t.type != tokenize.OP:
245-
raise ValueError("Invalid parameters.")
246-
if t.string == ",":
247-
state = ParserState.PARAM
248-
elif t.string == ")":
249-
state = ParserState.CLOSE
250-
else:
251-
raise ValueError("Invalid parameters.")
252-
253-
elif state == ParserState.CLOSE:
254-
# must be a closing bracket
255-
if t.type not in [tokenize.NEWLINE, tokenize.ENDMARKER]:
256-
raise ValueError("Expecting end of command after closing bracket.")
257-
258-
# return results
259-
if module is None or command is None:
260-
raise ValueError("Found end of command without module and/or command.")
261-
return module, command, params
262-
263-
# if we came here, something went wrong
264-
raise ValueError("Invalid parameters.")
265-
266176
def execute_command(self, command: str) -> None:
267177
asyncio.create_task(self._execute_command(command))
268178

269179
async def _execute_command(self, command: str) -> None:
270-
# log command
271-
self.command_number += 1
272-
self._add_command_log("$ (#%d) %s" % (self.command_number, command))
273-
274-
# parse command
275180
try:
276-
client, command, params = self._parse_command(command)
181+
cmd = ShellCommand.parse(command)
182+
self._add_command_log(str(cmd))
277183
except Exception as e:
278-
self._add_command_log("(#%d): %s" % (self.command_number, str(e)), "red")
279-
return
280-
281-
# get proxy
282-
try:
283-
proxy = await self.comm.proxy(client)
284-
except ValueError:
285-
self._add_command_log(f"(#{self.command_number}): Could not find module: {str(client)}", "red")
184+
self._add_command_log(f"$ {command}")
185+
self._add_command_log(f"{str(e)}", "red")
286186
return
287187

288188
# execute command
289-
try:
290-
response = await proxy.execute(command, *params)
291-
except ValueError as e:
292-
log.exception(f"(#{self.command_number}): Something has gone wrong.")
293-
self._add_command_log(f"(#{self.command_number}): Invalid parameter: {str(e)}", "red")
294-
return
295-
except exc.RemoteError as e:
296-
self._add_command_log(f"(#{self.command_number}) Exception raised: {str(e)}", "red")
297-
return
189+
response = await cmd.execute(self.comm)
298190

299191
# log response
300-
msg = "OK" if response is None else pprint.pformat(response)
301-
self._add_command_log("(#%d) %s" % (self.command_number, msg), "lime")
192+
self._add_command_log(str(response), response.color)
302193

303194
def _update_docs(self) -> None:
304195
return

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "pyobs-gui"
3-
version = "1.5.1"
3+
version = "1.6.0"
44
description = "A remote GUI for pyobs"
55
authors = [{ name = "Tim-Oliver Husser", email = "[email protected]" }]
66
requires-python = ">=3.11,<3.14"
@@ -12,7 +12,7 @@ dependencies = [
1212
"sunpy>=6.1.1,<7",
1313
"QtAwesome>=1.4.0,<2",
1414
"qfitswidget>=0.13.1",
15-
"pyobs-core>=1.24.0",
15+
"pyobs-core>=1.34.0",
1616
"pyside6>=6.10.1",
1717
]
1818

uv.lock

Lines changed: 15 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)