Fixed website. Fixing references to db_references, not sure how to add the m2m field access to the admin. Fixed wrapper for db_home.
This commit is contained in:
parent
272a6ddc2d
commit
fd9acd6bf9
11 changed files with 187 additions and 261 deletions
|
|
@ -72,7 +72,7 @@ class CommandTest(TestCase):
|
||||||
"sets up testing environment"
|
"sets up testing environment"
|
||||||
self.player = create.create_player("TestPlayer%i" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
|
self.player = create.create_player("TestPlayer%i" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
|
||||||
self.player2 = create.create_player("TestPlayer%ib" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
|
self.player2 = create.create_player("TestPlayer%ib" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
|
||||||
self.room1 = create.create_object("src.objects.objects.Room", key="Room%i"%self.CID)
|
self.room1 = create.create_object("src.objects.objects.Room", key="Room%i"%self.CID, testmode=True)
|
||||||
self.room1.db.desc = "room_desc"
|
self.room1.db.desc = "room_desc"
|
||||||
self.room2 = create.create_object("src.objects.objects.Room", key="Room%ib" % self.CID)
|
self.room2 = create.create_object("src.objects.objects.Room", key="Room%ib" % self.CID)
|
||||||
self.obj1 = create.create_object(TestObjectClass, key="Obj%i" % self.CID, location=self.room1, home=self.room1)
|
self.obj1 = create.create_object(TestObjectClass, key="Obj%i" % self.CID, location=self.room1, home=self.room1)
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,8 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from src.typeclasses.models import Attribute
|
from src.typeclasses.models import Attribute, Tag
|
||||||
from src.objects.models import ObjectDB
|
from src.objects.models import ObjectDB
|
||||||
from src.typeclasses.models import Tag, LiteAttribute
|
|
||||||
|
|
||||||
|
|
||||||
class AttributeInline(admin.TabularInline):
|
class AttributeInline(admin.TabularInline):
|
||||||
# This class is currently not used, because PickleField objects are not editable.
|
# This class is currently not used, because PickleField objects are not editable.
|
||||||
|
|
@ -23,11 +21,6 @@ class TagInline(admin.TabularInline):
|
||||||
raw_id_fields = ('tag',)
|
raw_id_fields = ('tag',)
|
||||||
extra = 0
|
extra = 0
|
||||||
|
|
||||||
class LiteAttributeInline(admin.TabularInline):
|
|
||||||
model = LiteAttribute
|
|
||||||
fields = ('db_key', 'db_category', 'db_data')
|
|
||||||
extra = 0
|
|
||||||
|
|
||||||
class TagAdmin(admin.ModelAdmin):
|
class TagAdmin(admin.ModelAdmin):
|
||||||
fields = ('db_key', 'db_category', 'db_data')
|
fields = ('db_key', 'db_category', 'db_data')
|
||||||
|
|
||||||
|
|
@ -41,11 +34,11 @@ class ObjectCreateForm(forms.ModelForm):
|
||||||
db_typeclass_path = forms.CharField(label="Typeclass",initial="Change to (for example) %s or %s." % (settings.BASE_OBJECT_TYPECLASS, settings.BASE_CHARACTER_TYPECLASS),
|
db_typeclass_path = forms.CharField(label="Typeclass",initial="Change to (for example) %s or %s." % (settings.BASE_OBJECT_TYPECLASS, settings.BASE_CHARACTER_TYPECLASS),
|
||||||
widget=forms.TextInput(attrs={'size':'78'}),
|
widget=forms.TextInput(attrs={'size':'78'}),
|
||||||
help_text="This defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. If you are creating a Character you should use the typeclass defined by settings.BASE_CHARACTER_TYPECLASS or one derived from that.")
|
help_text="This defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. If you are creating a Character you should use the typeclass defined by settings.BASE_CHARACTER_TYPECLASS or one derived from that.")
|
||||||
db_permissions = forms.CharField(label="Permissions",
|
#db_permissions = forms.CharField(label="Permissions",
|
||||||
initial=settings.PERMISSION_PLAYER_DEFAULT,
|
# initial=settings.PERMISSION_PLAYER_DEFAULT,
|
||||||
required=False,
|
# required=False,
|
||||||
widget=forms.TextInput(attrs={'size':'78'}),
|
# widget=forms.TextInput(attrs={'size':'78'}),
|
||||||
help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.")
|
# help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.")
|
||||||
db_cmdset_storage = forms.CharField(label="CmdSet",
|
db_cmdset_storage = forms.CharField(label="CmdSet",
|
||||||
initial=settings.CMDSET_CHARACTER,
|
initial=settings.CMDSET_CHARACTER,
|
||||||
required=False,
|
required=False,
|
||||||
|
|
@ -75,17 +68,24 @@ class ObjectDBAdmin(admin.ModelAdmin):
|
||||||
save_as = True
|
save_as = True
|
||||||
save_on_top = True
|
save_on_top = True
|
||||||
list_select_related = True
|
list_select_related = True
|
||||||
list_filter = ('db_permissions', 'db_typeclass_path')
|
list_filter = ('db_typeclass_path',)
|
||||||
|
#list_filter = ('db_permissions', 'db_typeclass_path')
|
||||||
|
|
||||||
# editing fields setup
|
# editing fields setup
|
||||||
|
|
||||||
form = ObjectEditForm
|
form = ObjectEditForm
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
|
'fields': (('db_key','db_typeclass_path'), ('db_lock_storage', ),
|
||||||
('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
|
('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
|
||||||
)}),
|
)}),
|
||||||
)
|
)
|
||||||
|
#fieldsets = (
|
||||||
|
# (None, {
|
||||||
|
# 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
|
||||||
|
# ('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
|
||||||
|
# )}),
|
||||||
|
# )
|
||||||
|
|
||||||
#deactivated temporarily, they cause empty objects to be created in admin
|
#deactivated temporarily, they cause empty objects to be created in admin
|
||||||
inlines = [TagInline]
|
inlines = [TagInline]
|
||||||
|
|
@ -96,10 +96,16 @@ class ObjectDBAdmin(admin.ModelAdmin):
|
||||||
add_form = ObjectCreateForm
|
add_form = ObjectCreateForm
|
||||||
add_fieldsets = (
|
add_fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
'fields': (('db_key','db_typeclass_path'), 'db_permissions',
|
'fields': (('db_key','db_typeclass_path'),
|
||||||
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||||
)}),
|
)}),
|
||||||
)
|
)
|
||||||
|
#add_fieldsets = (
|
||||||
|
# (None, {
|
||||||
|
# 'fields': (('db_key','db_typeclass_path'), 'db_permissions',
|
||||||
|
# ('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||||
|
# )}),
|
||||||
|
# )
|
||||||
def get_fieldsets(self, request, obj=None):
|
def get_fieldsets(self, request, obj=None):
|
||||||
if not obj:
|
if not obj:
|
||||||
return self.add_fieldsets
|
return self.add_fieldsets
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
||||||
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache
|
from src.server.caches import get_prop_cache, set_prop_cache
|
||||||
|
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
|
|
@ -165,7 +164,8 @@ class ObjectDB(TypedObject):
|
||||||
We have to be careful here since Player is also
|
We have to be careful here since Player is also
|
||||||
a TypedObject, so as to not create a loop.
|
a TypedObject, so as to not create a loop.
|
||||||
"""
|
"""
|
||||||
player = get_field_cache(self, "player")
|
player = _GA(self, "db_player")
|
||||||
|
#player = get_field_cache(self, "player")
|
||||||
if player:
|
if player:
|
||||||
try:
|
try:
|
||||||
return player.typeclass
|
return player.typeclass
|
||||||
|
|
@ -178,7 +178,9 @@ class ObjectDB(TypedObject):
|
||||||
"Setter. Allows for self.player = value"
|
"Setter. Allows for self.player = value"
|
||||||
if inherits_from(player, TypeClass):
|
if inherits_from(player, TypeClass):
|
||||||
player = player.dbobj
|
player = player.dbobj
|
||||||
set_field_cache(self, "player", player)
|
_SA(self, "db_player", player)
|
||||||
|
_GA(self, "save")()
|
||||||
|
#set_field_cache(self, "player", player)
|
||||||
# we must set this here or superusers won't be able to
|
# we must set this here or superusers won't be able to
|
||||||
# bypass lockchecks unless they start the game connected
|
# bypass lockchecks unless they start the game connected
|
||||||
# to the character in question.
|
# to the character in question.
|
||||||
|
|
@ -187,30 +189,37 @@ class ObjectDB(TypedObject):
|
||||||
#@player.deleter
|
#@player.deleter
|
||||||
def __player_del(self):
|
def __player_del(self):
|
||||||
"Deleter. Allows for del self.player"
|
"Deleter. Allows for del self.player"
|
||||||
del_field_cache(self, "player")
|
_SA(self, "db_player", None)
|
||||||
|
_GA(self, "save")()
|
||||||
|
#del_field_cache(self, "player")
|
||||||
player = property(__player_get, __player_set, __player_del)
|
player = property(__player_get, __player_set, __player_del)
|
||||||
|
|
||||||
# sessid property (wraps db_sessid)
|
#sessid property (wraps db_sessid)
|
||||||
#@property
|
#@property
|
||||||
#def __sessid_get(self):
|
def __sessid_get(self):
|
||||||
# """
|
"""
|
||||||
# Getter. Allows for value = self.sessid. Since sessid
|
Getter. Allows for value = self.sessid. Since sessid
|
||||||
# is directly related to self.player, we cannot have
|
is directly related to self.player, we cannot have
|
||||||
# a sessid without a player being connected (but the
|
a sessid without a player being connected (but the
|
||||||
# opposite could be true).
|
opposite could be true).
|
||||||
# """
|
"""
|
||||||
# if not get_field_cache(self, "sessid"):
|
return _GA(self, "db_sessid")
|
||||||
# del_field_cache(self, "sessid")
|
#if not get_field_cache(self, "sessid"):
|
||||||
# return get_field_cache(self, "sessid")
|
# del_field_cache(self, "sessid")
|
||||||
##@sessid.setter
|
#return get_field_cache(self, "sessid")
|
||||||
#def __sessid_set(self, sessid):
|
#@sessid.setter
|
||||||
# "Setter. Allows for self.player = value"
|
def __sessid_set(self, sessid):
|
||||||
# set_field_cache(self, "sessid", sessid)
|
"Setter. Allows for self.player = value"
|
||||||
##@sessid.deleter
|
_SA(self, "db_sessid", sessid)
|
||||||
#def __sessid_del(self):
|
_GA(self, "save")()
|
||||||
# "Deleter. Allows for del self.player"
|
#set_field_cache(self, "sessid", sessid)
|
||||||
# del_field_cache(self, "sessid")
|
#@sessid.deleter
|
||||||
#sessid = property(__sessid_get, __sessid_set, __sessid_del)
|
def __sessid_del(self):
|
||||||
|
"Deleter. Allows for del self.player"
|
||||||
|
_SA(self, "db_sessid", None)
|
||||||
|
_GA(self, "save")()
|
||||||
|
#del_field_cache(self, "sessid")
|
||||||
|
sessid = property(__sessid_get, __sessid_set, __sessid_del)
|
||||||
|
|
||||||
def _at_db_location_save(self, new_value, old_value=None):
|
def _at_db_location_save(self, new_value, old_value=None):
|
||||||
"This is called automatically just before a new location is saved."
|
"This is called automatically just before a new location is saved."
|
||||||
|
|
@ -311,79 +320,79 @@ class ObjectDB(TypedObject):
|
||||||
|
|
||||||
# home property (wraps db_home)
|
# home property (wraps db_home)
|
||||||
#@property
|
#@property
|
||||||
def __home_get(self):
|
#def __home_get(self):
|
||||||
"Getter. Allows for value = self.home"
|
# "Getter. Allows for value = self.home"
|
||||||
home = get_field_cache(self, "home")
|
# home = get_field_cache(self, "home")
|
||||||
if home:
|
# if home:
|
||||||
return _GA(home, "typeclass")
|
# return _GA(home, "typeclass")
|
||||||
return None
|
# return None
|
||||||
#@home.setter
|
##@home.setter
|
||||||
def __home_set(self, home):
|
#def __home_set(self, home):
|
||||||
"Setter. Allows for self.home = value"
|
# "Setter. Allows for self.home = value"
|
||||||
try:
|
# try:
|
||||||
if home == None or type(home) == ObjectDB:
|
# if home == None or type(home) == ObjectDB:
|
||||||
hom = home
|
# hom = home
|
||||||
elif ObjectDB.objects.dbref(home):
|
# elif ObjectDB.objects.dbref(home):
|
||||||
hom = ObjectDB.objects.dbref_search(home)
|
# hom = ObjectDB.objects.dbref_search(home)
|
||||||
if hom and hasattr(hom,'dbobj'):
|
# if hom and hasattr(hom,'dbobj'):
|
||||||
hom = _GA(hom, "dbobj")
|
# hom = _GA(hom, "dbobj")
|
||||||
else:
|
# else:
|
||||||
hom = _GA(home, "dbobj")
|
# hom = _GA(home, "dbobj")
|
||||||
else:
|
# else:
|
||||||
hom = _GA(home, "dbobj")
|
# hom = _GA(home, "dbobj")
|
||||||
set_field_cache(self, "home", hom)
|
# set_field_cache(self, "home", hom)
|
||||||
except Exception:
|
# except Exception:
|
||||||
string = "Cannot set home: "
|
# string = "Cannot set home: "
|
||||||
string += "%s is not a valid home."
|
# string += "%s is not a valid home."
|
||||||
_GA(self, "msg")(_(string) % home)
|
# _GA(self, "msg")(_(string) % home)
|
||||||
logger.log_trace(string)
|
# logger.log_trace(string)
|
||||||
#raise
|
# #raise
|
||||||
#@home.deleter
|
##@home.deleter
|
||||||
def __home_del(self):
|
#def __home_del(self):
|
||||||
"Deleter. Allows for del self.home."
|
# "Deleter. Allows for del self.home."
|
||||||
_SA(self, "db_home", None)
|
# _SA(self, "db_home", None)
|
||||||
_GA(self, "save")()
|
# _GA(self, "save")()
|
||||||
del_field_cache(self, "home")
|
# del_field_cache(self, "home")
|
||||||
home = property(__home_get, __home_set, __home_del)
|
#home = property(__home_get, __home_set, __home_del)
|
||||||
|
|
||||||
# destination property (wraps db_destination)
|
# destination property (wraps db_destination)
|
||||||
#@property
|
#@property
|
||||||
def __destination_get(self):
|
#def __destination_get(self):
|
||||||
"Getter. Allows for value = self.destination."
|
# "Getter. Allows for value = self.destination."
|
||||||
dest = get_field_cache(self, "destination")
|
# dest = get_field_cache(self, "destination")
|
||||||
if dest:
|
# if dest:
|
||||||
return _GA(dest, "typeclass")
|
# return _GA(dest, "typeclass")
|
||||||
return None
|
# return None
|
||||||
#@destination.setter
|
##@destination.setter
|
||||||
def __destination_set(self, destination):
|
#def __destination_set(self, destination):
|
||||||
"Setter. Allows for self.destination = destination"
|
# "Setter. Allows for self.destination = destination"
|
||||||
try:
|
# try:
|
||||||
if destination == None or type(destination) == ObjectDB:
|
# if destination == None or type(destination) == ObjectDB:
|
||||||
# destination is None or a valid object
|
# # destination is None or a valid object
|
||||||
dest = destination
|
# dest = destination
|
||||||
elif ObjectDB.objects.dbref(destination):
|
# elif ObjectDB.objects.dbref(destination):
|
||||||
# destination is a dbref; search
|
# # destination is a dbref; search
|
||||||
dest = ObjectDB.objects.dbref_search(destination)
|
# dest = ObjectDB.objects.dbref_search(destination)
|
||||||
if dest and _GA(self, "_hasattr")(dest,'dbobj'):
|
# if dest and _GA(self, "_hasattr")(dest,'dbobj'):
|
||||||
dest = _GA(dest, "dbobj")
|
# dest = _GA(dest, "dbobj")
|
||||||
else:
|
# else:
|
||||||
dest = _GA(destination, "dbobj")
|
# dest = _GA(destination, "dbobj")
|
||||||
else:
|
# else:
|
||||||
dest = destination.dbobj
|
# dest = destination.dbobj
|
||||||
set_field_cache(self, "destination", dest)
|
# set_field_cache(self, "destination", dest)
|
||||||
except Exception:
|
# except Exception:
|
||||||
string = "Cannot set destination: "
|
# string = "Cannot set destination: "
|
||||||
string += "%s is not a valid destination." % destination
|
# string += "%s is not a valid destination." % destination
|
||||||
_GA(self, "msg")(string)
|
# _GA(self, "msg")(string)
|
||||||
logger.log_trace(string)
|
# logger.log_trace(string)
|
||||||
raise
|
# raise
|
||||||
#@destination.deleter
|
##@destination.deleter
|
||||||
def __destination_del(self):
|
#def __destination_del(self):
|
||||||
"Deleter. Allows for del self.destination"
|
# "Deleter. Allows for del self.destination"
|
||||||
_SA(self, "db_destination", None)
|
# _SA(self, "db_destination", None)
|
||||||
_GA(self, "save")()
|
# _GA(self, "save")()
|
||||||
del_field_cache(self, "destination")
|
# del_field_cache(self, "destination")
|
||||||
destination = property(__destination_get, __destination_set, __destination_del)
|
#destination = property(__destination_get, __destination_set, __destination_del)
|
||||||
|
|
||||||
# cmdset_storage property.
|
# cmdset_storage property.
|
||||||
# This seems very sensitive to caching, so leaving it be for now. /Griatch
|
# This seems very sensitive to caching, so leaving it be for now. /Griatch
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,11 @@ class PlayerForm(forms.ModelForm):
|
||||||
initial=settings.BASE_PLAYER_TYPECLASS,
|
initial=settings.BASE_PLAYER_TYPECLASS,
|
||||||
widget=forms.TextInput(attrs={'size':'78'}),
|
widget=forms.TextInput(attrs={'size':'78'}),
|
||||||
help_text="Required. Defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. Defaults to settings.BASE_PLAYER_TYPECLASS.")
|
help_text="Required. Defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. Defaults to settings.BASE_PLAYER_TYPECLASS.")
|
||||||
db_permissions = forms.CharField(label="Permissions",
|
#db_permissions = forms.CharField(label="Permissions",
|
||||||
initial=settings.PERMISSION_PLAYER_DEFAULT,
|
# initial=settings.PERMISSION_PLAYER_DEFAULT,
|
||||||
required=False,
|
# required=False,
|
||||||
widget=forms.TextInput(attrs={'size':'78'}),
|
# widget=forms.TextInput(attrs={'size':'78'}),
|
||||||
help_text="In-game permissions. A comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.")
|
# help_text="In-game permissions. A comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.")
|
||||||
db_lock_storage = forms.CharField(label="Locks",
|
db_lock_storage = forms.CharField(label="Locks",
|
||||||
widget=forms.Textarea(attrs={'cols':'100', 'rows':'2'}),
|
widget=forms.Textarea(attrs={'cols':'100', 'rows':'2'}),
|
||||||
required=False,
|
required=False,
|
||||||
|
|
@ -116,7 +116,8 @@ class PlayerInline(admin.StackedInline):
|
||||||
form = PlayerForm
|
form = PlayerForm
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
("In-game Permissions and Locks",
|
("In-game Permissions and Locks",
|
||||||
{'fields': ('db_permissions', 'db_lock_storage'),
|
{'fields': ('db_lock_storage',),
|
||||||
|
#{'fields': ('db_permissions', 'db_lock_storage'),
|
||||||
'description':"<i>These are permissions/locks for in-game use. They are unrelated to website access rights.</i>"}),
|
'description':"<i>These are permissions/locks for in-game use. They are unrelated to website access rights.</i>"}),
|
||||||
("In-game Player data",
|
("In-game Player data",
|
||||||
{'fields':('db_typeclass_path', 'db_cmdset_storage'),
|
{'fields':('db_typeclass_path', 'db_cmdset_storage'),
|
||||||
|
|
@ -140,8 +141,10 @@ class PlayerDBAdmin(BaseUserAdmin):
|
||||||
'description':'<i>Relevant only to the website.</i>'}),
|
'description':'<i>Relevant only to the website.</i>'}),
|
||||||
('Website Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions','groups'),
|
('Website Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions','groups'),
|
||||||
'description': "<i>These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights.</i>"}),
|
'description': "<i>These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights.</i>"}),
|
||||||
('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'),
|
('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_lock_storage'),
|
||||||
'description': '<i>These are attributes that are more relevant to gameplay.</i>'}))
|
'description': '<i>These are attributes that are more relevant to gameplay.</i>'}))
|
||||||
|
#('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'),
|
||||||
|
# 'description': '<i>These are attributes that are more relevant to gameplay.</i>'}))
|
||||||
|
|
||||||
|
|
||||||
add_fieldsets = (
|
add_fieldsets = (
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@ from django.db import models
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
from src.server.caches import get_field_cache, set_field_cache
|
|
||||||
|
|
||||||
from src.players import manager
|
from src.players import manager
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
||||||
|
|
@ -165,19 +163,19 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
||||||
|
|
||||||
#@property
|
##@property
|
||||||
def is_connected_get(self):
|
#def is_connected_get(self):
|
||||||
"Getter. Allows for value = self.is_connected"
|
# "Getter. Allows for value = self.is_connected"
|
||||||
return get_field_cache(self, "is_connected")
|
# return get_field_cache(self, "is_connected")
|
||||||
#@is_connected.setter
|
##@is_connected.setter
|
||||||
def is_connected_set(self, value):
|
#def is_connected_set(self, value):
|
||||||
"Setter. Allows for self.is_connected = value"
|
# "Setter. Allows for self.is_connected = value"
|
||||||
set_field_cache(self, "is_connected", value)
|
# set_field_cache(self, "is_connected", value)
|
||||||
#@is_connected.deleter
|
##@is_connected.deleter
|
||||||
def is_connected_del(self):
|
#def is_connected_del(self):
|
||||||
"Deleter. Allows for del is_connected"
|
# "Deleter. Allows for del is_connected"
|
||||||
set_field_cache(self, "is_connected", False)
|
# set_field_cache(self, "is_connected", False)
|
||||||
is_connected = property(is_connected_get, is_connected_set, is_connected_del)
|
#is_connected = property(is_connected_get, is_connected_set, is_connected_del)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ Central caching module.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from sys import getsizeof
|
||||||
import os, threading
|
import os, threading
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
@ -21,16 +22,9 @@ _IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread"
|
||||||
# Set up the cache stores
|
# Set up the cache stores
|
||||||
#
|
#
|
||||||
|
|
||||||
_FIELD_CACHE = {}
|
|
||||||
_ATTR_CACHE = {}
|
_ATTR_CACHE = {}
|
||||||
_PROP_CACHE = defaultdict(dict)
|
_PROP_CACHE = defaultdict(dict)
|
||||||
|
|
||||||
# OOB trackers
|
|
||||||
_TRACKED_FIELDS = {}
|
|
||||||
_TRACKED_ATTRS = {}
|
|
||||||
_TRACKED_CACHE = {}
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Cache key hash generation
|
# Cache key hash generation
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
@ -110,7 +104,7 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
||||||
if callable(handler):
|
if callable(handler):
|
||||||
#hid = hashid(instance, "-%s" % fieldname)
|
#hid = hashid(instance, "-%s" % fieldname)
|
||||||
try:
|
try:
|
||||||
old_value = _GA(instance, _GA(field, "get_cache_name")())#_FIELD_CACHE.get(hid) if hid else None
|
old_value = _GA(instance, _GA(field, "get_cache_name")())
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
old_value=None
|
old_value=None
|
||||||
# the handler may modify the stored value in various ways
|
# the handler may modify the stored value in various ways
|
||||||
|
|
@ -127,21 +121,6 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
||||||
|
|
||||||
def get_cache_sizes():
|
def get_cache_sizes():
|
||||||
return (0, 0), (0, 0), (0, 0)
|
return (0, 0), (0, 0), (0, 0)
|
||||||
def get_field_cache(obj, name):
|
|
||||||
return _GA(obj, "db_%s" % name)
|
|
||||||
def set_field_cache(obj, name, val):
|
|
||||||
_SA(obj, "db_%s" % name, val)
|
|
||||||
_GA(obj, "save")()
|
|
||||||
#hid = hashid(obj)
|
|
||||||
#if _OOB_FIELD_UPDATE_HOOKS[hid].get(name):
|
|
||||||
# _OOB_HANDLER.update(hid, name, val)
|
|
||||||
def del_field_cache(obj, name):
|
|
||||||
_SA(obj, "db_%s" % name, None)
|
|
||||||
_GA(obj, "save")()
|
|
||||||
#hid = hashid(obj)
|
|
||||||
#if _OOB_FIELD_UPDATE_HOOKS[hid].get(name):
|
|
||||||
# _OOB_HANDLER.update(hid, name, None)
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Attr cache - caching the attribute objects related to a given object to
|
# Attr cache - caching the attribute objects related to a given object to
|
||||||
|
|
@ -151,11 +130,10 @@ def del_field_cache(obj, name):
|
||||||
|
|
||||||
# connected to m2m_changed signal in respective model class
|
# connected to m2m_changed signal in respective model class
|
||||||
def post_attr_update(sender, **kwargs):
|
def post_attr_update(sender, **kwargs):
|
||||||
"Called when the many2many relation changes some way"
|
"Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
|
||||||
obj = kwargs['instance']
|
obj = kwargs['instance']
|
||||||
model = kwargs['model']
|
model = kwargs['model']
|
||||||
action = kwargs['action']
|
action = kwargs['action']
|
||||||
#print "update_attr_cache:", obj, model, action
|
|
||||||
if kwargs['reverse']:
|
if kwargs['reverse']:
|
||||||
# the reverse relation changed (the Attribute itself was acted on)
|
# the reverse relation changed (the Attribute itself was acted on)
|
||||||
pass
|
pass
|
||||||
|
|
@ -183,7 +161,7 @@ def post_attr_update(sender, **kwargs):
|
||||||
def get_attr_cache(obj, attrname):
|
def get_attr_cache(obj, attrname):
|
||||||
"Called by getting attribute"
|
"Called by getting attribute"
|
||||||
hid = hashid(obj, "-%s" % attrname)
|
hid = hashid(obj, "-%s" % attrname)
|
||||||
return hid and _ATTR_CACHE.get(hid, None) or None
|
return _ATTR_CACHE.get(hid, None)
|
||||||
|
|
||||||
def set_attr_cache(obj, attrname, attrobj):
|
def set_attr_cache(obj, attrname, attrobj):
|
||||||
"Set the attr cache manually; this can be used to update"
|
"Set the attr cache manually; this can be used to update"
|
||||||
|
|
@ -217,28 +195,20 @@ def clear_obj_attr_cache(obj):
|
||||||
def get_prop_cache(obj, propname):
|
def get_prop_cache(obj, propname):
|
||||||
"retrieve data from cache"
|
"retrieve data from cache"
|
||||||
hid = hashid(obj, "-%s" % propname)
|
hid = hashid(obj, "-%s" % propname)
|
||||||
if hid:
|
return _PROP_CACHE[hid].get(propname, None) if hid else None
|
||||||
#print "get_prop_cache", hid, propname, _PROP_CACHE.get(hid, None)
|
|
||||||
return _PROP_CACHE[hid].get(propname, None)
|
|
||||||
|
|
||||||
def set_prop_cache(obj, propname, propvalue):
|
def set_prop_cache(obj, propname, propvalue):
|
||||||
"Set property cache"
|
"Set property cache"
|
||||||
hid = hashid(obj, "-%s" % propname)
|
hid = hashid(obj, "-%s" % propname)
|
||||||
if obj and hasattr(obj, "oobhandler"):
|
|
||||||
obj.oobhandler.update(propname, _GA(obj, propname), propvalue, type="property", action="set")
|
|
||||||
if hid:
|
if hid:
|
||||||
#print "set_prop_cache", propname, propvalue
|
|
||||||
_PROP_CACHE[hid][propname] = propvalue
|
_PROP_CACHE[hid][propname] = propvalue
|
||||||
#_PROP_CACHE.set(hid, propvalue)
|
|
||||||
|
|
||||||
def del_prop_cache(obj, propname):
|
def del_prop_cache(obj, propname):
|
||||||
"Delete element from property cache"
|
"Delete element from property cache"
|
||||||
hid = hashid(obj, "-%s" % propname)
|
hid = hashid(obj, "-%s" % propname)
|
||||||
if obj and hasattr(obj, "oobhandler"):
|
if hid:
|
||||||
obj.oobhandler.update(propname, _GA(obj, propname), None, type="property", action="delete")
|
if propname in _PROP_CACHE[hid]:
|
||||||
if hid and propname in _PROP_CACHE[hid]:
|
del _PROP_CACHE[hid][propname]
|
||||||
del _PROP_CACHE[hid][propname]
|
|
||||||
#_PROP_CACHE.delete(hid)
|
|
||||||
|
|
||||||
def flush_prop_cache():
|
def flush_prop_cache():
|
||||||
"Clear property cache"
|
"Clear property cache"
|
||||||
|
|
@ -246,84 +216,17 @@ def flush_prop_cache():
|
||||||
_PROP_CACHE = defaultdict(dict)
|
_PROP_CACHE = defaultdict(dict)
|
||||||
#_PROP_CACHE.clear()
|
#_PROP_CACHE.clear()
|
||||||
|
|
||||||
|
def get_cache_sizes():
|
||||||
|
"""
|
||||||
|
Get cache sizes, expressed in number of objects and memory size in MB
|
||||||
|
"""
|
||||||
|
global _ATTR_CACHE, _PROP_CACHE
|
||||||
|
attr_n = len(_ATTR_CACHE)
|
||||||
|
attr_mb = sum(getsizeof(obj) for obj in _ATTR_CACHE) / 1024.0
|
||||||
|
field_n = 0 #sum(len(dic) for dic in _FIELD_CACHE.values())
|
||||||
|
field_mb = 0 # sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _FIELD_CACHE.values()) / 1024.0
|
||||||
|
prop_n = sum(len(dic) for dic in _PROP_CACHE.values())
|
||||||
|
prop_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _PROP_CACHE.values()) / 1024.0
|
||||||
|
return (attr_n, attr_mb), (field_n, field_mb), (prop_n, prop_mb)
|
||||||
|
|
||||||
|
|
||||||
#_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE
|
|
||||||
## oob helper functions
|
|
||||||
# OOB hooks (OOB not yet functional, don't use yet)
|
|
||||||
#_OOB_FIELD_UPDATE_HOOKS = defaultdict(dict)
|
|
||||||
#_OOB_PROP_UPDATE_HOOKS = defaultdict(dict)
|
|
||||||
#_OOB_ATTR_UPDATE_HOOKS = defaultdict(dict)
|
|
||||||
#_OOB_NDB_UPDATE_HOOKS = defaultdict(dict)
|
|
||||||
#_OOB_CUSTOM_UPDATE_HOOKS = defaultdict(dict)
|
|
||||||
#
|
|
||||||
#_OOB_HANDLER = None # set by oob handler when it initializes
|
|
||||||
#def register_oob_update_hook(obj,name, entity="field"):
|
|
||||||
# """
|
|
||||||
# Register hook function to be called when field/property/db/ndb is updated.
|
|
||||||
# Given function will be called with function(obj, entityname, newvalue, *args, **kwargs)
|
|
||||||
# entity - one of "field", "property", "db", "ndb" or "custom"
|
|
||||||
# """
|
|
||||||
# hid = hashid(obj)
|
|
||||||
# if hid:
|
|
||||||
# if entity == "field":
|
|
||||||
# global _OOB_FIELD_UPDATE_HOOKS
|
|
||||||
# _OOB_FIELD_UPDATE_HOOKS[hid][name] = True
|
|
||||||
# return
|
|
||||||
# elif entity == "property":
|
|
||||||
# global _OOB_PROP_UPDATE_HOOKS
|
|
||||||
# _OOB_PROP_UPDATE_HOOKS[hid][name] = True
|
|
||||||
# elif entity == "db":
|
|
||||||
# global _OOB_ATTR_UPDATE_HOOKS
|
|
||||||
# _OOB_ATTR_UPDATE_HOOKS[hid][name] = True
|
|
||||||
# elif entity == "ndb":
|
|
||||||
# global _OOB_NDB_UPDATE_HOOKS
|
|
||||||
# _OOB_NDB_UPDATE_HOOKS[hid][name] = True
|
|
||||||
# elif entity == "custom":
|
|
||||||
# global _OOB_CUSTOM_UPDATE_HOOKS
|
|
||||||
# _OOB_CUSTOM_UPDATE_HOOKS[hid][name] = True
|
|
||||||
# else:
|
|
||||||
# return None
|
|
||||||
#
|
|
||||||
#def unregister_oob_update_hook(obj, name, entity="property"):
|
|
||||||
# """
|
|
||||||
# Un-register a report hook
|
|
||||||
# """
|
|
||||||
# hid = hashid(obj)
|
|
||||||
# if hid:
|
|
||||||
# global _OOB_FIELD_UPDATE_HOOKS,_OOB_PROP_UPDATE_HOOKS, _OOB_ATTR_UPDATE_HOOKS
|
|
||||||
# global _OOB_CUSTOM_UPDATE_HOOKS, _OOB_NDB_UPDATE_HOOKS
|
|
||||||
# if entity == "field" and name in _OOB_FIELD_UPDATE_HOOKS:
|
|
||||||
# del _OOB_FIELD_UPDATE_HOOKS[hid][name]
|
|
||||||
# elif entity == "property" and name in _OOB_PROP_UPDATE_HOOKS:
|
|
||||||
# del _OOB_PROP_UPDATE_HOOKS[hid][name]
|
|
||||||
# elif entity == "db" and name in _OOB_ATTR_UPDATE_HOOKS:
|
|
||||||
# del _OOB_ATTR_UPDATE_HOOKS[hid][name]
|
|
||||||
# elif entity == "ndb" and name in _OOB_NDB_UPDATE_HOOKS:
|
|
||||||
# del _OOB_NDB_UPDATE_HOOKS[hid][name]
|
|
||||||
# elif entity == "custom" and name in _OOB_CUSTOM_UPDATE_HOOKS:
|
|
||||||
# del _OOB_CUSTOM_UPDATE_HOOKS[hid][name]
|
|
||||||
# else:
|
|
||||||
# return None
|
|
||||||
#
|
|
||||||
#def call_ndb_hooks(obj, attrname, value):
|
|
||||||
# """
|
|
||||||
# No caching is done of ndb here, but
|
|
||||||
# we use this as a way to call OOB hooks.
|
|
||||||
# """
|
|
||||||
# hid = hashid(obj)
|
|
||||||
# if hid:
|
|
||||||
# oob_hook = _OOB_NDB_UPDATE_HOOKS[hid].get(attrname)
|
|
||||||
# if oob_hook:
|
|
||||||
# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2])
|
|
||||||
#
|
|
||||||
#def call_custom_hooks(obj, attrname, value):
|
|
||||||
# """
|
|
||||||
# Custom handler for developers adding their own oob hooks, e.g. to
|
|
||||||
# custom typeclass properties.
|
|
||||||
# """
|
|
||||||
# hid = hashid(obj)
|
|
||||||
# if hid:
|
|
||||||
# oob_hook = _OOB_CUSTOM_UPDATE_HOOKS[hid].get(attrname)
|
|
||||||
# if oob_hook:
|
|
||||||
# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2])
|
|
||||||
#
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
return [sess for sess in self.get_sessions(include_unloggedin=True)
|
return [sess for sess in self.get_sessions(include_unloggedin=True)
|
||||||
if hasattr(sess, 'suid') and sess.suid == suid]
|
if hasattr(sess, 'suid') and sess.suid == suid]
|
||||||
|
|
||||||
def data_in(self, session, string="", **kwargs):
|
def data_in(self, session, text="", **kwargs):
|
||||||
"""
|
"""
|
||||||
Called by portal sessions for relaying data coming
|
Called by portal sessions for relaying data coming
|
||||||
in from the protocol to the server. data is
|
in from the protocol to the server. data is
|
||||||
|
|
@ -129,7 +129,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
#print "portal_data_in:", string
|
#print "portal_data_in:", string
|
||||||
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
||||||
msg=string,
|
msg=text,
|
||||||
data=kwargs)
|
data=kwargs)
|
||||||
def announce_all(self, message):
|
def announce_all(self, message):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,9 @@ class WebClient(resource.Resource):
|
||||||
sess = self.sessionhandler.session_from_suid(suid)
|
sess = self.sessionhandler.session_from_suid(suid)
|
||||||
if sess:
|
if sess:
|
||||||
sess = sess[0]
|
sess = sess[0]
|
||||||
string = request.args.get('msg', [''])[0]
|
text = request.args.get('msg', [''])[0]
|
||||||
data = request.args.get('data', [None])[0]
|
data = request.args.get('data', [None])[0]
|
||||||
sess.sessionhandler.data_in(sess, string, data)
|
sess.sessionhandler.data_in(sess, text, data=data)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def mode_receive(self, request):
|
def mode_receive(self, request):
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ from django.db.models.signals import pre_save
|
||||||
from src.server.caches import field_pre_save
|
from src.server.caches import field_pre_save
|
||||||
pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
||||||
|
|
||||||
|
from django.db.models.signals import m2m_changed
|
||||||
|
from src.typeclasses.models import TypedObject
|
||||||
|
from src.server.caches import post_attr_update
|
||||||
|
# connect to attribute cache signal
|
||||||
|
m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
|
||||||
|
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ from django.db.models import Q
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
|
|
||||||
from src.utils.idmapper.models import SharedMemoryModel
|
from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
|
||||||
from src.server.caches import get_attr_cache, del_attr_cache, set_attr_cache
|
from src.server.caches import get_attr_cache, del_attr_cache, set_attr_cache
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache, flush_attr_cache
|
from src.server.caches import get_prop_cache, set_prop_cache, flush_attr_cache
|
||||||
from src.server.caches import post_attr_update
|
from src.server.caches import post_attr_update
|
||||||
|
|
@ -363,7 +362,7 @@ class AttributeHandler(object):
|
||||||
if attr_obj.count():
|
if attr_obj.count():
|
||||||
# re-use old attribute object
|
# re-use old attribute object
|
||||||
attr_obj = attr_obj[0]
|
attr_obj = attr_obj[0]
|
||||||
set_attr_cache(self.obj, key, attr_obj) # renew cache
|
#set_attr_cache(self.obj, key, attr_obj) # renew cache
|
||||||
else:
|
else:
|
||||||
# no old attr available; create new (caches automatically)
|
# no old attr available; create new (caches automatically)
|
||||||
attr_obj = Attribute(db_key=key, db_category=category)
|
attr_obj = Attribute(db_key=key, db_category=category)
|
||||||
|
|
@ -1423,5 +1422,3 @@ class TypedObject(SharedMemoryModel):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# connect to attribute cache signal
|
|
||||||
m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ _GA = object.__getattribute__
|
||||||
|
|
||||||
def create_object(typeclass, key=None, location=None,
|
def create_object(typeclass, key=None, location=None,
|
||||||
home=None, permissions=None, locks=None,
|
home=None, permissions=None, locks=None,
|
||||||
aliases=None, destination=None, report_to=None):
|
aliases=None, destination=None, report_to=None, testmode=False):
|
||||||
"""
|
"""
|
||||||
Create a new in-game object. Any game object is a combination
|
Create a new in-game object. Any game object is a combination
|
||||||
of a database object that stores data persistently to
|
of a database object that stores data persistently to
|
||||||
|
|
@ -69,6 +69,7 @@ def create_object(typeclass, key=None, location=None,
|
||||||
If report_to is not set, errors will be raised as en Exception
|
If report_to is not set, errors will be raised as en Exception
|
||||||
containing the error message. If set, this method will return
|
containing the error message. If set, this method will return
|
||||||
None upon errors.
|
None upon errors.
|
||||||
|
testmode is only intended for Evennia unittest system
|
||||||
"""
|
"""
|
||||||
global _Object, _ObjectDB
|
global _Object, _ObjectDB
|
||||||
if not _Object:
|
if not _Object:
|
||||||
|
|
@ -134,6 +135,9 @@ def create_object(typeclass, key=None, location=None,
|
||||||
# perform a move_to in order to display eventual messages.
|
# perform a move_to in order to display eventual messages.
|
||||||
if home:
|
if home:
|
||||||
new_object.home = home
|
new_object.home = home
|
||||||
|
elif testmode:
|
||||||
|
# this is required by unittest
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
new_object.home = settings.CHARACTER_DEFAULT_HOME
|
new_object.home = settings.CHARACTER_DEFAULT_HOME
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue