Attribute cache is working, lots of other updates, but still not a cleanly updatable system. It seems the Attribute-migrations are not coming through properly. Fixed a misnamed table in the comm app.

This commit is contained in:
Griatch 2013-07-11 09:51:52 +02:00
parent 033344ad2c
commit 2b332c3b9a
16 changed files with 229 additions and 179 deletions

3
ev.py
View file

@ -116,9 +116,10 @@ README = __doc__
# help entries # help entries
from src.help.models import HelpEntry from src.help.models import HelpEntry
from src.typeclasses.models import Attribute
# players # players
from src.players.player import Player from src.players.player import Player
from src.players.models import PlayerDB, PlayerAttribute, PlayerNick from src.players.models import PlayerDB, PlayerNick
# commands # commands
from src.commands.command import Command from src.commands.command import Command

View file

@ -4,8 +4,7 @@ Building and world design commands
""" """
from django.conf import settings from django.conf import settings
from src.objects.models import ObjectDB, ObjAttribute from src.objects.models import ObjectDB
from src.players.models import PlayerAttribute
from src.utils import create, utils from src.utils import create, utils
from src.utils.ansi import raw from src.utils.ansi import raw
from src.commands.default.muxcommand import MuxCommand from src.commands.default.muxcommand import MuxCommand
@ -1545,10 +1544,7 @@ class CmdExamine(ObjManipCommand):
except Exception: except Exception:
ndb_attr = None ndb_attr = None
else: else:
if self.player_mode: db_attr = [(attr.key, attr.value) for attr in obj.db_attributes.all()]
db_attr = [(attr.key, attr.value) for attr in PlayerAttribute.objects.filter(db_obj=obj)]
else:
db_attr = [(attr.key, attr.value) for attr in ObjAttribute.objects.filter(db_obj=obj)]
try: try:
ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items() if not aname.startswith("_")] ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items() if not aname.startswith("_")]
except Exception: except Exception:

View file

