diff --git a/evennia/__init__.py b/evennia/__init__.py index 865b547b7b..679825bd70 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -116,13 +116,6 @@ def _init(): Evennia has fully initialized all its models. It sets up the API in a safe environment where all models are available already. """ - def imp(path, variable=True): - "Helper function" - mod, fromlist = path, "None" - if variable: - mod, fromlist = path.rsplit('.', 1) - return __import__(mod, fromlist=[fromlist]) - global DefaultPlayer, DefaultObject, DefaultGuest, DefaultCharacter global DefaultRoom, DefaultExit, DefaultChannel, DefaultScript global ObjectDB, PlayerDB, ScriptDB, ChannelDB, Msg @@ -263,9 +256,9 @@ def _init(): def __init__(self): "populate the object with commands" - def add_cmds(module): "helper method for populating this object with cmds" + from evennia.utils import utils cmdlist = utils.variable_from_module(module, module.__all__) self.__dict__.update(dict([(c.__name__, c) for c in cmdlist])) diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index ae87b62b63..795e0d0cf5 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -197,8 +197,6 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype): """ try: - local_obj_cmdsets = [None] - @inlineCallbacks def _get_channel_cmdset(player_or_obj): """ @@ -568,6 +566,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess sysarg = yield _SEARCH_AT_RESULT([match[2] for match in matches], caller, query=matches[0][0]) raise ExecSystemCommand(syscmd, sysarg) + cmdname, args, cmd = "", "", None if len(matches) == 1: # We have a unique command match. But it may still be invalid. match = matches[0] diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index ca0c9df517..fa86734242 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -532,6 +532,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)): for thiscmd in self.commands: if thiscmd == cmd: return thiscmd + return None def count(self): """ diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index a77243a1ca..d76db3c169 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -182,7 +182,6 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): #instantiate the cmdset (and catch its errors) if callable(cmdsetclass): cmdsetclass = cmdsetclass(cmdsetobj) - errstring = "" return cmdsetclass except ImportError as err: logger.log_trace() @@ -213,6 +212,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): else: errstring = errstring.format(path=python_path, traceback=err, timestamp=logger.timeformat()) break + return None # an error if errstring: # returning an empty error cmdset diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 2f85979678..a67316daf5 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -563,22 +563,6 @@ class CmdDesc(COMMAND_DEFAULT_CLASS): if not obj: return - def load(caller): - return caller.db.evmenu_target.db.desc or "" - - def save(caller, buf): - """ - Save line buffer to the desc prop. This should - return True if successful and also report its status to the user. - """ - caller.db.evmenu_target.db.desc = buf - caller.msg("Saved.") - return True - - def quit(caller): - caller.attributes.remove("evmenu_target") - caller.msg("Exited editor.") - self.caller.db.evmenu_target = obj # launch the editor EvEditor(self.caller, loadfunc=_desc_load, savefunc=_desc_save, quitfunc=_desc_quit, key="desc", persistent=True) @@ -1140,6 +1124,7 @@ class CmdName(ObjManipCommand): caller.msg("Usage: @name = [;alias;alias;...]") return + obj = None if self.lhs_objs: objname = self.lhs_objs[0]['name'] if objname.startswith("*"): @@ -1224,7 +1209,7 @@ class CmdOpen(ObjManipCommand): if len(exit_obj) > 1: # give error message and return caller.search(exit_name, location=location, exact=True) - return + return None if exit_obj: exit_obj = exit_obj[0] if not exit_obj.destination: @@ -1315,11 +1300,11 @@ class CmdOpen(ObjManipCommand): back_exit_name = self.lhs_objs[1]['name'] back_exit_aliases = self.lhs_objs[1]['aliases'] back_exit_typeclass = self.lhs_objs[1]['option'] - ok = self.create_exit(back_exit_name, - destination, - location, - back_exit_aliases, - back_exit_typeclass) + self.create_exit(back_exit_name, + destination, + location, + back_exit_aliases, + back_exit_typeclass) def _convert_from_string(cmd, strobj): @@ -1634,6 +1619,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS): if "show" in self.switches: string = "%s's current typeclass is %s." % (obj.name, obj.__class__) + caller.msg(string) return if self.cmdstring == "@swap": diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index 3271bcc869..d091ef0821 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -938,7 +938,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS): return try: import feedparser - feedparser # to avoid checker error of not being used + assert(feedparser) # to avoid checker error of not being used except ImportError: string = ("RSS requires python-feedparser (https://pypi.python.org/pypi/feedparser). " "Install before continuing.") diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index 22b0f9da48..8ad2eaff8f 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -11,7 +11,7 @@ import datetime import sys import django import twisted -from time import time as timemeasure +import time from django.conf import settings from evennia.server.sessionhandler import SESSIONS @@ -191,9 +191,9 @@ class CmdPy(COMMAND_DEFAULT_CLASS): duration = "" if "time" in self.switches: - t0 = timemeasure() + t0 = time.time() ret = eval(pycode_compiled, {}, available_vars) - t1 = timemeasure() + t1 = time.time() duration = " (runtime ~ %.4f ms)" % ((t1 - t0) * 1000) else: ret = eval(pycode_compiled, {}, available_vars) diff --git a/evennia/commands/default/unloggedin.py b/evennia/commands/default/unloggedin.py index 86a143ab24..ae8f3b0c0f 100644 --- a/evennia/commands/default/unloggedin.py +++ b/evennia/commands/default/unloggedin.py @@ -67,6 +67,8 @@ def _throttle(session, maxlim=None, timeout=None, storage=_LATEST_FAILED_LOGINS) # timeout has passed. Reset faillist storage[address] = [] return False + else: + return False else: # store the time of the latest fail storage[address].append(time.time()) @@ -101,24 +103,28 @@ def create_guest_player(session): try: # Find an available guest name. - for playername in settings.GUEST_LIST: - if not PlayerDB.objects.filter(username__iexact=playername): + playername = None + for name in settings.GUEST_LIST: + if not PlayerDB.objects.filter(username__iexact=playername).count(): + playername = name break - playername = None - if playername is None: + if not playername: session.msg("All guest accounts are in use. Please try again later.") return True, None + else: + # build a new player with the found guest playername + password = "%016x" % getrandbits(64) + home = ObjectDB.objects.get_id(settings.GUEST_HOME) + permissions = settings.PERMISSION_GUEST_DEFAULT + typeclass = settings.BASE_CHARACTER_TYPECLASS + ptypeclass = settings.BASE_GUEST_TYPECLASS + new_player = _create_player(session, playername, password, + permissions, ptypeclass) + if new_player: + _create_character(session, new_player, typeclass, + home, permissions) + return True, new_player - password = "%016x" % getrandbits(64) - home = ObjectDB.objects.get_id(settings.GUEST_HOME) - permissions = settings.PERMISSION_GUEST_DEFAULT - typeclass = settings.BASE_CHARACTER_TYPECLASS - ptypeclass = settings.BASE_GUEST_TYPECLASS - new_player = _create_player(session, playername, password, - permissions, ptypeclass) - if new_player: - _create_character(session, new_player, typeclass, - home, permissions) except Exception: # We are in the middle between logged in and -not, so we have @@ -566,5 +572,3 @@ def _create_character(session, new_player, typeclass, home, permissions): except Exception as e: session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e) logger.log_trace() - return False - diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index b8f53d47af..709e87d761 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -105,6 +105,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): mutelist.append(subscriber) self.db.mute_list = mutelist return True + return False def unmute(self, subscriber): """ @@ -117,6 +118,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): mutelist.remove(subscriber) self.db.mute_list = mutelist return True + return False def connect(self, subscriber): diff --git a/evennia/comms/managers.py b/evennia/comms/managers.py index bd13ef72a4..48b9bbf2b2 100644 --- a/evennia/comms/managers.py +++ b/evennia/comms/managers.py @@ -31,13 +31,13 @@ class CommError(Exception): # helper functions # -def dbref(dbref, reqhash=True): +def dbref(inp, reqhash=True): """ Valid forms of dbref (database reference number) are either a string '#N' or an integer N. Args: - dbref (int or str): A possible dbref to check syntactically. + inp (int or str): A possible dbref to check syntactically. reqhash (bool): Require an initial hash `#` to accept. Returns: @@ -45,16 +45,16 @@ def dbref(dbref, reqhash=True): dbref, otherwise `None`. """ - if reqhash and not (isinstance(dbref, basestring) and dbref.startswith("#")): + if reqhash and not (isinstance(inp, basestring) and inp.startswith("#")): return None - if isinstance(dbref, basestring): - dbref = dbref.lstrip('#') + if isinstance(inp, basestring): + inp = inp.lstrip('#') try: - if int(dbref) < 0: + if int(inp) < 0: return None except Exception: return None - return dbref + return inp def identify_object(inp): @@ -128,6 +128,8 @@ def to_object(inp, objtype='player'): return _ChannelDB.objects.get(id=obj) logger.log_err("%s %s %s %s %s", objtype, inp, obj, typ, type(inp)) raise CommError() + # an unknown + return None # # Msg manager diff --git a/evennia/contrib/barter.py b/evennia/contrib/barter.py index 36146387bf..f0df3afc84 100644 --- a/evennia/contrib/barter.py +++ b/evennia/contrib/barter.py @@ -314,6 +314,7 @@ class TradeHandler(object): else: raise ValueError return self.finish() # try to close the deal + return False def decline(self, party): """ @@ -345,6 +346,7 @@ class TradeHandler(object): return False else: raise ValueError + return False def finish(self, force=False): """ @@ -354,6 +356,8 @@ class TradeHandler(object): force (bool, optional): Force cleanup regardless of if the trade was accepted or not (if not, no goods will change hands but trading will stop anyway) + Returns: + result (bool): If the finish was successful. """ fin = False @@ -376,6 +380,7 @@ class TradeHandler(object): if self.partB.ndb.tradehandler: del self.partB.ndb.tradehandler return True + return False # trading commands (will go into CmdsetTrade, initialized by the diff --git a/evennia/contrib/extended_room.py b/evennia/contrib/extended_room.py index 54c3ac0e34..26a4c93f45 100644 --- a/evennia/contrib/extended_room.py +++ b/evennia/contrib/extended_room.py @@ -222,7 +222,6 @@ class ExtendedRoom(DefaultRoom): description (str): Our description. """ - raw_desc = self.db.raw_desc or "" update = False # get current time and season diff --git a/evennia/contrib/mapbuilder.py b/evennia/contrib/mapbuilder.py index f42b62251c..0f57417006 100644 --- a/evennia/contrib/mapbuilder.py +++ b/evennia/contrib/mapbuilder.py @@ -208,7 +208,7 @@ def example2_build_forest(x, y, **kwargs): """A basic room""" # If on anything other than the first iteration - Do nothing. if kwargs["iteration"] > 0: - return + return None room = create_object(rooms.Room, key="forest" + str(x) + str(y)) room.db.desc = "Basic forest room." @@ -227,11 +227,12 @@ def example2_build_verticle_exit(x, y, **kwargs): north_room = kwargs["room_dict"][(x, y-1)] south_room = kwargs["room_dict"][(x, y+1)] - north = create_object(exits.Exit, key="south", + # create exits in the rooms + create_object(exits.Exit, key="south", aliases=["s"], location=north_room, destination=south_room) - south = create_object(exits.Exit, key="north", + create_object(exits.Exit, key="north", aliases=["n"], location=south_room, destination=north_room) @@ -248,11 +249,11 @@ def example2_build_horizontal_exit(x, y, **kwargs): west_room = kwargs["room_dict"][(x-1, y)] east_room = kwargs["room_dict"][(x+1, y)] - west = create_object(exits.Exit, key="east", + create_object(exits.Exit, key="east", aliases=["e"], location=west_room, destination=east_room) - east = create_object(exits.Exit, key="west", + create_object(exits.Exit, key="west", aliases=["w"], location=east_room, destination=west_room) @@ -438,29 +439,29 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True): # north if (x, y-1) in room_dict: if room_dict[(x, y-1)]: - exit = create_object(exits.Exit, key="north", - aliases=["n"], location=location, - destination=room_dict[(x, y-1)]) + create_object(exits.Exit, key="north", + aliases=["n"], location=location, + destination=room_dict[(x, y-1)]) # east if (x+1, y) in room_dict: if room_dict[(x+1, y)]: - exit = create_object(exits.Exit, key="east", - aliases=["e"], location=location, - destination=room_dict[(x+1, y)]) + create_object(exits.Exit, key="east", + aliases=["e"], location=location, + destination=room_dict[(x+1, y)]) # south if (x, y+1) in room_dict: if room_dict[(x, y+1)]: - exit = create_object(exits.Exit, key="south", - aliases=["s"], location=location, - destination=room_dict[(x, y+1)]) + create_object(exits.Exit, key="south", + aliases=["s"], location=location, + destination=room_dict[(x, y+1)]) # west if (x-1, y) in room_dict: if room_dict[(x-1, y)]: - exit = create_object(exits.Exit, key="west", - aliases=["w"], location=location, - destination=room_dict[(x-1, y)]) + create_object(exits.Exit, key="west", + aliases=["w"], location=location, + destination=room_dict[(x-1, y)]) caller.msg("Map Created.") diff --git a/evennia/contrib/menu_login.py b/evennia/contrib/menu_login.py index 002ece7de5..59b85275e0 100644 --- a/evennia/contrib/menu_login.py +++ b/evennia/contrib/menu_login.py @@ -122,13 +122,13 @@ def username(caller, string_input): }, { "key": "_default", - "goto": "password", + "goto": "ask_password", }, ) return text, options -def password(caller, string_input): +def ask_password(caller, string_input): """Ask the user to enter the password to this player. This is assuming the user exists (see 'create_username' and @@ -174,7 +174,7 @@ def password(caller, string_input): }, { "key": "_default", - "goto": "password", + "goto": "ask_password", }, ) elif banned: diff --git a/evennia/contrib/rpsystem.py b/evennia/contrib/rpsystem.py index 503c250cfa..73a682eb95 100644 --- a/evennia/contrib/rpsystem.py +++ b/evennia/contrib/rpsystem.py @@ -137,13 +137,6 @@ _RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.UNICODE _RE_PREFIX = re.compile(r"^%s" % _PREFIX, re.UNICODE) -# The num_sep is the (single-character) symbol used to separate the -# sdesc from the number when trying to separate identical sdescs from -# one another. This is the same syntax used in the rest of Evennia, so -# by default, multiple "tall" can be separated by entering 1-tall, -# 2-tall etc. -_NUM_SEP = "-" - # This regex will return groups (num, word), where num is an optional counter to # separate multimatches from one another and word is the first word in the # marker. So entering "/tall man" will return groups ("", "tall") @@ -244,7 +237,7 @@ def ordered_permutation_regex(sentence): solution.append(_PREFIX + r"[0-9]*%s*%s(?=\W|$)+" % (_NUM_SEP, re_escape(" ".join(comb)).rstrip("\\"))) # combine into a match regex, first matching the longest down to the shortest components - regex = r"|".join(sorted(set(solution), key=lambda o:len(o), reverse=True)) + regex = r"|".join(sorted(set(solution), key=len, reverse=True)) return regex def regex_tuple_from_key_alias(obj): @@ -521,7 +514,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"): receiver_lang_mapping[key] = process_language(saytext, sender, langname) # map the language {##num} markers. This will convert the escaped sdesc markers on # the form {{#num}} to {#num} markers ready to sdescmat in the next step. - send_emote = emote.format(**receiver_lang_mapping) + sendemote = emote.format(**receiver_lang_mapping) # handle sdesc mappings. we make a temporary copy that we can modify try: @@ -547,7 +540,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"): receiver_sdesc_mapping[rkey] = process_sdesc(receiver.key, receiver) # do the template replacement of the sdesc/recog {#num} markers - receiver.msg(send_emote.format(**receiver_sdesc_mapping)) + receiver.msg(sendemote.format(**receiver_sdesc_mapping)) #------------------------------------------------------------ # Handlers for sdesc and recog @@ -1340,7 +1333,7 @@ class ContribRPObject(DefaultObject): looker (Object): Object doing the looking. """ if not looker: - return + return "" # get and identify all objects visible = (con for con in self.contents if con != looker and con.access(looker, "view")) diff --git a/evennia/contrib/simpledoor.py b/evennia/contrib/simpledoor.py index 8a2b20093e..12a6b4ed49 100644 --- a/evennia/contrib/simpledoor.py +++ b/evennia/contrib/simpledoor.py @@ -101,7 +101,7 @@ class CmdOpen(default_cmds.CmdOpen): # we don't create a return exit if it was already created (because # we created a door) del self.return_exit_already_created - return + return None # create a new exit as normal new_exit = super(CmdOpen, self).create_exit(exit_name, location, destination, exit_aliases=exit_aliases, typeclass=typeclass) diff --git a/evennia/contrib/tutorial_world/objects.py b/evennia/contrib/tutorial_world/objects.py index 31be8824ca..2188d1e923 100644 --- a/evennia/contrib/tutorial_world/objects.py +++ b/evennia/contrib/tutorial_world/objects.py @@ -826,13 +826,14 @@ class CmdAttack(Command): # call enemy hook if hasattr(target, "at_hit"): # should return True if target is defeated, False otherwise. - return target.at_hit(self.obj, self.caller, damage) + target.at_hit(self.obj, self.caller, damage) + return elif target.db.health: target.db.health -= damage else: # sorry, impossible to fight this enemy ... self.caller.msg("The enemy seems unaffacted.") - return False + return else: self.caller.msg(string + "{rYou miss.{n") target.msg(tstring + "{gThey miss you.{n") diff --git a/evennia/contrib/tutorial_world/rooms.py b/evennia/contrib/tutorial_world/rooms.py index 26948a81a7..5310dfa106 100644 --- a/evennia/contrib/tutorial_world/rooms.py +++ b/evennia/contrib/tutorial_world/rooms.py @@ -191,7 +191,7 @@ class CmdTutorialLook(default_cmds.CmdLook): caller.msg(looking_at_obj.return_appearance(caller)) # the object's at_desc() method. looking_at_obj.at_desc(looker=caller) - + return class TutorialRoomCmdSet(CmdSet): diff --git a/evennia/locks/lockfuncs.py b/evennia/locks/lockfuncs.py index 138d31f2f7..d1166b0616 100644 --- a/evennia/locks/lockfuncs.py +++ b/evennia/locks/lockfuncs.py @@ -383,6 +383,7 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs): accessing_obj = accessing_obj.obj if hasattr(accessing_obj, "location"): return attr(accessing_obj.location, accessed_obj, *args, **kwargs) + return False def objlocattr(accessing_obj, accessed_obj, *args, **kwargs): """ @@ -402,6 +403,7 @@ def objlocattr(accessing_obj, accessed_obj, *args, **kwargs): accessed_obj = accessed_obj.obj if hasattr(accessed_obj, "location"): return attr(accessed_obj.location, accessed_obj, *args, **kwargs) + return False def attr_eq(accessing_obj, accessed_obj, *args, **kwargs): @@ -550,6 +552,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs): for obj in contents: if obj.attributes.get(args[0]) == args[1]: return True + return False def superuser(*args, **kwargs): diff --git a/evennia/locks/lockhandler.py b/evennia/locks/lockhandler.py index c13a204f41..2c0884d452 100644 --- a/evennia/locks/lockhandler.py +++ b/evennia/locks/lockhandler.py @@ -525,9 +525,10 @@ class LockHandler(object): else: return self._eval_access_type( accessing_obj, locks, access_type) - - for access_type in locks: - return self._eval_access_type(accessing_obj, locks, access_type) + else: + # if no access types was given and multiple locks were + # embedded in the lockstring we assume all must be true + return all(self._eval_access_type(accessing_obj, locks, access_type) for access_type in locks) def _test(): diff --git a/evennia/objects/models.py b/evennia/objects/models.py index 0d5c553174..b000fd0cb0 100644 --- a/evennia/objects/models.py +++ b/evennia/objects/models.py @@ -278,6 +278,7 @@ class ObjectDB(TypedObject): except Exception as e: errmsg = "Error (%s): %s is not a valid location." % (str(e), location) raise RuntimeError(errmsg) + return def __location_del(self): "Cleanly delete the location reference" diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 4fe8143a8d..fbce4e338e 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -645,6 +645,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): "Simple log helper method" logger.log_trace() self.msg("%s%s" % (string, "" if err is None else " (%s)" % err)) + return errtxt = _("Couldn't perform move ('%s'). Contact an admin.") if not emit_to_obj: @@ -1336,7 +1337,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): looker (Object): Object doing the looking. """ if not looker: - return + return "" # get and identify all objects visible = (con for con in self.contents if con != looker and con.access(looker, "view")) @@ -1555,6 +1556,7 @@ class DefaultCharacter(DefaultObject): idle = [session.cmd_last_visible for session in self.sessions.all()] if idle: return time.time() - float(max(idle)) + return None @property def connection_time(self): @@ -1565,6 +1567,7 @@ class DefaultCharacter(DefaultObject): conn = [session.conn_time for session in self.sessions.all()] if conn: return time.time() - float(min(conn)) + return None # # Base Room object diff --git a/evennia/players/admin.py b/evennia/players/admin.py index 62c2761bea..227a3828f7 100644 --- a/evennia/players/admin.py +++ b/evennia/players/admin.py @@ -252,23 +252,4 @@ class PlayerDBAdmin(BaseUserAdmin): return HttpResponseRedirect(reverse("admin:players_playerdb_change", args=[obj.id])) return HttpResponseRedirect(reverse("admin:players_playerdb_change", args=[obj.id])) - ## TODO! Remove User reference! - #def save_formset(self, request, form, formset, change): - # """ - # Run all hooks on the player object - # """ - # super(PlayerDBAdmin, self).save_formset(request, form, formset, change) - # userobj = form.instance - # userobj.name = userobj.username - # if not change: - # # uname, passwd, email = str(request.POST.get(u"username")), \ - # # str(request.POST.get(u"password1")), \ - # # str(request.POST.get(u"email")) - # typeclass = str(request.POST.get( - # u"playerdb_set-0-db_typeclass_path")) - # create.create_player("", "", "", - # user=userobj, - # typeclass=typeclass, - # player_dbobj=userobj) - admin.site.register(PlayerDB, PlayerDBAdmin) diff --git a/evennia/players/players.py b/evennia/players/players.py index 10ce498c30..094790de81 100644 --- a/evennia/players/players.py +++ b/evennia/players/players.py @@ -544,6 +544,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): idle = [session.cmd_last_visible for session in self.sessions.all()] if idle: return time.time() - float(max(idle)) + return None @property def connection_time(self): @@ -554,6 +555,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): conn = [session.conn_time for session in self.sessions.all()] if conn: return time.time() - float(min(conn)) + return None ## player hooks diff --git a/evennia/scripts/scripts.py b/evennia/scripts/scripts.py index 2ef5930cf5..6764b2e7a8 100644 --- a/evennia/scripts/scripts.py +++ b/evennia/scripts/scripts.py @@ -18,9 +18,6 @@ from future.utils import with_metaclass __all__ = ["DefaultScript", "DoNothing", "Store"] -_GA = object.__getattribute__ -_SESSIONS = None - class ExtendedLoopingCall(LoopingCall): """ LoopingCall that can start at a delay different @@ -241,6 +238,7 @@ class DefaultScript(ScriptBase): return maybeDeferred(self._step_callback).addErrback(self._step_errback) except Exception: logger.log_trace() + return None # Public methods @@ -279,6 +277,7 @@ class DefaultScript(ScriptBase): task = self.ndb._task if task: return max(0, self.db_repeats - task.callcount) + return None def start(self, force_restart=False): """ diff --git a/evennia/scripts/tickerhandler.py b/evennia/scripts/tickerhandler.py index 801c33ca04..57a276f5c5 100644 --- a/evennia/scripts/tickerhandler.py +++ b/evennia/scripts/tickerhandler.py @@ -73,7 +73,7 @@ from django.core.exceptions import ObjectDoesNotExist from evennia.scripts.scripts import ExtendedLoopingCall from evennia.server.models import ServerConfig from evennia.utils.logger import log_trace, log_err -from evennia.utils.dbserialize import dbserialize, dbunserialize, pack_dbobj, unpack_dbobj +from evennia.utils.dbserialize import dbserialize, dbunserialize, pack_dbobj from evennia.utils import variable_from_module _GA = object.__getattribute__ @@ -568,6 +568,7 @@ class TickerHandler(object): ticker = self.ticker_pool.tickers.get(interval, None) if ticker: return {interval: ticker.subscriptions} + return None def all_display(self): """ diff --git a/evennia/server/amp.py b/evennia/server/amp.py index e9cf526c11..621600e158 100644 --- a/evennia/server/amp.py +++ b/evennia/server/amp.py @@ -19,8 +19,8 @@ from __future__ import print_function # imports needed on both server and portal side import os -from time import time -from collections import defaultdict +import time +from collections import defaultdict, namedtuple from itertools import count from cStringIO import StringIO try: @@ -33,9 +33,7 @@ from twisted.internet.defer import Deferred from evennia.utils import logger from evennia.utils.utils import to_str, variable_from_module -class DummySession(object): - sessid = 0 -DUMMYSESSION = DummySession() +DUMMYSESSION = namedtuple('DummySession', ['sessid'])(0) # communication bits # (chr(9) and chr(10) are \t and \n, so skipping them) @@ -350,7 +348,7 @@ class AMPProtocol(amp.AMP): """ self.send_batch_counter = 0 - self.send_reset_time = time() + self.send_reset_time = time.time() self.send_mode = True self.send_task = None diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 06989b66d1..923f28e5d9 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -161,13 +161,13 @@ ERROR_SETTINGS = \ 1) You are not running this command from your game directory. Change directory to your game directory and try again (or create a new game directory using evennia --init ) - 2) The settings file contains a syntax error. If you see a + 2) The ettings file contains a syntax error. If you see a traceback above, review it, resolve the problem and try again. 3) Django is not correctly installed. This usually shows as errors mentioning 'DJANGO_SETTINGS_MODULE'. If you run a virtual machine, it might be worth to restart it to see if this resolves the issue. - """.format(settingsfile=SETTINGFILE, settingspath=SETTINGS_PATH) + """.format(settingspath=SETTINGS_PATH) ERROR_INITSETTINGS = \ """ @@ -402,7 +402,6 @@ def evennia_version(): """ version = "Unknown" try: - import evennia version = evennia.__version__ except ImportError: # even if evennia is not found, we should not crash here. @@ -594,7 +593,6 @@ def check_database(): tables = [tableinfo.name for tableinfo in tables] if tables and u'players_playerdb' in tables: # database exists and seems set up. Initialize evennia. - import evennia evennia._init() # Try to get Player#1 from evennia.players.models import PlayerDB @@ -668,6 +666,7 @@ def get_pid(pidfile): with open(pidfile, 'r') as f: pid = f.read() return pid + return None def del_pid(pidfile): @@ -684,7 +683,7 @@ def del_pid(pidfile): os.remove(pidfile) -def kill(pidfile, signal=SIG, succmsg="", errmsg="", +def kill(pidfile, killsignal=SIG, succmsg="", errmsg="", restart_file=SERVER_RESTART, restart=False): """ Send a kill signal to a process based on PID. A customized @@ -693,7 +692,7 @@ def kill(pidfile, signal=SIG, succmsg="", errmsg="", Args: pidfile (str): The path of the pidfile to get the PID from. - signal (int, optional): Signal identifier. + killsignal (int, optional): Signal identifier for signal to send. succmsg (str, optional): Message to log on success. errmsg (str, optional): Message to log on failure. restart_file (str, optional): Restart file location. @@ -728,7 +727,7 @@ def kill(pidfile, signal=SIG, succmsg="", errmsg="", else: # Linux can send the SIGINT signal directly # to the specified PID. - os.kill(int(pid), signal) + os.kill(int(pid), killsignal) except OSError: print("Process %(pid)s cannot be stopped. "\ @@ -751,10 +750,8 @@ def show_version_info(about=False): version_info (str): A complete version info string. """ - import os import sys import twisted - import django return VERSION_INFO.format( version=EVENNIA_VERSION, about=ABOUT_INFO if about else "", diff --git a/evennia/server/inputfuncs.py b/evennia/server/inputfuncs.py index 2770f0792a..e48aaa3549 100644 --- a/evennia/server/inputfuncs.py +++ b/evennia/server/inputfuncs.py @@ -56,28 +56,28 @@ def text(session, *args, **kwargs): #from evennia.server.profiling.timetrace import timetrace #text = timetrace(text, "ServerSession.data_in") - text = args[0] if args else None + txt = args[0] if args else None #explicitly check for None since text can be an empty string, which is #also valid - if text is None: + if txt is None: return # this is treated as a command input # handle the 'idle' command - if text.strip() in _IDLE_COMMAND: + if txt.strip() in _IDLE_COMMAND: session.update_session_counters(idle=True) return if session.player: # nick replacement puppet = session.puppet if puppet: - text = puppet.nicks.nickreplace(text, + txt = puppet.nicks.nickreplace(txt, categories=("inputline", "channel"), include_player=True) else: - text = session.player.nicks.nickreplace(text, + txt = session.player.nicks.nickreplace(txt, categories=("inputline", "channel"), include_player=False) kwargs.pop("options", None) - cmdhandler(session, text, callertype="session", session=session, **kwargs) + cmdhandler(session, txt, callertype="session", session=session, **kwargs) session.update_session_counters() @@ -92,20 +92,20 @@ def bot_data_in(session, *args, **kwargs): """ - text = args[0] if args else None + txt = args[0] if args else None # Explicitly check for None since text can be an empty string, which is # also valid - if text is None: + if txt is None: return # this is treated as a command input # handle the 'idle' command - if text.strip() in _IDLE_COMMAND: + if txt.strip() in _IDLE_COMMAND: session.update_session_counters(idle=True) return kwargs.pop("options", None) # Trigger the execute_cmd method of the corresponding bot. - session.player.execute_cmd(text=text, session=session) + session.player.execute_cmd(text=txt, session=session) session.update_session_counters() diff --git a/evennia/server/manager.py b/evennia/server/manager.py index 5765164bfe..c9907ab982 100644 --- a/evennia/server/manager.py +++ b/evennia/server/manager.py @@ -49,4 +49,4 @@ class ServerConfigManager(models.Manager): if not conf: return default return conf[0].value - + return None diff --git a/evennia/server/portal/mssp.py b/evennia/server/portal/mssp.py index c953254080..5ff0a7b319 100644 --- a/evennia/server/portal/mssp.py +++ b/evennia/server/portal/mssp.py @@ -70,7 +70,6 @@ class Mssp(object): """ self.protocol.handshake_done() - pass def do_mssp(self, option): """ diff --git a/evennia/server/portal/portal.py b/evennia/server/portal/portal.py index b39081878e..56579a2ba6 100644 --- a/evennia/server/portal/portal.py +++ b/evennia/server/portal/portal.py @@ -350,7 +350,6 @@ for plugin_module in PORTAL_SERVICES_PLUGIN_MODULES: print('-' * 50) # end of terminal output if os.name == 'nt': - factory.noisy = False # Windows only: Set PID file manually with open(PORTAL_PIDFILE, 'w') as f: f.write(str(os.getpid())) diff --git a/evennia/server/portal/portalsessionhandler.py b/evennia/server/portal/portalsessionhandler.py index f556bfbe8c..93bb7a95e3 100644 --- a/evennia/server/portal/portalsessionhandler.py +++ b/evennia/server/portal/portalsessionhandler.py @@ -4,8 +4,8 @@ Sessionhandler for portal sessions from __future__ import print_function from __future__ import division -from time import time -from collections import deque +import time +from collections import deque, namedtuple from twisted.internet import reactor from django.conf import settings from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, \ @@ -26,9 +26,7 @@ _ERROR_MAX_CHAR = settings.MAX_CHAR_LIMIT_WARNING _CONNECTION_QUEUE = deque() -class DummySession(object): - sessid = 0 -DUMMYSESSION = DummySession() +DUMMYSESSION = namedtuple('DummySession', ['sessid'])(0) #------------------------------------------------------------ # Portal-SessionHandler class @@ -53,13 +51,13 @@ class PortalSessionHandler(SessionHandler): super(PortalSessionHandler, self).__init__(*args, **kwargs) self.portal = None self.latest_sessid = 0 - self.uptime = time() + self.uptime = time.time() self.connection_time = 0 - self.connection_last = time() + self.connection_last = self.uptime self.connection_task = None self.command_counter = 0 - self.command_counter_reset = time() + self.command_counter_reset = self.uptime self.command_overflow = False def at_server_connection(self): @@ -68,7 +66,7 @@ class PortalSessionHandler(SessionHandler): At this point, the AMP connection is already established. """ - self.connection_time = time() + self.connection_time = time.time() def connect(self, session): """ @@ -98,7 +96,7 @@ class PortalSessionHandler(SessionHandler): session.data_out(text=[["%s DoS protection is active. You are queued to connect in %g seconds ..." % ( settings.SERVERNAME, len(_CONNECTION_QUEUE)*_MIN_TIME_BETWEEN_CONNECTS)],{}]) - now = time() + now = time.time() if (now - self.connection_last < _MIN_TIME_BETWEEN_CONNECTS) or not self.portal.amp_protocol: if not session or not self.connection_task: self.connection_task = reactor.callLater(_MIN_TIME_BETWEEN_CONNECTS, self.connect, None) @@ -257,7 +255,7 @@ class PortalSessionHandler(SessionHandler): for session in self.values(): session.disconnect(reason) del session - self = {} + self.clear() def server_logged_in(self, session, data): """ @@ -366,7 +364,7 @@ class PortalSessionHandler(SessionHandler): # if there is a problem to send, we continue pass if session: - now = time() + now = time.time() if self.command_counter > _MAX_COMMAND_RATE: # data throttle (anti DoS measure) dT = now - self.command_counter_reset diff --git a/evennia/server/portal/ssl.py b/evennia/server/portal/ssl.py index 99f4de1666..c48cbf0a1a 100644 --- a/evennia/server/portal/ssl.py +++ b/evennia/server/portal/ssl.py @@ -10,13 +10,13 @@ import sys try: import OpenSSL from twisted.internet import ssl as twisted_ssl -except ImportError as err: +except ImportError as error: errstr = """ {err} SSL requires the PyOpenSSL library: pip install pyopenssl """ - raise ImportError(errstr.format(err=err)) + raise ImportError(errstr.format(err=error)) from django.conf import settings from evennia.server.portal.telnet import TelnetProtocol diff --git a/evennia/server/portal/telnet_oob.py b/evennia/server/portal/telnet_oob.py index 3b0f335a3e..24f74f0779 100644 --- a/evennia/server/portal/telnet_oob.py +++ b/evennia/server/portal/telnet_oob.py @@ -184,7 +184,6 @@ class TelnetOOB(object): msdp_args += "{msdp_array_open}" \ "{msdp_args}" \ "{msdp_array_close}".format( - msdp_var=MSDP_VAR, msdp_array_open=MSDP_ARRAY_OPEN, msdp_array_close=MSDP_ARRAY_CLOSE, msdp_args= "".join("%s%s" % ( diff --git a/evennia/server/portal/webclient_ajax.py b/evennia/server/portal/webclient_ajax.py index 9ca2462866..cc65625dc7 100644 --- a/evennia/server/portal/webclient_ajax.py +++ b/evennia/server/portal/webclient_ajax.py @@ -18,8 +18,8 @@ http://localhost:8000/webclient.) """ import json import re +import time -from time import time from twisted.web import server, resource from twisted.internet.task import LoopingCall from django.utils.functional import Promise @@ -83,7 +83,7 @@ class WebClient(resource.Resource): """ Callback for checking the connection is still alive. """ - now = time() + now = time.time() to_remove = [] keep_alives = ((csessid, remove) for csessid, (t, remove) in self.last_alive.iteritems() if now - t > _KEEPALIVE) @@ -170,7 +170,7 @@ class WebClient(resource.Resource): sess.sessionhandler.connect(sess) - self.last_alive[csessid] = (time(), False) + self.last_alive[csessid] = (time.time(), False) if not self.keep_alive: # the keepalive is not running; start it. self.keep_alive = LoopingCall(self._keepalive) @@ -184,7 +184,7 @@ class WebClient(resource.Resource): client is replying to the keepalive. """ csessid = request.args.get('csessid')[0] - self.last_alive[csessid] = (time(), False) + self.last_alive[csessid] = (time.time(), False) return '""' def mode_input(self, request): @@ -198,7 +198,7 @@ class WebClient(resource.Resource): """ csessid = request.args.get('csessid')[0] - self.last_alive[csessid] = (time(), False) + self.last_alive[csessid] = (time.time(), False) sess = self.sessionhandler.sessions_from_csessid(csessid) if sess: sess = sess[0] @@ -218,7 +218,7 @@ class WebClient(resource.Resource): """ csessid = request.args.get('csessid')[0] - self.last_alive[csessid] = (time(), False) + self.last_alive[csessid] = (time.time(), False) dataentries = self.databuffer.get(csessid, []) if dataentries: @@ -244,7 +244,6 @@ class WebClient(resource.Resource): sess.sessionhandler.disconnect(sess) except IndexError: self.client_disconnect(csessid) - pass return '""' def render_POST(self, request): diff --git a/evennia/server/profiling/timetrace.py b/evennia/server/profiling/timetrace.py index 85866dc521..18a7000770 100644 --- a/evennia/server/profiling/timetrace.py +++ b/evennia/server/profiling/timetrace.py @@ -2,7 +2,7 @@ Trace a message through the messaging system """ from __future__ import print_function -from time import time +import time def timetrace(message, idstring, tracemessage="TEST_MESSAGE", final=False): """ @@ -24,11 +24,11 @@ def timetrace(message, idstring, tracemessage="TEST_MESSAGE", final=False): prefix, tlast, t0 = message.split(None, 2) tlast, t0 = float(tlast), float(t0) except (IndexError, ValueError): - t0 = time() + t0 = time.time() tlast = t0 t1 = t0 else: - t1 = time() + t1 = time.time() # print to log (important!) print("** timetrace (%s): dT=%fs, total=%fs." % (idstring, t1-tlast, t1-t0)) diff --git a/evennia/server/serversession.py b/evennia/server/serversession.py index fddaa38c61..878bc884f5 100644 --- a/evennia/server/serversession.py +++ b/evennia/server/serversession.py @@ -8,10 +8,9 @@ are stored on the Portal side) """ from builtins import object -import re import weakref import importlib -from time import time +import time from django.utils import timezone from django.conf import settings from evennia.comms.models import ChannelDB @@ -218,7 +217,7 @@ class ServerSession(Session): self.uid = self.player.id self.uname = self.player.username self.logged_in = True - self.conn_time = time() + self.conn_time = time.time() self.puid = None self.puppet = None self.cmdset_storage = settings.CMDSET_SESSION @@ -332,7 +331,7 @@ class ServerSession(Session): """ # Idle time used for timeout calcs. - self.cmd_last = time() + self.cmd_last = time.time() # Store the timestamp of the user's last command. if not idle: @@ -508,7 +507,7 @@ class ServerSession(Session): """ string = "Cannot assign directly to ndb object! " - string = "Use ndb.attr=value instead." + string += "Use ndb.attr=value instead." raise Exception(string) #@ndb.deleter diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 517cee4af3..d7896b6560 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -12,10 +12,10 @@ There are two similar but separate stores of sessions: handle network communication but holds no game info. """ +import time from builtins import object from future.utils import listvalues -from time import time from django.conf import settings from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.utils.logger import log_trace @@ -89,7 +89,10 @@ def delayed_import(): if not _ScriptDB: from evennia.scripts.models import ScriptDB as _ScriptDB # including once to avoid warnings in Python syntax checkers - _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB + assert(_ServerSession) + assert(_PlayerDB) + assert(_ServerConfig) + assert(_ScriptDB) #----------------------------------------------------------- @@ -565,7 +568,7 @@ class ServerSessionHandler(SessionHandler): see if any are dead or idle. """ - tcurr = time() + tcurr = time.time() reason = _("Idle timeout exceeded, disconnecting.") for session in (session for session in self.values() if session.logged_in and _IDLE_TIMEOUT > 0 diff --git a/evennia/typeclasses/django_new_patch.py b/evennia/typeclasses/django_new_patch.py index 064effcfc5..685b16b97a 100644 --- a/evennia/typeclasses/django_new_patch.py +++ b/evennia/typeclasses/django_new_patch.py @@ -46,6 +46,7 @@ def patched_new(cls, name, bases, attrs): # Look for an application configuration to attach the model to. app_config = apps.get_containing_app_config(module) + kwargs = {} if getattr(meta, 'app_label', None) is None: if app_config is None: @@ -69,8 +70,6 @@ def patched_new(cls, name, bases, attrs): "else was imported before its application was loaded. " % (module, name)) raise RuntimeError(msg) - else: - kwargs = {} new_class.add_to_class('_meta', Options(meta, **kwargs)) if not abstract: diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index d33d75a193..a267408d69 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -616,18 +616,6 @@ class TypedObject(SharedMemoryModel): self.delete = self._deleted super(TypedObject, self).delete() - # - # Memory management - # - - #def flush_from_cache(self): - # """ - # Flush this object instance from cache, forcing an object reload. - # Note that this will kill all temporary attributes on this object - # since it will be recreated as a new Typeclass instance. - # """ - # self.__class__.flush_cached_instance(self) - # # Attribute storage # diff --git a/evennia/utils/batchprocessors.py b/evennia/utils/batchprocessors.py index 65c9bb5d77..cf89634f58 100644 --- a/evennia/utils/batchprocessors.py +++ b/evennia/utils/batchprocessors.py @@ -351,10 +351,10 @@ class BatchCodeProcessor(object): headers = [] codes = [] for imatch, match in enumerate(list(_RE_CODE_OR_HEADER.finditer(text))): - type = match.group(1) + mtype = match.group(1) istart, iend = match.span(2) code = text[istart:iend] - if type == "#HEADER": + if mtype == "#HEADER": headers.append(code) else: # either #CODE or matching from start of file codes.append(code) diff --git a/evennia/utils/create.py b/evennia/utils/create.py index 34aa1e06bd..0ba36cefa9 100644 --- a/evennia/utils/create.py +++ b/evennia/utils/create.py @@ -293,7 +293,7 @@ def create_message(senderobj, message, channels=None, from evennia.comms.models import Msg as _Msg if not message: # we don't allow empty messages. - return + return None new_message = _Msg(db_message=message) new_message.save() for sender in make_iter(senderobj): diff --git a/evennia/utils/evform.py b/evennia/utils/evform.py index c24157e5dc..cce15a8dbd 100644 --- a/evennia/utils/evform.py +++ b/evennia/utils/evform.py @@ -345,7 +345,7 @@ class EvForm(object): for il, rectline in enumerate(rect): formline = form[iy0+il] # insert new content, replacing old - form[iy0+il] = formline = formline[:ix0] + rectline + formline[ix0+width:] + form[iy0+il] = formline[:ix0] + rectline + formline[ix0+width:] return form def map(self, cells=None, tables=None, **kwargs): diff --git a/evennia/utils/evmenu.py b/evennia/utils/evmenu.py index 923e426625..987a8ba184 100644 --- a/evennia/utils/evmenu.py +++ b/evennia/utils/evmenu.py @@ -238,6 +238,7 @@ class CmdEvMenuNode(Command): # this will create a completely new menu call EvMenu(caller, *saved_options[0], **saved_options[1]) return True + return None caller = self.caller # we store Session on the menu since this can be hard to @@ -330,7 +331,6 @@ def evtable_options_formatter(optionlist, caller=None): table.append(" |lc%s|lt|w%s|n|le: %s" % (raw_key, raw_key, desc)) ncols = (_MAX_TEXT_WIDTH // table_width_max) + 1 # number of ncols - nlastcol = nlist % ncols # number of elements left in last row # get the amount of rows needed (start with 4 rows) nrows = 4 @@ -779,6 +779,7 @@ class EvMenu(object): if isinstance(ret, basestring): # only return a value if a string (a goto target), ignore all other returns return ret + return None def goto(self, nodename, raw_string): """ diff --git a/evennia/utils/evtable.py b/evennia/utils/evtable.py index 3648df0ddb..3dfbd67fe6 100644 --- a/evennia/utils/evtable.py +++ b/evennia/utils/evtable.py @@ -157,8 +157,9 @@ class ANSITextWrapper(TextWrapper): whitespace characters to spaces. Eg. " foo\tbar\n\nbaz" becomes " foo bar baz". """ - # ignore expand_tabs/replace_whitespace until ANSISTring handles them return text +##TODO: Ignore expand_tabs/replace_whitespace until ANSISTring handles them. +## - don't remove this code. /Griatch # if self.expand_tabs: # text = text.expandtabs() # if self.replace_whitespace: @@ -1269,9 +1270,8 @@ class EvTable(object): for ix, col in enumerate(self.worktable): try: col.reformat(width=cwidths[ix], **options) - except Exception as e: - msg = "ix=%s, width=%s: %s" % (ix, cwidths[ix], e.message) - raise #Exception ("Error in horizontal allign:\n %s" % msg) + except Exception: + raise # equalize heights for each row (we must do this here, since it may have changed to fit new widths) cheights = [max(cell.get_height() for cell in (col[iy] for col in self.worktable)) for iy in range(nrowmax)] diff --git a/evennia/utils/gametime.py b/evennia/utils/gametime.py index b2322d1101..0dfecde038 100644 --- a/evennia/utils/gametime.py +++ b/evennia/utils/gametime.py @@ -6,8 +6,7 @@ in-mud time and real-world time as well allows to get the total runtime of the server and the current uptime. """ from __future__ import division - -from time import time +import time from django.conf import settings from evennia.server.models import ServerConfig @@ -83,10 +82,10 @@ def runtime(format=False): into time units. """ - runtime = SERVER_RUNTIME + (time() - SERVER_RUNTIME_LAST_UPDATED) + rtime = SERVER_RUNTIME + (time.time() - SERVER_RUNTIME_LAST_UPDATED) if format: - return _format(runtime, 31536000, 2628000, 604800, 86400, 3600, 60) - return runtime + return _format(rtime, 31536000, 2628000, 604800, 86400, 3600, 60) + return rtime def uptime(format=False): @@ -101,10 +100,10 @@ def uptime(format=False): into time units. """ - uptime = time() - SERVER_START_TIME + utime = time.time() - SERVER_START_TIME if format: - return _format(uptime, 31536000, 2628000, 604800, 86400, 3600, 60) - return uptime + return _format(utime, 31536000, 2628000, 604800, 86400, 3600, 60) + return utime def gametime(format=False): @@ -119,10 +118,10 @@ def gametime(format=False): into time units. """ - gametime = (runtime() - GAME_TIME_OFFSET) * TIMEFACTOR + gtime = (runtime() - GAME_TIME_OFFSET) * TIMEFACTOR if format: - return _format(gametime, YEAR, MONTH, WEEK, DAY, HOUR, MIN) - return gametime + return _format(gtime, YEAR, MONTH, WEEK, DAY, HOUR, MIN) + return gtime def reset_gametime(): @@ -159,11 +158,11 @@ def gametime_to_realtime(secs=0, mins=0, hrs=0, days=0, now after which 2 in-game days will have passed. """ - realtime = (secs + mins * MIN + hrs * HOUR + days * DAY + weeks * WEEK + \ + rtime = (secs + mins * MIN + hrs * HOUR + days * DAY + weeks * WEEK + \ months * MONTH + yrs * YEAR) / TIMEFACTOR if format: - return _format(realtime, 31536000, 2628000, 604800, 86400, 3600, 60) - return realtime + return _format(rtime, 31536000, 2628000, 604800, 86400, 3600, 60) + return rtime def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, @@ -186,9 +185,9 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, corresponding to 2 real days. """ - gametime = TIMEFACTOR * (secs + mins * 60 + hrs * 3600 + days * 86400 + + gtime = TIMEFACTOR * (secs + mins * 60 + hrs * 3600 + days * 86400 + weeks * 604800 + months * 2628000 + yrs * 31536000) if format: - return _format(gametime, YEAR, MONTH, WEEK, DAY, HOUR, MIN) - return gametime + return _format(gtime, YEAR, MONTH, WEEK, DAY, HOUR, MIN) + return gtime diff --git a/evennia/utils/idmapper/models.py b/evennia/utils/idmapper/models.py index 4ecbd3e994..06e303be1a 100644 --- a/evennia/utils/idmapper/models.py +++ b/evennia/utils/idmapper/models.py @@ -292,6 +292,7 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): else: cls._dbclass__.__instance_cache__[key].refresh_from_db() except KeyError: + # No need to remove if cache doesn't contain it already pass @classmethod @@ -367,7 +368,7 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): """ global _MONITOR_HANDLER if not _MONITOR_HANDLER: - from evennia.scripts.monitorhandler import MONITOR_HANDLER as _MONITORHANDLER + from evennia.scripts.monitorhandler import MONITOR_HANDLER as _MONITOR_HANDLER if _IS_SUBPROCESS: # we keep a store of objects modified in subprocesses so @@ -398,7 +399,7 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): for field in update_fields: fieldname = field.name # trigger eventual monitors - _MONITORHANDLER.at_update(self, fieldname) + _MONITOR_HANDLER.at_update(self, fieldname) # if a hook is defined it must be named exactly on this form hookname = "at_%s_postsave" % fieldname if hasattr(self, hookname) and callable(_GA(self, hookname)): diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index 48646b0566..f1f5cdced8 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -249,6 +249,7 @@ def tail_log_file(filename, offset, nlines, callback=None): lines_found = lines_found[-nlines-offset:-offset if offset else None] if callback: callback(lines_found) + return None else: return lines_found @@ -262,6 +263,5 @@ def tail_log_file(filename, offset, nlines, callback=None): return deferToThread(seek_file, filehandle, offset, nlines, callback).addErrback(errback) else: return seek_file(filehandle, offset, nlines, callback) - - - + else: + return None diff --git a/evennia/utils/prettytable.py b/evennia/utils/prettytable.py index b3fdc3eb96..cecd86c921 100644 --- a/evennia/utils/prettytable.py +++ b/evennia/utils/prettytable.py @@ -439,6 +439,7 @@ class PrettyTable(object): def _set_field_names(self, val): val = [self._unicode(x) for x in val] self._validate_option("field_names", val) + old_names = [] if self._field_names: old_names = self._field_names[:] self._field_names = val diff --git a/evennia/utils/search.py b/evennia/utils/search.py index 60828a0366..e46b2a55c2 100644 --- a/evennia/utils/search.py +++ b/evennia/utils/search.py @@ -101,13 +101,13 @@ objects = search_objects # # Search for players # -# def player_search(self, ostring): -# """ +# player_search(self, ostring) + # Searches for a particular player by name or # database id. # # ostring = a string or database id. -# """ +# search_player = PlayerDB.objects.player_search search_players = search_player @@ -117,15 +117,15 @@ players = search_players # # Searching for scripts # -# def script_search(self, ostring, obj=None, only_timed=False): -# """ +# script_search(self, ostring, obj=None, only_timed=False) +# # Search for a particular script. # # ostring - search criterion - a script ID or key # obj - limit search to scripts defined on this object # only_timed - limit search only to scripts that run # on a timer. -# """ +# search_script = ScriptDB.objects.script_search search_scripts = search_script @@ -135,8 +135,8 @@ scripts = search_scripts # Searching for communication messages # # -# def message_search(self, sender=None, receiver=None, channel=None, freetext=None): -# """ +# message_search(self, sender=None, receiver=None, channel=None, freetext=None) +# # Search the message database for particular messages. At least one # of the arguments must be given to do a search. # @@ -146,7 +146,7 @@ scripts = search_scripts # freetext - Search for a text string in a message. # NOTE: This can potentially be slow, so make sure to supply # one of the other arguments to limit the search. -# """ +# search_message = Msg.objects.message_search search_messages = search_message @@ -156,13 +156,13 @@ messages = search_messages # # Search for Communication Channels # -# def channel_search(self, ostring) -# """ +# channel_search(self, ostring) +# # Search the channel database for a particular channel. # # ostring - the key or database id of the channel. # exact - requires an exact ostring match (not case sensitive) -# """ +# search_channel = Channel.objects.channel_search search_channels = search_channel @@ -172,13 +172,13 @@ channels = search_channels # # Find help entry objects. # -# def search_help(self, ostring, help_category=None): -# """ +# search_help(self, ostring, help_category=None) +# # Retrieve a search entry object. # # ostring - the help topic to look for # category - limit the search to a particular help topic -# """ +# search_help = HelpEntry.objects.search_help search_help_entry = search_help diff --git a/evennia/utils/text2html.py b/evennia/utils/text2html.py index b7107a97a9..f04382b20b 100644 --- a/evennia/utils/text2html.py +++ b/evennia/utils/text2html.py @@ -273,6 +273,7 @@ class TextToHTMLparser(object): text = match.group().replace('\t', ' ' * self.tabstop) text = text.replace(' ', ' ') return text + return None def parse(self, text, strip_ansi=False): """ diff --git a/evennia/utils/txws.py b/evennia/utils/txws.py index dc16a93cec..1bbf756a07 100644 --- a/evennia/utils/txws.py +++ b/evennia/utils/txws.py @@ -559,6 +559,7 @@ class WebSocketProtocol(ProtocolWrapper): if "\r\n" in self.buf: request, chaff, self.buf = self.buf.partition("\r\n") try: + # verb and version are never used, maybe in the future. verb, self.location, version = request.split(" ") except ValueError: self.loseConnection() diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index 135df9bdec..5576d7fa9e 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -344,6 +344,8 @@ def time_format(seconds, style=0): 1. "1d" 2. "1 day, 8 hours, 30 minutes" 3. "1 day, 8 hours, 30 minutes, 10 seconds" + Returns: + timeformatted (str): A pretty time string. """ if seconds < 0: seconds = 0 @@ -358,7 +360,8 @@ def time_format(seconds, style=0): minutes = seconds // 60 seconds -= minutes * 60 - if style is 0: + retval = "" + if style == 0: """ Standard colon-style output. """ @@ -368,7 +371,7 @@ def time_format(seconds, style=0): retval = '%02i:%02i' % (hours, minutes,) return retval - elif style is 1: + elif style == 1: """ Simple, abbreviated form that only shows the highest time amount. """ @@ -380,7 +383,7 @@ def time_format(seconds, style=0): return '%im' % (minutes,) else: return '%is' % (seconds,) - elif style is 2: + elif style == 2: """ Full-detailed, long-winded format. We ignore seconds. """ @@ -403,7 +406,7 @@ def time_format(seconds, style=0): else: minutes_str = '%i minutes ' % minutes retval = '%s%s%s' % (days_str, hours_str, minutes_str) - elif style is 3: + elif style == 3: """ Full-detailed, long-winded format. Includes seconds. """ @@ -541,12 +544,12 @@ def pypath_to_realpath(python_path, file_ending='.py', pypath_prefixes=None): return list(set(p for p in paths if os.path.isfile(p))) -def dbref(dbref, reqhash=True): +def dbref(inp, reqhash=True): """ Converts/checks if input is a valid dbref. Args: - dbref (int or str): A database ref on the form N or #N. + inp (int, str): A database ref on the form N or #N. reqhash (bool, optional): Require the #N form to accept input as a valid dbref. @@ -556,16 +559,16 @@ def dbref(dbref, reqhash=True): """ if reqhash: - num = (int(dbref.lstrip('#')) if (isinstance(dbref, basestring) and - dbref.startswith("#") and - dbref.lstrip('#').isdigit()) + num = (int(inp.lstrip('#')) if (isinstance(inp, basestring) and + inp.startswith("#") and + inp.lstrip('#').isdigit()) else None) return num if num > 0 else None - elif isinstance(dbref, basestring): - dbref = dbref.lstrip('#') - return int(dbref) if dbref.isdigit() and int(dbref) > 0 else None + elif isinstance(inp, basestring): + inp = inp.lstrip('#') + return int(inp) if inp.isdigit() and int(inp) > 0 else None else: - return dbref if isinstance(dbref, int) else None + return inp if isinstance(inp, int) else None def dbref_to_obj(inp, objclass, raise_errors=True): @@ -882,27 +885,27 @@ def uses_database(name="sqlite3"): return engine == "django.db.backends.%s" % name -def delay(delay, callback, *args, **kwargs): +def delay(timedelay, callback, *args, **kwargs): """ Delay the return of a value. Args: - delay (int or float): The delay in seconds + timedelay (int or float): The delay in seconds callback (callable): Will be called with optional - arguments after `delay` seconds. + arguments after `timedelay` seconds. args (any, optional): Will be used as arguments to callback Kwargs: any (any): Will be used to call the callback. Returns: deferred (deferred): Will fire fire with callback after - `delay` seconds. Note that if `delay()` is used in the + `timedelay` seconds. Note that if `timedelay()` is used in the commandhandler callback chain, the callback chain can be defined directly in the command body and don't need to be specified here. """ - return reactor.callLater(delay, callback, *args, **kwargs) + return reactor.callLater(timedelay, callback, *args, **kwargs) _TYPECLASSMODELS = None @@ -1107,7 +1110,7 @@ def mod_import(module): result = imp.find_module(modname, [path]) except ImportError: logger.log_trace("Could not find module '%s' (%s.py) at path '%s'" % (modname, modname, path)) - return + return None try: mod = imp.load_module(modname, *result) except ImportError: @@ -1643,7 +1646,7 @@ def calledby(callerdepth=1): us. """ - import inspect, os + import inspect stack = inspect.stack() # we must step one extra level back in stack since we don't want # to include the call of this function itself.