mirror of
https://github.com/evennia/evennia.git
synced 2026-03-21 23:36:30 +01:00
145 lines
4.7 KiB
Python
145 lines
4.7 KiB
Python
"""
|
|
This implements the common managers that are used by the
|
|
abstract models in dbobjects.py (and which are thus shared by
|
|
all Attributes and TypedObjects).
|
|
"""
|
|
from functools import update_wrapper
|
|
from django.db import models
|
|
from src.utils import idmapper
|
|
from src.utils.utils import make_iter
|
|
__all__ = ("AttributeManager", "TypedObjectManager")
|
|
|
|
# Managers
|
|
|
|
class AttributeManager(models.Manager):
|
|
"Manager for handling Attributes."
|
|
|
|
def attr_namesearch(self, searchstr, obj, exact_match=True):
|
|
"""
|
|
Searches the object's attributes for name matches.
|
|
|
|
searchstr: (str) A string to search for.
|
|
"""
|
|
# Retrieve the list of attributes for this object.
|
|
if exact_match:
|
|
return self.filter(db_obj=obj).filter(
|
|
db_key__iexact=searchstr)
|
|
else:
|
|
return self.filter(db_obj=obj).filter(
|
|
db_key__icontains=searchstr)
|
|
|
|
#
|
|
# helper functions for the TypedObjectManager.
|
|
#
|
|
|
|
def returns_typeclass_list(method):
|
|
"""
|
|
Decorator: Changes return of the decorated method (which are
|
|
TypeClassed objects) into object_classes(s) instead. Will always
|
|
return a list (may be empty).
|
|
"""
|
|
def func(self, *args, **kwargs):
|
|
"decorator. Returns a list."
|
|
self.__doc__ = method.__doc__
|
|
matches = method(self, *args, **kwargs)
|
|
return [(hasattr(dbobj, "typeclass") and dbobj.typeclass) or dbobj for dbobj in make_iter(matches)]
|
|
return update_wrapper(func, method)
|
|
|
|
def returns_typeclass(method):
|
|
"""
|
|
Decorator: Will always return a single typeclassed result or None.
|
|
"""
|
|
def func(self, *args, **kwargs):
|
|
"decorator. Returns result or None."
|
|
self.__doc__ = method.__doc__
|
|
matches = method(self, *args, **kwargs)
|
|
dbobj = matches and make_iter(matches)[0] or None
|
|
if dbobj:
|
|
return (hasattr(dbobj, "typeclass") and dbobj.typeclass) or dbobj
|
|
return None
|
|
return update_wrapper(func, method)
|
|
|
|
|
|
#class TypedObjectManager(idmap.CachingManager):
|
|
#class TypedObjectManager(models.Manager):
|
|
class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|
"""
|
|
Common ObjectManager for all dbobjects.
|
|
"""
|
|
|
|
def dbref(self, dbref, reqhash=True):
|
|
"""
|
|
Valid forms of dbref (database reference number)
|
|
are either a string '#N' or an integer N.
|
|
Output is the integer part.
|
|
reqhash - require input to be on form "#N" to be
|
|
identified as a dbref
|
|
"""
|
|
if reqhash and not (isinstance(dbref, basestring) and dbref.startswith("#")):
|
|
return None
|
|
if isinstance(dbref, basestring):
|
|
dbref = dbref.lstrip('#')
|
|
try:
|
|
if int(dbref) < 0:
|
|
return None
|
|
except Exception:
|
|
return None
|
|
return dbref
|
|
|
|
@returns_typeclass
|
|
def get_id(self, dbref):
|
|
"""
|
|
Find object with given dbref
|
|
"""
|
|
dbref = self.dbref(dbref, reqhash=False)
|
|
try:
|
|
return self.get(id=dbref)
|
|
except self.model.DoesNotExist:
|
|
pass
|
|
return None
|
|
|
|
def dbref_search(self, dbref):
|
|
"""
|
|
Alias to get_id
|
|
"""
|
|
return self.get_id(dbref)
|
|
|
|
@returns_typeclass_list
|
|
def get_dbref_range(self, min_dbref=None, max_dbref=None):
|
|
"""
|
|
Return all objects inside and including the
|
|
given boundaries.
|
|
"""
|
|
min_dbref, max_dbref = self.dbref(min_dbref), self.dbref(max_dbref)
|
|
if not min_dbref or not max_dbref:
|
|
return self.all()
|
|
if not min_dbref:
|
|
return self.filter(id__lte=max_dbref)
|
|
elif not max_dbref:
|
|
return self.filter(id__gte=min_dbref)
|
|
return self.filter(id__gte=min_dbref).filter(id__lte=min_dbref)
|
|
|
|
def object_totals(self):
|
|
"""
|
|
Returns a dictionary with all the typeclasses active in-game
|
|
as well as the number of such objects defined (i.e. the number
|
|
of database object having that typeclass set on themselves).
|
|
"""
|
|
dbtotals = {}
|
|
typeclass_paths = set(self.values_list('db_typeclass_path', flat=True))
|
|
for typeclass_path in typeclass_paths:
|
|
dbtotals[typeclass_path] = \
|
|
self.filter(db_typeclass_path=typeclass_path).count()
|
|
return dbtotals
|
|
|
|
@returns_typeclass_list
|
|
def typeclass_search(self, typeclass):
|
|
"""
|
|
Searches through all objects returning those which has a certain
|
|
typeclass. If location is set, limit search to objects in
|
|
that location.
|
|
"""
|
|
if callable(typeclass):
|
|
cls = typeclass.__class__
|
|
typeclass = "%s.%s" % (cls.__module__, cls.__name__)
|
|
return self.filter(db_typeclass_path__exact=typeclass)
|