@ -0,0 +1,135 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Renaming M2M table for field db_hide_from_channles on 'Msg'
db.rename_table('comms_msg_db_hide_from_channles', 'comms_msg_db_hide_from_channels')
def backwards(self, orm):
raise RuntimeException("Cannot revert this migration.")
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'comms.channel': {
'Meta': {'object_name': 'Channel'},
'db_aliases': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'db_desc': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'db_keep_log': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'comms.externalchannelconnection': {
'Meta': {'object_name': 'ExternalChannelConnection'},
'db_channel': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['comms.Channel']"}),
'db_external_config': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_external_key': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'db_external_send_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_is_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'comms.msg': {
'Meta': {'object_name': 'Msg'},
'db_date_sent': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'db_header': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'db_hide_from_channels': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_channels_set'", 'null': 'True', 'to': u"orm['comms.Channel']"}),
'db_hide_from_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_objects_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_hide_from_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_players_set'", 'null': 'True', 'to': u"orm['players.PlayerDB']"}),
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_message': ('django.db.models.fields.TextField', [], {}),
'db_receivers_channels': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'channel_set'", 'null': 'True', 'to': u"orm['comms.Channel']"}),
'db_receivers_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_object_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_receivers_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_player_set'", 'null': 'True', 'to': u"orm['players.PlayerDB']"}),
'db_sender_external': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'db_sender_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_object_set'", 'null': 'True', 'db_index': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_sender_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_player_set'", 'null': 'True', 'db_index': 'True', 'to': u"orm['players.PlayerDB']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'comms.playerchannelconnection': {
'Meta': {'object_name': 'PlayerChannelConnection'},
'db_channel': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['comms.Channel']"}),
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'objects.objectdb': {
'Meta': {'object_name': 'ObjectDB'},
'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}),
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}),
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'players.playerdb': {
'Meta': {'object_name': 'PlayerDB'},
'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}),
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
},
u'typeclasses.attribute': {
'Meta': {'object_name': 'Attribute'},
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['comms']

View file

@ -88,7 +88,7 @@ class Msg(SharedMemoryModel):
# these can be used to filter/hide a given message from supplied objects/players/channels # these can be used to filter/hide a given message from supplied objects/players/channels
db_hide_from_players = models.ManyToManyField("players.PlayerDB", related_name='hide_from_players_set', null=True) db_hide_from_players = models.ManyToManyField("players.PlayerDB", related_name='hide_from_players_set', null=True)
db_hide_from_objects = models.ManyToManyField("objects.ObjectDB", related_name='hide_from_objects_set', null=True) db_hide_from_objects = models.ManyToManyField("objects.ObjectDB", related_name='hide_from_objects_set', null=True)
db_hide_from_channles = models.ManyToManyField("Channel", related_name='hide_from_channels_set', null=True) db_hide_from_channels = models.ManyToManyField("Channel", related_name='hide_from_channels_set', null=True)
# Database manager # Database manager
objects = managers.MsgManager() objects = managers.MsgManager()

View file

@ -134,7 +134,7 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
permission is also granted to all ranks higher up in the hierarchy. permission is also granted to all ranks higher up in the hierarchy.
If accessing_object is an Object controlled by a Player, the If accessing_object is an Object controlled by a Player, the
permissions of the Player is used unless the PlayerAttribute _quell permissions of the Player is used unless the Attribute _quell
is set to True on the Object. In this case however, the is set to True on the Object. In this case however, the
LOWEST hieararcy-permission of the Player/Object-pair will be used LOWEST hieararcy-permission of the Player/Object-pair will be used
(this is order to avoid Players potentially escalating their own permissions (this is order to avoid Players potentially escalating their own permissions

View file

@ -6,12 +6,13 @@
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.objects.models import ObjAttribute, ObjectDB, ObjectNick, Alias from src.typeclases.models import Attribute
from src.objects.models import ObjectDB, ObjectNick, Alias
from src.utils.utils import mod_import from src.utils.utils import mod_import
class ObjAttributeInline(admin.TabularInline): class AttributeInline(admin.TabularInline):
model = ObjAttribute model = Attribute
fields = ('db_key', 'db_value') fields = ('db_key', 'db_value')
extra = 0 extra = 0
@ -80,7 +81,7 @@ class ObjectDBAdmin(admin.ModelAdmin):
) )
#deactivated temporarily, they cause empty objects to be created in admin #deactivated temporarily, they cause empty objects to be created in admin
#inlines = [AliasInline, ObjAttributeInline] #inlines = [AliasInline, AttributeInline]
# Custom modification to give two different forms wether adding or not. # Custom modification to give two different forms wether adding or not.

View file

@ -13,7 +13,7 @@ __all__ = ("ObjectManager",)
_GA = object.__getattribute__ _GA = object.__getattribute__
# delayed import # delayed import
_OBJATTR = None _ATTR = None
# Try to use a custom way to parse id-tagged multimatches. # Try to use a custom way to parse id-tagged multimatches.
@ -139,15 +139,16 @@ class ObjectManager(TypedObjectManager):
#q = self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name) & Q(objattribute__db_value=attribute_value)) #q = self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name) & Q(objattribute__db_value=attribute_value))
#return list(q) #return list(q)
if isinstance(attribute_value, (basestring, int, float, bool, long)): #if isinstance(attribute_value, (basestring, int, float, bool, long)):
return self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name, objattribute__db_value=attribute_value)) return self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name, db_attributes__db_value=attribute_value))
else: #else:
# We have to loop for safety since the referenced lookup gives deepcopy error if attribute value is an object. # # We have to loop for safety since the referenced lookup gives deepcopy error if attribute value is an object.
global _OBJATTR # global _ATTR
if not _OBJATTR: # if not _ATTR:
from src.objects.models import ObjAttribute as _OBJATTR # from src.typeclasses.models import Attribute as _ATTR
cands = list(self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name))) # cands = list(self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name)))
return [_GA(attr, "db_obj") for attr in _OBJATTR.objects.filter(db_obj__in=cands, db_value=attribute_value)] # return [_ATTR.
# return [_GA(attr, "db_obj") for attr in _OBJATTR.objects.filter(db_obj__in=cands, db_value=attribute_value)]
@returns_typeclass_list @returns_typeclass_list
def get_objs_with_db_property(self, property_name, candidates=None): def get_objs_with_db_property(self, property_name, candidates=None):

