diff --git a/game/gamesrc/objects/examples/red_button.py b/game/gamesrc/objects/examples/red_button.py index fbb0d9b8ff..51d97f3c41 100644 --- a/game/gamesrc/objects/examples/red_button.py +++ b/game/gamesrc/objects/examples/red_button.py @@ -90,7 +90,7 @@ class RedButton(Object): # scripts that depend on the lid to be closed. self.scripts.validate() # now add new scripts that define the open-lid state - self.obj.scripts.add(scriptexamples.OpenLidState) + self.scripts.add(scriptexamples.OpenLidState) # we also add a scripted event that will close the lid after a while. # (this one cleans itself after being called once) self.scripts.add(scriptexamples.CloseLidEvent) @@ -125,7 +125,7 @@ class RedButton(Object): """ self.db.lamp_works = False - self.obj.db.desc = "The big red button has stopped blinking for the time being." + self.db.desc = "The big red button has stopped blinking for the time being." if feedback and self.location: string = "The lamp flickers, the button going dark." diff --git a/src/objects/migrations/0002_auto__del_field_objattribute_db_mode.py b/src/objects/migrations/0002_auto__del_field_objattribute_db_mode.py new file mode 100644 index 0000000000..f1be4dc3d2 --- /dev/null +++ b/src/objects/migrations/0002_auto__del_field_objattribute_db_mode.py @@ -0,0 +1,127 @@ +# encoding: 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): + + # Deleting field 'ObjAttribute.db_mode' + + from src.objects.models import ObjAttribute + from src.typeclasses.models import PackedDBobject + for attr in ObjAttribute.objects.all(): + # resave attributes + db_mode = attr.db_mode + if db_mode and db_mode != 'pickle': + # an object. We need to resave this. + if db_mode == 'object': + val = PackedDBobject(attr.db_value, "objectdb") + elif db_mode == 'player': + val = PackedDBobject(attr.db_value, "playerdb") + elif db_mode == 'script': + val = PackedDBobject(attr.db_value, "scriptdb") + elif db_mode == 'help': + val = PackedDBobject(attr.db_value, "helpentry") + else: + val = PackedDBobject(attr.db_value, db_mode) # channel, msg + attr.value = val + + db.delete_column('objects_objattribute', 'db_mode') + + + def backwards(self, orm): + + # Adding field 'ObjAttribute.db_mode' + db.add_column('objects_objattribute', 'db_mode', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True), keep_default=False) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + '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'}), + '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'}) + }, + 'objects.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'objects.nick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'Nick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'objects.objattribute': { + 'Meta': {'object_name': 'ObjAttribute'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}), + 'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'objects.objectdb': { + 'Meta': {'object_name': 'ObjectDB'}, + 'db_cmdset_storage': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'players.playerdb': { + 'Meta': {'object_name': 'PlayerDB'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + } + } + + complete_apps = ['objects'] diff --git a/src/players/manager.py b/src/players/manager.py index e164d6810f..5038c95325 100644 --- a/src/players/manager.py +++ b/src/players/manager.py @@ -5,7 +5,7 @@ The managers for the custom Player object and permissions. import datetime from django.db import models from django.contrib.auth.models import User -from src.typeclasses.managers import returns_typeclass_list, returns_typeclass +from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager from src.utils import logger # @@ -59,7 +59,7 @@ def returns_player(method): return None return func -class PlayerManager(models.Manager): +class PlayerManager(TypedObjectManager): """ Custom manager for the player profile model. We use this to wrap users in general in evennia, and supply some useful diff --git a/src/players/migrations/0002_auto__del_field_playerattribute_db_mode.py b/src/players/migrations/0002_auto__del_field_playerattribute_db_mode.py new file mode 100644 index 0000000000..3a30ec0bd8 --- /dev/null +++ b/src/players/migrations/0002_auto__del_field_playerattribute_db_mode.py @@ -0,0 +1,113 @@ +# encoding: 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): + + # Deleting field 'PlayerAttribute.db_mode' + + from src.players.models import PlayerAttribute + from src.typeclasses.models import PackedDBobject + for attr in PlayerAttribute.objects.all(): + # resave attributes + db_mode = attr.db_mode + if db_mode and db_mode != 'pickle': + # an object. We need to resave this. + if db_mode == 'object': + val = PackedDBobject(attr.db_value, "objectdb") + elif db_mode == 'player': + val = PackedDBobject(attr.db_value, "playerdb") + elif db_mode == 'script': + val = PackedDBobject(attr.db_value, "scriptdb") + elif db_mode == 'help': + val = PackedDBobject(attr.db_value, "helpentry") + else: + val = PackedDBobject(attr.db_value, db_mode) # channel, msg + attr.value = val + + db.delete_column('players_playerattribute', 'db_mode') + + + def backwards(self, orm): + + # Adding field 'PlayerAttribute.db_mode' + db.add_column('players_playerattribute', 'db_mode', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True), keep_default=False) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + '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'}), + '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'}) + }, + 'objects.objectdb': { + 'Meta': {'object_name': 'ObjectDB'}, + 'db_cmdset_storage': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'players.playerattribute': { + 'Meta': {'object_name': 'PlayerAttribute'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}), + 'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'players.playerdb': { + 'Meta': {'object_name': 'PlayerDB'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + } + } + + complete_apps = ['players'] diff --git a/src/scripts/migrations/0002_auto__del_field_scriptattribute_db_mode.py b/src/scripts/migrations/0002_auto__del_field_scriptattribute_db_mode.py new file mode 100644 index 0000000000..6777333c3f --- /dev/null +++ b/src/scripts/migrations/0002_auto__del_field_scriptattribute_db_mode.py @@ -0,0 +1,129 @@ +# encoding: 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): + + # Deleting field 'ScriptAttribute.db_mode' + + from src.scripts.models import ScriptAttribute + from src.typeclasses.models import PackedDBobject + for attr in ScriptAttribute.objects.all(): + # resave attributes + db_mode = attr.db_mode + if db_mode and db_mode != 'pickle': + # an object. We need to resave this. + if db_mode == 'object': + val = PackedDBobject(attr.db_value, "objectdb") + elif db_mode == 'player': + val = PackedDBobject(attr.db_value, "playerdb") + elif db_mode == 'script': + val = PackedDBobject(attr.db_value, "scriptdb") + elif db_mode == 'help': + val = PackedDBobject(attr.db_value, "helpentry") + else: + val = PackedDBobject(attr.db_value, db_mode) # channel, msg + attr.value = val + + db.delete_column('scripts_scriptattribute', 'db_mode') + + + def backwards(self, orm): + + # Adding field 'ScriptAttribute.db_mode' + db.add_column('scripts_scriptattribute', 'db_mode', self.gf('django.db.models.fields.CharField')(max_length=20, null=True, blank=True), keep_default=False) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + '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'}), + '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'}) + }, + 'objects.objectdb': { + 'Meta': {'object_name': 'ObjectDB'}, + 'db_cmdset_storage': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'players.playerdb': { + 'Meta': {'object_name': 'PlayerDB'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + }, + 'scripts.scriptattribute': { + 'Meta': {'object_name': 'ScriptAttribute'}, + '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_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['scripts.ScriptDB']"}), + 'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'scripts.scriptdb': { + 'Meta': {'object_name': 'ScriptDB'}, + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_desc': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'db_interval': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'db_is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']", 'null': 'True', 'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'db_persistent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'db_repeats': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'db_start_delay': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['scripts'] diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index ce8105f64b..215ab87647 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -30,6 +30,7 @@ import traceback from django.db import models from django.conf import settings from django.utils.encoding import smart_str +from django.contrib.contenttypes.models import ContentType from src.utils.idmapper.models import SharedMemoryModel from src.typeclasses import managers from src.locks.lockhandler import LockHandler @@ -42,12 +43,12 @@ PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] # Note that these have to be updated if directory structure changes. PARENTS = { "typeclass":"src.typeclasses.typeclass.TypeClass", - "object":"src.objects.models.ObjectDB", - "player":"src.players.models.PlayerDB", - "script":"src.scripts.models.ScriptDB", + "objectdb":"src.objects.models.ObjectDB", + "layerdb":"src.players.models.PlayerDB", + "scriptdb":"src.scripts.models.ScriptDB", "msg":"src.comms.models.Msg", "channel":"src.comms.models.Channel", - "help":"src.help.models.HelpEntry"} + "helpentry":"src.help.models.HelpEntry"} # cached typeclasses for all typed models TYPECLASS_CACHE = {} @@ -63,6 +64,12 @@ def reset(): # #------------------------------------------------------------ +class PackedDBobject(object): + "Simple helper class for storing database object ids." + def __init__(self, ID, db_model): + self.id = ID + self.db_model = db_model + class Attribute(SharedMemoryModel): """ Abstract django model. @@ -94,8 +101,6 @@ class Attribute(SharedMemoryModel): db_key = models.CharField(max_length=255) # access through the value property db_value = models.TextField(blank=True, null=True) - # tells us what type of data is stored in the attribute - db_mode = models.CharField(max_length=20, null=True, blank=True) # Lock storage db_lock_storage = models.TextField(blank=True) # references the object the attribute is linked to (this is set @@ -106,7 +111,7 @@ class Attribute(SharedMemoryModel): # Database manager objects = managers.AttributeManager() - + # Lock handler self.locks def __init__(self, *args, **kwargs): "Initializes the parent first -important!" @@ -143,23 +148,6 @@ class Attribute(SharedMemoryModel): raise Exception("Cannot delete attribute key!") key = property(key_get, key_set, key_del) - # mode property (wraps db_mode) - #@property - def mode_get(self): - "Getter. Allows for value = self.mode" - return self.db_mode - #@mode.setter - def mode_set(self, value): - "Setter. Allows for self.mode = value" - self.db_mode = value - self.save() - #@mode.deleter - def mode_del(self): - "Deleter. Allows for del self.mode" - self.db_mode = None - self.save() - mode = property(mode_get, mode_set, mode_del) - # obj property (wraps db_obj) #@property def obj_get(self): @@ -198,44 +186,14 @@ class Attribute(SharedMemoryModel): """ Getter. Allows for value = self.value. """ - db_value = self.db_value - db_mode = self.db_mode try: - if not db_mode: - # it's a string, just return plain db_value below - pass - elif db_mode == 'pickle': - db_value = pickle.loads(str(db_value)) - elif db_mode == 'object': - from src.objects.models import ObjectDB - db_value = ObjectDB.objects.dbref_search(db_value) - elif db_mode == 'script': - from src.scripts.models import ScriptDB - db_value = ScriptDB.objects.dbref_search(db_value) - elif db_mode == 'player': - from src.players.models import PlayerDB - db_value = PlayerDB.objects.get(id=int(db_value)) - elif db_mode == 'msg': - from src.comms.models import Msg - db_value = Msg.objects.objects.get(id=int(db_value)) - elif db_mode == 'channel': - from src.comms.models import Channel - db_value = Channel.objects.get(id=int(db_value)) - elif db_mode == 'help': - from src.help.models import HelpEntry - db_value = HelpEntry.objects.get(id=int(db_value)) - except Exception: - logger.log_trace() #TODO: Remove when stable? - db_value = None - return db_value + return self.validate_data(pickle.loads(str(self.db_value))) + except pickle.UnpicklingError: + return self.db_value #@value.setter def value_set(self, new_value): "Setter. Allows for self.value = value" - new_value, mode = self._convert_value(new_value) - if mode == "pickle": - new_value = pickle.dumps(new_value) #,pickle.HIGHEST_PROTOCOL) - self.db_value = new_value - self.db_mode = mode + self.db_value = pickle.dumps(self.validate_data(new_value)) self.save() #@value.deleter def value_del(self): @@ -272,52 +230,55 @@ class Attribute(SharedMemoryModel): def __unicode__(self): return u"%s(%s)" % (self.key, self.id) - def _convert_value(self, in_value): + def validate_data(self, item): """ - We have to be careful as to what we store. Some things, such - as django model instances, cannot be directly stored/pickled - in an attribute, so we have to be clever about it. Types of - objects and how they are handled: - * str - stored directly in field - * django model object - store its dbref in field - * any other python structure - pickle in field + We have to make sure to not store database objects raw, since this will + crash the system. Instead we must store their IDs and make sure to convert + back when the attribute is read back later. - """ - - if isinstance(in_value, basestring): - # (basestring matches both str and unicode) - # strings we just store directly. - return in_value, None + We handle only lists and dicts for iterables. + """ + if isinstance(item, basestring): + # a string is unmodified + ret = item + elif type(item) == PackedDBobject: + # unpack a previously packed object + try: + mclass = ContentType.objects.get(model=item.db_model).model_class() + try: + ret = mclass.objects.dbref_search(item.id) + except AttributeError: + ret = mclass.objects.get(id=item.id) + except Exception: + logger.log_trace("Attribute error: %s, %s" % (item.db_model, item.id)) #TODO: Remove when stable? + ret = None + elif type(item) == dict: + # handle dictionaries + ret = {} + for key, it in item.items(): + ret[key] = self.validate_data(it) + elif is_iter(item): + # Note: ALL other iterables are considered to be lists! + ret = [] + for it in item: + ret.append(self.validate_data(it)) + elif has_parent('django.db.models.base.Model', item) or has_parent(PARENTS['typeclass'], item): + # db models must be stored as dbrefs + db_model = [parent for parent, path in PARENTS.items() if has_parent(path, item)] + if db_model and db_model[0] == 'typeclass': + # the typeclass alone can't help us, we have to know the db object. + db_model = [parent for parent, path in PARENTS.items() + if has_parent(path, item.dbobj)] + if db_model: + # store the object in an easily identifiable container + ret = PackedDBobject(str(item.id), db_model[0]) + else: + # not a valid object - some third-party class or primitive? + ret = item + else: + ret = item - if is_iter(in_value): - # an iterable. This is normally something to pickle, - # but we have to be careful so as to not find - # django model instances nested in the iterable. - pass #TODO! - - - if not has_parent('django.db.models.base.Model', in_value) \ - and not has_parent(PARENTS['typeclass'], in_value): - # non-django models that are not strings we pickle - #print "type identified: to_pickle" - #print "found a non-django parent." - return in_value, 'pickle' - - # this is a db model. Try to determine what type of db object it is. - db_type = [parent for parent, path in PARENTS.items() - if has_parent(path, in_value)] - if db_type and db_type[0] == 'typeclass': - # the typeclass alone can't help us, we have to know the db object. - db_type = [parent for parent, path in PARENTS.items() - if has_parent(path, in_value.dbobj)] - - if not db_type: - # no match; maybe it's a non-model from inside django(?). - return in_value, "pickle" - - # it's a db model. Return its dbref as a string instead. - #print "type identified: %s" % db_type[0] - return str(in_value.id), db_type[0] + return ret def access(self, accessing_obj, access_type='read', default=False): """ @@ -329,7 +290,6 @@ class Attribute(SharedMemoryModel): return self.locks.check(accessing_obj, access_type=access_type, default=default) - #------------------------------------------------------------ # # Typed Objects