aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@outlook.com>2016-11-04 20:19:12 +0800
committerAaron LI <aaronly.me@outlook.com>2016-11-04 20:19:12 +0800
commit939e92de6241906bdfd39b51552079855af2eaf5 (patch)
tree886421d80e728711db2b3737e7237bf21fcf0f44
parent72b257e03b1e3405e2233a0cf86b2d8f851d6c14 (diff)
downloadfg21sim-939e92de6241906bdfd39b51552079855af2eaf5.tar.bz2
webui: websocket.py: Implement "set" action for "_handle_configs()"
Finish the "_set_configs()" function to implement the "set" action for "_handle_configs()". Also change the "status" keyword to "success" to be more intuitive.
-rw-r--r--fg21sim/configs/manager.py10
-rw-r--r--fg21sim/webui/websocket.py45
2 files changed, 39 insertions, 16 deletions
diff --git a/fg21sim/configs/manager.py b/fg21sim/configs/manager.py
index 0809126..b19978b 100644
--- a/fg21sim/configs/manager.py
+++ b/fg21sim/configs/manager.py
@@ -337,7 +337,7 @@ class ConfigManager:
val_new = reduce(operator.getitem, key, config_new)
d2 = reduce(lambda x, y: {y: x}, reversed(key), val_new)
self.merge(d2)
- logger.info("Set config: {key}: {val_new} <= {val_old}".format(
+ logger.info("Set config: {key}: {val_new} <- {val_old}".format(
key="/".join(key), val_new=val_new, val_old=val_old))
def get_path(self, key):
@@ -364,9 +364,9 @@ class ConfigManager:
NOTE
----
- - The "~" (tilde) inside path is expanded to the user home directory.
+ - The beginning ``~`` (tilde) is expanded to user's home directory.
- The relative path (with respect to the user configuration file)
- is converted to absolute path if `self.userconfig` presents.
+ is converted to absolute path if ``self.userconfig`` is valid.
"""
value = self.getn(key)
if value is None:
@@ -379,8 +379,8 @@ class ConfigManager:
#
path = os.path.expanduser(value)
if not os.path.isabs(path):
- # Got relative path, try to convert to the absolute path
- if hasattr(self, "userconfig"):
+ # Got a relative path, try to convert to the absolute path
+ if self.userconfig is not None:
# User configuration loaded
path = os.path.join(os.path.dirname(self.userconfig), path)
else:
diff --git a/fg21sim/webui/websocket.py b/fg21sim/webui/websocket.py
index 76258a4..1e9b9d6 100644
--- a/fg21sim/webui/websocket.py
+++ b/fg21sim/webui/websocket.py
@@ -17,6 +17,7 @@ References
http://caniuse.com/#feat=websockets
"""
+import os
import json
import logging
@@ -117,7 +118,7 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
The sent message also has a ``type`` item of same value, which the
client can be used to figure out the proper actions.
- There is a ``status`` item which indicates the status of the
+ There is a ``success`` item which indicates the status of the
requested operation, and a ``data`` item containing the response
data.
"""
@@ -128,10 +129,10 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
except json.JSONDecodeError:
logger.warning("WebSocket: {0}: ".format(self.name) +
"message is not a valid JSON string")
- response = {"status": False, "type": None}
+ response = {"success": False, "type": None}
except (KeyError, TypeError):
logger.warning("WebSocket: %s: skip invalid message" % self.name)
- response = {"status": False, "type": None}
+ response = {"success": False, "type": None}
else:
# Check the message type and dispatch task
if msg_type == "configs":
@@ -147,7 +148,7 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
# Message of unknown type
logger.warning("WebSocket: {0}: ".format(self.name) +
"unknown message type: {0}".format(msg_type))
- response = {"status": False, "type": msg_type}
+ response = {"success": False, "type": msg_type}
#
msg_response = json.dumps(response)
self.write_message(msg_response)
@@ -189,24 +190,24 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
if msg_action == "get":
# Get the values of the specified options
data, errors = self._get_configs(keys=msg_data)
- response["status"] = True if errors == {} else False
+ response["success"] = True if errors == {} else False
response["data"] = data
response["errors"] = errors
elif msg_action == "set":
# Set the values of the specified options
errors = self._set_configs(data=msg_data)
- response["status"] = True if errors == {} else False
+ response["success"] = True if errors == {} else False
response["data"] = {}
response["errors"] = errors
else:
logger.warning("WebSocket: {0}: ".format(self.name) +
"unknown action: {0}".format(msg_action))
- response["status"] = False
+ response["success"] = False
response["data"] = {}
response["errors"] = {}
except KeyError:
# Received message has wrong syntax/format
- response = {"status": False, "type": msg_type, "action": None}
+ response = {"success": False, "type": msg_type, "action": None}
#
logger.debug("WebSocket: {0}: ".format(self.name) +
"response: {0}".format(response))
@@ -264,6 +265,10 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
A dictionary of key-value pairs, with keys specifying the config
options whose value will be changed, and values the new values
to which config options will be set.
+ NOTE:
+ If want to set the ``userconfig`` option, an *absolute path*
+ must be provided (i.e., client should take care of the ``workdir``
+ value and generate a absolute path for ``userconfig``).
Returns
-------
@@ -271,14 +276,32 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
When error occurs (e.g., invalid key, invalid values), then the
specific errors with details are stored in this dictionary.
"""
- pass
+ errors = {}
+ for key, value in data.items():
+ if key == "userconfig":
+ # NOTE: The ``userconfig`` must be an absolute path
+ if os.path.isabs(value):
+ self.configs.userconfig = value
+ else:
+ errors["userconfig"] = "Not an absolute path"
+ else:
+ try:
+ self.configs.setn(key, value)
+ except KeyError as e:
+ errors[key] = str(e)
+ # NOTE:
+ # Check the whole configurations after all provided options are
+ # updated, and merge the validation errors.
+ __, cherr = self.configs.check_all(raise_exception=False)
+ errors.update(cherr)
+ return errors
def _handle_console(self, msg):
# Got a message of supported types
msg_type = msg["type"]
logger.info("WebSocket: {0}: ".format(self.name) +
"handle message of type: {0}".format(msg_type))
- response = {"status": True, "type": msg_type}
+ response = {"success": True, "type": msg_type}
return response
def _handle_results(self, msg):
@@ -286,5 +309,5 @@ class FG21simWSHandler(tornado.websocket.WebSocketHandler):
msg_type = msg["type"]
logger.info("WebSocket: {0}: ".format(self.name) +
"handle message of type: {0}".format(msg_type))
- response = {"status": True, "type": msg_type}
+ response = {"success": True, "type": msg_type}
return response