Port SessionHandler for Py3.

This commit is contained in:
Ryan Stein 2017-10-29 22:17:00 -04:00
parent aaf13eec16
commit 9d48e616b1

View file

@ -24,11 +24,9 @@ from evennia.utils.utils import (variable_from_module, is_iter,
make_iter,
callables_from_module)
from evennia.utils.inlinefuncs import parse_inlinefunc
from codecs import decode as codecs_decode
try:
import pickle as pickle
except ImportError:
import pickle
import pickle
_INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED
@ -39,6 +37,8 @@ _ServerConfig = None
_ScriptDB = None
_OOB_HANDLER = None
_ERR_BAD_UTF8 = 'Your client sent an incorrect UTF-8 sequence.'
class DummySession(object):
sessid = 0
@ -47,17 +47,8 @@ class DummySession(object):
DUMMYSESSION = DummySession()
# AMP signals
PCONN = chr(1) # portal session connect
PDISCONN = chr(2) # portal session disconnect
PSYNC = chr(3) # portal session sync
SLOGIN = chr(4) # server session login
SDISCONN = chr(5) # server session disconnect
SDISCONNALL = chr(6) # server session disconnect all
SSHUTD = chr(7) # server shutdown
SSYNC = chr(8) # server session sync
SCONN = chr(11) # server portal connection (for bots)
PCONNSYNC = chr(12) # portal post-syncing session
PDISCONNALL = chr(13) # portal session discnnect all
from .amp import (PCONN, PDISCONN, PSYNC, SLOGIN, SDISCONN, SDISCONNALL,
SSHUTD, SSYNC, SCONN, PCONNSYNC, PDISCONNALL, )
# i18n
from django.utils.translation import ugettext as _
@ -185,6 +176,21 @@ class SessionHandler(dict):
raw = options.get("raw", False)
strip_inlinefunc = options.get("strip_inlinefunc", False)
def _utf8(data):
if isinstance(data, bytes):
try:
data = codecs_decode(data, session.protocol_flags["ENCODING"])
except LookupError:
# wrong encoding set on the session. Set it to a safe one
session.protocol_flags["ENCODING"] = "utf-8"
data = codecs_decode(data, "utf-8")
except UnicodeDecodeError:
# incorrect unicode sequence
session.sendLine(_ERR_BAD_UTF8)
data = ''
return data
def _validate(data):
"Helper function to convert data to AMP-safe (picketable) values"
if isinstance(data, dict):
@ -192,24 +198,15 @@ class SessionHandler(dict):
for key, part in list(data.items()):
newdict[key] = _validate(part)
return newdict
elif hasattr(data, "__iter__"):
elif is_iter(data):
return [_validate(part) for part in data]
elif isinstance(data, str):
# make sure strings are in a valid encoding
try:
data = data and to_str(to_unicode(data), encoding=session.protocol_flags["ENCODING"])
except LookupError:
# wrong encoding set on the session. Set it to a safe one
session.protocol_flags["ENCODING"] = "utf-8"
data = to_str(to_unicode(data), encoding=session.protocol_flags["ENCODING"])
elif isinstance(data, (str, bytes, )):
data = _utf8(data)
if _INLINEFUNC_ENABLED and not raw and isinstance(self, ServerSessionHandler):
# only parse inlinefuncs on the outgoing path (sessionhandler->)
data = parse_inlinefunc(data, strip=strip_inlinefunc, session=session)
# At this point the object is certainly the right encoding, but may still be a unicode object--
# to_str does not actually force objects to become bytestrings.
# If the unicode object is a subclass of unicode, such as ANSIString, this can cause a problem,
# as special behavior for that class will still be in play. Since we're now transferring raw data,
# we must now force this to be a proper bytestring.
return str(data)
elif hasattr(data, "id") and hasattr(data, "db_date_created") \
and hasattr(data, '__dbclass__'):
@ -229,10 +226,10 @@ class SessionHandler(dict):
rkwargs[key] = [[], {}]
elif isinstance(data, dict):
rkwargs[key] = [[], _validate(data)]
elif hasattr(data, "__iter__"):
elif is_iter(data):
if isinstance(data[-1], dict):
if len(data) == 2:
if hasattr(data[0], "__iter__"):
if is_iter(data[0]):
rkwargs[key] = [_validate(data[0]), _validate(data[1])]
else:
rkwargs[key] = [[_validate(data[0])], _validate(data[1])]