Implemented NickHandler, AliasHandler and TagHandler in the typeclass to replace the old handlers. Some errors during login.

This commit is contained in:
Griatch 2013-07-12 14:44:49 +02:00
parent 2c17b7b675
commit 0061f884ae
7 changed files with 176 additions and 222 deletions

View file

@ -346,52 +346,104 @@ class Tag(models.Model):
def __str__(self):
return str(self.db_key)
#------------------------------------------------------------
#
# Nicks
# Helper handlers
#
#------------------------------------------------------------
class TypeNick(SharedMemoryModel):
class TagHandler(object):
"""
This model holds whichever alternate names this object
has for OTHER objects, but also for arbitrary strings,
channels, players etc. Setting a nick does not affect
the nicknamed object at all (as opposed to Aliases above),
and only this object will be able to refer to the nicknamed
object by the given nick.
The default nick types used by Evennia are:
inputline (default) - match against all input
player - match against player searches
obj - match against object searches
channel - used to store own names for channels
Generic tag-handler. Accessed via TypedObject.tags.
"""
db_nick = models.CharField('nickname',max_length=255, db_index=True, help_text='the alias')
db_real = models.TextField('realname', help_text='the original string to match and replace.')
db_type = models.CharField('nick type',default="inputline", max_length=16, null=True, blank=True,
help_text="the nick type describes when the engine tries to do nick-replacement. Common options are 'inputline','player','obj' and 'channel'. Inputline checks everything being inserted, whereas the other cases tries to replace in various searches or when posting to channels.")
db_obj = None #models.ForeignKey("ObjectDB")
class Meta:
"Define Django meta options"
abstract = True
verbose_name = "Nickname"
unique_together = ("db_nick", "db_type", "db_obj")
class TypeNickHandler(object):
"""
Handles nick access and setting. Accessed through ObjectDB.nicks
"""
NickClass = TypeNick
def __init__(self, obj):
def __init__(self, obj, category_prefix=""):
"""
This handler allows for accessing and setting nicks -
on-the-fly replacements for various text input passing through
this object (most often a Character)
Tags are stored internally in the TypedObject.db_tags m2m field
using the category <category_prefix><tag_category>
"""
self.obj = obj
self.prefix = category_prefix.strip().lower() if category_prefix else ""
def add(self, tag, category=None, data=None):
"Add a new tag to the handler"
tag = tag.strip().lower() if tag!=None else None
category = "%s%s" % (self.prefix, category.strip.lower()) if category!=None else None
data = str(data) if data!=None else None
# this will only create tag if no matches existed beforehand (it will overload
# data on an existing tag since that is not considered part of making the tag unique)
tagobj = Tag.objects.create_tag(key=tag, category=category, data=data)
self.obj.db_tags.add(tagobj)
def remove(self, tag, category=None):
"Remove a tag from the handler"
tag = tag.strip().lower() if tag!=None else None
category = "%s%s" % (self.prefix, category.strip.lower()) if category!=None else None
#TODO This does not delete the tag object itself. Maybe it should do that when no
# objects reference the tag anymore?
tagobj = self.obj.db_tags.filter(db_key=tag, db_category=category)
if tagobj:
self.obj.remove(tagobj[0])
def all(self):
"Get all tags in this handler"
return self.obj.db_tags.all().get_values("db_key")
def __str__(self):
return ",".join(self.all())
def __unicode(self):
return u",".join(self.all())
class AliasHandler(object):
"""
Handles alias access and setting. Accessed through TypedObject.aliases.
"""
def __init__(self, obj, category_prefix="object_"):
"""
Aliases are alternate names for an entity.
Implements the alias handler, using Tags for storage and
the <categoryprefix>_alias tag category. It is available
as TypedObjects.aliases.
"""
self.obj = obj
self.category = "%salias" % category_prefix
def add(self, alias):
"Add a new nick to the handler"
if not alias or not alias.strip():
return
alias = alias.strip()
# create a unique tag only if it didn't already exist
aliasobj = Tag.objects.create_tag(key=alias, category=self.category)
self.obj.db_tags.add(aliasobj)
def remove(self, alias):
"Remove alias from handler."
aliasobj = Tag.objects.filter(db_key__iexact=alias.strip(), category=self.category).count()
#TODO note that this doesn't delete the tag itself. We might want to do this when no object
# uses it anymore ...
self.obj.db_tags.remove(aliasobj)
def all(self):
"Get all aliases in this handler"
return self.obj.db_tags.filter(db_category=self.category).get_values("db_key")
def __str__(self):
return ",".join(self.all())
def __unicode(self):
return u",".join(self.all())
class NickHandler(object):
"""
Handles nick access and setting. Accessed through TypedObject.nicks.
"""
def __init__(self, obj, category_prefix="object_"):
"""
Nicks are alternate names an entity as of ANOTHER entity. The
engine will auto-replace nicks under circumstances dictated
by the nick category. It uses LiteAttributes for storage.
The default nick types used by Evennia are:
@ -400,13 +452,11 @@ class TypeNickHandler(object):
obj - match against object searches
channel - used to store own names for channels
You can define other nicktypes by using the add() method of
this handler and set nick_type to whatever you want. It's then
up to you to somehow make use of this nick_type in your game
(such as for a "recog" system).
These are all stored interally using categories
<category_prefix>nick_inputline etc.
"""
self.obj = obj
self.prefix = "%snick_" % category_prefix.strip().lower() if category_prefix else ""
def add(self, nick, realname, nick_type="inputline"):
"""
@ -417,50 +467,47 @@ class TypeNickHandler(object):
if not nick or not nick.strip():
return
nick = nick.strip()
real = realname.strip()
query = self.NickClass.objects.filter(db_obj=self.obj, db_nick__iexact=nick, db_type__iexact=nick_type)
real = realname
nick_type = "%s%s" % (self.prefix, nick_type.strip().lower())
query = self.obj.db_liteattributes.filter(db_key__iexact=nick, db_category__iexact=nick_type)
if query.count():
old_nick = query[0]
old_nick.db_real = real
old_nick.db_data = real
old_nick.save()
else:
new_nick = self.NickClass(db_nick=nick, db_real=real, db_type=nick_type, db_obj=self.obj)
new_nick = LiteAttribute(db_key=nick, db_category=nick_type, db_data=real)
new_nick.save()
def delete(self, nick, nick_type="inputline"):
self.obj.db_liteattributes.add(new_nick)
def remove(self, nick, nick_type="inputline"):
"Removes a previously stored nick"
nick = nick.strip()
query = self.NickClass.objects.filter(db_obj=self.obj, db_nick__iexact=nick, db_type__iexact=nick_type)
nick_type = "%s%s" % (self.prefix, nick_type.strip().lower())
query = self.obj.liteattributes.filter(db_key__iexact=nick, db_category__iexact=nick_type)
if query.count():
# remove the found nick(s)
query.delete()
def get(self, nick=None, nick_type="inputline", obj=None):
"""
Retrieves a given nick (with a specified nick_type) on an object. If no nick is given, returns a list
of all nicks on the object, or the empty list.
Defaults to searching the current object.
"""
if not obj:
# defaults to the current object
obj = self.obj
if nick:
query = self.NickClass.objects.filter(db_obj=obj, db_nick__iexact=nick, db_type__iexact=nick_type)
query = query.values_list("db_real", flat=True)
if query.count():
return query[0]
else:
return nick
else:
return self.NickClass.objects.filter(db_obj=obj)
def has(self, nick, nick_type="inputline", obj=None):
"""
Returns true/false if this nick and nick_type is defined on the given
object or not. If no obj is given, default to the current object the
handler is defined on.
def delete(self, *args, **kwargs):
"alias wrapper"
self.remove(self, *args, **kwargs)
def get(self, nick=None, nick_type="inputline", default=None):
"""
if not obj:
obj = self.obj
return self.NickClass.objects.filter(db_obj=obj, db_nick__iexact=nick, db_type__iexact=nick_type).count()
Retrieves a given nick replacement based on the input nick. If
given but no matching conversion was found, returns
original input or default if given
If no nick is given, returns a list of all matching nick
objects (LiteAttributes) on the object, or the empty list.
"""
nick = nick.strip().lower() if nick!=None else None
nick_type = "%s%s" % (self.prefix, nick_type.strip().lower())
if nick:
nicks = _GA(self.obj, "db_liteattributes").objects.filter(db_key=nick, db_category=nick_type).prefetch_related("db_data")
default = default if default!=None else nick
return nicks[0].db_data if nicks else default
else:
return list(self.obj.db_liteattributes.all())
#------------------------------------------------------------