View file

@ -17,7 +17,6 @@ transparently through the decorating TypeClass.
import traceback import traceback
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.db.models.signals import m2m_changed
from src.utils.idmapper.models import SharedMemoryModel from src.utils.idmapper.models import SharedMemoryModel
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
@ -49,26 +48,6 @@ _ME = _("me")
_SELF = _("self") _SELF = _("self")
_HERE = _("here") _HERE = _("here")
#------------------------------------------------------------
#
# ObjAttribute
#
#------------------------------------------------------------
#class ObjAttribute(Attribute):
# "Attributes for ObjectDB objects."
# db_obj = models.ForeignKey("ObjectDB")
#
# class Meta:
# "Define Django meta options"
# verbose_name = "Object Attribute"
# verbose_name_plural = "Object Attributes"
#
# attach the cache handlers
#post_init.connect(attr_post_init, sender=ObjAttribute, dispatch_uid="objattrcache")
#pre_delete.connect(attr_pre_delete, sender=ObjAttribute, dispatch_uid="objattrcache")
#------------------------------------------------------------ #------------------------------------------------------------
# #
# Alias # Alias

View file

@ -34,19 +34,20 @@ class TestObjAttrs(TestCase):
""" """
Test aspects of ObjAttributes Test aspects of ObjAttributes
""" """
def setUp(self): pass
"set up the test" # def setUp(self):
self.attr = models.ObjAttribute() # "set up the test"
self.obj1 = create.create_object(objects.Object, key="testobj1", location=None) # self.attr = models.ObjAttribute()
self.obj2 = create.create_object(objects.Object, key="testobj2", location=self.obj1) # self.obj1 = create.create_object(objects.Object, key="testobj1", location=None)
def test_store_str(self): # self.obj2 = create.create_object(objects.Object, key="testobj2", location=self.obj1)
hstring = u"sdfv00=97sfjs842 ivfjlQKFos9GF^8dddsöäå-?%" # def test_store_str(self):
self.obj1.db.testattr = hstring # hstring = u"sdfv00=97sfjs842 ivfjlQKFos9GF^8dddsöäå-?%"
self.assertEqual(hstring, self.obj1.db.testattr) # self.obj1.db.testattr = hstring
def test_store_obj(self): # self.assertEqual(hstring, self.obj1.db.testattr)
self.obj1.db.testattr = self.obj2 # def test_store_obj(self):
self.assertEqual(self.obj2 ,self.obj1.db.testattr) # self.obj1.db.testattr = self.obj2
self.assertEqual(self.obj2.location, self.obj1.db.testattr.location) # self.assertEqual(self.obj2 ,self.obj1.db.testattr)
# self.assertEqual(self.obj2.location, self.obj1.db.testattr.location)
def suite(): def suite():
""" """

View file

@ -11,7 +11,8 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.admin import widgets from django.contrib.admin import widgets
from django.contrib.auth.forms import UserChangeForm, UserCreationForm from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from src.players.models import PlayerDB, PlayerAttribute from src.players.models import PlayerDB
from src.typeclasses.models import Attribute
from src.utils import logger, create from src.utils import logger, create
# remove User itself from admin site # remove User itself from admin site
@ -49,20 +50,20 @@ class CustomUserCreationForm(UserCreationForm):
# # The Player editor # # The Player editor
# class PlayerAttributeForm(forms.ModelForm): # class AttributeForm(forms.ModelForm):
# "Defines how to display the atttributes" # "Defines how to display the atttributes"
# class Meta: # class Meta:
# model = PlayerAttribute # model = Attribute
# db_key = forms.CharField(label="Key", # db_key = forms.CharField(label="Key",
# widget=forms.TextInput(attrs={'size':'15'})) # widget=forms.TextInput(attrs={'size':'15'}))
# db_value = forms.CharField(label="Value", # db_value = forms.CharField(label="Value",
# widget=forms.Textarea(attrs={'rows':'2'})) # widget=forms.Textarea(attrs={'rows':'2'}))
# class PlayerAttributeInline(admin.TabularInline): # class AttributeInline(admin.TabularInline):
# "Inline creation of player attributes" # "Inline creation of player attributes"
# model = PlayerAttribute # model = Attribute
# extra = 0 # extra = 0
# form = PlayerAttributeForm # form = AttributeForm
# fieldsets = ( # fieldsets = (
# (None, {'fields' : (('db_key', 'db_value'))}),) # (None, {'fields' : (('db_key', 'db_value'))}),)

View file

@ -58,26 +58,6 @@ _DA = object.__delattr__
_TYPECLASS = None _TYPECLASS = None
#------------------------------------------------------------
#
# PlayerAttribute
#
#------------------------------------------------------------
#class PlayerAttribute(Attribute):
# """
# PlayerAttributes work the same way as Attributes on game objects,
# but are intended to store OOC information specific to each user
# and game (example would be configurations etc).
# """
# db_obj = models.ForeignKey("PlayerDB")
#
# class Meta:
# "Define Django meta options"
# verbose_name = "Player Attribute"
#
#post_init.connect(attr_post_init, sender=PlayerAttribute, dispatch_uid="playerattrcache")
#pre_delete.connect(attr_pre_delete, sender=PlayerAttribute, dispatch_uid="playerattrcache")
#------------------------------------------------------------ #------------------------------------------------------------
# #

View file

@ -3,11 +3,12 @@
# in the web admin interface. # in the web admin interface.
# #
from src.scripts.models import ScriptAttribute, ScriptDB from src.typeclasses.models import Attribute
from src.scripts.models import ScriptDB
from django.contrib import admin from django.contrib import admin
class ScriptAttributeInline(admin.TabularInline): class AttributeInline(admin.TabularInline):
model = ScriptAttribute model = Attribute
fields = ('db_key', 'db_value') fields = ('db_key', 'db_value')
max_num = 1 max_num = 1
@ -25,7 +26,7 @@ class ScriptDBAdmin(admin.ModelAdmin):
(None, { (None, {
'fields':(('db_key', 'db_typeclass_path'), 'db_interval', 'db_repeats', 'db_start_delay', 'db_persistent', 'db_obj')}), 'fields':(('db_key', 'db_typeclass_path'), 'db_interval', 'db_repeats', 'db_start_delay', 'db_persistent', 'db_obj')}),
) )
#inlines = [ScriptAttributeInline] #inlines = [AttributeInline]
admin.site.register(ScriptDB, ScriptDBAdmin) admin.site.register(ScriptDB, ScriptDBAdmin)

View file

@ -34,24 +34,6 @@ from src.scripts.manager import ScriptManager
__all__ = ("ScriptDB",) __all__ = ("ScriptDB",)
#------------------------------------------------------------
#
# ScriptAttribute
#
#------------------------------------------------------------
#class ScriptAttribute(Attribute):
# "Attributes for ScriptDB objects."
# db_obj = models.ForeignKey("ScriptDB", verbose_name='script')
#
# class Meta:
# "Define Django meta options"
# verbose_name = "Script Attribute"
# verbose_name_plural = "Script Attributes"
#
## attach cache handlers for attribute lookup
#post_init.connect(attr_post_init, sender=ScriptAttribute, dispatch_uid="scriptattrcache")
#pre_delete.connect(attr_pre_delete, sender=ScriptAttribute, dispatch_uid="scriptattrcache")
#------------------------------------------------------------ #------------------------------------------------------------
# #

View file

@ -5,7 +5,7 @@ Central caching module.
import os, threading import os, threading
from collections import defaultdict from collections import defaultdict
from django.dispatch import Signal
from django.core.cache import get_cache from django.core.cache import get_cache
from src.server.models import ServerConfig from src.server.models import ServerConfig
from src.utils.utils import uses_database, to_str, get_evennia_pids from src.utils.utils import uses_database, to_str, get_evennia_pids
@ -84,16 +84,18 @@ def hashid(obj, suffix=""):
def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwargs): def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwargs):
""" """
Called at the beginning of the save operation. The save method Called at the beginning of the save operation. The save method
must be called with the update_fields keyword in order to must be called with the update_fields keyword in order to be most efficient.
This method should NOT save; rather it is the save() that triggers this function.
Its main purpose is to allow to plug-in a save handler.
""" """
if raw: if raw:
return return
print "field_pre_save:", _GA(instance, "db_key"), update_fields# if hasattr(instance, "db_key") else instance, update_fields print "field_pre_save:", instance, update_fields# if hasattr(instance, "db_key") else instance, update_fields
if update_fields: if update_fields:
# this is a list of strings at this point. We want field objects # this is a list of strings at this point. We want field objects
update_fields = (_GA(_GA(instance, "_meta"), "get_field_by_name")(field)[0] for field in update_fields) update_fields = (_GA(_GA(instance, "_meta"), "get_field_by_name")(field)[0] for field in update_fields)
else: else:
# meta.fields are already field objects # meta.fields are already field objects; get them all
update_fields = _GA(_GA(instance, "_meta"), "fields") update_fields = _GA(_GA(instance, "_meta"), "fields")
for field in update_fields: for field in update_fields:
fieldname = field.name fieldname = field.name
@ -116,7 +118,7 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
_SA(instance, fieldname, new_value) _SA(instance, fieldname, new_value)
#if hid: #if hid:
# # update cache # # update cache
# _FIELD_CACHE.set(hid, new_value) # _FIELD_CACHE[hid] = new_value
# access method # access method
# #
@ -134,6 +136,23 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
# "Clear the field cache" # "Clear the field cache"
# _FIELD_CACHE.clear() # _FIELD_CACHE.clear()
def get_cache_sizes():
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
@ -142,11 +161,12 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
#------------------------------------------------------------ #------------------------------------------------------------
# connected to m2m_changed signal in respective model class # connected to m2m_changed signal in respective model class
def update_attr_cache(sender, **kwargs): def post_attr_update(sender, **kwargs):
"Called when the many2many relation changes some way" "Called when the many2many relation changes some way"
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
@ -499,22 +519,6 @@ def flush_prop_cache():
#else: #else:
# local caches disabled. Use simple pass-through replacements # local caches disabled. Use simple pass-through replacements
def get_cache_sizes():
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)
#def flush_field_cache(obj=None): #def flush_field_cache(obj=None):
# pass # pass
# these should get oob handlers when oob is implemented. # these should get oob handlers when oob is implemented.
@ -531,7 +535,7 @@ def del_field_cache(obj, name):
#def set_attr_cache(obj, attrname, attrobj): #def set_attr_cache(obj, attrname, attrobj):
# pass # pass
#def del_attr_cache(obj, attrname): #def del_attr_cache(obj, attrname):
# passk # pass
#def flush_attr_cache(obj=None): #def flush_attr_cache(obj=None):
# pass # pass

View file

@ -156,7 +156,7 @@ class Evennia(object):
#from src.players.models import PlayerDB #from src.players.models import PlayerDB
for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches): for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches):
# update the database # update the database
print " one or more default cmdset/typeclass settings changed. Updating defaults stored in database ..." print " %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..." % (settings_names[i], prev, curr)
if i == 0: [obj.__setattr__("cmdset_storage", curr) for obj in ObjectDB.objects.filter(db_cmdset_storage__exact=prev)] if i == 0: [obj.__setattr__("cmdset_storage", curr) for obj in ObjectDB.objects.filter(db_cmdset_storage__exact=prev)]
if i == 1: [ply.__setattr__("cmdset_storage", curr) for ply in PlayerDB.objects.filter(db_cmdset_storage__exact=prev)] if i == 1: [ply.__setattr__("cmdset_storage", curr) for ply in PlayerDB.objects.filter(db_cmdset_storage__exact=prev)]
if i == 2: [ply.__setattr__("typeclass_path", curr) for ply in PlayerDB.objects.filter(db_typeclass_path__exact=prev)] if i == 2: [ply.__setattr__("typeclass_path", curr) for ply in PlayerDB.objects.filter(db_typeclass_path__exact=prev)]

View file

@ -44,7 +44,7 @@ from src.server.caches import get_attr_cache, set_attr_cache
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache, flush_attr_cache from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache, flush_attr_cache
from django.db.models.signals import m2m_changed from django.db.models.signals import m2m_changed
from src.server.caches import update_attr_cache from src.server.caches import post_attr_update
#from src.server.caches import call_ndb_hooks #from src.server.caches import call_ndb_hooks
from src.server.models import ServerConfig from src.server.models import ServerConfig
@ -999,22 +999,6 @@ class TypedObject(SharedMemoryModel):
set_attr_cache(self, attribute_name, attr_obj) set_attr_cache(self, attribute_name, attr_obj)
return attr_obj.value return attr_obj.value
# def get_attribute_raise(self, attribute_name):
# """
# Returns value of an attribute. Raises AttributeError
# if no match is found.
#
# attribute_name: (str) The attribute's name.
# """
# attr_obj = get_attr_cache(self, attribute_name)
# if not attr_obj:
# attr_obj = _GA(self, "attributes").filter(db_key__iexact=attribute_name)
# if not attr_obj:
# raise AttributeError
# attr_obj = attrib_obj[0] # query is evaluated here
# set_attr_cache(self, attribute_name, attr_obj[0])
# return attr_obj.value
def del_attribute(self, attribute_name, raise_exception=False): def del_attribute(self, attribute_name, raise_exception=False):
""" """
Removes an attribute entirely. Removes an attribute entirely.
@ -1024,32 +1008,16 @@ class TypedObject(SharedMemoryModel):
could not be found could not be found
""" """
attr_obj = get_attr_cache(self, attribute_name) attr_obj = get_attr_cache(self, attribute_name)
if attr_obj: if not attr_obj:
attr_obj.delete() # this will clear attr cache automatically
else:
attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name)
if attr_obj: attr_obj = attr_obj[0] if attr_obj else None
attr_obj[0].delete() if not attr_obj:
elif raise_exception: if raise_exception:
raise AttributeError raise AttributeError
return
# def del_attribute_raise(self, attribute_name): # the post-remove cache signal will auto-delete the attribute as well,
# """ # don't call attr_obj.delete() after this.
# Removes and attribute. Raises AttributeError if self.db_attributes.remove(attr_obj)
# attribute is not found.
#
# attribute_name: (str) The attribute's name.
# """
# attr_obj = get_attr_cache(self, attribute_name)
# if attr_obj:
# attr_obj.delete() # this will clear attr cache automatically
# else:
# try:
# _GA(self, "_attribute_class").objects.filter(
# db_obj=self, db_key__iexact=attribute_name)[0].delete()
# except IndexError:
# pass
# raise AttributeError
def get_all_attributes(self): def get_all_attributes(self):
""" """
@ -1301,5 +1269,5 @@ class TypedObject(SharedMemoryModel):
self.__class__.flush_cached_instance(self) self.__class__.flush_cached_instance(self)
# connect to signal # connect to attribut cache signal
#m2m_changed.connect(update_attr_cache, sender=TypedObject.db_attributes.through) m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)