From 6bc16e46cc964269dfd65af6c7c85cda2cca8e0b Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 12 Jul 2013 20:21:52 +0200 Subject: [PATCH] Made aliases work with the new handler. The location.contents updated is not working yet - this causes locational information to not be available until objects and manually initialized (e.g. by calling examine #dbref) --- src/commands/default/building.py | 4 +- src/commands/default/comms.py | 18 +-- src/commands/default/general.py | 7 +- src/commands/default/player.py | 11 +- src/commands/default/tests.py | 6 +- src/comms/managers.py | 2 +- src/objects/manager.py | 5 +- src/objects/models.py | 10 +- src/players/models.py | 6 +- .../0014_create_db_liteattributes_db_tags.py | 146 ++++++++++++++++++ src/scripts/models.py | 5 +- src/typeclasses/managers.py | 30 ++-- src/typeclasses/models.py | 62 +++++--- 13 files changed, 236 insertions(+), 76 deletions(-) create mode 100644 src/scripts/migrations/0014_create_db_liteattributes_db_tags.py diff --git a/src/commands/default/building.py b/src/commands/default/building.py index 076714c56c..2293363ef9 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -153,7 +153,7 @@ class CmdSetObjAlias(MuxCommand): # save back to object. obj.aliases.add(aliases) # we treat this as a re-caching (relevant for exits to re-build their exit commands with the correct aliases) - caller.msg("Aliases for '%s' are now set to %s." % (obj.key, ", ".join(obj.aliases))) + caller.msg("Aliases for '%s' are now %s." % (obj.key, str(obj.aliases))) class CmdCopy(ObjManipCommand): """ @@ -1569,7 +1569,7 @@ class CmdExamine(ObjManipCommand): string = "\n{wName/key{n: {c%s{n (%s)" % (obj.name, obj.dbref) if hasattr(obj, "aliases") and obj.aliases.all(): - string += "\n{wAliases{n: %s" % (", ".join(utils.make_iter(obj.aliases.all()))) + string += "\n{wAliases{n: %s" % (", ".join(utils.make_iter(str(obj.aliases)))) if hasattr(obj, "sessid") and obj.sessid: string += "\n{wsession{n: %s" % obj.sessid elif hasattr(obj, "sessions") and obj.sessions: diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index 4bee66e81e..700466d377 100644 --- a/src/commands/default/comms.py +++ b/src/commands/default/comms.py @@ -103,7 +103,7 @@ class CmdAddCom(MuxPlayerCommand): if alias: # create a nick and add it to the caller. - caller.nicks.add(alias, channel.key, nick_type="channel") + caller.nicks.add(alias, channel.key, category="channel") string += " You can now refer to the channel %s with the alias '%s'." self.msg(string % (channel.key, alias)) else: @@ -147,21 +147,21 @@ class CmdDelCom(MuxPlayerCommand): return chkey = channel.key.lower() # find all nicks linked to this channel and delete them - for nick in [nick for nick in caller.nicks.get(nick_type="channel") - if nick.db_real.lower() == chkey]: + for nick in [nick for nick in caller.nicks.get(category="channel") + if nick.db_data.lower() == chkey]: nick.delete() channel.disconnect_from(player) self.msg("You stop listening to channel '%s'. Eventual aliases were removed." % channel.key) return else: # we are removing a channel nick - channame = caller.nicks.get(ostring, nick_type="channel") + channame = caller.nicks.get_replace(key=ostring, category="channel") channel = find_channel(caller, channame, silent=True) if not channel: self.msg("No channel with alias '%s' was found." % ostring) else: - if caller.nicks.get(ostring, nick_type="channel", default=False): - caller.nicks.delete(ostring, nick_type="channel") + if caller.nicks.get(ostring, category="channel"): + caller.nicks.remove(ostring, category="channel") self.msg("Your alias '%s' for channel %s was cleared." % (ostring, channel.key)) else: self.msg("You had no such alias defined for this channel.") @@ -263,7 +263,7 @@ class CmdChannels(MuxPlayerCommand): comtable = prettytable.PrettyTable(["{wchannel","{wmy aliases", "{wdescription"]) for chan in subs: clower = chan.key.lower() - nicks = [nick for nick in caller.nicks.get(nick_type="channel")] + nicks = [nick for nick in caller.nicks.get(category="channel")] comtable.add_row(["%s%s" % (chan.key, chan.aliases and "(%s)" % ",".join(chan.aliases) or ""), "%s".join(nick.db_nick for nick in nicks if nick.db_real.lower()==clower()), chan.desc]) @@ -272,7 +272,7 @@ class CmdChannels(MuxPlayerCommand): # full listing (of channels caller is able to listen to) comtable = prettytable.PrettyTable(["{wsub","{wchannel","{wmy aliases","{wlocks","{wdescription"]) for chan in channels: - nicks = [nick for nick in caller.nicks.get(nick_type="channel")] + nicks = [nick for nick in caller.nicks.get(category="channel")] comtable.add_row([chan in subs and "{gYes{n" or "{rNo{n", "%s%s" % (chan.key, chan.aliases and "(%s)" % ",".join(chan.aliases) or ""), "%s".join(nick.db_nick for nick in nicks if nick.db_real.lower()==clower()), @@ -368,7 +368,7 @@ class CmdCBoot(MuxPlayerCommand): string = "%s boots %s from channel.%s" % (self.caller, player.key, reason) channel.msg(string) # find all player's nicks linked to this channel and delete them - for nick in [nick for nick in player.character.nicks.get(nick_type="channel") + for nick in [nick for nick in player.character.nicks.get(category="channel") if nick.db_real.lower() == channel.key]: nick.delete() # disconnect player diff --git a/src/commands/default/general.py b/src/commands/default/general.py index d843be95f9..99ad4c8195 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -151,13 +151,14 @@ class CmdNick(MuxCommand): switches = ["inputline"] string = "" for switch in switches: - oldnick = Nick.objects.filter(db_obj=caller.dbobj, db_nick__iexact=nick, db_type__iexact=switch) + oldnick = caller.nicks.get(key=nick, category=switch) + #oldnick = Nick.objects.filter(db_obj=caller.dbobj, db_nick__iexact=nick, db_type__iexact=switch) if not real: # removal of nick if oldnick: # clear the alias string += "\nNick '%s' (= '%s') was cleared." % (nick, oldnick[0].db_real) - caller.nicks.delete(nick, nick_type=switch) + caller.nicks.delete(nick, category=switch) else: string += "\nNo nick '%s' found, so it could not be removed." % nick else: @@ -166,7 +167,7 @@ class CmdNick(MuxCommand): string += "\nNick %s changed from '%s' to '%s'." % (nick, oldnick[0].db_real, real) else: string += "\nNick set: '%s' = '%s'." % (nick, real) - caller.nicks.add(nick, real, nick_type=switch) + caller.nicks.add(nick, real, category=switch) caller.msg(string) class CmdInventory(MuxCommand): diff --git a/src/commands/default/player.py b/src/commands/default/player.py index cec03d2cb2..a94de645df 100644 --- a/src/commands/default/player.py +++ b/src/commands/default/player.py @@ -465,18 +465,13 @@ class CmdPassword(MuxPlayerCommand): return oldpass = self.lhslist[0] # this is already stripped by parse() newpass = self.rhslist[0] # '' - try: - uaccount = player.user - except AttributeError: - self.msg("This is only applicable for players.") - return - if not uaccount.check_password(oldpass): + if not player.check_password(oldpass): self.msg("The specified old password isn't correct.") elif len(newpass) < 3: self.msg("Passwords must be at least three characters long.") else: - uaccount.set_password(newpass) - uaccount.save() + player.set_password(newpass) + player.save() self.msg("Password changed.") class CmdQuit(MuxPlayerCommand): diff --git a/src/commands/default/tests.py b/src/commands/default/tests.py index ccad26bf56..c9ef9cc701 100644 --- a/src/commands/default/tests.py +++ b/src/commands/default/tests.py @@ -110,9 +110,9 @@ class TestGeneral(CommandTest): self.call(general.CmdNick(), "testalias = testaliasedstring1", "Nick set:") self.call(general.CmdNick(), "/player testalias = testaliasedstring2", "Nick set:") self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Nick set:") - self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias")) - self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", nick_type="player")) - self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", nick_type="object")) + self.assertEqual(u"testaliasedstring1", self.char1.nicks.get_replace("testalias")) + self.assertEqual(u"testaliasedstring2", self.char1.nicks.get_replace("testalias", category="player")) + self.assertEqual(u"testaliasedstring3", self.char1.nicks.get_replace("testalias", category="object")) self.call(general.CmdGet(), "Obj1", "You pick up Obj1.") self.call(general.CmdDrop(), "Obj1", "You drop Obj1.") self.call(general.CmdSay(), "Testing", "You say, \"Testing\"") diff --git a/src/comms/managers.py b/src/comms/managers.py index 6362471ae0..118fcc5039 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -346,7 +346,7 @@ class ChannelManager(models.Manager): channels = self.filter(db_key__iexact=ostring) if not channels: # still no match. Search by alias. - channels = [channel for channel in self.all() if ostring.lower in [a.lower for a in channel.aliases]] + channels = [channel for channel in self.all() if ostring.lower() in [a.lower for a in channel.aliases]] return channels # diff --git a/src/objects/manager.py b/src/objects/manager.py index 6721ea3d87..ea0d3ebf8a 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -198,7 +198,8 @@ class ObjectManager(TypedObjectManager): type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q() if exact: # exact match - do direct search - return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct() + return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) | + Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_category__iexact="object_alias"))).distinct() elif candidates: # fuzzy with candidates key_candidates = self.filter(cand_restriction & type_restriction) @@ -212,7 +213,7 @@ class ObjectManager(TypedObjectManager): if index_matches: return [obj for ind, obj in enumerate(key_candidates) if ind in index_matches] else: - alias_candidates = self.model.alias_set.related.model.objects.filter(db_obj__pk__in=candidates_id) + alias_candidates = self.filter(id__in=candidates_id, db_tags__db_category__iexact="object_alias") alias_strings = alias_candidates.values_list("db_key", flat=True) index_matches = string_partial_matching(alias_strings, ostring, ret_index=True) if index_matches: diff --git a/src/objects/models.py b/src/objects/models.py index 54c378fc22..887e7b5848 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -140,9 +140,9 @@ class ObjectDB(TypedObject): _SA(self, "cmdset", CmdSetHandler(self)) _GA(self, "cmdset").update(init_mode=True) _SA(self, "scripts", ScriptHandler(self)) - _SA(self, "tags", TagHandler(self, "object")) - _SA(self, "aliases", AliasHandler(self, "object")) - _SA(self, "nicks", NickHandler(self, "object")) + _SA(self, "tags", TagHandler(self, category_prefix="object_")) + _SA(self, "aliases", AliasHandler(self, category_prefix="object_")) + _SA(self, "nicks", NickHandler(self, category_prefix="object_")) # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using @@ -569,8 +569,8 @@ class ObjectDB(TypedObject): pnicks = self.nicks.get(category="player_nick_%s" % nicktype) nicks = nicks + pnicks for nick in nicks: - if searchdata == nick.db_nick: - searchdata = nick.db_real + if searchdata == nick.db_key: + searchdata = nick.db_data break candidates=None diff --git a/src/players/models.py b/src/players/models.py index af7d0f7f65..9f2f1eadfb 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -120,9 +120,9 @@ class PlayerDB(TypedObject, AbstractUser): # handlers _SA(self, "cmdset", CmdSetHandler(self)) _GA(self, "cmdset").update(init_mode=True) - _SA(self, "tags", TagHandler(self, "player")) - _SA(self, "aliases", AliasHandler(self, "player")) - _SA(self, "nicks", NickHandler(self, "player")) + _SA(self, "tags", TagHandler(self, category_prefix="player_")) + _SA(self, "aliases", AliasHandler(self, category_prefix="player_")) + _SA(self, "nicks", NickHandler(self, category_prefix="player_")) # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using diff --git a/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py b/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py new file mode 100644 index 0000000000..9a24cb6a0f --- /dev/null +++ b/src/scripts/migrations/0014_create_db_liteattributes_db_tags.py @@ -0,0 +1,146 @@ +# -*- 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): + # Adding M2M table for field db_liteattributes on 'ScriptDB' + m2m_table_name = db.shorten_name(u'scripts_scriptdb_db_liteattributes') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('scriptdb', models.ForeignKey(orm[u'scripts.scriptdb'], null=False)), + ('liteattribute', models.ForeignKey(orm[u'typeclasses.liteattribute'], null=False)) + )) + db.create_unique(m2m_table_name, ['scriptdb_id', 'liteattribute_id']) + + # Adding M2M table for field db_tags on 'ScriptDB' + m2m_table_name = db.shorten_name(u'scripts_scriptdb_db_tags') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('scriptdb', models.ForeignKey(orm[u'scripts.scriptdb'], null=False)), + ('tag', models.ForeignKey(orm[u'typeclasses.tag'], null=False)) + )) + db.create_unique(m2m_table_name, ['scriptdb_id', 'tag_id']) + + + def backwards(self, orm): + # Removing M2M table for field db_liteattributes on 'ScriptDB' + db.delete_table(db.shorten_name(u'scripts_scriptdb_db_liteattributes')) + + # Removing M2M table for field db_tags on 'ScriptDB' + db.delete_table(db.shorten_name(u'scripts_scriptdb_db_tags')) + + + 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'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_liteattributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.LiteAttribute']", 'null': 'True', 'symmetrical': 'False'}), + '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_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + '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'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + '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_liteattributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.LiteAttribute']", 'null': 'True', 'symmetrical': 'False'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'db_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + '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'scripts.scriptdb': { + 'Meta': {'object_name': 'ScriptDB'}, + 'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}), + '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_index': 'True'}), + 'db_liteattributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.LiteAttribute']", 'null': 'True', 'symmetrical': 'False'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']", 'null': 'True', 'blank': 'True'}), + 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', '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_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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'}) + }, + u'typeclasses.liteattribute': { + 'Meta': {'object_name': 'LiteAttribute', 'index_together': "(('db_key', 'db_category'),)"}, + 'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'db_data': ('django.db.models.fields.TextField', [], {}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'typeclasses.tag': { + 'Meta': {'unique_together': "(('db_key', 'db_category'),)", 'object_name': 'Tag', 'index_together': "(('db_key', 'db_category'),)"}, + 'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}), + 'db_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['scripts'] \ No newline at end of file diff --git a/src/scripts/models.py b/src/scripts/models.py index ca2d2f5ef6..8614a481fe 100644 --- a/src/scripts/models.py +++ b/src/scripts/models.py @@ -33,6 +33,7 @@ from django.contrib.contenttypes.models import ContentType from src.scripts.manager import ScriptManager __all__ = ("ScriptDB",) +_SA = object.__setattr__ #------------------------------------------------------------ @@ -106,8 +107,8 @@ class ScriptDB(TypedObject): def __init__(self, *args, **kwargs): super(ScriptDB, self).__init__(*args, **kwargs) - _SA(self, "tags", TagHandler(self, "script")) - _SA(self, "aliases", AliasHandler(self, "script")) + _SA(self, "tags", TagHandler(self, category_prefix="script_")) + _SA(self, "aliases", AliasHandler(self, category_prefix="script_")) # Wrapper properties to easily set database fields. These are diff --git a/src/typeclasses/managers.py b/src/typeclasses/managers.py index ae84ce2389..2ac277c6b1 100644 --- a/src/typeclasses/managers.py +++ b/src/typeclasses/managers.py @@ -150,18 +150,18 @@ class TagManager(models.Manager): """ Extra manager methods for Tags """ - def get_tags_on_obj(self, obj, search_key=None, category=None): + def get_tags_on_obj(self, obj, key=None, category=None): """ Get all tags on obj, optionally limited by key and/or category """ - if search_key or category: - key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q() - cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q() + if key or category: + key_cands = Q(db_key__iexact=key.lower().strip()) if key!=None else Q() + cat_cands = Q(db_category__iexact=category.lower.strip()) if key!=None else Q() return _GA(obj, "db_tags").filter(cat_cands & key_cands) else: return list(_GA(obj, "db_tags").all()) - def get_tag(self, search_key=None, category=None): + def get_tag(self, key=None, category=None): """ Search and return all tags matching any combination of the search criteria. @@ -171,23 +171,23 @@ class TagManager(models.Manager): Returns a single Tag (or None) if both key and category is given, otherwise it will return a list. """ - key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q() - cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q() + key_cands = Q(db_key__iexact=key.lower().strip()) if key!=None else Q() + cat_cands = Q(db_category__iexact=category.lower().strip()) if category!=None else Q() tags = self.filter(key_cands & cat_cands) - if search_key and category: + if key and category: return tags[0] if tags else None else: return list(tags) - def get_objs_with_tag(self, objclass, search_key=None, category=None): + def get_objs_with_tag(self, objclass, key=None, category=None): """ Search and return all objects of objclass that has tags matching the given search criteria. objclass (dbmodel) - the object class to search - search_key (string) - the tag identifier + key (string) - the tag identifier category (string) - the tag category """ - key_cands = Q(db_tags__db_key__iexact=search_key.lower().strip()) if search_key!=None else Q() + key_cands = Q(db_tags__db_key__iexact=key.lower().strip()) if search_key!=None else Q() cat_cands = Q(db_tags__db_category__iexact=category.lower().strip()) if category!=None else Q() return objclass.objects.filter(key_cands & cat_cands) @@ -201,14 +201,14 @@ class TagManager(models.Manager): """ data = str(data) if data!=None else None - tag = self.get_tag(search_key=key, search_category=category) + tag = self.get_tag(key=key, category=category) if tag and data != None: tag.db_data = data tag.save() elif not tag: - tag = self.objects.create(db_key=key.lower().strip() if key!=None else None, - db_category=category.lower().strip() if key!=None else None, - db_data=str(data) if data!=None else None) + tag = self.create(db_key=key.lower().strip() if key!=None else None, + db_category=category.lower().strip() if key!=None else None, + db_data=str(data) if data!=None else None) tag.save() return tag diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index b816b2eb6d..068795c524 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -390,7 +390,7 @@ class TagHandler(object): def all(self): "Get all tags in this handler" - return self.obj.db_tags.all().values_list("db_key") + return [p[0] for p in self.obj.db_tags.all().values_list("db_key")] def __str__(self): return ",".join(self.all()) @@ -415,9 +415,9 @@ class AliasHandler(object): def add(self, alias): "Add a new nick to the handler" - if not alias or not alias.strip(): - return for al in make_iter(alias): + if not al or not al.strip(): + continue al = al.strip() # create a unique tag only if it didn't already exist aliasobj = Tag.objects.create_tag(key=al, category=self.category) @@ -436,7 +436,7 @@ class AliasHandler(object): def all(self): "Get all aliases in this handler" - return list(self.obj.db_tags.filter(db_category=self.category).values_list("db_key")) + return [p[0] for p in self.obj.db_tags.filter(db_category=self.category).values_list("db_key")] def __str__(self): return ",".join(self.all()) @@ -468,10 +468,10 @@ class NickHandler(object): self.obj = obj self.prefix = "%snick_" % category_prefix.strip().lower() if category_prefix else "" - def add(self, nick, realname, nick_type="inputline"): + def add(self, nick, realname, category="inputline"): """ Assign a new nick for realname. - nick_types used by Evennia are + category used by Evennia are 'inputline', 'player', 'obj' and 'channel' """ if not nick or not nick.strip(): @@ -479,7 +479,7 @@ class NickHandler(object): for nick in make_iter(nick): nick = nick.strip() real = realname - nick_type = "%s%s" % (self.prefix, nick_type.strip().lower()) + nick_type = "%s%s" % (self.prefix, category.strip().lower()) query = self.obj.db_liteattributes.filter(db_key__iexact=nick, db_category__iexact=nick_type) if query.count(): old_nick = query[0] @@ -490,21 +490,38 @@ class NickHandler(object): new_nick.save() self.obj.db_liteattributes.add(new_nick) - def remove(self, nick, nick_type="inputline"): + def remove(self, key, category="inputline"): "Removes a previously stored nick" - for nick in make_iter(nick): + for nick in make_iter(key): nick = nick.strip() - nick_type = "%s%s" % (self.prefix, nick_type.strip().lower()) - query = self.obj.liteattributes.filter(db_key__iexact=nick, db_category__iexact=nick_type) + nick_type = "%s%s" % (self.prefix, category.strip().lower()) + query = self.obj.db_liteattributes.filter(db_key__iexact=nick, db_category__iexact=nick_type) if query.count(): # remove the found nick(s) - query.delete() + self.obj.db_liteattributes.remove(query[0]) def delete(self, *args, **kwargs): "alias wrapper" - self.remove(self, *args, **kwargs) + self.remove(*args, **kwargs) - def get(self, nick=None, nick_type="inputline", default=None): + def get(self, key=None, category="inputline"): + """ + Retrieves a given nick object based on the input key and category. + If no key is given, returns a list of all matching nick + objects (LiteAttributes) on the object, or the empty list. + """ + returns = [] + for nick in make_iter(key): + nick = nick.strip().lower() if nick!=None else None + nick_type = "%s%s" % (self.prefix, category.strip().lower()) + if nick: + nicks = _GA(self.obj, "db_liteattributes").filter(db_key=nick, db_category=nick_type) + return nicks[0] if nicks else None + else: + returns.extend(list(self.obj.db_liteattributes.all())) + return returns + + def get_replace(self, key, category="inputline", default=None): """ Retrieves a given nick replacement based on the input nick. If given but no matching conversion was found, returns @@ -513,20 +530,19 @@ class NickHandler(object): objects (LiteAttributes) on the object, or the empty list. """ returns = [] - for nick in make_iter(nick): + for nick in make_iter(key): nick = nick.strip().lower() if nick!=None else None - nick_type = "%s%s" % (self.prefix, nick_type.strip().lower()) - if nick: - nicks = _GA(self.obj, "db_liteattributes").objects.filter(db_key=nick, db_category=nick_type).prefetch_related("db_data") - default = default if default!=None else nick - return nicks[0].db_data if nicks else default - else: - returns.extend(list(self.obj.db_liteattributes.all())) + nick_type = "%s%s" % (self.prefix, category.strip().lower()) + nicks = _GA(self.obj, "db_liteattributes").filter(db_key=nick, db_category=nick_type) + default = default if default!=None else nick + returns.append(nicks[0].db_data) if nicks else returns.append(default) + if len(returns) == 1: + return returns[0] return returns def all(self): "Get all nicks in this handler" - return list(self.obj.db_nicks.filter(db_category=self.category).values_list("db_key")) + return [p[0] for p in self.obj.db_nicks.filter(db_category=self.category).values_list("db_key")]