From bad24513e0d331a6219fe70a5aab18fd4552b6c6 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 16 Feb 2014 21:27:42 +0100 Subject: [PATCH] Fixed and corrected various bugs resulting from the change to Attributes/Tags). --- game/evennia.py | 2 +- src/commands/default/general.py | 10 ++--- src/objects/models.py | 15 +------ src/players/models.py | 12 +----- src/server/serversession.py | 19 +++----- src/typeclasses/managers.py | 2 +- ...08_converting_tags_attribute_categories.py | 2 + src/typeclasses/models.py | 43 +++++++++++++------ src/utils/search.py | 25 +++++++---- 9 files changed, 66 insertions(+), 64 deletions(-) diff --git a/game/evennia.py b/game/evennia.py index 23e519d5bf..bf14e901d3 100755 --- a/game/evennia.py +++ b/game/evennia.py @@ -158,7 +158,7 @@ except DatabaseError, e: Please run: - python manage.py syncdb (create an admin user when prompted) + python manage.py syncdb python manage.py migrate When you have a database set up, rerun evennia.py. diff --git a/src/commands/default/general.py b/src/commands/default/general.py index fe56a35009..c7366275b2 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -126,14 +126,14 @@ class CmdNick(MuxCommand): caller = self.caller switches = self.switches - nicks = caller.nicks.get(category="channel") + nicks = caller.nicks.get(return_obj=True) if 'list' in switches: table = prettytable.PrettyTable(["{wNickType", "{wNickname", "{wTranslates-to"]) - for nick in nicks: - table.add_row([nick.db_category, nick.db_key, nick.db_data]) + for nick in utils.make_iter(nicks): + table.add_row([nick.db_category, nick.db_key, nick.db_strvalue]) string = "{wDefined Nicks:{n\n%s" % table caller.msg(string) return @@ -162,14 +162,14 @@ class CmdNick(MuxCommand): # removal of nick if oldnick: # clear the alias - string += "\nNick '%s' (= '%s') was cleared." % (nick, oldnick[0].db_real) + string += "\nNick '%s' (= '%s') was cleared." % (nick, oldnick) caller.nicks.delete(nick, category=switch) else: string += "\nNo nick '%s' found, so it could not be removed." % nick else: # creating new nick if oldnick: - string += "\nNick %s changed from '%s' to '%s'." % (nick, oldnick[0].db_real, real) + string += "\nNick %s changed from '%s' to '%s'." % (nick, oldnick, real) else: string += "\nNick set: '%s' = '%s'." % (nick, real) caller.nicks.add(nick, real, category=switch) diff --git a/src/objects/models.py b/src/objects/models.py index 3d81c1325f..1dcd27ef68 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -457,19 +457,8 @@ class ObjectDB(TypedObject): # do text encoding conversion raw_string = to_unicode(raw_string) - - raw_list = raw_string.split(None) - raw_list = [" ".join(raw_list[:i + 1]) for i in range(len(raw_list)) - if raw_list[:i + 1]] - # fetch the nick data efficiently - nicks = self.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel")) - if self.has_player: - # attach player nicks as well, but after the object-level nicks - nicks = list(nicks) + list(self.player.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel"))) - for nick in nicks: - if nick.db_key in raw_list: - raw_string = raw_string.replace(nick.db_key, nick.db_strvalue, 1) - break + raw_string = self.nicks.nickreplace(raw_string, + categories=("inputline", "channels"), include_player=True) return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, callertype="object", sessid=sessid) def msg(self, text=None, from_obj=None, sessid=0, **kwargs): diff --git a/src/players/models.py b/src/players/models.py index e97fb04ee0..03789e52f6 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -424,16 +424,8 @@ class PlayerDB(TypedObject, AbstractUser): # nick replacement - we require full-word matching. raw_string = utils.to_unicode(raw_string) - - raw_list = raw_string.split(None) - raw_list = [" ".join(raw_list[:i + 1]) for i in range(len(raw_list)) if raw_list[:i + 1]] - # get the nick replacement data directly from the database to be - # able to use db_category__in - nicks = self.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel")) - for nick in nicks: - if nick.db_key in raw_list: - raw_string = raw_string.replace(nick.db_key, nick.db_strvalue, 1) - break + raw_string = self.nicks.nickreplacement(raw_string, + categories=("inputline", "channels"), include_player=False) if not sessid and _MULTISESSION_MODE in (0, 1): # in this case, we should either have only one sessid, or the sessid # should not matter (since the return goes to all of them we can diff --git a/src/server/serversession.py b/src/server/serversession.py index e751ad54c9..1ecb56440d 100644 --- a/src/server/serversession.py +++ b/src/server/serversession.py @@ -13,7 +13,7 @@ from django.conf import settings #from src.scripts.models import ScriptDB from src.comms.models import ChannelDB from src.utils import logger, utils -from src.utils.utils import make_iter, to_str +from src.utils.utils import make_iter, to_unicode from src.commands import cmdhandler, cmdsethandler from src.server.session import Session @@ -181,25 +181,20 @@ class ServerSession(Session): """ if text: # this is treated as a command input - text = to_str(text) + text = to_unicode(text) # handle the 'idle' command if text.strip() == IDLE_COMMAND: self.update_session_counters(idle=True) return if self.player: # nick replacement - nicks = self.player.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel")) puppet = self.player.get_puppet(self.sessid) if puppet: - # merge, give prio to the lowest level (puppet) - nicks = list(puppet.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel"))) + list(nicks) - raw_list = text.split(None) - raw_list = [" ".join(raw_list[:i + 1]) - for i in range(len(raw_list)) if raw_list[:i + 1]] - for nick in nicks: - if nick.db_key in raw_list: - text = text.replace(nick.db_key, nick.db_strvalue, 1) - break + text = puppet.nicks.nickreplace(text, + categories=("inputline", "channels"), include_player=True) + else: + text = self.player.nicks.nickreplace(text, + categories=("inputline", "channels"), include_player=False) cmdhandler.cmdhandler(self, text, callertype="session", sessid=self.sessid) self.update_session_counters() if "oob" in kwargs: diff --git a/src/typeclasses/managers.py b/src/typeclasses/managers.py index e0a9a314d4..f928494d27 100644 --- a/src/typeclasses/managers.py +++ b/src/typeclasses/managers.py @@ -147,7 +147,7 @@ class TagManager(models.Manager): objclass = ContentType.objects.get_by_natural_key(*model.split(".", 1)).model_class() key_cands = Q(db_tags__db_key__iexact=key.lower().strip()) if key is not None else Q() cat_cands = Q(db_tags__db_category__iexact=category.lower().strip()) if category is not None else Q() - return objclass.objects.filter(db_model=model, db_tagtype=tagtype).filter(key_cands & cat_cands) + return objclass.objects.filter(db_tags__db_model=model, db_tags__db_tagtype=tagtype).filter(key_cands & cat_cands) def create_tag(self, key=None, category=None, data=None, model="objects.objectdb", tagtype=None): """ diff --git a/src/typeclasses/migrations/0008_converting_tags_attribute_categories.py b/src/typeclasses/migrations/0008_converting_tags_attribute_categories.py index 2c801041ea..4816701477 100644 --- a/src/typeclasses/migrations/0008_converting_tags_attribute_categories.py +++ b/src/typeclasses/migrations/0008_converting_tags_attribute_categories.py @@ -6,6 +6,8 @@ from django.db import models class Migration(DataMigration): + depends_on = (("comms", "0017_renaming_typeclass_from_comm_to_channel"), ) + def forwards(self, orm): "Write your forwards methods here." # Note: Don't use "from appname.models import ModelName". diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 5a047fedec..a9a7b35af6 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -41,7 +41,7 @@ from django.contrib.contenttypes.models import ContentType from src.utils.idmapper.models import SharedMemoryModel from src.server.caches import get_prop_cache, set_prop_cache -from src.server.caches import set_attr_cache +#from src.server.caches import set_attr_cache #from src.server.caches import call_ndb_hooks from src.server.models import ServerConfig @@ -232,10 +232,10 @@ class AttributeHandler(object): """ if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE: self._recache() - key = [key.strip().lower() if key is not None else None for key in make_iter(key)] + key = [k.strip().lower() for k in make_iter(key) if k] category = category.strip().lower() if category is not None else None searchkeys = ["%s-%s" % (k, category) for k in make_iter(key)] - ret = [self._cache.get(skey) for skey in searchkeys] + ret = [self._cache.get(skey) for skey in searchkeys if skey in self._cache] return ret[0] if len(ret) == 1 else ret def get(self, key=None, category=None, default=None, return_obj=False, @@ -258,12 +258,13 @@ class AttributeHandler(object): if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE: self._recache() ret = [] - key = [key.strip().lower() if key is not None else None for key in make_iter(key)] + key = [k.strip().lower() for k in make_iter(key) if k] category = category.strip().lower() if category is not None else None + #print "cache:", self._cache.keys(), key if not key: # return all with matching category (or no category) - catkey = "-%s" % category - ret = [attr for key, attr in self._cache.items() if key.endswith(catkey)] + catkey = "-%s" % category if category is not None else None + ret = [attr for key, attr in self._cache.items() if key and key.endswith(catkey)] else: for searchkey in ("%s-%s" % (k, category) for k in key): attr_obj = self._cache.get(searchkey) @@ -278,9 +279,9 @@ class AttributeHandler(object): # check 'attrread' locks ret = [attr for attr in ret if attr.access(accessing_obj, self._attrread, default=default_access)] if strattr: - ret = ret if return_obj else [attr.strvalue if attr else None for attr in ret] + ret = ret if return_obj else [attr.strvalue for attr in ret if attr] else: - ret = ret if return_obj else [attr.value if attr else None for attr in ret] + ret = ret if return_obj else [attr.value for attr in ret if attr] return ret[0] if len(ret)==1 else ret def add(self, key, value, category=None, lockstring="", @@ -301,7 +302,9 @@ class AttributeHandler(object): return if self._cache is None: self._recache() - key = key.strip().lower() if key is not None else None + if not key: + return + key = key.strip().lower() category = category.strip().lower() if category is not None else None cachekey = "%s-%s" % (key, category) attr_obj = self._cache.get(cachekey) @@ -334,7 +337,7 @@ class AttributeHandler(object): """ if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE: self._recache() - key = [key.strip().lower() if key is not None else None for key in make_iter(key)] + key = [k.strip().lower() for k in make_iter(key) if k] category = category.strip().lower() if category is not None else None for searchstr in ("%s-%s" % (k, category) for k in key): attr_obj = self._cache.get(searchstr) @@ -358,7 +361,7 @@ class AttributeHandler(object): attr.delete() self._recache() - def all(self, category=None, accessing_obj=None, default_access=True): + def all(self, accessing_obj=None, default_access=True): """ Return all Attribute objects on this object. @@ -368,8 +371,7 @@ class AttributeHandler(object): """ if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE: self._recache() - catkey = "-%s" % (category.strip().lower() if category is not None else None) - return [attr for key, attr in self._cache.items() if key and key.endswith(catkey)] + return self._cache.values() class NickHandler(AttributeHandler): """ @@ -396,6 +398,21 @@ class NickHandler(AttributeHandler): "Remove Nick with matching category" super(NickHandler, self).remove(key, category=category, **kwargs) + def nickreplace(self, raw_string, categories=("inputline", "channels"), include_player=True): + "Replace entries in raw_string with nick replacement" + obj_nicks = [] + for category in make_iter(categories): + obj_nicks.extend(make_iter(self.get(category=category, return_obj=True))) + if include_player and self.obj.has_player: + player_nicks = [] + for category in make_iter(categories): + player_nicks.extend(make_iter(self.obj.player.nicks.get(category=category, return_obj=True))) + for nick in obj_nicks + player_nicks: + if raw_string.startswith(nick.db_key): + raw_string = raw_string.replace(nick.db_key, nick.db_strvalue, 1) + break + return raw_string + class NAttributeHandler(object): """ diff --git a/src/utils/search.py b/src/utils/search.py index f524520453..8b951a7b77 100644 --- a/src/utils/search.py +++ b/src/utils/search.py @@ -180,26 +180,33 @@ help_entries = search_help_entries # Locate Tags -# def get_objs_with_tag(self, objclass, key=None, category=None): -# """ -# Search and return all objects of objclass that has tags matching -# the given search criteria. -# objclass (dbmodel) - the object class to search -# key (string) - the tag identifier -# category (string) - the tag category -# """ + +# search_object_tag(key, category=None) (also search_tag works) +# search_player_tag(key, category=None) +# search_script_tag(key, category=None) +# search_channel_tag(key, category=None) + # Note that this returns the object attached to the tag, not the tag itself # (this is usually what you want) search_tag = Tag.objects.get_objs_with_tag +search_player_tag = lambda key, category: Tag.objects.get_objs_with_tag(key, category, model="objects.objectdb") +search_player_tag = lambda key, category: Tag.objects.get_objs_with_tag(key, category, model="players.playerdb") +search_script_tag = lambda key, category: Tag.objects.get_objs_with_tag(key, category, model="scripts.scriptdb") +search_channel_tag = lambda key, category: Tag.objects.get_objs_with_tag(key, category, model="comms.channeldb") # """ # Search and return all tags matching any combination of # the search criteria. # search_key (string) - the tag identifier # category (string) - the tag category +# model - one of +# "objects.objectdb" (default), "players.playerdb", +# "scripts.scriptdb" or "comms.channeldb" # # Returns a single Tag (or None) if both key and category is given, # otherwise it will return a list. # """ -# This returns the tag object itself +# This returns the tag object itself. search_tag_object = Tag.objects.get_tag + +