Fix load error with the new overridable ajax webclient
This commit is contained in:
parent
5cd58f4ef8
commit
e544b50866
1 changed files with 142 additions and 143 deletions
|
|
@ -24,14 +24,13 @@ import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
from twisted.internet.task import LoopingCall
|
|
||||||
from twisted.web import resource, server
|
|
||||||
|
|
||||||
from evennia.server import session
|
from evennia.server import session
|
||||||
from evennia.utils import utils
|
from evennia.utils import utils
|
||||||
from evennia.utils.ansi import parse_ansi
|
from evennia.utils.ansi import parse_ansi
|
||||||
from evennia.utils.text2html import parse_html
|
from evennia.utils.text2html import parse_html
|
||||||
from evennia.utils.utils import to_bytes, class_from_module, ip_from_request
|
from evennia.utils.utils import class_from_module, ip_from_request, to_bytes
|
||||||
|
from twisted.internet.task import LoopingCall
|
||||||
|
from twisted.web import resource, server
|
||||||
|
|
||||||
_CLIENT_SESSIONS = utils.mod_import(settings.SESSION_ENGINE).SessionStore
|
_CLIENT_SESSIONS = utils.mod_import(settings.SESSION_ENGINE).SessionStore
|
||||||
_RE_SCREENREADER_REGEX = re.compile(
|
_RE_SCREENREADER_REGEX = re.compile(
|
||||||
|
|
@ -58,6 +57,145 @@ def jsonify(obj):
|
||||||
return to_bytes(json.dumps(obj, ensure_ascii=False, cls=LazyEncoder))
|
return to_bytes(json.dumps(obj, ensure_ascii=False, cls=LazyEncoder))
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# A session type handling communication over the
|
||||||
|
# web client interface.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class AjaxWebClientSession(session.Session):
|
||||||
|
"""
|
||||||
|
This represents a session running in an AjaxWebclient.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.protocol_key = "webclient/ajax"
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_client_session(self):
|
||||||
|
"""
|
||||||
|
Get the Client browser session (used for auto-login based on browser session)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
csession (ClientSession): This is a django-specific internal representation
|
||||||
|
of the browser session.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self.csessid:
|
||||||
|
return _CLIENT_SESSIONS(session_key=self.csessid)
|
||||||
|
|
||||||
|
def disconnect(self, reason="Server disconnected."):
|
||||||
|
"""
|
||||||
|
Disconnect from server.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
reason (str): Motivation for the disconnect.
|
||||||
|
"""
|
||||||
|
csession = self.get_client_session()
|
||||||
|
|
||||||
|
if csession:
|
||||||
|
csession["webclient_authenticated_uid"] = None
|
||||||
|
csession.save()
|
||||||
|
self.logged_in = False
|
||||||
|
self.client.lineSend(self.csessid, ["connection_close", [reason], {}])
|
||||||
|
self.client.client_disconnect(self.csessid)
|
||||||
|
self.sessionhandler.disconnect(self)
|
||||||
|
|
||||||
|
def at_login(self):
|
||||||
|
csession = self.get_client_session()
|
||||||
|
if csession:
|
||||||
|
csession["webclient_authenticated_uid"] = self.uid
|
||||||
|
csession.save()
|
||||||
|
|
||||||
|
def data_in(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Data User -> Evennia
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
kwargs (any): Incoming data.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.sessionhandler.data_in(self, **kwargs)
|
||||||
|
|
||||||
|
def data_out(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Data Evennia -> User
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
kwargs (any): Options to the protocol
|
||||||
|
"""
|
||||||
|
self.sessionhandler.data_out(self, **kwargs)
|
||||||
|
|
||||||
|
def send_text(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Send text data. This will pre-process the text for
|
||||||
|
color-replacement, conversion to html etc.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (str): Text to send.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
options (dict): Options-dict with the following keys understood:
|
||||||
|
- raw (bool): No parsing at all (leave ansi-to-html markers unparsed).
|
||||||
|
- nocolor (bool): Remove all color.
|
||||||
|
- screenreader (bool): Use Screenreader mode.
|
||||||
|
- send_prompt (bool): Send a prompt with parsed html
|
||||||
|
|
||||||
|
"""
|
||||||
|
if args:
|
||||||
|
args = list(args)
|
||||||
|
text = args[0]
|
||||||
|
if text is None:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
flags = self.protocol_flags
|
||||||
|
text = utils.to_str(text)
|
||||||
|
|
||||||
|
options = kwargs.pop("options", {})
|
||||||
|
raw = options.get("raw", flags.get("RAW", False))
|
||||||
|
xterm256 = options.get("xterm256", flags.get("XTERM256", True))
|
||||||
|
useansi = options.get("ansi", flags.get("ANSI", True))
|
||||||
|
nocolor = options.get("nocolor", flags.get("NOCOLOR") or not (xterm256 or useansi))
|
||||||
|
screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
|
||||||
|
prompt = options.get("send_prompt", False)
|
||||||
|
|
||||||
|
if screenreader:
|
||||||
|
# screenreader mode cleans up output
|
||||||
|
text = parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
||||||
|
text = _RE_SCREENREADER_REGEX.sub("", text)
|
||||||
|
cmd = "prompt" if prompt else "text"
|
||||||
|
if raw:
|
||||||
|
args[0] = text
|
||||||
|
else:
|
||||||
|
args[0] = parse_html(text, strip_ansi=nocolor)
|
||||||
|
|
||||||
|
# send to client on required form [cmdname, args, kwargs]
|
||||||
|
self.client.lineSend(self.csessid, [cmd, args, kwargs])
|
||||||
|
|
||||||
|
def send_prompt(self, *args, **kwargs):
|
||||||
|
kwargs["options"].update({"send_prompt": True})
|
||||||
|
self.send_text(*args, **kwargs)
|
||||||
|
|
||||||
|
def send_default(self, cmdname, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Data Evennia -> User.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmdname (str): The first argument will always be the oob cmd name.
|
||||||
|
*args (any): Remaining args will be arguments for `cmd`.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
options (dict): These are ignored for oob commands. Use command
|
||||||
|
arguments (which can hold dicts) to send instructions to the
|
||||||
|
client instead.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not cmdname == "options":
|
||||||
|
self.client.lineSend(self.csessid, [cmdname, args, kwargs])
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# AjaxWebClient resource - this is called by the ajax client
|
# AjaxWebClient resource - this is called by the ajax client
|
||||||
# using POST requests to /webclientdata.
|
# using POST requests to /webclientdata.
|
||||||
|
|
@ -344,142 +482,3 @@ class AjaxWebClient(resource.Resource):
|
||||||
else:
|
else:
|
||||||
# This should not happen if client sends valid data.
|
# This should not happen if client sends valid data.
|
||||||
return b'""'
|
return b'""'
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# A session type handling communication over the
|
|
||||||
# web client interface.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
class AjaxWebClientSession(session.Session):
|
|
||||||
"""
|
|
||||||
This represents a session running in an AjaxWebclient.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.protocol_key = "webclient/ajax"
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_client_session(self):
|
|
||||||
"""
|
|
||||||
Get the Client browser session (used for auto-login based on browser session)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
csession (ClientSession): This is a django-specific internal representation
|
|
||||||
of the browser session.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if self.csessid:
|
|
||||||
return _CLIENT_SESSIONS(session_key=self.csessid)
|
|
||||||
|
|
||||||
def disconnect(self, reason="Server disconnected."):
|
|
||||||
"""
|
|
||||||
Disconnect from server.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
reason (str): Motivation for the disconnect.
|
|
||||||
"""
|
|
||||||
csession = self.get_client_session()
|
|
||||||
|
|
||||||
if csession:
|
|
||||||
csession["webclient_authenticated_uid"] = None
|
|
||||||
csession.save()
|
|
||||||
self.logged_in = False
|
|
||||||
self.client.lineSend(self.csessid, ["connection_close", [reason], {}])
|
|
||||||
self.client.client_disconnect(self.csessid)
|
|
||||||
self.sessionhandler.disconnect(self)
|
|
||||||
|
|
||||||
def at_login(self):
|
|
||||||
csession = self.get_client_session()
|
|
||||||
if csession:
|
|
||||||
csession["webclient_authenticated_uid"] = self.uid
|
|
||||||
csession.save()
|
|
||||||
|
|
||||||
def data_in(self, **kwargs):
|
|
||||||
"""
|
|
||||||
Data User -> Evennia
|
|
||||||
|
|
||||||
Keyword Args:
|
|
||||||
kwargs (any): Incoming data.
|
|
||||||
|
|
||||||
"""
|
|
||||||
self.sessionhandler.data_in(self, **kwargs)
|
|
||||||
|
|
||||||
def data_out(self, **kwargs):
|
|
||||||
"""
|
|
||||||
Data Evennia -> User
|
|
||||||
|
|
||||||
Keyword Args:
|
|
||||||
kwargs (any): Options to the protocol
|
|
||||||
"""
|
|
||||||
self.sessionhandler.data_out(self, **kwargs)
|
|
||||||
|
|
||||||
def send_text(self, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Send text data. This will pre-process the text for
|
|
||||||
color-replacement, conversion to html etc.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
text (str): Text to send.
|
|
||||||
|
|
||||||
Keyword Args:
|
|
||||||
options (dict): Options-dict with the following keys understood:
|
|
||||||
- raw (bool): No parsing at all (leave ansi-to-html markers unparsed).
|
|
||||||
- nocolor (bool): Remove all color.
|
|
||||||
- screenreader (bool): Use Screenreader mode.
|
|
||||||
- send_prompt (bool): Send a prompt with parsed html
|
|
||||||
|
|
||||||
"""
|
|
||||||
if args:
|
|
||||||
args = list(args)
|
|
||||||
text = args[0]
|
|
||||||
if text is None:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
flags = self.protocol_flags
|
|
||||||
text = utils.to_str(text)
|
|
||||||
|
|
||||||
options = kwargs.pop("options", {})
|
|
||||||
raw = options.get("raw", flags.get("RAW", False))
|
|
||||||
xterm256 = options.get("xterm256", flags.get("XTERM256", True))
|
|
||||||
useansi = options.get("ansi", flags.get("ANSI", True))
|
|
||||||
nocolor = options.get("nocolor", flags.get("NOCOLOR") or not (xterm256 or useansi))
|
|
||||||
screenreader = options.get("screenreader", flags.get("SCREENREADER", False))
|
|
||||||
prompt = options.get("send_prompt", False)
|
|
||||||
|
|
||||||
if screenreader:
|
|
||||||
# screenreader mode cleans up output
|
|
||||||
text = parse_ansi(text, strip_ansi=True, xterm256=False, mxp=False)
|
|
||||||
text = _RE_SCREENREADER_REGEX.sub("", text)
|
|
||||||
cmd = "prompt" if prompt else "text"
|
|
||||||
if raw:
|
|
||||||
args[0] = text
|
|
||||||
else:
|
|
||||||
args[0] = parse_html(text, strip_ansi=nocolor)
|
|
||||||
|
|
||||||
# send to client on required form [cmdname, args, kwargs]
|
|
||||||
self.client.lineSend(self.csessid, [cmd, args, kwargs])
|
|
||||||
|
|
||||||
def send_prompt(self, *args, **kwargs):
|
|
||||||
kwargs["options"].update({"send_prompt": True})
|
|
||||||
self.send_text(*args, **kwargs)
|
|
||||||
|
|
||||||
def send_default(self, cmdname, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Data Evennia -> User.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
cmdname (str): The first argument will always be the oob cmd name.
|
|
||||||
*args (any): Remaining args will be arguments for `cmd`.
|
|
||||||
|
|
||||||
Keyword Args:
|
|
||||||
options (dict): These are ignored for oob commands. Use command
|
|
||||||
arguments (which can hold dicts) to send instructions to the
|
|
||||||
client instead.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not cmdname == "options":
|
|
||||||
self.client.lineSend(self.csessid, [cmdname, args, kwargs])
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue