diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 1c81e97c9f..a87b6979ba 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -196,18 +196,18 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): @lazy_property def sessions(self): return AccountSessionHandler(self) - + # Do not make this a lazy property; the web UI will not refresh it! @property def characters(self): # Get playable characters list objs = self.db._playable_characters - + # Rebuild the list if legacy code left null values after deletion if None in objs: objs = [x for x in self.db._playable_characters if x] self.db._playable_characters = objs - + return objs # session-related methods diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index f7ae94a910..e3104bd686 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -229,13 +229,13 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): """ Creates a basic Channel with default parameters, unless otherwise specified or extended. - + Provides a friendlier interface to the utils.create_channel() function. - + Args: key (str): This must be unique. account (Account): Account to attribute this object to. - + Kwargs: aliases (list of str): List of alternative (likely shorter) keynames. description (str): A description of the channel, for use in listings. @@ -248,26 +248,26 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): Returns: channel (Channel): A newly created Channel. errors (list): A list of errors in string form, if any. - + """ errors = [] obj = None ip = kwargs.pop('ip', '') - + try: kwargs['desc'] = kwargs.pop('description', '') obj = create.create_channel(key, *args, **kwargs) - + # Record creator id and creation IP if ip: obj.db.creator_ip = ip if account: obj.db.creator_id = account.id - + except Exception as exc: errors.append("An error occurred while creating this '%s' object." % key) logger.log_err(exc) - + return obj, errors - + def delete(self): """ Deletes channel while also cleaning up channelhandler. @@ -773,4 +773,4 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): return '#' # Used by Django Sites/Admin - get_absolute_url = web_get_detail_url \ No newline at end of file + get_absolute_url = web_get_detail_url diff --git a/evennia/server/session.py b/evennia/server/session.py index 5481860163..7f02b69323 100644 --- a/evennia/server/session.py +++ b/evennia/server/session.py @@ -4,12 +4,14 @@ This module defines a generic session class. All connection instances """ from builtins import object +from django.conf import settings import time -#------------------------------------------------------------ +# ------------------------------------------------------------ # Server Session -#------------------------------------------------------------ +# ------------------------------------------------------------ + class Session(object): """ @@ -135,41 +137,6 @@ class Session(object): if self.account: self.protocol_flags.update(self.account.attributes.get("_saved_protocol_flags", {})) - # helpers - - def try_encode(self, text): - """ - Try to encode the given text, following the session's protocol flag. - - Args: - text (str or bytes): the text to encode to bytes. - - Returns: - encoded_text (bytes): the encoded text following the session's - protocol flag. If the converting fails, log the error - and send the text with "?" in place of problematic - characters. If the specified encoding cannot be found, - the protocol flag is reset to utf-8. - In any case, returns bytes. - - Note: - If the argument is bytes, return it as is. - - """ - if isinstance(text, bytes): - return text - - try: - encoded = text.encode(self.protocol_flags["ENCODING"]) - except LookupError: - self.protocol_flags["ENCODING"] = 'utf-8' - encoded = text.encode('utf-8') - except UnicodeEncodeError: - print("An error occurred during string encoding to {encoding}. Will remove errors and try again.".format(encoding=self.protocol_flags["ENCODING"])) - encoded = text.encode(self.protocol_flags["ENCODING"], errors="replace") - - return encoded - # access hooks def disconnect(self, reason=None): diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index 410d32e66f..cba2305e07 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -784,6 +784,53 @@ def latinify(unicode_string, default='?', pure_ascii=False): return ''.join(converted) +def to_bytes(self, text, session=None): + """ + Try to encode the given text to bytes, using encodings from settings or from Session. + + Args: + text (str or bytes): The text to encode to bytes. + session (Session, optional): A Session to receive the bytes. If given, + the Session.protocol_flags['ENCODING'] will be used to encode first. + + Returns: + encoded_text (bytes): the encoded text following the session's + protocol flag. If the converting fails, log the error + and send the text with "?" in place of problematic + characters. If the specified encoding cannot be found, + the protocol flag is reset to utf-8. + In any case, returns bytes. + + Note: + If the argument is bytes, return it as is. + + """ + if isinstance(text, bytes): + return text + + encoding = self.protocol_flags.get("ENCODING", 'utf-8') + try: + encoded = text.encode(encoding) + except LookupError: + for encoding in settings.ENCODINGS: + try: + encoded = text.encode('utf-8') + break + except LookupError: + pass + + self.protocol_flags["ENCODING"] = 'utf-8' + + encoded = text.encode('utf-8') + except UnicodeEncodeError: + print("An error occurred during string encoding to {encoding}. " + "Will remove errors and try again.".format( + encoding=self.protocol_flags["ENCODING"])) + encoded = text.encode(self.protocol_flags["ENCODING"], errors="replace") + + return encoded + + def to_str(obj, encoding='utf-8', force_string=False): """ This function is deprecated in the Python 3 version of Evennia and is