mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Moved object methods up from ObjectDB and mainly onto the typeclass. In the process of converting players in the same way.
This commit is contained in:
parent
302f5bdd81
commit
db512cbbf5
6 changed files with 175 additions and 226 deletions
|
|
@ -823,6 +823,7 @@ class DefaultObject(ObjectDB):
|
|||
return True
|
||||
# methods inherited from the typeclass system
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
Checks for equality against an id string or another object or user.
|
||||
|
|
|
|||
|
|
@ -24,12 +24,9 @@ from django.utils.encoding import smart_str
|
|||
from src.players.manager import PlayerDBManager
|
||||
from src.scripts.models import ScriptDB
|
||||
from src.typeclasses.models import TypedObject
|
||||
from src.typeclasses.attributes import NickHandler
|
||||
from src.scripts.scripthandler import ScriptHandler
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.commands import cmdhandler
|
||||
from src.utils import utils, logger
|
||||
from src.utils.utils import to_str, make_iter, lazy_property
|
||||
from src.utils.utils import to_str, make_iter
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
|
@ -111,20 +108,6 @@ class PlayerDB(TypedObject, AbstractUser):
|
|||
app_label = 'players'
|
||||
verbose_name = 'Player'
|
||||
|
||||
# lazy-loading of handlers
|
||||
@lazy_property
|
||||
def cmdset(self):
|
||||
return CmdSetHandler(self, True)
|
||||
|
||||
@lazy_property
|
||||
def scripts(self):
|
||||
return ScriptHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def nicks(self):
|
||||
return NickHandler(self)
|
||||
|
||||
|
||||
# alias to the objs property
|
||||
def __characters_get(self):
|
||||
return self.objs
|
||||
|
|
@ -143,7 +126,7 @@ class PlayerDB(TypedObject, AbstractUser):
|
|||
"""
|
||||
Getter. Allows for value = self.name. Returns a list of cmdset_storage.
|
||||
"""
|
||||
storage = _GA(self, "db_cmdset_storage")
|
||||
storage = self.db_cmdset_storage
|
||||
# we need to check so storage is not None
|
||||
return [path.strip() for path in storage.split(',')] if storage else []
|
||||
|
||||
|
|
@ -168,20 +151,22 @@ class PlayerDB(TypedObject, AbstractUser):
|
|||
#
|
||||
|
||||
def __str__(self):
|
||||
return smart_str("%s(player %s)" % (_GA(self, "name"), _GA(self, "dbid")))
|
||||
return smart_str("%s(player %s)" % (self.name, self.dbid))
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s(player#%s)" % (_GA(self, "name"), _GA(self, "dbid"))
|
||||
return u"%s(player#%s)" % (self.name, self.dbid)
|
||||
|
||||
#@property
|
||||
def __username_get(self):
|
||||
return _GA(self, "username")
|
||||
return self.username
|
||||
|
||||
def __username_set(self, value):
|
||||
_SA(self, "username", value)
|
||||
self.username = value
|
||||
self.save(update_fields=["username"])
|
||||
|
||||
def __username_del(self):
|
||||
_DA(self, "username")
|
||||
del self.username
|
||||
|
||||
# aliases
|
||||
name = property(__username_get, __username_set, __username_del)
|
||||
key = property(__username_get, __username_set, __username_del)
|
||||
|
|
@ -198,64 +183,10 @@ class PlayerDB(TypedObject, AbstractUser):
|
|||
raise Exception("User id cannot be deleted!")
|
||||
uid = property(__uid_get, __uid_set, __uid_del)
|
||||
|
||||
#@property
|
||||
#def __is_superuser_get(self):
|
||||
# "Superusers have all permissions."
|
||||
# return self.db_is_superuser
|
||||
# #is_suser = get_prop_cache(self, "_is_superuser")
|
||||
# #if is_suser == None:
|
||||
# # is_suser = _GA(self, "user").is_superuser
|
||||
# # set_prop_cache(self, "_is_superuser", is_suser)
|
||||
# #return is_suser
|
||||
#is_superuser = property(__is_superuser_get)
|
||||
|
||||
#
|
||||
# PlayerDB class access methods
|
||||
#
|
||||
|
||||
def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
|
||||
"""
|
||||
Evennia -> User
|
||||
This is the main route for sending data back to the user from the
|
||||
server.
|
||||
|
||||
outgoing_string (string) - text data to send
|
||||
from_obj (Object/Player) - source object of message to send. Its
|
||||
at_msg_send() hook will be called.
|
||||
sessid - the session id of the session to send to. If not given, return
|
||||
to all sessions connected to this player. This is usually only
|
||||
relevant when using msg() directly from a player-command (from
|
||||
a command on a Character, the character automatically stores
|
||||
and handles the sessid). Can also be a list of sessids.
|
||||
kwargs (dict) - All other keywords are parsed as extra data.
|
||||
"""
|
||||
if "data" in kwargs:
|
||||
# deprecation warning
|
||||
logger.log_depmsg("PlayerDB:msg() 'data'-dict keyword is deprecated. Use **kwargs instead.")
|
||||
data = kwargs.pop("data")
|
||||
if isinstance(data, dict):
|
||||
kwargs.update(data)
|
||||
|
||||
text = to_str(text, force_string=True) if text else ""
|
||||
if from_obj:
|
||||
# call hook
|
||||
try:
|
||||
_GA(from_obj, "at_msg_send")(text=text, to_obj=self, **kwargs)
|
||||
except Exception:
|
||||
pass
|
||||
sessions = _MULTISESSION_MODE > 1 and sessid and _GA(self, "get_session")(sessid) or None
|
||||
if sessions:
|
||||
for session in make_iter(sessions):
|
||||
obj = session.puppet
|
||||
if obj and not obj.at_msg_receive(text=text, **kwargs):
|
||||
# if hook returns false, cancel send
|
||||
continue
|
||||
session.msg(text=text, **kwargs)
|
||||
else:
|
||||
# if no session was specified, send to them all
|
||||
for sess in _GA(self, 'get_all_sessions')():
|
||||
sess.msg(text=text, **kwargs)
|
||||
|
||||
# session-related methods
|
||||
|
||||
def get_session(self, sessid):
|
||||
|
|
|
|||
|
|
@ -18,7 +18,13 @@ from src.players.manager import PlayerManager
|
|||
from src.players.models import PlayerDB
|
||||
from src.comms.models import ChannelDB
|
||||
from src.utils import logger
|
||||
__all__ = ("Player",)
|
||||
from src.utils.utils import lazy_property, to_str, make_iter
|
||||
from src.typeclasses.attributes import NickHandler
|
||||
from src.scripts.scripthandler import ScriptHandler
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
|
||||
|
||||
__all__ = ("DefaultPlayer",)
|
||||
|
||||
_MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||
_CMDSET_PLAYER = settings.CMDSET_PLAYER
|
||||
|
|
@ -26,105 +32,140 @@ _CONNECT_CHANNEL = None
|
|||
|
||||
class DefaultPlayer(PlayerDB):
|
||||
"""
|
||||
Base typeclass for all Players.
|
||||
"""
|
||||
This is the base Typeclass for all Players. Players represent
|
||||
the person playing the game and tracks account info, password
|
||||
etc. They are OOC entities without presence in-game. A Player
|
||||
can connect to a Character Object in order to "enter" the
|
||||
game.
|
||||
|
||||
Player Typeclass API:
|
||||
|
||||
* Available properties (only available on initiated typeclass objects)
|
||||
|
||||
key (string) - name of player
|
||||
name (string)- wrapper for user.username
|
||||
aliases (list of strings) - aliases to the object. Will be saved to
|
||||
database as AliasDB entries but returned as strings.
|
||||
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||
dbobj (Player, read-only) - link to database model. dbobj.typeclass
|
||||
points back to this class
|
||||
typeclass (Player, read-only) - this links back to this class as an
|
||||
identified only. Use self.swap_typeclass() to switch.
|
||||
date_created (string) - time stamp of object creation
|
||||
permissions (list of strings) - list of permission strings
|
||||
|
||||
user (User, read-only) - django User authorization object
|
||||
obj (Object) - game object controlled by player. 'character' can also
|
||||
be used.
|
||||
sessions (list of Sessions) - sessions connected to this player
|
||||
is_superuser (bool, read-only) - if the connected user is a superuser
|
||||
|
||||
* Handlers
|
||||
|
||||
locks - lock-handler: use locks.add() to add new lock strings
|
||||
db - attribute-handler: store/retrieve database attributes on this
|
||||
self.db.myattr=val, val=self.db.myattr
|
||||
ndb - non-persistent attribute handler: same as db but does not
|
||||
create a database entry when storing data
|
||||
scripts - script-handler. Add new scripts to object with scripts.add()
|
||||
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
||||
nicks - nick-handler. New nicks with nicks.add().
|
||||
|
||||
* Helper methods
|
||||
|
||||
msg(outgoing_string, from_obj=None, **kwargs)
|
||||
swap_character(new_character, delete_old_character=False)
|
||||
execute_cmd(raw_string)
|
||||
search(ostring, global_search=False, attribute_name=None,
|
||||
use_nicks=False, location=None,
|
||||
ignore_errors=False, player=False)
|
||||
is_typeclass(typeclass, exact=False)
|
||||
swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)
|
||||
access(accessing_obj, access_type='read', default=False)
|
||||
check_permstring(permstring)
|
||||
|
||||
* Hook methods
|
||||
|
||||
basetype_setup()
|
||||
at_player_creation()
|
||||
|
||||
- note that the following hooks are also found on Objects and are
|
||||
usually handled on the character level:
|
||||
|
||||
at_init()
|
||||
at_access()
|
||||
at_cmdset_get(**kwargs)
|
||||
at_first_login()
|
||||
at_post_login(sessid=None)
|
||||
at_disconnect()
|
||||
at_message_receive()
|
||||
at_message_send()
|
||||
at_server_reload()
|
||||
at_server_shutdown()
|
||||
|
||||
"""
|
||||
|
||||
__metaclass__ = TypeclassBase
|
||||
objects = PlayerManager()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
This is the base Typeclass for all Players. Players represent
|
||||
the person playing the game and tracks account info, password
|
||||
etc. They are OOC entities without presence in-game. A Player
|
||||
can connect to a Character Object in order to "enter" the
|
||||
game.
|
||||
# properties
|
||||
@lazy_property
|
||||
def cmdset(self):
|
||||
return CmdSetHandler(self, True)
|
||||
|
||||
Player Typeclass API:
|
||||
@lazy_property
|
||||
def scripts(self):
|
||||
return ScriptHandler(self)
|
||||
|
||||
* Available properties (only available on initiated typeclass objects)
|
||||
@lazy_property
|
||||
def nicks(self):
|
||||
return NickHandler(self)
|
||||
|
||||
key (string) - name of player
|
||||
name (string)- wrapper for user.username
|
||||
aliases (list of strings) - aliases to the object. Will be saved to
|
||||
database as AliasDB entries but returned as strings.
|
||||
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||
dbobj (Player, read-only) - link to database model. dbobj.typeclass
|
||||
points back to this class
|
||||
typeclass (Player, read-only) - this links back to this class as an
|
||||
identified only. Use self.swap_typeclass() to switch.
|
||||
date_created (string) - time stamp of object creation
|
||||
permissions (list of strings) - list of permission strings
|
||||
|
||||
user (User, read-only) - django User authorization object
|
||||
obj (Object) - game object controlled by player. 'character' can also
|
||||
be used.
|
||||
sessions (list of Sessions) - sessions connected to this player
|
||||
is_superuser (bool, read-only) - if the connected user is a superuser
|
||||
|
||||
* Handlers
|
||||
|
||||
locks - lock-handler: use locks.add() to add new lock strings
|
||||
db - attribute-handler: store/retrieve database attributes on this
|
||||
self.db.myattr=val, val=self.db.myattr
|
||||
ndb - non-persistent attribute handler: same as db but does not
|
||||
create a database entry when storing data
|
||||
scripts - script-handler. Add new scripts to object with scripts.add()
|
||||
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
||||
nicks - nick-handler. New nicks with nicks.add().
|
||||
|
||||
* Helper methods
|
||||
|
||||
msg(outgoing_string, from_obj=None, **kwargs)
|
||||
swap_character(new_character, delete_old_character=False)
|
||||
execute_cmd(raw_string)
|
||||
search(ostring, global_search=False, attribute_name=None,
|
||||
use_nicks=False, location=None,
|
||||
ignore_errors=False, player=False)
|
||||
is_typeclass(typeclass, exact=False)
|
||||
swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)
|
||||
access(accessing_obj, access_type='read', default=False)
|
||||
check_permstring(permstring)
|
||||
|
||||
* Hook methods
|
||||
|
||||
basetype_setup()
|
||||
at_player_creation()
|
||||
|
||||
- note that the following hooks are also found on Objects and are
|
||||
usually handled on the character level:
|
||||
|
||||
at_init()
|
||||
at_access()
|
||||
at_cmdset_get(**kwargs)
|
||||
at_first_login()
|
||||
at_post_login(sessid=None)
|
||||
at_disconnect()
|
||||
at_message_receive()
|
||||
at_message_send()
|
||||
at_server_reload()
|
||||
at_server_shutdown()
|
||||
|
||||
"""
|
||||
super(DefaultPlayer, self).__init__(*args, **kwargs)
|
||||
|
||||
## methods inherited from database model
|
||||
|
||||
def msg(self, text=None, from_obj=None, sessid=None, **kwargs):
|
||||
"""
|
||||
Evennia -> User
|
||||
This is the main route for sending data back to the user from
|
||||
the server.
|
||||
This is the main route for sending data back to the user from the
|
||||
server.
|
||||
|
||||
text (string) - text data to send
|
||||
from_obj (Object/DefaultPlayer) - source object of message to send
|
||||
sessid - the session id of the session to send to. If not given,
|
||||
return to all sessions connected to this player. This is usually only
|
||||
relevant when using msg() directly from a player-command (from
|
||||
a command on a Character, the character automatically stores and
|
||||
handles the sessid).
|
||||
kwargs - extra data to send through protocol
|
||||
outgoing_string (string) - text data to send
|
||||
from_obj (Object/Player) - source object of message to send. Its
|
||||
at_msg_send() hook will be called.
|
||||
sessid - the session id of the session to send to. If not given, return
|
||||
to all sessions connected to this player. This is usually only
|
||||
relevant when using msg() directly from a player-command (from
|
||||
a command on a Character, the character automatically stores
|
||||
and handles the sessid). Can also be a list of sessids.
|
||||
kwargs (dict) - All other keywords are parsed as extra data.
|
||||
"""
|
||||
super(DefaultPlayer, self).msg(text=text, from_obj=from_obj, sessid=sessid, **kwargs)
|
||||
if "data" in kwargs:
|
||||
# deprecation warning
|
||||
logger.log_depmsg("PlayerDB:msg() 'data'-dict keyword is deprecated. Use **kwargs instead.")
|
||||
data = kwargs.pop("data")
|
||||
if isinstance(data, dict):
|
||||
kwargs.update(data)
|
||||
|
||||
text = to_str(text, force_string=True) if text else ""
|
||||
if from_obj:
|
||||
# call hook
|
||||
try:
|
||||
from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
|
||||
except Exception:
|
||||
pass
|
||||
sessions = _MULTISESSION_MODE > 1 and sessid and self.get_session(sessid) or None
|
||||
if sessions:
|
||||
for session in make_iter(sessions):
|
||||
obj = session.puppet
|
||||
if obj and not obj.at_msg_receive(text=text, **kwargs):
|
||||
# if hook returns false, cancel send
|
||||
continue
|
||||
session.msg(text=text, **kwargs)
|
||||
else:
|
||||
# if no session was specified, send to them all
|
||||
for sess in self.get_all_sessions():
|
||||
sess.msg(text=text, **kwargs)
|
||||
|
||||
def swap_character(self, new_character, delete_old_character=False):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import django
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils.translation import ugettext as _
|
||||
from src.players.models import PlayerDB
|
||||
from src.server.models import ServerConfig
|
||||
from src.utils import create
|
||||
from src.utils.utils import class_from_module
|
||||
|
|
@ -26,15 +27,14 @@ def get_god_player():
|
|||
"""
|
||||
Creates the god user.
|
||||
"""
|
||||
Player = class_from_module(settings.BASE_PLAYER_TYPECLASS)
|
||||
try:
|
||||
god_player = Player.objects.get(id=1)
|
||||
except Player.DoesNotExist:
|
||||
txt = "\n\nNo superuser exists yet. The superuser is the 'owner'"
|
||||
txt += "\account on the Evennia server. Create a new superuser using"
|
||||
txt += "\nthe command"
|
||||
txt += "\n\n python manage.py createsuperuser"
|
||||
txt += "\n\nFollow the prompts, then restart the server."
|
||||
god_player = PlayerDB.objects.get(id=1)
|
||||
except PlayerDB.DoesNotExist:
|
||||
txt = "\n\nNo superuser exists yet. The superuser is the 'owner'\n" \
|
||||
"account on the Evennia server. Create a new superuser using\n" \
|
||||
"the command\n\n" \
|
||||
" python manage.py createsuperuser\n\n" \
|
||||
"Follow the prompts, then restart the server."
|
||||
raise Exception(txt)
|
||||
return god_player
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ def create_objects():
|
|||
|
||||
# run all creation hooks on god_player (we must do so manually
|
||||
# since the manage.py command does not)
|
||||
god_player.typeclass_path = player_typeclass
|
||||
god_player.swap_typeclass(player_typeclass, clean_attributes=True)
|
||||
god_player.basetype_setup()
|
||||
god_player.at_player_creation()
|
||||
god_player.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all()")
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ TICKER_HANDLER = None
|
|||
|
||||
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
_TYPECLASS_AGGRESSIVE_CACHE = settings.TYPECLASS_AGGRESSIVE_CACHE
|
||||
_GA = object.__getattribute__
|
||||
_SA = object.__setattr__
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
|
|
@ -150,16 +152,12 @@ class TypedObject(SharedMemoryModel):
|
|||
# Main identifier of the object, for searching. Is accessed with self.key
|
||||
# or self.name
|
||||
db_key = models.CharField('key', max_length=255, db_index=True)
|
||||
# This is the python path to the type class this object is tied to the
|
||||
# This is the python path to the type class this object is tied to. The
|
||||
# typeclass is what defines what kind of Object this is)
|
||||
db_typeclass_path = models.CharField('typeclass', max_length=255, null=True,
|
||||
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.")
|
||||
# Creation date. This is not changed once the object is created.
|
||||
db_date_created = models.DateTimeField('creation date', editable=False, auto_now_add=True)
|
||||
# Permissions (access these through the 'permissions' property)
|
||||
#db_permissions = models.CharField('permissions', max_length=255, blank=True,
|
||||
# help_text="a comma-separated list of text strings checked by
|
||||
# in-game locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Character objects use 'Players' by default. Most other objects don't have any permissions.")
|
||||
# Lock storage
|
||||
db_lock_storage = models.TextField('locks', blank=True,
|
||||
help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.")
|
||||
|
|
@ -178,6 +176,11 @@ class TypedObject(SharedMemoryModel):
|
|||
# typeclass mechanism
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
This is the main function of the typeclass system -
|
||||
to dynamically re-apply a class based on the
|
||||
db_typeclass_path rather than use the one in the model.
|
||||
"""
|
||||
typeclass_path = kwargs.pop("typeclass", None)
|
||||
super(TypedObject, self).__init__(*args, **kwargs)
|
||||
if typeclass_path:
|
||||
|
|
@ -250,8 +253,6 @@ class TypedObject(SharedMemoryModel):
|
|||
#
|
||||
#
|
||||
|
||||
_typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
||||
|
||||
def __eq__(self, other):
|
||||
return other and hasattr(other, 'dbid') and self.dbid == other.dbid
|
||||
|
||||
|
|
@ -332,16 +333,13 @@ class TypedObject(SharedMemoryModel):
|
|||
boolean True/False depending on if the swap worked or not.
|
||||
|
||||
"""
|
||||
if callable(new_typeclass):
|
||||
# this is an actual class object - build the path
|
||||
cls = new_typeclass
|
||||
new_typeclass = "%s.%s" % (cls.__module__, cls.__name__)
|
||||
else:
|
||||
new_typeclass = "%s" % to_str(new_typeclass)
|
||||
|
||||
# Try to set the new path
|
||||
# this will automatically save to database
|
||||
old_typeclass_path = self.typeclass_path
|
||||
if not callable(new_typeclass):
|
||||
# this is an actual class object - build the path
|
||||
new_typeclass = class_from_module(new_typeclass)
|
||||
|
||||
# if we get to this point, the class is ok.
|
||||
|
||||
|
||||
if inherits_from(self, "src.scripts.models.ScriptDB"):
|
||||
if self.interval > 0:
|
||||
|
|
@ -349,15 +347,7 @@ class TypedObject(SharedMemoryModel):
|
|||
"Script '%s'.\nStop and start a new Script of the " \
|
||||
"right type instead." % self.key)
|
||||
|
||||
self.typeclass_path = new_typeclass.strip()
|
||||
# this will automatically use a default class if
|
||||
# there is an error with the given typeclass.
|
||||
new_typeclass = self
|
||||
if self.typeclass_path != new_typeclass.path and no_default:
|
||||
# something went wrong; the default was loaded instead,
|
||||
# and we don't allow that; instead we return to previous.
|
||||
self.typeclass_path = old_typeclass_path
|
||||
return False
|
||||
self.typeclass_path = new_typeclass.path
|
||||
|
||||
if clean_attributes:
|
||||
# Clean out old attributes
|
||||
|
|
@ -373,21 +363,7 @@ class TypedObject(SharedMemoryModel):
|
|||
self.nattributes.clear()
|
||||
|
||||
if run_start_hooks:
|
||||
# run hooks for this new typeclass
|
||||
if inherits_from(self, "src.objects.models.ObjectDB"):
|
||||
new_typeclass.basetype_setup()
|
||||
new_typeclass.at_object_creation()
|
||||
elif inherits_from(self, "src.players.models.PlayerDB"):
|
||||
new_typeclass.basetype_setup()
|
||||
new_typeclass.at_player_creation()
|
||||
elif inherits_from(self, "src.scripts.models.ScriptDB"):
|
||||
new_typeclass.at_script_creation()
|
||||
new_typeclass.start()
|
||||
elif inherits_from(self, "src.channels.models.Channel"):
|
||||
# channels do no initial setup
|
||||
pass
|
||||
|
||||
return True
|
||||
self.at_instance_creation()
|
||||
|
||||
#
|
||||
# Lock / permission methods
|
||||
|
|
@ -493,25 +469,25 @@ class TypedObject(SharedMemoryModel):
|
|||
class DbHolder(object):
|
||||
"Holder for allowing property access of attributes"
|
||||
def __init__(self, obj):
|
||||
self.attrhandler = obj.attributes
|
||||
_SA(self, "attrhandler", obj.attributes)
|
||||
|
||||
def __getattribute__(self, attrname):
|
||||
if attrname == 'all':
|
||||
# we allow to overload our default .all
|
||||
attr = self.attrhandler.get("all")
|
||||
attr = _GA(self, "attrhandler").get("all")
|
||||
if attr:
|
||||
return attr
|
||||
return self.all
|
||||
return self.attrhandler.get(attrname)
|
||||
return _GA(self, "attrhandler").get(attrname)
|
||||
|
||||
def __setattr__(self, attrname, value):
|
||||
self.attrhandler.add(attrname, value)
|
||||
_GA(self, "attrhandler").add(attrname, value)
|
||||
|
||||
def __delattr__(self, attrname):
|
||||
self.attrhandler.remove(attrname)
|
||||
_GA(self, "attrhandler").remove(attrname)
|
||||
|
||||
def get_all(self):
|
||||
return self.attrhandler.all()
|
||||
return _GA(self, "attrhandler").all()
|
||||
all = property(get_all)
|
||||
self._db_holder = DbHolder(self)
|
||||
return self._db_holder
|
||||
|
|
@ -547,25 +523,25 @@ class TypedObject(SharedMemoryModel):
|
|||
class NDbHolder(object):
|
||||
"Holder for allowing property access of attributes"
|
||||
def __init__(self, obj):
|
||||
self.nattrhandler = obj.nattributes
|
||||
_SA(self, "nattrhandler", obj.nattributes)
|
||||
|
||||
def __getattribute__(self, attrname):
|
||||
if attrname == 'all':
|
||||
# we allow to overload our default .all
|
||||
attr = self.nattrhandler.get('all')
|
||||
attr = _GA(self, "nattrhandler").get('all')
|
||||
if attr:
|
||||
return attr
|
||||
return self.all
|
||||
return self.nattrhandler.get(attrname)
|
||||
return _GA(self, "nattrhandler").get(attrname)
|
||||
|
||||
def __setattr__(self, attrname, value):
|
||||
self.nattrhandler.add(attrname, value)
|
||||
_GA(self, "nattrhandler").add(attrname, value)
|
||||
|
||||
def __delattr__(self, attrname):
|
||||
self.nattrhandler.remove(attrname)
|
||||
_GA(self, "nattrhandler").remove(attrname)
|
||||
|
||||
def get_all(self):
|
||||
return self.nattrhandler.all()
|
||||
return _GA(self, "nattrhandler").all()
|
||||
all = property(get_all)
|
||||
self._ndb_holder = NDbHolder(self)
|
||||
return self._ndb_holder
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ def pack_dbobj(item):
|
|||
_init_globals()
|
||||
obj = hasattr(item, 'dbobj') and item.dbobj or item
|
||||
natural_key = _FROM_MODEL_MAP[hasattr(obj, "id") and hasattr(obj, "db_date_created") and
|
||||
hasattr(obj, '__class__') and obj.__class__.__name__.lower()]
|
||||
hasattr(obj, '__dbclass__') and obj.__dbclass__.__name__.lower()]
|
||||
# build the internal representation as a tuple
|
||||
# ("__packed_dbobj__", key, creation_time, id)
|
||||
return natural_key and ('__packed_dbobj__', natural_key,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue