diff --git a/ev.py b/ev.py index ce7f3b85af..81e9968ea2 100644 --- a/ev.py +++ b/ev.py @@ -116,9 +116,10 @@ README = __doc__ # help entries from src.help.models import HelpEntry +from src.typeclasses.models import Attribute # players from src.players.player import Player -from src.players.models import PlayerDB, PlayerAttribute, PlayerNick +from src.players.models import PlayerDB # commands from src.commands.command import Command diff --git a/game/evennia.py b/game/evennia.py index a42835b352..b17a97743c 100755 --- a/game/evennia.py +++ b/game/evennia.py @@ -129,11 +129,9 @@ PORTAL_LOGFILE = settings.PORTAL_LOG_FILE # Check so a database exists and is accessible from django.db import DatabaseError -from src.objects.models import ObjectDB +from src.players.models import PlayerDB try: - test = ObjectDB.objects.get(id=1) -except ObjectDB.DoesNotExist: - pass # this is fine at this point + superuser = PlayerDB.objects.get(id=1) except DatabaseError,e: print """ Your database does not seem to be set up correctly. @@ -147,6 +145,11 @@ except DatabaseError,e: When you have a database set up, rerun evennia.py. """ % e sys.exit() +except PlayerDB.DoesNotExist: + # no superuser yet. We need to create it. + from django.core.management import call_command + print "\nCreate a superuser below. The superuser is Player #1, the 'owner' account of the server.\n" + call_command("createsuperuser", interactive=True) # Add this to the environmental variable for the 'twistd' command. currpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -403,6 +406,7 @@ def error_check_python_modules(): deprstring = "settings.%s should be renamed to %s. If defaults are used, their path/classname must be updated (see src/settings_default.py)." if hasattr(settings, "CMDSET_DEFAULT"): raise DeprecationWarning(deprstring % ("CMDSET_DEFAULT", "CMDSET_CHARACTER")) if hasattr(settings, "CMDSET_OOC"): raise DeprecationWarning(deprstring % ("CMDSET_OOC", "CMDSET_PLAYER")) + if settings.WEBSERVER_ENABLED and not isinstance(settings.WEBSERVER_PORTS[0], tuple): raise DeprecationWarning("settings.WEBSERVER_PORTS must be on the form [(proxyport, serverport), ...]") from src.commands import cmdsethandler if not cmdsethandler.import_cmdset(settings.CMDSET_UNLOGGEDIN, None): print "Warning: CMDSET_UNLOGGED failed to load!" diff --git a/game/runner.py b/game/runner.py index e1e0d292f5..584183ac8c 100644 --- a/game/runner.py +++ b/game/runner.py @@ -50,7 +50,7 @@ from django.conf import settings # Setup access of the evennia server itself SERVER_PY_FILE = os.path.join(settings.SRC_DIR, 'server/server.py') -PORTAL_PY_FILE = os.path.join(settings.SRC_DIR, 'server/portal.py') +PORTAL_PY_FILE = os.path.join(settings.SRC_DIR, 'server/portal/portal.py') # Get logfile names SERVER_LOGFILE = settings.SERVER_LOG_FILE diff --git a/locale/sv/LC_MESSAGES/django.po b/locale/sv/LC_MESSAGES/django.po index c3eb93fd34..ab1016686f 100644 --- a/locale/sv/LC_MESSAGES/django.po +++ b/locale/sv/LC_MESSAGES/django.po @@ -37,7 +37,7 @@ msgid " Type \"help\" for help." msgstr "Skriv \"help\" för hjälp." #: src/commands/cmdhandler.py:212 -msgid "There where multiple matches." +msgid "There were multiple matches." msgstr "Det fanns många träffar." #: src/commands/cmdparser.py:144 diff --git a/src/commands/cmdparser.py b/src/commands/cmdparser.py index 386ed8f0c6..1b4650eaa2 100644 --- a/src/commands/cmdparser.py +++ b/src/commands/cmdparser.py @@ -245,7 +245,7 @@ def at_multimatch_cmd(caller, matches): """ Format multiple command matches to a useful error. """ - string = "There where multiple matches:" + string = "There were multiple matches:" for num, match in enumerate(matches): # each match is a tuple (candidate, cmd) cmdname, arg, cmd, dum, dum = match diff --git a/src/commands/default/admin.py b/src/commands/default/admin.py index 4eb8e6ec7e..861f875247 100644 --- a/src/commands/default/admin.py +++ b/src/commands/default/admin.py @@ -298,12 +298,8 @@ class CmdDelPlayer(MuxCommand): string = "No Player nor User found matching '%s'." % args self.msg(string) return - try: - player = user.get_profile() - except Exception: - player = None - if player and not player.access(caller, 'delete'): + if user and not user.access(caller, 'delete'): string = "You don't have the permissions to delete this player." self.msg(string) return @@ -311,9 +307,9 @@ class CmdDelPlayer(MuxCommand): string = "" name = user.username user.delete() - if player: - name = player.name - player.delete() + if user: + name = user.name + user.delete() string = "Player %s was deleted." % name else: string += "The User %s was deleted. It had no Player associated with it." % name @@ -322,16 +318,16 @@ class CmdDelPlayer(MuxCommand): elif utils.is_iter(players): string = "There were multiple matches:" - for player in players: - string += "\n %s %s" % (player.id, player.key) + for user in players: + string += "\n %s %s" % (user.id, user.key) return else: # one single match - player = players - user = player.user + user = players + user = user.user - if not player.access(caller, 'delete'): + if not user.access(caller, 'delete'): string = "You don't have the permissions to delete that player." self.msg(string) return @@ -342,12 +338,12 @@ class CmdDelPlayer(MuxCommand): string = "\nYour account '%s' is being *permanently* deleted.\n" % uname if reason: string += " Reason given:\n '%s'" % reason - player.unpuppet_all() - for session in SESSIONS.sessions_from_player(player): - player.msg(string, sessid=session.sessid) - player.disconnect_session_from_player(session.sessid) + user.unpuppet_all() + for session in SESSIONS.sessions_from_player(user): + user.msg(string, sessid=session.sessid) + user.disconnect_session_from_player(session.sessid) + user.delete() user.delete() - player.delete() self.msg("Player %s was successfully deleted." % uname) diff --git a/src/commands/default/building.py b/src/commands/default/building.py index 82d229d021..2293363ef9 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -4,8 +4,7 @@ Building and world design commands """ from django.conf import settings -from src.objects.models import ObjectDB, ObjAttribute -from src.players.models import PlayerAttribute +from src.objects.models import ObjectDB from src.utils import create, utils from src.utils.ansi import raw from src.commands.default.muxcommand import MuxCommand @@ -124,7 +123,7 @@ class CmdSetObjAlias(MuxCommand): return if self.rhs == None: # no =, so we just list aliases on object. - aliases = obj.aliases + aliases = obj.aliases.all() if aliases: caller.msg("Aliases for '%s': %s" % (obj.key, ", ".join(aliases))) else: @@ -137,24 +136,24 @@ class CmdSetObjAlias(MuxCommand): if not self.rhs: # we have given an empty =, so delete aliases - old_aliases = obj.aliases + old_aliases = obj.aliases.all() if old_aliases: caller.msg("Cleared aliases from %s: %s" % (obj.key, ", ".join(old_aliases))) - del obj.dbobj.aliases + obj.dbobj.db_aliases.clear() else: caller.msg("No aliases to clear.") return # merge the old and new aliases (if any) - old_aliases = obj.aliases + old_aliases = obj.aliases.all() new_aliases = [alias.strip().lower() for alias in self.rhs.split(',') if alias.strip()] # make the aliases only appear once old_aliases.extend(new_aliases) aliases = list(set(old_aliases)) # save back to object. - obj.aliases = aliases + 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): """ @@ -192,7 +191,7 @@ class CmdCopy(ObjManipCommand): if not from_obj: return to_obj_name = "%s_copy" % from_obj_name - to_obj_aliases = ["%s_copy" % alias for alias in from_obj.aliases] + to_obj_aliases = ["%s_copy" % alias for alias in from_obj.aliases.all()] copiedobj = ObjectDB.objects.copy_object(from_obj, new_key=to_obj_name, new_aliases=to_obj_aliases) if copiedobj: @@ -599,8 +598,8 @@ class CmdDig(ObjManipCommand): aliases=room["aliases"], report_to=caller) new_room.locks.add(lockstring) alias_string = "" - if new_room.aliases: - alias_string = " (%s)" % ", ".join(new_room.aliases) + if new_room.aliases.all(): + alias_string = " (%s)" % ", ".join(new_room.aliases.all()) room_string = "Created room %s(%s)%s of type %s." % (new_room, new_room.dbref, alias_string, typeclass) @@ -627,8 +626,8 @@ class CmdDig(ObjManipCommand): aliases=to_exit["aliases"], locks=lockstring, destination=new_room, report_to=caller) alias_string = "" - if new_to_exit.aliases: - alias_string = " (%s)" % ", ".join(new_to_exit.aliases) + if new_to_exit.aliases.all(): + alias_string = " (%s)" % ", ".join(new_to_exit.aliases.all()) exit_to_string = "\nCreated Exit from %s to %s: %s(%s)%s." exit_to_string = exit_to_string % (location.name, new_room.name, new_to_exit, new_to_exit.dbref, alias_string) @@ -652,8 +651,8 @@ class CmdDig(ObjManipCommand): new_room, aliases=back_exit["aliases"], locks=lockstring, destination=location, report_to=caller) alias_string = "" - if new_back_exit.aliases: - alias_string = " (%s)" % ", ".join(new_back_exit.aliases) + if new_back_exit.aliases.all(): + alias_string = " (%s)" % ", ".join(new_back_exit.aliases.all()) exit_back_string = "\nCreated Exit back from %s to %s: %s(%s)%s." exit_back_string = exit_back_string % (new_room.name, location.name, new_back_exit, new_back_exit.dbref, alias_string) @@ -980,7 +979,7 @@ class CmdName(ObjManipCommand): obj.name = newname astring = "" if aliases: - obj.aliases = aliases + [obj.aliases.add(alias) for alias in aliases] astring = " (%s)" % (", ".join(aliases)) # fix for exits - we need their exit-command to change name too if obj.destination: @@ -1038,7 +1037,7 @@ class CmdOpen(ObjManipCommand): if old_destination.id != destination.id: # reroute the old exit. exit_obj.destination = destination - exit_obj.aliases = exit_aliases + [exit_obj.aliases.add(alias) for alias in exit_aliases] string += " Rerouted its old destination '%s' to '%s' and changed aliases." % \ (old_destination.name, destination.name) else: @@ -1545,10 +1544,7 @@ class CmdExamine(ObjManipCommand): except Exception: ndb_attr = None else: - if self.player_mode: - 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)] + db_attr = [(attr.key, attr.value) for attr in obj.db_attributes.all()] try: ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items() if not aname.startswith("_")] except Exception: @@ -1572,8 +1568,8 @@ class CmdExamine(ObjManipCommand): """ string = "\n{wName/key{n: {c%s{n (%s)" % (obj.name, obj.dbref) - if hasattr(obj, "aliases") and obj.aliases: - string += "\n{wAliases{n: %s" % (", ".join(utils.make_iter(obj.aliases))) + if hasattr(obj, "aliases") and 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: @@ -1789,7 +1785,7 @@ class CmdFind(MuxCommand): nresults = results.count() if not nresults: # no matches on the keys. Try aliases instead. - results = results = ObjectDB.alias_set.related.model.objects.filter(db_key=searchstring) + results = ObjectDB.db_aliases.filter(db_key=searchstring) if "room" in switches: results = results.filter(db_obj__db_location__isnull=True) if "exit" in switches: diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index b886306c41..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.has(ostring, nick_type="channel"): - 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 1c8c313d10..99ad4c8195 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -3,7 +3,6 @@ General Character commands usually availabe to all characters """ from django.conf import settings from src.utils import utils, prettytable -from src.objects.models import ObjectNick as Nick from src.commands.default.muxcommand import MuxCommand @@ -124,17 +123,17 @@ class CmdNick(MuxCommand): caller = self.caller switches = self.switches - nicks = Nick.objects.filter(db_obj=caller.dbobj).exclude(db_type="channel") + nicks = caller.nicks.get(category="channel") if 'list' in switches: table = prettytable.PrettyTable(["{wNickType", "{wNickname", "{wTranslates-to"]) for nick in nicks: - table.add_row([nick.db_type, nick.db_nick, nick.db_real]) + table.add_row([nick.db_category, nick.db_key, nick.db_data]) string = "{wDefined Nicks:{n\n%s" % table caller.msg(string) return if 'clearall' in switches: - nicks.delete() + caller.nicks.clear() caller.msg("Cleared all aliases.") return if not self.args or not self.lhs: @@ -152,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: @@ -167,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/syscommands.py b/src/commands/default/syscommands.py index ccd46f9e9d..cab02d66dd 100644 --- a/src/commands/default/syscommands.py +++ b/src/commands/default/syscommands.py @@ -88,7 +88,7 @@ class SystemMultimatch(MuxCommand): src.commands.cmdhandler. """ - string = "There where multiple matches:" + string = "There were multiple matches:" for num, match in enumerate(matches): # each match is a tuple (candidate, cmd) candidate, cmd = match diff --git a/src/commands/default/system.py b/src/commands/default/system.py index 6288b8b095..fe4b56bfeb 100644 --- a/src/commands/default/system.py +++ b/src/commands/default/system.py @@ -213,6 +213,15 @@ def format_script_list(scripts): table.align = 'r' for script in scripts: nextrep = script.time_until_next_repeat() + #print ([script.id, + # (not hasattr(script, 'obj') or not script.obj) and "" or script.obj.key, + # script.key, + # (not hasattr(script, 'interval') or script.interval < 0) and "--" or "%ss" % script.interval, + # not nextrep and "--" or "%ss" % nextrep, + # (not hasattr(script, 'repeats') or not script.repeats) and "--" or "%i" % script.repeats, + # script.persistent and "*" or "-", + # script.typeclass_path.rsplit('.', 1)[-1], + # script.desc]) table.add_row([script.id, (not hasattr(script, 'obj') or not script.obj) and "" or script.obj.key, script.key, 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/commands/default/unloggedin.py b/src/commands/default/unloggedin.py index d9c5145f7c..6ac8e7daeb 100644 --- a/src/commands/default/unloggedin.py +++ b/src/commands/default/unloggedin.py @@ -4,7 +4,6 @@ Commands that are available from the connect screen. import re import traceback from django.conf import settings -from django.contrib.auth.models import User from src.players.models import PlayerDB from src.objects.models import ObjectDB from src.server.models import ServerConfig @@ -68,7 +67,7 @@ class CmdUnconnectedConnect(MuxCommand): player = PlayerDB.objects.get_player_from_name(playername) pswd = None if player: - pswd = player.user.check_password(password) + pswd = player.check_password(password) if not (player and pswd): # No playername or password match @@ -142,7 +141,7 @@ class CmdUnconnectedCreate(MuxCommand): return # strip excessive spaces in playername playername = re.sub(r"\s+", " ", playername).strip() - if PlayerDB.objects.filter(user__username__iexact=playername) or User.objects.filter(username__iexact=playername): + if PlayerDB.objects.filter(username__iexact=playername): # player already exists (we also ignore capitalization here) session.msg("Sorry, there is already a player with the name '%s'." % playername) return @@ -167,6 +166,7 @@ class CmdUnconnectedCreate(MuxCommand): except Exception, e: session.msg("There was an error creating the default Player/Character:\n%s\n If this problem persists, contact an admin." % e) + logger.log_trace() return # This needs to be called so the engine knows this player is logging in for the first time. diff --git a/src/comms/managers.py b/src/comms/managers.py index 6362471ae0..d54cba0391 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -65,7 +65,6 @@ def identify_object(inp): obj = inp typ = type(obj) if typ == _PlayerDB: return obj, "player" - if typ == _User: return obj.get_profile(), "player" elif typ == _ObjectDB: return obj, "object" elif typ == _Channel: return obj, "channel" elif dbref(obj): return dbref(obj), "dbref" @@ -346,7 +345,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/comms/migrations/0011_renaming_channles_to_channels.py b/src/comms/migrations/0011_renaming_channles_to_channels.py new file mode 100644 index 0000000000..b859446955 --- /dev/null +++ b/src/comms/migrations/0011_renaming_channles_to_channels.py @@ -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'] diff --git a/src/comms/models.py b/src/comms/models.py index a0110f5ff7..ecda0db840 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -88,7 +88,7 @@ class Msg(SharedMemoryModel): # 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_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 objects = managers.MsgManager() @@ -303,8 +303,6 @@ class Msg(SharedMemoryModel): logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del) - _db_model_name = "msg" # used by attributes to safely store objects - # # Msg class methods # diff --git a/src/help/models.py b/src/help/models.py index e61474e67d..8890009004 100644 --- a/src/help/models.py +++ b/src/help/models.py @@ -45,7 +45,7 @@ class HelpEntry(SharedMemoryModel): # These database fields are all set using their corresponding properties, # named same as the field, but withtout the db_* prefix. - # title of the help + # title of the help entry db_key = models.CharField('help key', max_length=255, unique=True, help_text='key to search for') # help category db_help_category = models.CharField("help category", max_length=255, default="General", @@ -72,9 +72,6 @@ class HelpEntry(SharedMemoryModel): verbose_name = "Help Entry" verbose_name_plural = "Help Entries" - # used by Attributes to safely retrieve stored object - _db_model_name = "helpentry" - # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using # normal python operations (without having to remember to save() @@ -85,53 +82,53 @@ class HelpEntry(SharedMemoryModel): # key property (wraps db_key) #@property - def __key_get(self): - "Getter. Allows for value = self.key" - return self.db_key - #@key.setter - def __key_set(self, value): - "Setter. Allows for self.key = value" - self.db_key = value - self.save() - #@key.deleter - def __key_del(self): - "Deleter. Allows for del self.key. Deletes entry." - self.delete() - key = property(__key_get, __key_set, __key_del) + #def __key_get(self): + # "Getter. Allows for value = self.key" + # return self.db_key + ##@key.setter + #def __key_set(self, value): + # "Setter. Allows for self.key = value" + # self.db_key = value + # self.save() + ##@key.deleter + #def __key_del(self): + # "Deleter. Allows for del self.key. Deletes entry." + # self.delete() + #key = property(__key_get, __key_set, __key_del) - # help_category property (wraps db_help_category) - #@property - def __help_category_get(self): - "Getter. Allows for value = self.help_category" - return self.db_help_category - #@help_category.setter - def __help_category_set(self, value): - "Setter. Allows for self.help_category = value" - self.db_help_category = value - self.save() - #@help_category.deleter - def __help_category_del(self): - "Deleter. Allows for del self.help_category" - self.db_help_category = "General" - self.save() - help_category = property(__help_category_get, __help_category_set, __help_category_del) + ## help_category property (wraps db_help_category) + ##@property + #def __help_category_get(self): + # "Getter. Allows for value = self.help_category" + # return self.db_help_category + ##@help_category.setter + #def __help_category_set(self, value): + # "Setter. Allows for self.help_category = value" + # self.db_help_category = value + # self.save() + ##@help_category.deleter + #def __help_category_del(self): + # "Deleter. Allows for del self.help_category" + # self.db_help_category = "General" + # self.save() + #help_category = property(__help_category_get, __help_category_set, __help_category_del) - # entrytext property (wraps db_entrytext) - #@property - def __entrytext_get(self): - "Getter. Allows for value = self.entrytext" - return self.db_entrytext - #@entrytext.setter - def __entrytext_set(self, value): - "Setter. Allows for self.entrytext = value" - self.db_entrytext = value - self.save() - #@entrytext.deleter - def __entrytext_del(self): - "Deleter. Allows for del self.entrytext" - self.db_entrytext = "" - self.save() - entrytext = property(__entrytext_get, __entrytext_set, __entrytext_del) + ## entrytext property (wraps db_entrytext) + ##@property + #def __entrytext_get(self): + # "Getter. Allows for value = self.entrytext" + # return self.db_entrytext + ##@entrytext.setter + #def __entrytext_set(self, value): + # "Setter. Allows for self.entrytext = value" + # self.db_entrytext = value + # self.save() + ##@entrytext.deleter + #def __entrytext_del(self): + # "Deleter. Allows for del self.entrytext" + # self.db_entrytext = "" + # self.save() + #entrytext = property(__entrytext_get, __entrytext_set, __entrytext_del) # permissions property #@property @@ -153,20 +150,20 @@ class HelpEntry(SharedMemoryModel): permissions = property(__permissions_get, __permissions_set, __permissions_del) # lock_storage property (wraps db_lock_storage) - #@property - def __lock_storage_get(self): - "Getter. Allows for value = self.lock_storage" - return self.db_lock_storage - #@nick.setter - def __lock_storage_set(self, value): - """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()""" - self.db_lock_storage = value - self.save() - #@nick.deleter - def __lock_storage_del(self): - "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" - logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) - lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del) + ##@property + #def __lock_storage_get(self): + # "Getter. Allows for value = self.lock_storage" + # return self.db_lock_storage + ##@nick.setter + #def __lock_storage_set(self, value): + # """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()""" + # self.db_lock_storage = value + # self.save() + ##@nick.deleter + #def __lock_storage_del(self): + # "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" + # logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) + #lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del) # diff --git a/src/locks/lockfuncs.py b/src/locks/lockfuncs.py index 2c85a38b95..0e9d85f283 100644 --- a/src/locks/lockfuncs.py +++ b/src/locks/lockfuncs.py @@ -134,7 +134,7 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs): permission is also granted to all ranks higher up in the hierarchy. 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 LOWEST hieararcy-permission of the Player/Object-pair will be used (this is order to avoid Players potentially escalating their own permissions @@ -420,7 +420,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs): return True objid = objid.lower() return any((True for obj in contents - if obj.key.lower() == objid or objid in [al.lower() for al in obj.aliases])) + if obj.key.lower() == objid or objid in [al.lower() for al in obj.aliases.all()])) if not args: # holds() - check if accessed_obj or accessed_obj.obj is held by accessing_obj try: diff --git a/src/objects/admin.py b/src/objects/admin.py index 81d3f96501..f57d6faf31 100644 --- a/src/objects/admin.py +++ b/src/objects/admin.py @@ -6,23 +6,24 @@ from django import forms from django.conf import settings from django.contrib import admin -from src.objects.models import ObjAttribute, ObjectDB, ObjectNick, Alias -from src.utils.utils import mod_import +from src.typeclasses.models import Attribute +from src.objects.models import ObjectDB +from src.typeclasses.models import Tag, LiteAttribute -class ObjAttributeInline(admin.TabularInline): - model = ObjAttribute +class AttributeInline(admin.TabularInline): + model = Attribute fields = ('db_key', 'db_value') extra = 0 -class NickInline(admin.TabularInline): - model = ObjectNick - fields = ('db_nick', 'db_real', 'db_type') +class TagInline(admin.TabularInline): + model = Tag + fields = ('db_key', 'db_category', 'db_data') extra = 0 -class AliasInline(admin.TabularInline): - model = Alias - fields = ("db_key",) +class LiteAttributeInline(admin.TabularInline): + model = LiteAttribute + fields = ('db_key', 'db_category', 'db_data') extra = 0 class ObjectCreateForm(forms.ModelForm): @@ -45,6 +46,7 @@ class ObjectCreateForm(forms.ModelForm): required=False, widget=forms.TextInput(attrs={'size':'78'}), help_text="Most non-character objects don't need a cmdset and can leave this field blank.") + raw_id_fields = ('db_destination', 'db_location', 'db_home') @@ -59,15 +61,16 @@ class ObjectEditForm(ObjectCreateForm): class ObjectDBAdmin(admin.ModelAdmin): - list_display = ('id', 'db_key', 'db_location', 'db_player', 'db_typeclass_path') + list_display = ('id', 'db_key', 'db_player', 'db_typeclass_path') list_display_links = ('id', 'db_key') ordering = ['db_player', 'db_typeclass_path', 'id'] search_fields = ['^db_key', 'db_typeclass_path'] + raw_id_fields = ('db_destination', 'db_location', 'db_home') save_as = True save_on_top = True list_select_related = True - list_filter = ('db_permissions', 'db_location', 'db_typeclass_path') + list_filter = ('db_permissions', 'db_typeclass_path') # editing fields setup @@ -80,7 +83,7 @@ class ObjectDBAdmin(admin.ModelAdmin): ) #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. @@ -89,7 +92,7 @@ class ObjectDBAdmin(admin.ModelAdmin): add_fieldsets = ( (None, { 'fields': (('db_key','db_typeclass_path'), 'db_permissions', - ('db_location', 'db_home'), 'db_destination','db_cmdset_storage' + ('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage' )}), ) def get_fieldsets(self, request, obj=None): @@ -111,6 +114,7 @@ class ObjectDBAdmin(admin.ModelAdmin): return super(ObjectDBAdmin, self).get_form(request, obj, **defaults) def save_model(self, request, obj, form, change): + obj.save() if not change: # adding a new object obj = obj.typeclass diff --git a/src/objects/manager.py b/src/objects/manager.py index 0d2ed20c06..b5471052d7 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -1,6 +1,7 @@ """ Custom manager for Objects. """ +from itertools import chain from django.db.models import Q from django.conf import settings from django.db.models.fields import exceptions @@ -13,7 +14,7 @@ __all__ = ("ObjectManager",) _GA = object.__getattribute__ # delayed import -_OBJATTR = None +_ATTR = None # Try to use a custom way to parse id-tagged multimatches. @@ -34,7 +35,6 @@ class ObjectManager(TypedObjectManager): get_dbref_range object_totals typeclass_search - get_object_with_user get_object_with_player get_objs_with_key_and_typeclass get_objs_with_attr @@ -52,29 +52,8 @@ class ObjectManager(TypedObjectManager): # ObjectManager Get methods # - # user/player related + # player related - @returns_typeclass - def get_object_with_user(self, user): - """ - Matches objects with obj.player.user matching the argument. - A player<->user is a one-to-relationship, so this always - returns just one result or None. - - user - may be a user object or user id. - """ - dbref = self.dbref(user) - if dbref: - try: - return self.get(db_player__user__id=dbref) - except self.model.DoesNotExist: - pass - try: - return self.get(db_player__user=user) - except self.model.DoesNotExist: - return None - - # This returns typeclass since get_object_with_user and get_dbref does. @returns_typeclass def get_object_with_player(self, ostring, exact=True, candidates=None): """ @@ -92,10 +71,10 @@ class ObjectManager(TypedObjectManager): # not a dbref. Search by name. cand_restriction = candidates != None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q() if exact: - return self.filter(cand_restriction & Q(db_player__user__username__iexact=ostring)) + return self.filter(cand_restriction & Q(db_player__username__iexact=ostring)) else: # fuzzy matching - ply_cands = self.filter(cand_restriction & Q(playerdb__user__username__istartswith=ostring)).values_list("db_key", flat=True) - if candidates != None: + ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True) + if candidates: index_matches = string_partial_matching(ply_cands, ostring, ret_index=True) return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches] else: @@ -136,18 +115,17 @@ class ObjectManager(TypedObjectManager): type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q() ## This doesn't work if attribute_value is an object. Workaround below - #q = self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name) & Q(objattribute__db_value=attribute_value)) - #return list(q) 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: # We have to loop for safety since the referenced lookup gives deepcopy error if attribute value is an object. - global _OBJATTR - if not _OBJATTR: - from src.objects.models import ObjAttribute as _OBJATTR - 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)] + global _ATTR + if not _ATTR: + from src.typeclasses.models import Attribute as _ATTR + cands = list(self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name))) + results = [attr.objectdb_set.all() for attr in _ATTR.objects.filter(objectdb__in=cands, db_value=attribute_value)] + return chain(*results) @returns_typeclass_list def get_objs_with_db_property(self, property_name, candidates=None): @@ -219,8 +197,9 @@ 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() - elif candidates != None: + 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) else: @@ -233,7 +212,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/migrations/0001_initial.py b/src/objects/migrations/0001_initial.py index dc5e35441f..ceae227c74 100644 --- a/src/objects/migrations/0001_initial.py +++ b/src/objects/migrations/0001_initial.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -90,8 +101,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -159,7 +170,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } 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 index 6c17ca99a6..521fcc9d96 100644 --- a/src/objects/migrations/0002_auto__del_field_objattribute_db_mode.py +++ b/src/objects/migrations/0002_auto__del_field_objattribute_db_mode.py @@ -49,6 +49,17 @@ class PackedDBobject(object): def __unicode__(self): return u"%s(#%s)" % (self.key, self.id) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -96,8 +107,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -164,7 +175,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0003_auto__add_field_objectdb_db_destination.py b/src/objects/migrations/0003_auto__add_field_objectdb_db_destination.py index 121608c063..b35157b09a 100644 --- a/src/objects/migrations/0003_auto__add_field_objectdb_db_destination.py +++ b/src/objects/migrations/0003_auto__add_field_objectdb_db_destination.py @@ -6,6 +6,17 @@ from django.db import models from src.objects.models import ObjectDB from south import orm +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -41,8 +52,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -110,7 +121,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0004_rename_nick_to_objectnick.py b/src/objects/migrations/0004_rename_nick_to_objectnick.py index ec185397a7..2c51c6f0c6 100644 --- a/src/objects/migrations/0004_rename_nick_to_objectnick.py +++ b/src/objects/migrations/0004_rename_nick_to_objectnick.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -47,8 +58,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -117,7 +128,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0005_add_object_default_locks.py b/src/objects/migrations/0005_add_object_default_locks.py index 0ae1bd3dd4..9be0da80d9 100644 --- a/src/objects/migrations/0005_add_object_default_locks.py +++ b/src/objects/migrations/0005_add_object_default_locks.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -44,8 +55,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -114,7 +125,7 @@ class Migration(DataMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0006_add_view_lock.py b/src/objects/migrations/0006_add_view_lock.py index 5de7d2be95..ed69c8a90b 100644 --- a/src/objects/migrations/0006_add_view_lock.py +++ b/src/objects/migrations/0006_add_view_lock.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -42,8 +53,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -112,7 +123,7 @@ class Migration(DataMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0007_auto__chg_field_objectdb_db_cmdset_storage__chg_field_objectdb_db_lock.py b/src/objects/migrations/0007_auto__chg_field_objectdb_db_cmdset_storage__chg_field_objectdb_db_lock.py index ba4cef59b3..685dc6a0ee 100644 --- a/src/objects/migrations/0007_auto__chg_field_objectdb_db_cmdset_storage__chg_field_objectdb_db_lock.py +++ b/src/objects/migrations/0007_auto__chg_field_objectdb_db_cmdset_storage__chg_field_objectdb_db_lock.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -50,8 +61,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -120,7 +131,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0008_auto.py b/src/objects/migrations/0008_auto.py index 0a6ab7995a..6ff2b3a649 100644 --- a/src/objects/migrations/0008_auto.py +++ b/src/objects/migrations/0008_auto.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -44,8 +55,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -114,7 +125,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0009_converting_attributes.py b/src/objects/migrations/0009_converting_attributes.py index 4368b592de..702e46349a 100644 --- a/src/objects/migrations/0009_converting_attributes.py +++ b/src/objects/migrations/0009_converting_attributes.py @@ -361,6 +361,17 @@ def from_attr(attr, datatuple): # all types of iterables return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -400,8 +411,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -470,7 +481,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0010_converting_attributes.py b/src/objects/migrations/0010_converting_attributes.py index 253c20e391..af7eebc8d6 100644 --- a/src/objects/migrations/0010_converting_attributes.py +++ b/src/objects/migrations/0010_converting_attributes.py @@ -269,6 +269,17 @@ def from_attr(attr, datatuple): # all types of iterables return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -301,8 +312,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -371,7 +382,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0011_typeclass_and_cmdset_to_new_api_default.py b/src/objects/migrations/0011_typeclass_and_cmdset_to_new_api_default.py index 9586ef8437..677520dedc 100644 --- a/src/objects/migrations/0011_typeclass_and_cmdset_to_new_api_default.py +++ b/src/objects/migrations/0011_typeclass_and_cmdset_to_new_api_default.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -50,8 +61,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -120,7 +131,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0012_index_objattr_values.py b/src/objects/migrations/0012_index_objattr_values.py index af622d9e74..85b5ae3d5b 100644 --- a/src/objects/migrations/0012_index_objattr_values.py +++ b/src/objects/migrations/0012_index_objattr_values.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -102,7 +113,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0013_revert_objattr_index.py b/src/objects/migrations/0013_revert_objattr_index.py index 2df3a2032c..88347fc62a 100644 --- a/src/objects/migrations/0013_revert_objattr_index.py +++ b/src/objects/migrations/0013_revert_objattr_index.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -30,8 +41,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -101,7 +112,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0014_auto__chg_field_objectdb_db_lock_storage.py b/src/objects/migrations/0014_auto__chg_field_objectdb_db_lock_storage.py index 8528242ef3..674545fc1b 100644 --- a/src/objects/migrations/0014_auto__chg_field_objectdb_db_lock_storage.py +++ b/src/objects/migrations/0014_auto__chg_field_objectdb_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -102,7 +113,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0015_auto__chg_field_objattribute_db_lock_storage.py b/src/objects/migrations/0015_auto__chg_field_objattribute_db_lock_storage.py index c8a6597ff9..227f7ccd9e 100644 --- a/src/objects/migrations/0015_auto__chg_field_objattribute_db_lock_storage.py +++ b/src/objects/migrations/0015_auto__chg_field_objattribute_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -102,7 +113,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0016_add_sessid.py b/src/objects/migrations/0016_add_sessid.py index ff9d42e6bf..87f9591826 100644 --- a/src/objects/migrations/0016_add_sessid.py +++ b/src/objects/migrations/0016_add_sessid.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -104,7 +115,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0017_rename_default_cmdsets.py b/src/objects/migrations/0017_rename_default_cmdsets.py index 2a3d93d5e4..8412a4d03f 100644 --- a/src/objects/migrations/0017_rename_default_cmdsets.py +++ b/src/objects/migrations/0017_rename_default_cmdsets.py @@ -4,8 +4,20 @@ from south.db import db from south.v2 import DataMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): + depends_on = (('players', '0014_add_attr__playable_characters'),) def forwards(self, orm): "Write your forwards methods here." # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." @@ -32,8 +44,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -103,7 +115,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0018_add_picklefield.py b/src/objects/migrations/0018_add_picklefield.py index f298420dc7..d44499fdd6 100644 --- a/src/objects/migrations/0018_add_picklefield.py +++ b/src/objects/migrations/0018_add_picklefield.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -105,7 +116,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0019_convert_attrdata.py b/src/objects/migrations/0019_convert_attrdata.py index eebe9117f2..33cce76875 100644 --- a/src/objects/migrations/0019_convert_attrdata.py +++ b/src/objects/migrations/0019_convert_attrdata.py @@ -331,6 +331,17 @@ def to_attr(data): return ("simple", data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -435,8 +446,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -507,7 +518,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0020_remove_old_attr_value_field.py b/src/objects/migrations/0020_remove_old_attr_value_field.py index 477c7694ed..aca95071c9 100644 --- a/src/objects/migrations/0020_remove_old_attr_value_field.py +++ b/src/objects/migrations/0020_remove_old_attr_value_field.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -36,8 +47,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -107,7 +118,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/objects/migrations/0021_auto__del_objattribute.py b/src/objects/migrations/0021_auto__del_objattribute.py new file mode 100644 index 0000000000..2ac2ccb5c5 --- /dev/null +++ b/src/objects/migrations/0021_auto__del_objattribute.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'ObjAttribute' + db.delete_table(u'objects_objattribute') + + # Adding M2M table for field db_attributes on 'ObjectDB' + db.create_table(u'objects_objectdb_db_attributes', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('objectdb', models.ForeignKey(orm[u'objects.objectdb'], null=False)), + ('attribute', models.ForeignKey(orm[u'typeclasses.attribute'], null=False)) + )) + db.create_unique(u'objects_objectdb_db_attributes', ['objectdb_id', 'attribute_id']) + + + def backwards(self, orm): + # Adding model 'ObjAttribute' + db.create_table(u'objects_objattribute', ( + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_value2', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['objects.ObjectDB'])), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('objects', ['ObjAttribute']) + + # Removing M2M table for field db_attributes on 'ObjectDB' + db.delete_table('objects_objectdb_db_attributes') + + + 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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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'objects.objectnick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'}), + 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': "orm['%s']" % user_orm_label, '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 = ['objects'] \ No newline at end of file diff --git a/src/objects/migrations/0022_add_db_liteattributes_db_tags.py b/src/objects/migrations/0022_add_db_liteattributes_db_tags.py new file mode 100644 index 0000000000..9fcefb6a4a --- /dev/null +++ b/src/objects/migrations/0022_add_db_liteattributes_db_tags.py @@ -0,0 +1,141 @@ +# -*- 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 'ObjectDB' + m2m_table_name = db.shorten_name(u'objects_objectdb_db_liteattributes') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('objectdb', models.ForeignKey(orm[u'objects.objectdb'], null=False)), + ('liteattribute', models.ForeignKey(orm[u'typeclasses.liteattribute'], null=False)) + )) + db.create_unique(m2m_table_name, ['objectdb_id', 'liteattribute_id']) + + # Adding M2M table for field db_tags on 'ObjectDB' + m2m_table_name = db.shorten_name(u'objects_objectdb_db_tags') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('objectdb', models.ForeignKey(orm[u'objects.objectdb'], null=False)), + ('tag', models.ForeignKey(orm[u'typeclasses.tag'], null=False)) + )) + db.create_unique(m2m_table_name, ['objectdb_id', 'tag_id']) + + + def backwards(self, orm): + # Removing M2M table for field db_liteattributes on 'ObjectDB' + db.delete_table(db.shorten_name(u'objects_objectdb_db_liteattributes')) + + # Removing M2M table for field db_tags on 'ObjectDB' + db.delete_table(db.shorten_name(u'objects_objectdb_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.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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'objects.objectnick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'}), + 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'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 = ['objects'] diff --git a/src/objects/migrations/0023_auto__del_objectnick__del_unique_objectnick_db_nick_db_type_db_obj__de.py b/src/objects/migrations/0023_auto__del_objectnick__del_unique_objectnick_db_nick_db_type_db_obj__de.py new file mode 100644 index 0000000000..3f8ba80cab --- /dev/null +++ b/src/objects/migrations/0023_auto__del_objectnick__del_unique_objectnick_db_nick_db_type_db_obj__de.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + depends_on = (('typeclasses', '0004_copy_nicks_to_liteattrs_aliases_to_tags'),) + + def forwards(self, orm): + # Removing unique constraint on 'ObjectNick', fields ['db_nick', 'db_type', 'db_obj'] + db.delete_unique(u'objects_objectnick', ['db_nick', 'db_type', 'db_obj_id']) + + # Deleting model 'ObjectNick' + db.delete_table(u'objects_objectnick') + + # Deleting model 'Alias' + db.delete_table(u'objects_alias') + + + def backwards(self, orm): + # Adding model 'ObjectNick' + db.create_table(u'objects_objectnick', ( + ('db_type', self.gf('django.db.models.fields.CharField')(default='inputline', max_length=16, null=True, blank=True)), + ('db_nick', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['objects.ObjectDB'])), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_real', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'objects', ['ObjectNick']) + + # Adding unique constraint on 'ObjectNick', fields ['db_nick', 'db_type', 'db_obj'] + db.create_unique(u'objects_objectnick', ['db_nick', 'db_type', 'db_obj_id']) + + # Adding model 'Alias' + db.create_table(u'objects_alias', ( + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['objects.ObjectDB'])), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal(u'objects', ['Alias']) + + + 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'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 = ['objects'] diff --git a/src/objects/models.py b/src/objects/models.py index b0e2773269..eca42c30c8 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -18,12 +18,11 @@ import traceback from django.db import models from django.conf import settings -from src.utils.idmapper.models import SharedMemoryModel -from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler +from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler from src.server.caches import get_field_cache, set_field_cache, del_field_cache -from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache +from src.server.caches import get_prop_cache, set_prop_cache + from src.typeclasses.typeclass import TypeClass -from src.players.models import PlayerNick from src.objects.manager import ObjectManager from src.players.models import PlayerDB from src.commands.cmdsethandler import CmdSetHandler @@ -34,7 +33,7 @@ from src.utils.utils import make_iter, to_unicode, variable_from_module, inherit from django.utils.translation import ugettext as _ -#__all__ = ("ObjAttribute", "Alias", "ObjectNick", "ObjectDB") +#__all__ = ("ObjectDB", ) _ScriptDB = None _AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) @@ -47,78 +46,6 @@ _ME = _("me") _SELF = _("self") _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" - -#------------------------------------------------------------ -# -# Alias -# -#------------------------------------------------------------ - -class Alias(SharedMemoryModel): - """ - This model holds a range of alternate names for an object. - These are intrinsic properties of the object. The split - is so as to allow for effective global searches also by - alias. - """ - db_key = models.CharField('alias', max_length=255, db_index=True) - db_obj = models.ForeignKey("ObjectDB", verbose_name='object') - - class Meta: - "Define Django meta options" - verbose_name = "Object alias" - verbose_name_plural = "Object aliases" - def __unicode__(self): - return u"%s" % self.db_key - def __str__(self): - return str(self.db_key) - - - -#------------------------------------------------------------ -# -# Object Nicks -# -#------------------------------------------------------------ - -class ObjectNick(TypeNick): - """ - - The default nick types used by Evennia are: - inputline (default) - match against all input - player - match against player searches - obj - match against object searches - channel - used to store own names for channels - """ - db_obj = models.ForeignKey("ObjectDB", verbose_name='object') - - class Meta: - "Define Django meta options" - verbose_name = "Nickname for Objects" - verbose_name_plural = "Nicknames for Objects" - unique_together = ("db_nick", "db_type", "db_obj") - -class ObjectNickHandler(TypeNickHandler): - """ - Handles nick access and setting. Accessed through ObjectDB.nicks - """ - NickClass = ObjectNick - - #------------------------------------------------------------ # # ObjectDB @@ -171,9 +98,10 @@ class ObjectDB(TypedObject): # db_key (also 'name' works), db_typeclass_path, db_date_created, # db_permissions # - # These databse fields (including the inherited ones) are all set - # using their corresponding properties, named same as the field, - # but withtout the db_* prefix. + # These databse fields (including the inherited ones) should normally be set + # using their corresponding wrapper properties, named same as the field, but without + # the db_* prefix (e.g. the db_key field is set with self.key instead). The wrappers + # will automatically save and cache the data more efficiently. # If this is a character object, the player is connected here. db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player', @@ -200,8 +128,11 @@ class ObjectDB(TypedObject): # Database manager objects = ObjectManager() - # Add the object-specific handlers + # caches for quick lookups of typeclass loading. + _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS + _default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object" + # Add the object-specific handlers def __init__(self, *args, **kwargs): "Parent must be initialized first." TypedObject.__init__(self, *args, **kwargs) @@ -209,8 +140,11 @@ class ObjectDB(TypedObject): _SA(self, "cmdset", CmdSetHandler(self)) _GA(self, "cmdset").update(init_mode=True) _SA(self, "scripts", ScriptHandler(self)) - _SA(self, "nicks", ObjectNickHandler(self)) - # store the attribute class + _SA(self, "tags", TagHandler(self, category_prefix="object_")) + _SA(self, "aliases", AliasHandler(self, category_prefix="object_")) + _SA(self, "nicks", NickHandler(self, category_prefix="object_")) + # make sure to sync the contents cache when initializing + self.contents_update() # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using @@ -220,30 +154,7 @@ class ObjectDB(TypedObject): # value = self.attr and del self.attr respectively (where self # is the object in question). - # aliases property (wraps (db_aliases) - #@property - def __aliases_get(self): - "Getter. Allows for value = self.aliases" - aliases = get_prop_cache(self, "_aliases") - if aliases == None: - aliases = list(Alias.objects.filter(db_obj=self).values_list("db_key", flat=True)) - set_prop_cache(self, "_aliases", aliases) - return aliases - #@aliases.setter - def __aliases_set(self, aliases): - "Setter. Allows for self.aliases = value" - for alias in make_iter(aliases): - new_alias = Alias(db_key=alias, db_obj=self) - new_alias.save() - set_prop_cache(self, "_aliases", make_iter(aliases)) - #@aliases.deleter - def __aliases_del(self): - "Deleter. Allows for del self.aliases" - for alias in Alias.objects.filter(db_obj=self): - alias.delete() - del_prop_cache(self, "_aliases") - aliases = property(__aliases_get, __aliases_set, __aliases_del) - + #TODO - make player-handler # player property (wraps db_player) #@property def __player_get(self): @@ -279,47 +190,37 @@ class ObjectDB(TypedObject): # sessid property (wraps db_sessid) #@property - def __sessid_get(self): - """ - Getter. Allows for value = self.sessid. Since sessid - is directly related to self.player, we cannot have - a sessid without a player being connected (but the - opposite could be true). - """ - if not get_field_cache(self, "sessid"): - del_field_cache(self, "sessid") - return get_field_cache(self, "sessid") - #@sessid.setter - def __sessid_set(self, sessid): - "Setter. Allows for self.player = value" - set_field_cache(self, "sessid", sessid) - #@sessid.deleter - def __sessid_del(self): - "Deleter. Allows for del self.player" - del_field_cache(self, "sessid") - sessid = property(__sessid_get, __sessid_set, __sessid_del) + #def __sessid_get(self): + # """ + # Getter. Allows for value = self.sessid. Since sessid + # is directly related to self.player, we cannot have + # a sessid without a player being connected (but the + # opposite could be true). + # """ + # if not get_field_cache(self, "sessid"): + # del_field_cache(self, "sessid") + # return get_field_cache(self, "sessid") + ##@sessid.setter + #def __sessid_set(self, sessid): + # "Setter. Allows for self.player = value" + # set_field_cache(self, "sessid", sessid) + ##@sessid.deleter + #def __sessid_del(self): + # "Deleter. Allows for del self.player" + # del_field_cache(self, "sessid") + #sessid = property(__sessid_get, __sessid_set, __sessid_del) - # location property (wraps db_location) - #@property - def __location_get(self): - "Getter. Allows for value = self.location." - loc = get_field_cache(self, "location") - if loc: - return _GA(loc, "typeclass") - return None - #@location.setter - def __location_set(self, location): - "Setter. Allows for self.location = location" + def _db_location_handler(self, loc, old_value=None): + "This handles changes to the db_location field." + #print "db_location_handler:", loc, old_value try: - old_loc = _GA(self, "location") - if ObjectDB.objects.dbref(location): - # dbref search - loc = ObjectDB.objects.dbref_search(location) - loc = loc and _GA(loc, "dbobj") - elif location and type(location) != ObjectDB: - loc = _GA(location, "dbobj") - else: - loc = location + old_loc = old_value + # new_value can be dbref, typeclass or dbmodel + if ObjectDB.objects.dbref(loc, reqhash=False): + loc = ObjectDB.objects.dbref_search(loc) + if loc and type(loc) != ObjectDB: + # this should not fail if new_value is valid. + loc = _GA(loc, "dbobj") # recursive location check def is_loc_loop(loc, depth=0): @@ -332,13 +233,13 @@ class ObjectDB(TypedObject): try: is_loc_loop(loc) except RuntimeWarning: pass - # set the location - set_field_cache(self, "location", loc) + #print "db_location_handler2:", _GA(loc, "db_key") if loc else loc, type(loc) # update the contents of each location if old_loc: - _GA(_GA(old_loc, "dbobj"), "contents_update")() + _GA(_GA(old_loc, "dbobj"), "contents_update")(self, remove=True) if loc: - _GA(loc, "contents_update")() + _GA(loc, "contents_update")(self) + return loc except RuntimeError: string = "Cannot set location, " string += "%s.location = %s would create a location-loop." % (self.key, loc) @@ -347,18 +248,71 @@ class ObjectDB(TypedObject): raise RuntimeError(string) except Exception, e: string = "Cannot set location (%s): " % str(e) - string += "%s is not a valid location." % location + string += "%s is not a valid location." % loc _GA(self, "msg")(_(string)) logger.log_trace(string) raise Exception(string) - #@location.deleter - def __location_del(self): - "Deleter. Allows for del self.location" - _GA(self, "location").contents_update() - _SA(self, "db_location", None) - _GA(self, "save")() - del_field_cache(self, "location") - location = property(__location_get, __location_set, __location_del) + + ## location property (wraps db_location) + ##@property + #def __location_get(self): + # "Getter. Allows for value = self.location." + # loc = get_field_cache(self, "location") + # if loc: + # return _GA(loc, "typeclass") + # return None + ##@location.setter + #def __location_set(self, location): + # "Setter. Allows for self.location = location" + # try: + # old_loc = _GA(self, "location") + # if ObjectDB.objects.dbref(location): + # # dbref search + # loc = ObjectDB.objects.dbref_search(location) + # loc = loc and _GA(loc, "dbobj") + # elif location and type(location) != ObjectDB: + # loc = _GA(location, "dbobj") + # else: + # loc = location + + # # recursive location check + # def is_loc_loop(loc, depth=0): + # "Recursively traverse the target location to make sure we are not in it." + # if depth > 10: return + # elif loc == self: raise RuntimeError + # elif loc == None: raise RuntimeWarning # just to quickly get out + # return is_loc_loop(_GA(loc, "db_location"), depth+1) + # # check so we don't create a location loop - if so, RuntimeError will be raised. + # try: is_loc_loop(loc) + # except RuntimeWarning: pass + + # # set the location + # set_field_cache(self, "location", loc) + # # update the contents of each location + # if old_loc: + # _GA(_GA(old_loc, "dbobj"), "contents_update")() + # if loc: + # _GA(loc, "contents_update")() + # except RuntimeError: + # string = "Cannot set location, " + # string += "%s.location = %s would create a location-loop." % (self.key, loc) + # _GA(self, "msg")(_(string)) + # logger.log_trace(string) + # raise RuntimeError(string) + # except Exception, e: + # string = "Cannot set location (%s): " % str(e) + # string += "%s is not a valid location." % location + # _GA(self, "msg")(_(string)) + # logger.log_trace(string) + # raise Exception(string) + ##@location.deleter + #def __location_del(self): + # "Deleter. Allows for del self.location" + # _GA(self, "location").contents_update() + # _SA(self, "db_location", None) + # _GA(self, "save")() + # del_field_cache(self, "location") + #location = property(__location_get, __location_set, __location_del) # home property (wraps db_home) #@property @@ -466,11 +420,6 @@ class ObjectDB(TypedObject): # ObjectDB class access methods/properties # - # this is required to properly handle attributes and typeclass loading. - _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS - _attribute_class = ObjAttribute - _db_model_name = "objectdb" # used by attributes to safely store objects - _default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object" #@property def __sessions_get(self): @@ -515,19 +464,26 @@ class ObjectDB(TypedObject): exclude = make_iter(exclude) if cont == None: cont = _GA(self, "contents_update")() - return [obj for obj in cont if obj not in exclude] + return [obj for obj in cont.values() if obj not in exclude] contents = property(contents_get) - def contents_update(self): + def contents_update(self, obj=None, remove=False): """ - Updates the contents property of the object with a new - object Called by - self.location_set. + Updates the contents property of the object - obj - - remove (true/false) - remove obj from content list + add - object to add to content list + remove object to remove from content list """ - cont = ObjectDB.objects.get_contents(self) + cont = get_prop_cache(self, "_contents") + if not cont: + cont = {} + if obj: + if remove: + cont.pop(self.dbid, None) + else: + cont[self.dbid] = obj + else: + cont = dict((o.dbid, o) for o in ObjectDB.objects.get_contents(self)) set_prop_cache(self, "_contents", cont) return cont @@ -609,15 +565,15 @@ class ObjectDB(TypedObject): return self.typeclass if use_nicks: - nick = None nicktype = "object" - # look up nicks - nicks = ObjectNick.objects.filter(db_obj=self, db_type=nicktype) + # get all valid nicks to search + nicks = self.nicks.get(category="object_nick_%s" % nicktype) if self.has_player: - nicks = list(nicks) + list(PlayerNick.objects.filter(db_obj=self.db_player, db_type=nicktype)) + 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 @@ -689,12 +645,15 @@ class ObjectDB(TypedObject): raw_list = raw_string.split(None) raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]] - nicks = ObjectNick.objects.filter(db_obj=self, db_type__in=("inputline", "channel")) + # fetch the nick data efficiently + nicks = self.db_liteattributes.filter(db_category__in=("object_nick_inputline", "object_nick_channel")).prefetch_related("db_key","db_data") if self.has_player: - nicks = list(nicks) + list(PlayerNick.objects.filter(db_obj=self.db_player, db_type__in=("inputline","channel"))) + pnicks = self.player.db_liteattributes.filter( + db_category__in=("player_nick_inputline", "player_nick_channel")).prefetch_related("db_key","db_data") + nicks = list(nicks) + list(pnicks) for nick in nicks: - if nick.db_nick in raw_list: - raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1) + if nick.db_key in raw_list: + raw_string = raw_string.replace(nick.db_key, nick.db_data, 1) break return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, sessid=sessid) diff --git a/src/objects/objects.py b/src/objects/objects.py index 6a748cdbb3..aa83900758 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -910,7 +910,7 @@ class Exit(Object): # create an exit command. cmd = ExitCommand(key=exidbobj.db_key.strip().lower(), - aliases=exidbobj.aliases, + aliases=exidbobj.aliases.all(), locks=str(exidbobj.locks), auto_help=False, destination=exidbobj.db_destination, diff --git a/src/objects/tests.py b/src/objects/tests.py index a9e43cb915..dbf45d209e 100644 --- a/src/objects/tests.py +++ b/src/objects/tests.py @@ -34,19 +34,20 @@ class TestObjAttrs(TestCase): """ Test aspects of ObjAttributes """ - def setUp(self): - "set up the test" - self.attr = models.ObjAttribute() - self.obj1 = create.create_object(objects.Object, key="testobj1", location=None) - self.obj2 = create.create_object(objects.Object, key="testobj2", location=self.obj1) - def test_store_str(self): - hstring = u"sdfv00=97sfjs842 ivfjlQKFos9GF^8dddsöäå-?%" - self.obj1.db.testattr = hstring - self.assertEqual(hstring, self.obj1.db.testattr) - def test_store_obj(self): - self.obj1.db.testattr = self.obj2 - self.assertEqual(self.obj2 ,self.obj1.db.testattr) - self.assertEqual(self.obj2.location, self.obj1.db.testattr.location) + pass +# def setUp(self): +# "set up the test" +# self.attr = models.ObjAttribute() +# self.obj1 = create.create_object(objects.Object, key="testobj1", location=None) +# self.obj2 = create.create_object(objects.Object, key="testobj2", location=self.obj1) +# def test_store_str(self): +# hstring = u"sdfv00=97sfjs842 ivfjlQKFos9GF^8dddsöäå-?%" +# self.obj1.db.testattr = hstring +# self.assertEqual(hstring, self.obj1.db.testattr) +# def test_store_obj(self): +# self.obj1.db.testattr = self.obj2 +# self.assertEqual(self.obj2 ,self.obj1.db.testattr) +# self.assertEqual(self.obj2.location, self.obj1.db.testattr.location) def suite(): """ diff --git a/src/players/admin.py b/src/players/admin.py index 64e8e3d36b..52db397665 100644 --- a/src/players/admin.py +++ b/src/players/admin.py @@ -11,29 +11,38 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.admin import widgets from django.contrib.auth.forms import UserChangeForm, UserCreationForm 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 -# remove User itself from admin site -admin.site.unregister(User) # handle the custom User editor -class CustomUserChangeForm(UserChangeForm): +class PlayerDBChangeForm(UserChangeForm): + + class Meta: + model = PlayerDB + username = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$', widget=forms.TextInput(attrs={'size':'30'}), error_messages = {'invalid': "This value may contain only letters, spaces, numbers and @/./+/-/_ characters."}, help_text = "30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only.") + def clean_username(self): username = self.cleaned_data['username'] if username.upper() == self.instance.username.upper(): return username - elif User.objects.filter(username__iexact=username): + elif PlayerDB.objects.filter(username__iexact=username): raise forms.ValidationError('A player with that name already exists.') return self.cleaned_data['username'] -class CustomUserCreationForm(UserCreationForm): + +class PlayerDBCreationForm(UserCreationForm): + + class Meta: + model = PlayerDB + username = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$', @@ -43,26 +52,26 @@ class CustomUserCreationForm(UserCreationForm): def clean_username(self): username = self.cleaned_data['username'] - if User.objects.filter(username__iexact=username): + if PlayerDB.objects.filter(username__iexact=username): raise forms.ValidationError('A player with that name already exists.') return username # # The Player editor -# class PlayerAttributeForm(forms.ModelForm): +# class AttributeForm(forms.ModelForm): # "Defines how to display the atttributes" # class Meta: -# model = PlayerAttribute +# model = Attribute # db_key = forms.CharField(label="Key", # widget=forms.TextInput(attrs={'size':'15'})) # db_value = forms.CharField(label="Value", # widget=forms.Textarea(attrs={'rows':'2'})) -# class PlayerAttributeInline(admin.TabularInline): +# class AttributeInline(admin.TabularInline): # "Inline creation of player attributes" -# model = PlayerAttribute +# model = Attribute # extra = 0 -# form = PlayerAttributeForm +# form = AttributeForm # fieldsets = ( # (None, {'fields' : (('db_key', 'db_value'))}),) @@ -71,6 +80,7 @@ class PlayerForm(forms.ModelForm): class Meta: model = PlayerDB + db_key = forms.RegexField(label="Username", initial="PlayerDummy", max_length=30, @@ -116,16 +126,12 @@ class PlayerInline(admin.StackedInline): extra = 1 max_num = 1 -class UserAdmin(BaseUserAdmin): +class PlayerDBAdmin(BaseUserAdmin): "This is the main creation screen for Users/players" - list_display = ('username','email', 'is_staff', 'is_superuser') - form = CustomUserChangeForm - add_form = CustomUserCreationForm - inlines = [PlayerInline] - add_form_template = "admin/players/add_form.html" - change_form_template = "admin/players/change_form.html" - change_list_template = "admin/players/change_list.html" + list_display = ('username', 'email', 'is_staff', 'is_superuser') + form = PlayerDBChangeForm + add_form = PlayerDBCreationForm fieldsets = ( (None, {'fields': ('username', 'password', 'email')}), ('Website profile', {'fields': ('first_name', 'last_name'), @@ -133,7 +139,9 @@ class UserAdmin(BaseUserAdmin): ('Website dates', {'fields': ('last_login', 'date_joined'), 'description':'Relevant only to the website.'}), ('Website Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions','groups'), - 'description': "These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights."}),) + 'description': "These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights."}), + ('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'), + 'description': 'These are attributes that are more relevant to gameplay.'})) add_fieldsets = ( @@ -141,12 +149,12 @@ class UserAdmin(BaseUserAdmin): {'fields': ('username', 'password1', 'password2', 'email'), 'description':"These account details are shared by the admin system and the game."},),) + # TODO! Remove User reference! def save_formset(self, request, form, formset, change): "Run all hooks on the player object" - super(UserAdmin, self).save_formset(request, form, formset, change) + super(PlayerDBAdmin, self).save_formset(request, form, formset, change) userobj = form.instance - playerobj = userobj.get_profile() - playerobj.name = userobj.username + userobj.name = userobj.username if not change: #uname, passwd, email = str(request.POST.get(u"username")), \ # str(request.POST.get(u"password1")), str(request.POST.get(u"email")) @@ -154,6 +162,6 @@ class UserAdmin(BaseUserAdmin): create.create_player("","","", user=userobj, typeclass=typeclass, - player_dbobj=playerobj) + player_dbobj=userobj) -admin.site.register(User, UserAdmin) +admin.site.register(PlayerDB, PlayerDBAdmin) diff --git a/src/players/manager.py b/src/players/manager.py index 9916928f51..4bfc9605b0 100644 --- a/src/players/manager.py +++ b/src/players/manager.py @@ -3,8 +3,8 @@ The managers for the custom Player object and permissions. """ import datetime +from django.contrib.auth.models import UserManager from functools import update_wrapper -from django.contrib.auth.models import User from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager from src.utils import logger __all__ = ("PlayerManager",) @@ -13,54 +13,7 @@ __all__ = ("PlayerManager",) # Player Manager # -def returns_player_list(method): - """ - decorator that makes sure that a method - returns a Player object instead of a User - one (if you really want the User object, not - the player, use the player's 'user' property) - """ - def func(self, *args, **kwargs): - "This *always* returns a list." - match = method(self, *args, **kwargs) - if not match: - return [] - try: - match = list(match) - except TypeError: - match = [match] - players = [] - for user in match: - try: - players.append(user.get_profile()) - except Exception: - # there is something wrong with get_profile. But - # there is a 1-1 relation between Users-Players, so we - # try to go the other way instead. - from src.players.models import PlayerDB - match = PlayerDB.objects.filter(user__id=user.id) - if match: - players.append(match[0]) - else: - logger.log_trace("No connection User<->Player, maybe database was partially reset?") - return players - return update_wrapper(func, method) - -def returns_player(method): - """ - Decorator: Always returns a single result or None. - """ - def func(self, *args, **kwargs): - "decorator" - rfunc = returns_player_list(method) - match = rfunc(self, *args, **kwargs) - if match: - return match[0] - else: - return None - return update_wrapper(func, method) - -class PlayerManager(TypedObjectManager): +class PlayerManager(TypedObjectManager, UserManager): """ This PlayerManager implements methods for searching and manipulating Players directly from the database. @@ -87,7 +40,7 @@ class PlayerManager(TypedObjectManager): """ def num_total_players(self): """ - Returns the total number of registered users/players. + Returns the total number of registered players. """ return self.count() @@ -99,7 +52,6 @@ class PlayerManager(TypedObjectManager): return self.filter(db_is_connected=True) @returns_typeclass_list - @returns_player_list def get_recently_created_players(self, days=7): """ Returns a QuerySet containing the player User accounts that have been @@ -108,13 +60,12 @@ class PlayerManager(TypedObjectManager): end_date = datetime.datetime.now() tdelta = datetime.timedelta(days) start_date = end_date - tdelta - return User.objects.filter(date_joined__range=(start_date, end_date)) + return self.filter(date_joined__range=(start_date, end_date)) @returns_typeclass_list - @returns_player_list def get_recently_connected_players(self, days=7): """ - Returns a QuerySet containing the player User accounts that have been + Returns a QuerySet containing the player accounts that have been connected within the last days. days - number of days backwards to check @@ -122,33 +73,31 @@ class PlayerManager(TypedObjectManager): end_date = datetime.datetime.now() tdelta = datetime.timedelta(days) start_date = end_date - tdelta - return User.objects.filter(last_login__range=( + return self.filter(last_login__range=( start_date, end_date)).order_by('-last_login') @returns_typeclass - @returns_player def get_player_from_email(self, uemail): """ Returns a player object when given an email address. """ - return User.objects.filter(email__iexact=uemail) + return self.filter(email__iexact=uemail) @returns_typeclass - @returns_player def get_player_from_uid(self, uid): """ Returns a player object based on User id. """ try: - return User.objects.get(id=uid) - except User.model.DoesNotExist: + return self.get(id=uid) + except self.model.DoesNotExist: return None @returns_typeclass def get_player_from_name(self, uname): "Get player object based on name" try: - return self.get(user__username__iexact=uname) + return self.get(username__iexact=uname) except self.model.DoesNotExist: return None @@ -165,7 +114,7 @@ class PlayerManager(TypedObjectManager): matches = self.filter(id=dbref) if matches: return matches - return self.filter(user__username__iexact=ostring) + return self.filter(username__iexact=ostring) def swap_character(self, player, new_character, delete_old_character=False): """ diff --git a/src/players/migrations/0001_initial.py b/src/players/migrations/0001_initial.py index a865b555d8..82af0ca229 100644 --- a/src/players/migrations/0001_initial.py +++ b/src/players/migrations/0001_initial.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): depends_on = ( @@ -32,7 +43,7 @@ class Migration(SchemaMigration): ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), ('db_permissions', self.gf('django.db.models.fields.CharField')(max_length=512, blank=True)), ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[user_orm_label], unique=True)), ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['objects.ObjectDB'], null=True)), )) db.send_create_signal('players', ['PlayerDB']) @@ -64,8 +75,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -119,7 +130,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } 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 index e7872bf7ed..1fecfe6d40 100644 --- a/src/players/migrations/0002_auto__del_field_playerattribute_db_mode.py +++ b/src/players/migrations/0002_auto__del_field_playerattribute_db_mode.py @@ -398,6 +398,17 @@ def from_attr(datatuple): elif typ == 'iter': # all types of iterables return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -447,8 +458,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -501,7 +512,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py b/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py index c089e1f8ec..bef24f62ac 100644 --- a/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py +++ b/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py @@ -4,16 +4,27 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): - + # Adding field 'PlayerDB.db_cmdset_storage' db.add_column('players_playerdb', 'db_cmdset_storage', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False) def backwards(self, orm): - + # Deleting field 'PlayerDB.db_cmdset_storage' db.delete_column('players_playerdb', 'db_cmdset_storage') @@ -32,8 +43,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -88,7 +99,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) } } diff --git a/src/players/migrations/0004_auto__add_playernick__add_unique_playernick_db_nick_db_type_db_obj.py b/src/players/migrations/0004_auto__add_playernick__add_unique_playernick_db_nick_db_type_db_obj.py index c9f3bf9661..b2754d55fc 100644 --- a/src/players/migrations/0004_auto__add_playernick__add_unique_playernick_db_nick_db_type_db_obj.py +++ b/src/players/migrations/0004_auto__add_playernick__add_unique_playernick_db_nick_db_type_db_obj.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -45,8 +56,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -101,7 +112,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0005_adding_player_cmdset.py b/src/players/migrations/0005_adding_player_cmdset.py index e417132e06..ba198f4e33 100644 --- a/src/players/migrations/0005_adding_player_cmdset.py +++ b/src/players/migrations/0005_adding_player_cmdset.py @@ -6,6 +6,17 @@ from django.db import models, utils from django.conf import settings +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -37,8 +48,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -93,7 +104,7 @@ class Migration(DataMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0006_auto__chg_field_playerdb_db_cmdset_storage__chg_field_playerdb_db_lock.py b/src/players/migrations/0006_auto__chg_field_playerdb_db_cmdset_storage__chg_field_playerdb_db_lock.py index 6c5b35fd1c..e7f2574d3e 100644 --- a/src/players/migrations/0006_auto__chg_field_playerdb_db_cmdset_storage__chg_field_playerdb_db_lock.py +++ b/src/players/migrations/0006_auto__chg_field_playerdb_db_cmdset_storage__chg_field_playerdb_db_lock.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -50,8 +61,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -106,7 +117,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0007_auto.py b/src/players/migrations/0007_auto.py index 7080892483..9d5f4922bc 100644 --- a/src/players/migrations/0007_auto.py +++ b/src/players/migrations/0007_auto.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -38,8 +49,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -94,7 +105,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0008_converting_attributes.py b/src/players/migrations/0008_converting_attributes.py index d7d91294fd..5c86fb962e 100644 --- a/src/players/migrations/0008_converting_attributes.py +++ b/src/players/migrations/0008_converting_attributes.py @@ -10,7 +10,6 @@ except ImportError: import pickle from src.utils.utils import to_str, to_unicode #from src.typeclasses.models import PackedDBobject,PackedDict,PackedList -from src.players.models import PlayerAttribute from django.contrib.contenttypes.models import ContentType CTYPEGET = ContentType.objects.get @@ -366,11 +365,22 @@ def from_attr(attr, datatuple): return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): "Write your forwards methods here." - for attr in orm.PlayerAttribute.objects.all(): + for attr in orm['players.PlayerAttribute'].objects.all(): try: # repack attr into new format, and reimport val = pickle.loads(to_str(attr.db_value)) @@ -404,8 +414,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -460,7 +470,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0009_converting_attributes.py b/src/players/migrations/0009_converting_attributes.py index 3d2ddd083d..b978094950 100644 --- a/src/players/migrations/0009_converting_attributes.py +++ b/src/players/migrations/0009_converting_attributes.py @@ -10,7 +10,6 @@ except ImportError: import pickle from src.utils.utils import to_str, to_unicode #from src.typeclasses.models import PackedDBobject -from src.players.models import PlayerAttribute from django.contrib.contenttypes.models import ContentType CTYPEGET = ContentType.objects.get @@ -255,11 +254,22 @@ def from_attr(attr, datatuple): return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): "Write your forwards methods here." - for attr in orm.PlayerAttribute.objects.all(): + for attr in orm['players.PlayerAttribute'].objects.all(): try: # repack attr into new format, and reimport val = pickle.loads(to_str(attr.db_value)) @@ -287,8 +297,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -343,7 +353,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0010_typeclass_and_cmdset_to_new_api_default.py b/src/players/migrations/0010_typeclass_and_cmdset_to_new_api_default.py index 208ecef3a8..78528b7d54 100644 --- a/src/players/migrations/0010_typeclass_and_cmdset_to_new_api_default.py +++ b/src/players/migrations/0010_typeclass_and_cmdset_to_new_api_default.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -38,8 +49,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -94,7 +105,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0011_addin_is_connected_field.py b/src/players/migrations/0011_addin_is_connected_field.py index 4489d89ec9..140a3e8918 100644 --- a/src/players/migrations/0011_addin_is_connected_field.py +++ b/src/players/migrations/0011_addin_is_connected_field.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -90,7 +101,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0012_auto__chg_field_playerdb_db_lock_storage.py b/src/players/migrations/0012_auto__chg_field_playerdb_db_lock_storage.py index 4e3534e575..72043d5ca1 100644 --- a/src/players/migrations/0012_auto__chg_field_playerdb_db_lock_storage.py +++ b/src/players/migrations/0012_auto__chg_field_playerdb_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -88,7 +99,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0013_auto__chg_field_playerattribute_db_lock_storage.py b/src/players/migrations/0013_auto__chg_field_playerattribute_db_lock_storage.py index a3e25da8a2..65564d956d 100644 --- a/src/players/migrations/0013_auto__chg_field_playerattribute_db_lock_storage.py +++ b/src/players/migrations/0013_auto__chg_field_playerattribute_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -88,7 +99,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0014_add_attr__playable_characters.py b/src/players/migrations/0014_add_attr__playable_characters.py index 5e43d416b2..472f9e2d3d 100644 --- a/src/players/migrations/0014_add_attr__playable_characters.py +++ b/src/players/migrations/0014_add_attr__playable_characters.py @@ -21,6 +21,17 @@ class PackedDBobject(object): return u"%s(#%s)" % (self.key, self.id) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -76,8 +87,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -142,7 +153,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0015_removing_obj.py b/src/players/migrations/0015_removing_obj.py index 4601ee25e5..7ec2f00483 100644 --- a/src/players/migrations/0015_removing_obj.py +++ b/src/players/migrations/0015_removing_obj.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -34,8 +45,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -92,7 +103,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0016_rename_default_cmdsets.py b/src/players/migrations/0016_rename_default_cmdsets.py index d0fd40f9be..82ee447995 100644 --- a/src/players/migrations/0016_rename_default_cmdsets.py +++ b/src/players/migrations/0016_rename_default_cmdsets.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -32,8 +43,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -74,7 +85,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0017_add_picklefield.py b/src/players/migrations/0017_add_picklefield.py index 177dca1bcc..550768d4cb 100644 --- a/src/players/migrations/0017_add_picklefield.py +++ b/src/players/migrations/0017_add_picklefield.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -76,7 +87,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0018_convert_attrdata.py b/src/players/migrations/0018_convert_attrdata.py index 343bd030a2..bd7e77e935 100644 --- a/src/players/migrations/0018_convert_attrdata.py +++ b/src/players/migrations/0018_convert_attrdata.py @@ -269,6 +269,17 @@ class PackedSet(set): +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): depends_on = ( ("objects", "0018_add_picklefield"), @@ -371,8 +382,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -429,7 +440,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0019_remove_old_attr_value_field.py b/src/players/migrations/0019_remove_old_attr_value_field.py index db5472d449..5c3483f68b 100644 --- a/src/players/migrations/0019_remove_old_attr_value_field.py +++ b/src/players/migrations/0019_remove_old_attr_value_field.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -34,8 +45,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -76,7 +87,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'players.playernick': { 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, diff --git a/src/players/migrations/0020_auto__del_playerattribute.py b/src/players/migrations/0020_auto__del_playerattribute.py new file mode 100644 index 0000000000..4c2975df53 --- /dev/null +++ b/src/players/migrations/0020_auto__del_playerattribute.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'PlayerAttribute' + db.delete_table(u'players_playerattribute') + + # Adding M2M table for field db_attributes on 'PlayerDB' + db.create_table(u'players_playerdb_db_attributes', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('playerdb', models.ForeignKey(orm[u'players.playerdb'], null=False)), + ('attribute', models.ForeignKey(orm[u'typeclasses.attribute'], null=False)) + )) + db.create_unique(u'players_playerdb_db_attributes', ['playerdb_id', 'attribute_id']) + + + def backwards(self, orm): + # Adding model 'PlayerAttribute' + db.create_table(u'players_playerattribute', ( + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_value2', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['players.PlayerDB'])), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('players', ['PlayerAttribute']) + + # Removing M2M table for field db_attributes on 'PlayerDB' + db.delete_table('players_playerdb_db_attributes') + + + 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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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'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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + u'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': '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'}) + } + } + + complete_apps = ['players'] diff --git a/src/players/migrations/0021_add_playerdbtmp.py b/src/players/migrations/0021_add_playerdbtmp.py new file mode 100644 index 0000000000..08489a859b --- /dev/null +++ b/src/players/migrations/0021_add_playerdbtmp.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models, connection + + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'PlayerDBtmp' + if "auth_user" in connection.introspection.table_names(): + # auth_user exists ffrom before. Use that as a base. + db.rename_table('auth_user', 'players_playerdbtmp') + db.rename_table('auth_user_groups', 'players_playerdbtmp_groups') + db.rename_table('auth_user_user_permissions', 'players_playerdbtmp_user_permissions') + db.rename_column('players_playerdbtmp_groups', 'user_id', 'playerdbtmp_id') + db.rename_column('players_playerdbtmp_user_permissions', 'user_id', 'playerdbtmp_id') + + else: + # from-scratch creation; no auth_user table available. Create vanilla User table + db.create_table(u'players_playerdbtmp', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('password', self.gf('django.db.models.fields.CharField')(max_length=128)), + ('last_login', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), + ('is_superuser', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('username', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30)), + ('first_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)), + ('last_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)), + ('email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)), + ('is_staff', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('date_joined', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), + )) + db.send_create_signal(u'players', ['PlayerDBtmp']) + + # Adding M2M table for field groups on 'PlayerDBtmp' + db.create_table(u'players_playerdbtmp_groups', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('playerdbtmp', models.ForeignKey(orm[u'players.playerdbtmp'], null=False)), + ('group', models.ForeignKey(orm[u'auth.group'], null=False)) + )) + db.create_unique(u'players_playerdbtmp_groups', ['playerdbtmp_id', 'group_id']) + + # Adding M2M table for field user_permissions on 'PlayerDBtmp' + db.create_table(u'players_playerdbtmp_user_permissions', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('playerdbtmp', models.ForeignKey(orm[u'players.playerdbtmp'], null=False)), + ('permission', models.ForeignKey(orm[u'auth.permission'], null=False)) + )) + db.create_unique(u'players_playerdbtmp_user_permissions', ['playerdbtmp_id', 'permission_id']) + + # add Evennia-specific columns + db.add_column('players_playerdbtmp', 'db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True, null=True)) + db.add_column('players_playerdbtmp', 'db_typeclass_path', self.gf('django.db.models.fields.CharField')(max_length=255, null=True)) + db.add_column('players_playerdbtmp', 'db_date_created', self.gf('django.db.models.fields.DateTimeField')(null=True, auto_now_add=True, blank=True)) + db.add_column('players_playerdbtmp', 'db_permissions', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True, null=True)) + db.add_column('players_playerdbtmp', 'db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True, null=True)) + db.add_column('players_playerdbtmp', 'db_is_connected', self.gf('django.db.models.fields.BooleanField')(default=False)) + db.add_column('players_playerdbtmp', 'db_cmdset_storage', self.gf('django.db.models.fields.CharField')(max_length=255, null=True)) + + def backwards(self, orm): + raise RuntimeError("Cannot revert 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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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'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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + u'players.playerdbtmp': { + }, + 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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['players'] diff --git a/src/players/migrations/0022_copy_user_profile_to_tmp.py b/src/players/migrations/0022_copy_user_profile_to_tmp.py new file mode 100644 index 0000000000..302ccd1934 --- /dev/null +++ b/src/players/migrations/0022_copy_user_profile_to_tmp.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(DataMigration): + + def forwards(self, orm): + "Write your forwards methods here." + # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." + if not db.dry_run: + for profile in orm['players.PlayerDB'].objects.all(): + print "player orig:", profile.db_key, profile.db_cmdset_storage + plyr = orm['players.PlayerDBtmp'].objects.get(id=profile.user_id) + plyr.db_cmdset_storage = profile.db_cmdset_storage + plyr.db_date_created = profile.db_date_created + plyr.db_is_connected = profile.db_is_connected + plyr.db_key = profile.db_key + plyr.db_lock_storage = profile.db_lock_storage + plyr.db_typeclass_path = profile.db_typeclass_path + plyr.db_permissions = profile.db_permissions + plyr.save() + + def backwards(self, orm): + "Write your backwards methods here." + raise RuntimeError("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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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'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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + u'players.playerdbtmp': { + 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'}, + '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_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'}), + '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'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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['players'] + symmetrical = True diff --git a/src/players/migrations/0023_delete_old_profile.py b/src/players/migrations/0023_delete_old_profile.py new file mode 100644 index 0000000000..da7372c67a --- /dev/null +++ b/src/players/migrations/0023_delete_old_profile.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.delete_table('players_playerdb') + + def backwards(self, orm): + raise RuntimeError("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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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'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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + u'players.playerdbtmp': { + 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'}, + '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_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'}), + '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'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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['players'] diff --git a/src/players/migrations/0024_rename_tmp_to_player.py b/src/players/migrations/0024_rename_tmp_to_player.py new file mode 100644 index 0000000000..098ac9ae3e --- /dev/null +++ b/src/players/migrations/0024_rename_tmp_to_player.py @@ -0,0 +1,110 @@ +# -*- 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): + + db.rename_table('players_playerdbtmp', 'players_playerdb') + db.rename_table('players_playerdbtmp_groups', 'players_playerdb_groups') + db.rename_column('players_playerdb_groups', 'playerdbtmp_id', 'playerdb_id') + db.rename_table('players_playerdbtmp_user_permissions', 'players_playerdb_user_permissions') + db.rename_column('players_playerdb_user_permissions', 'playerdbtmp_id', 'playerdb_id') + + def backwards(self, orm): + db.rename_table('players_playerdb_groups', 'players_playerdbtmp_groups') + db.rename_column('players_playerdbtmp_groups', 'playerdb_id', 'playerdbtmp_id') + db.rename_table('players_playerdb_user_permissions', 'players_playerdbtmp_user_permissions') + db.rename_column('players_playerdbtmp_user_permissions', 'playerdb_id', 'playerdbtmp_id') + + 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'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_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'}), + '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'players.playerdbtmp': { + 'Meta': {'object_name': 'PlayerDBtmp'}, + '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_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'}), + '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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': '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'}) + } + } + + complete_apps = ['players'] diff --git a/src/players/migrations/0025_auto__add_db_liteattributes_db_tags.py b/src/players/migrations/0025_auto__add_db_liteattributes_db_tags.py new file mode 100644 index 0000000000..ad62bb2288 --- /dev/null +++ b/src/players/migrations/0025_auto__add_db_liteattributes_db_tags.py @@ -0,0 +1,117 @@ +# -*- 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 'PlayerDB' + m2m_table_name = db.shorten_name(u'players_playerdb_db_liteattributes') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('playerdb', models.ForeignKey(orm[u'players.playerdb'], null=False)), + ('liteattribute', models.ForeignKey(orm[u'typeclasses.liteattribute'], null=False)) + )) + db.create_unique(m2m_table_name, ['playerdb_id', 'liteattribute_id']) + + # Adding M2M table for field db_tags on 'PlayerDB' + m2m_table_name = db.shorten_name(u'players_playerdb_db_tags') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('playerdb', models.ForeignKey(orm[u'players.playerdb'], null=False)), + ('tag', models.ForeignKey(orm[u'typeclasses.tag'], null=False)) + )) + db.create_unique(m2m_table_name, ['playerdb_id', 'tag_id']) + + + def backwards(self, orm): + # Removing M2M table for field db_liteattributes on 'PlayerDB' + db.delete_table(db.shorten_name(u'players_playerdb_db_liteattributes')) + + # Removing M2M table for field db_tags on 'PlayerDB' + db.delete_table(db.shorten_name(u'players_playerdb_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'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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': '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 = ['players'] diff --git a/src/players/migrations/0026_auto__del_playernick__del_unique_playernick_db_nick_db_type_db_obj.py b/src/players/migrations/0026_auto__del_playernick__del_unique_playernick_db_nick_db_type_db_obj.py new file mode 100644 index 0000000000..f2b4a85b6c --- /dev/null +++ b/src/players/migrations/0026_auto__del_playernick__del_unique_playernick_db_nick_db_type_db_obj.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + depends_on = (('typeclasses', '0004_copy_nicks_to_liteattrs_aliases_to_tags'),) + + def forwards(self, orm): + # Removing unique constraint on 'PlayerNick', fields ['db_nick', 'db_type', 'db_obj'] + db.delete_unique(u'players_playernick', ['db_nick', 'db_type', 'db_obj_id']) + + # Deleting model 'PlayerNick' + db.delete_table(u'players_playernick') + + + def backwards(self, orm): + # Adding model 'PlayerNick' + db.create_table(u'players_playernick', ( + ('db_type', self.gf('django.db.models.fields.CharField')(default='inputline', max_length=16, null=True, blank=True)), + ('db_nick', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['players.PlayerDB'])), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_real', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'players', ['PlayerNick']) + + # Adding unique constraint on 'PlayerNick', fields ['db_nick', 'db_type', 'db_obj'] + db.create_unique(u'players_playernick', ['db_nick', 'db_type', 'db_obj_id']) + + + 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'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'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 = ['players'] diff --git a/src/players/models.py b/src/players/models.py index aaab60f7e1..1b28ee7885 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -1,21 +1,14 @@ """ Player -The Player class is a simple extension of the django User model using -the 'profile' system of django. A profile is a model that tack new -fields to the User model without actually editing the User model -(which would mean hacking into django internals which we want to avoid -for future compatability reasons). The profile, which we call -'Player', is accessed with user.get_profile() by the property 'player' -defined on ObjectDB objects. Since we can customize it, we will try to -abstract as many operations as possible to work on Player rather than -on User. +The player class is an extension of the default Django user class, +and is customized for the needs of Evennia. We use the Player to store a more mud-friendly style of permission system as well as to allow the admin more flexibility by storing attributes on the Player. Within the game we should normally use the -Player manager's methods to create users, since that automatically -adds the profile extension. +Player manager's methods to create users so that permissions are set +correctly. To make the Player model more flexible for your own game, it can also persistently store attributes of its own. This is ideal for extra @@ -25,23 +18,21 @@ account info and OOC account configuration variables etc. from django.conf import settings from django.db import models -from django.contrib.auth.models import User +from django.contrib.auth.models import AbstractUser from django.utils.encoding import smart_str -from src.server.caches import get_field_cache, set_field_cache, del_field_cache -from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache +from src.server.caches import get_field_cache, set_field_cache + from src.players import manager from src.scripts.models import ScriptDB -from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler -from src.typeclasses.typeclass import TypeClass +from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler from src.commands.cmdsethandler import CmdSetHandler from src.commands import cmdhandler -from src.utils import logger, utils -from src.utils.utils import inherits_from, make_iter +from src.utils import utils from django.utils.translation import ugettext as _ -__all__ = ("PlayerAttribute", "PlayerNick", "PlayerDB") +__all__ = ("PlayerDB",) _ME = _("me") _SELF = _("self") @@ -56,52 +47,6 @@ _DA = object.__delattr__ _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" - -#------------------------------------------------------------ -# -# Player Nicks -# -#------------------------------------------------------------ - -class PlayerNick(TypeNick): - """ - - The default nick types used by Evennia are: - inputline (default) - match against all input - player - match against player searches - obj - match against object searches - channel - used to store own names for channels - """ - db_obj = models.ForeignKey("PlayerDB", verbose_name="player") - - class Meta: - "Define Django meta options" - verbose_name = "Nickname for Players" - verbose_name_plural = "Nicknames Players" - unique_together = ("db_nick", "db_type", "db_obj") - -class PlayerNickHandler(TypeNickHandler): - """ - Handles nick access and setting. Accessed through ObjectDB.nicks - """ - NickClass = PlayerNick #------------------------------------------------------------ @@ -110,7 +55,8 @@ class PlayerNickHandler(TypeNickHandler): # #------------------------------------------------------------ -class PlayerDB(TypedObject): + +class PlayerDB(TypedObject, AbstractUser): """ This is a special model using Django's 'profile' functionality and extends the default Django User model. It is defined as such @@ -143,20 +89,20 @@ class PlayerDB(TypedObject): # inherited fields (from TypedObject): # db_key, db_typeclass_path, db_date_created, db_permissions - # this is the one-to-one link between the customized Player object and - # this profile model. It is required by django. - user = models.ForeignKey(User, unique=True, db_index=True, - help_text="The User object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.") # store a connected flag here too, not just in sessionhandler. # This makes it easier to track from various out-of-process locations db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not") # database storage of persistant cmdsets. db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, - help_text="optional python path to a cmdset class. If creating a Character, this will default to settings.CMDSET_CHARACTER.") + help_text="optional python path to a cmdset class. If creating a Character, this will default to settings.CMDSET_CHARACTER.") # Database manager objects = manager.PlayerManager() + # caches for quick lookups + _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS + _default_typeclass_path = settings.BASE_PLAYER_TYPECLASS or "src.players.player.Player" + class Meta: app_label = 'players' verbose_name = 'Player' @@ -167,7 +113,9 @@ class PlayerDB(TypedObject): # handlers _SA(self, "cmdset", CmdSetHandler(self)) _GA(self, "cmdset").update(init_mode=True) - _SA(self, "nicks", PlayerNickHandler(self)) + _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 @@ -244,27 +192,24 @@ class PlayerDB(TypedObject): def __unicode__(self): return u"%s(player#%s)" % (_GA(self, "name"), _GA(self, "dbid")) - # this is required to properly handle attributes and typeclass loading - _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS - _attribute_class = PlayerAttribute - _db_model_name = "playerdb" # used by attributes to safely store objects - _default_typeclass_path = settings.BASE_PLAYER_TYPECLASS or "src.players.player.Player" # name property (wraps self.user.username) #@property def __name_get(self): "Getter. Allows for value = self.name" - name = get_prop_cache(self, "_name") - if not name: - name = _GA(self,"user").username - set_prop_cache(self, "_name", name) - return name + return self.username + #name = get_prop_cache(self, "_name") + #if not name: + # name = _GA(self,"user").username + # set_prop_cache(self, "_name", name) + #return name #@name.setter def __name_set(self, value): "Setter. Allows for player.name = newname" - _GA(self, "user").username = value - _GA(self, "user").save() - set_prop_cache(self, "_name", value) + self.username = value + #_GA(self, "user").username = value + #_GA(self, "user").save() + #set_prop_cache(self, "_name", value) #@name.deleter def __name_del(self): "Deleter. Allows for del self.name" @@ -275,11 +220,12 @@ class PlayerDB(TypedObject): #@property def __uid_get(self): "Getter. Retrieves the user id" - uid = get_prop_cache(self, "_uid") - if not uid: - uid = _GA(self, "user").id - set_prop_cache(self, "_uid", uid) - return uid + return self.id + #uid = get_prop_cache(self, "_uid") + #if not uid: + # uid = _GA(self, "user").id + # set_prop_cache(self, "_uid", uid) + #return uid def __uid_set(self, value): raise Exception("User id cannot be set!") def __uid_del(self): @@ -287,14 +233,15 @@ class PlayerDB(TypedObject): uid = property(__uid_get, __uid_set, __uid_del) #@property - def __is_superuser_get(self): - "Superusers have all permissions." - is_suser = get_prop_cache(self, "_is_superuser") - if is_suser == None: - is_suser = _GA(self, "user").is_superuser - set_prop_cache(self, "_is_superuser", is_suser) - return is_suser - is_superuser = property(__is_superuser_get) + #def __is_superuser_get(self): + # "Superusers have all permissions." + # return self.db_is_superuser + # #is_suser = get_prop_cache(self, "_is_superuser") + # #if is_suser == None: + # # is_suser = _GA(self, "user").is_superuser + # # set_prop_cache(self, "_is_superuser", is_suser) + # #return is_suser + #is_superuser = property(__is_superuser_get) # # PlayerDB class access methods @@ -516,16 +463,12 @@ class PlayerDB(TypedObject): self.unpuppet_object(session.sessid) session.sessionhandler.disconnect(session, reason=_("Player being deleted.")) - try: - if _GA(self, "user"): - _GA(_GA(self, "user"), "delete")() - except AssertionError: - pass - try: - super(PlayerDB, self).delete(*args, **kwargs) - except AssertionError: - # this means deleting the user already cleared out the Player object. - pass + #try: + # if _GA(self, "user"): + # _GA(_GA(self, "user"), "delete")() + #except AssertionError: + # pass + super(PlayerDB, self).delete(*args, **kwargs) def execute_cmd(self, raw_string, sessid=None): """ @@ -539,9 +482,12 @@ class PlayerDB(TypedObject): raw_list = raw_string.split(None) raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]] - for nick in PlayerNick.objects.filter(db_obj=self, db_type__in=("inputline","channel")): - if nick.db_nick in raw_list: - raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1) + # get the nick replacement data directly from the database to be able to use db_category__in + nicks = self.db_liteattributes.filter( + db_category__in=("object_nick_inputline", "object_nick_channel")).prefetch_related("db_key","db_data") + for nick in nicks: + if nick.db_key in raw_list: + raw_string = raw_string.replace(nick.db_key, nick.db_data, 1) break if not sessid and _MULTISESSION_MODE in (0, 1): # in this case, we should either have only one sessid, or the sessid @@ -573,3 +519,4 @@ class PlayerDB(TypedObject): except: pass return matches + diff --git a/src/scripts/admin.py b/src/scripts/admin.py index b6ba5610b6..89e1413e76 100644 --- a/src/scripts/admin.py +++ b/src/scripts/admin.py @@ -1,31 +1,33 @@ # -# This sets up how models are displayed -# in the web admin interface. +# This sets up how models are displayed +# 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 -class ScriptAttributeInline(admin.TabularInline): - model = ScriptAttribute - fields = ('db_key', 'db_value') +class AttributeInline(admin.TabularInline): + model = Attribute + fields = ('db_key', 'db_value') max_num = 1 class ScriptDBAdmin(admin.ModelAdmin): list_display = ('id', 'db_key', 'db_typeclass_path', 'db_obj', 'db_interval', 'db_repeats', 'db_persistent') list_display_links = ('id', 'db_key') - ordering = ['db_obj', 'db_typeclass_path'] - search_fields = ['^db_key', 'db_typeclass_path'] - save_as = True + ordering = ['db_obj', 'db_typeclass_path'] + search_fields = ['^db_key', 'db_typeclass_path'] + save_as = True save_on_top = True - list_select_related = True + list_select_related = True + raw_id_fields = ('db_obj',) fieldsets = ( (None, { '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) diff --git a/src/scripts/migrations/0001_initial.py b/src/scripts/migrations/0001_initial.py index 3998ef1ae3..e5a78a9b79 100644 --- a/src/scripts/migrations/0001_initial.py +++ b/src/scripts/migrations/0001_initial.py @@ -4,7 +4,21 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): + + depends_on = ( + ('objects', '0001_initial'),) def forwards(self, orm): @@ -62,8 +76,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -107,7 +121,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, 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 index 495be061b8..d2822e03f4 100644 --- a/src/scripts/migrations/0002_auto__del_field_scriptattribute_db_mode.py +++ b/src/scripts/migrations/0002_auto__del_field_scriptattribute_db_mode.py @@ -60,6 +60,17 @@ class PackedDBobject(object): return "%s(#%s)" % (self.key, self.id) def __unicode__(self): return u"%s(#%s)" % (self.key, self.id) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -107,8 +118,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -152,7 +163,7 @@ class Migration(SchemaMigration): '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'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0003_auto__chg_field_scriptdb_db_lock_storage__chg_field_scriptdb_db_permis.py b/src/scripts/migrations/0003_auto__chg_field_scriptdb_db_lock_storage__chg_field_scriptdb_db_permis.py index 6a62b983d8..e34c0f3223 100644 --- a/src/scripts/migrations/0003_auto__chg_field_scriptdb_db_lock_storage__chg_field_scriptdb_db_permis.py +++ b/src/scripts/migrations/0003_auto__chg_field_scriptdb_db_lock_storage__chg_field_scriptdb_db_permis.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -44,8 +55,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -91,7 +102,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0004_auto.py b/src/scripts/migrations/0004_auto.py index d68addaad3..4f6b80e46e 100644 --- a/src/scripts/migrations/0004_auto.py +++ b/src/scripts/migrations/0004_auto.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -38,8 +49,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -85,7 +96,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0005_converting_attributes.py b/src/scripts/migrations/0005_converting_attributes.py index 1f37695772..cfeb9cecee 100644 --- a/src/scripts/migrations/0005_converting_attributes.py +++ b/src/scripts/migrations/0005_converting_attributes.py @@ -364,6 +364,17 @@ def from_attr(attr, datatuple): # all types of iterables return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -401,8 +412,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -448,7 +459,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0006_converting_attributes.py b/src/scripts/migrations/0006_converting_attributes.py index f236af33f2..b6bc873a69 100644 --- a/src/scripts/migrations/0006_converting_attributes.py +++ b/src/scripts/migrations/0006_converting_attributes.py @@ -254,6 +254,17 @@ def from_attr(attr, datatuple): # all types of iterables return iter_id2db(data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -285,8 +296,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -332,7 +343,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0007_typeclass_to_new_api_default.py b/src/scripts/migrations/0007_typeclass_to_new_api_default.py index d1f0d94699..faa1461701 100644 --- a/src/scripts/migrations/0007_typeclass_to_new_api_default.py +++ b/src/scripts/migrations/0007_typeclass_to_new_api_default.py @@ -4,6 +4,17 @@ from south.db import db from south.v2 import DataMigration from django.db import models, utils +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): def forwards(self, orm): @@ -39,8 +50,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -86,7 +97,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0008_auto__chg_field_scriptdb_db_lock_storage.py b/src/scripts/migrations/0008_auto__chg_field_scriptdb_db_lock_storage.py index 8e9dde21d9..261b498b7b 100644 --- a/src/scripts/migrations/0008_auto__chg_field_scriptdb_db_lock_storage.py +++ b/src/scripts/migrations/0008_auto__chg_field_scriptdb_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -79,7 +90,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0009_auto__chg_field_scriptattribute_db_lock_storage.py b/src/scripts/migrations/0009_auto__chg_field_scriptattribute_db_lock_storage.py index 35b04fcb12..46000571e0 100644 --- a/src/scripts/migrations/0009_auto__chg_field_scriptattribute_db_lock_storage.py +++ b/src/scripts/migrations/0009_auto__chg_field_scriptattribute_db_lock_storage.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -31,8 +42,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -79,7 +90,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0010_add_picklefield.py b/src/scripts/migrations/0010_add_picklefield.py index 85f126aead..174e25419c 100644 --- a/src/scripts/migrations/0010_add_picklefield.py +++ b/src/scripts/migrations/0010_add_picklefield.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -81,7 +92,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0011_convert_attrdata.py b/src/scripts/migrations/0011_convert_attrdata.py index 0c09d47796..373467a495 100644 --- a/src/scripts/migrations/0011_convert_attrdata.py +++ b/src/scripts/migrations/0011_convert_attrdata.py @@ -332,6 +332,17 @@ def to_attr(data): return ("simple", data) +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(DataMigration): depends_on = ( @@ -436,8 +447,8 @@ class Migration(DataMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -484,7 +495,7 @@ class Migration(DataMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0012_remove_old_attr_value_field.py b/src/scripts/migrations/0012_remove_old_attr_value_field.py index a9064d20ad..3d8a33a90e 100644 --- a/src/scripts/migrations/0012_remove_old_attr_value_field.py +++ b/src/scripts/migrations/0012_remove_old_attr_value_field.py @@ -5,6 +5,17 @@ from south.v2 import SchemaMigration from django.db import models +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + class Migration(SchemaMigration): def forwards(self, orm): @@ -33,8 +44,8 @@ class Migration(SchemaMigration): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, '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'}), @@ -81,7 +92,7 @@ class Migration(SchemaMigration): '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'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_orm_label, 'unique': 'True'}) }, 'scripts.scriptattribute': { 'Meta': {'object_name': 'ScriptAttribute'}, diff --git a/src/scripts/migrations/0013_auto__del_scriptattribute.py b/src/scripts/migrations/0013_auto__del_scriptattribute.py new file mode 100644 index 0000000000..0891184daf --- /dev/null +++ b/src/scripts/migrations/0013_auto__del_scriptattribute.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'ScriptAttribute' + db.delete_table(u'scripts_scriptattribute') + + # Adding M2M table for field db_attributes on 'ScriptDB' + db.create_table(u'scripts_scriptdb_db_attributes', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('scriptdb', models.ForeignKey(orm[u'scripts.scriptdb'], null=False)), + ('attribute', models.ForeignKey(orm[u'typeclasses.attribute'], null=False)) + )) + db.create_unique(u'scripts_scriptdb_db_attributes', ['scriptdb_id', 'attribute_id']) + + + def backwards(self, orm): + # Adding model 'ScriptAttribute' + db.create_table(u'scripts_scriptattribute', ( + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_value2', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['scripts.ScriptDB'])), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('scripts', ['ScriptAttribute']) + + # Removing M2M table for field db_attributes on 'ScriptDB' + db.delete_table('scripts_scriptdb_db_attributes') + + + 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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + 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_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_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'}) + } + } + + complete_apps = ['scripts'] \ No newline at end of file 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 538866bca9..032695c2e6 100644 --- a/src/scripts/models.py +++ b/src/scripts/models.py @@ -26,26 +26,14 @@ Common examples of uses of Scripts: """ from django.conf import settings from django.db import models -from src.typeclasses.models import Attribute, TypedObject +from django.db.models.signals import post_init, pre_delete + +from src.typeclasses.models import Attribute, TypedObject, TagHandler, AliasHandler, NickHandler from django.contrib.contenttypes.models import ContentType from src.scripts.manager import ScriptManager -__all__ = ("ScriptAttribute", "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" +__all__ = ("ScriptDB",) +_SA = object.__setattr__ #------------------------------------------------------------ @@ -109,10 +97,19 @@ class ScriptDB(TypedObject): # Database manager objects = ScriptManager() + # caches for quick lookups + _typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS + _default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS or "src.scripts.scripts.DoNothing" + class Meta: "Define Django meta options" verbose_name = "Script" + def __init__(self, *args, **kwargs): + super(ScriptDB, self).__init__(*args, **kwargs) + _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 # @property decorators that allows to access these fields using # normal python operations (without having to remember to save() @@ -246,11 +243,6 @@ class ScriptDB(TypedObject): # # - # this is required to properly handle attributes and typeclass loading - _typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS - _attribute_class = ScriptAttribute - _db_model_name = "scriptdb" # used by attributes to safely store objects - _default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS or "src.scripts.scripts.DoNothing" def at_typeclass_error(self): """ diff --git a/src/server/caches.py b/src/server/caches.py index d311b19fb4..54941a88c0 100644 --- a/src/server/caches.py +++ b/src/server/caches.py @@ -3,26 +3,40 @@ Central caching module. """ -from sys import getsizeof +import os, threading from collections import defaultdict -from django.conf import settings -_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE +from django.core.cache import get_cache +from src.server.models import ServerConfig +from src.utils.utils import uses_database, to_str, get_evennia_pids _GA = object.__getattribute__ _SA = object.__setattr__ _DA = object.__delattr__ -# OOB hooks (OOB not yet functional, don't use yet) -_OOB_FIELD_UPDATE_HOOKS = defaultdict(dict) -_OOB_PROP_UPDATE_HOOKS = defaultdict(dict) -_OOB_ATTR_UPDATE_HOOKS = defaultdict(dict) -_OOB_NDB_UPDATE_HOOKS = defaultdict(dict) -_OOB_CUSTOM_UPDATE_HOOKS = defaultdict(dict) +_IS_SUBPROCESS = os.getpid() in get_evennia_pids() +_IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread" -_OOB_HANDLER = None # set by oob handler when it initializes +# +# Set up the cache stores +# -def hashid(obj): +_FIELD_CACHE = {} +_ATTR_CACHE = {} +_PROP_CACHE = defaultdict(dict) + + +#------------------------------------------------------------ +# Cache key hash generation +#------------------------------------------------------------ + +if uses_database("mysql") and ServerConfig.objects.get_mysql_db_version() < '5.6.4': + # mysql <5.6.4 don't support millisecond precision + _DATESTRING = "%Y:%m:%d-%H:%M:%S:000000" +else: + _DATESTRING = "%Y:%m:%d-%H:%M:%S:%f" + +def hashid(obj, suffix=""): """ Returns a per-class unique that combines the object's class name with its idnum and creation time. This makes this id unique also @@ -35,12 +49,12 @@ def hashid(obj): hid = _GA(obj, "_hashid") except AttributeError: try: - date, idnum = _GA(obj, "db_date_created"), _GA(obj, "id") + date, idnum = _GA(obj, "db_date_created").strftime(_DATESTRING), _GA(obj, "id") except AttributeError: try: # maybe a typeclass, try to go to dbobj obj = _GA(obj, "dbobj") - date, idnum = _GA(obj, "db_date_created"), _GA(obj, "id") + date, idnum = _GA(obj, "db_date_created").strftime(_DATESTRING), _GA(obj, "id") except AttributeError: # this happens if hashing something like ndb. We have to # rely on memory adressing in this case. @@ -48,289 +62,484 @@ def hashid(obj): if not idnum or not date: # this will happen if setting properties on an object which is not yet saved return None - # build the hashid hid = "%s-%s-#%s" % (_GA(obj, "__class__"), date, idnum) + hid = hid.replace(" ", "") # we have to remove the class-name's space, for memcached's sake + # we cache the object part of the hashid to avoid too many object lookups _SA(obj, "_hashid", hid) - return hid + # build the complete hashid + hid = "%s%s" % (hid, suffix) + return to_str(hid) -# oob helper functions -def register_oob_update_hook(obj,name, entity="field"): + +#------------------------------------------------------------ +# Cache callback handlers +#------------------------------------------------------------ + +#------------------------------------------------------------ +# Field cache - makes sure to cache all database fields when +# they are saved, no matter from where. +#------------------------------------------------------------ + +# callback to pre_save signal (connected in src.server.server) +def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwargs): """ - Register hook function to be called when field/property/db/ndb is updated. - Given function will be called with function(obj, entityname, newvalue, *args, **kwargs) - entity - one of "field", "property", "db", "ndb" or "custom" + Called at the beginning of the save operation. The save method + 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. """ - hid = hashid(obj) - if hid: - if entity == "field": - global _OOB_FIELD_UPDATE_HOOKS - _OOB_FIELD_UPDATE_HOOKS[hid][name] = True + if raw: + return + #print "field_pre_save:", instance, update_fields# if hasattr(instance, "db_key") else instance, update_fields + if update_fields: + # 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) + else: + # meta.fields are already field objects; get them all + update_fields = _GA(_GA(instance, "_meta"), "fields") + for field in update_fields: + fieldname = field.name + new_value = field.value_from_object(instance) + handlername = "_%s_handler" % fieldname + try: + handler = _GA(instance, handlername) + except AttributeError: + handler = None + #hid = hashid(instance, "-%s" % fieldname) + if callable(handler): + try: + old_value = _GA(instance, _GA(field, "get_cache_name")())#_FIELD_CACHE.get(hid) if hid else None + except AttributeError: + old_value=None + # the handler may modify the stored value in various ways + # don't catch exceptions, the handler must work! + new_value = handler(new_value, old_value=old_value) + # we re-assign this to the field, save() will pick it up from there + _SA(instance, fieldname, new_value) + #if hid: + # # update cache + # _FIELD_CACHE[hid] = new_value + +# access method +# +#def get_field_cache(obj, fieldname): +# "Called by _get wrapper" +# hid = hashid(obj, "-%s" % fieldname) +# return hid and _FIELD_CACHE.get(hid, None) or None +# +#def set_field_cache(obj, fieldname, value): +# hid = hashi(obj, "-%s" % fieldname) +# if hid: +# _FIELD_CACHE.set(hid, value) +# +#def flush_field_cache(): +# "Clear the field cache" +# _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 +# avoid lookups more than necessary (this makes Attributes en par in speed +# to any property). +#------------------------------------------------------------ + +# connected to m2m_changed signal in respective model class +def post_attr_update(sender, **kwargs): + "Called when the many2many relation changes some way" + obj = kwargs['instance'] + model = kwargs['model'] + action = kwargs['action'] + #print "update_attr_cache:", obj, model, action + if kwargs['reverse']: + # the reverse relation changed (the Attribute itself was acted on) + pass + else: + # forward relation changed (the Object holding the Attribute m2m field) + if not kwargs["pk_set"]: return - elif entity == "property": - global _OOB_PROP_UPDATE_HOOKS - _OOB_PROP_UPDATE_HOOKS[hid][name] = True - elif entity == "db": - global _OOB_ATTR_UPDATE_HOOKS - _OOB_ATTR_UPDATE_HOOKS[hid][name] = True - elif entity == "ndb": - global _OOB_NDB_UPDATE_HOOKS - _OOB_NDB_UPDATE_HOOKS[hid][name] = True - elif entity == "custom": - global _OOB_CUSTOM_UPDATE_HOOKS - _OOB_CUSTOM_UPDATE_HOOKS[hid][name] = True - else: - return None + if action == "post_add": + # cache all added objects + for attr_id in kwargs["pk_set"]: + attr_obj = model.objects.get(pk=attr_id) + set_attr_cache(obj, _GA(attr_obj, "db_key"), attr_obj) + elif action == "post_remove": + # obj.db_attributes.remove(attr) was called + for attr_id in kwargs["pk_set"]: + attr_obj = model.objects.get(pk=attr_id) + del_attr_cache(obj, _GA(attr_obj, "db_key")) + attr_obj.delete() + elif action == "post_clear": + # obj.db_attributes.clear() was called + clear_obj_attr_cache(obj) -def unregister_oob_update_hook(obj, name, entity="property"): - """ - Un-register a report hook - """ +# access methods + +def get_attr_cache(obj, attrname): + "Called by get_attribute" + hid = hashid(obj, "-%s" % attrname) + return hid and _ATTR_CACHE.get(hid, None) or None + +def set_attr_cache(obj, attrname, attrobj): + "Set the attr cache manually; this can be used to update" + global _ATTR_CACHE + hid = hashid(obj, "-%s" % attrname) + _ATTR_CACHE[hid] = attrobj + +def del_attr_cache(obj, attrname): + "Del attribute cache" + global _ATTR_CACHE + hid = hashid(obj, "-%s" % attrname) + if hid in _ATTR_CACHE: + del _ATTR_CACHE[hid] + +def flush_attr_cache(): + "Clear attribute cache" + global _ATTR_CACHE + _ATTR_CACHE = {} + +def clear_obj_attr_cache(obj): + global _ATTR_CACHE hid = hashid(obj) + _ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)} + +#------------------------------------------------------------ +# Property cache - this is a generic cache for properties stored on models. +#------------------------------------------------------------ + +# access methods + +def get_prop_cache(obj, propname): + "retrieve data from cache" + hid = hashid(obj, "-%s" % propname) if hid: - global _OOB_FIELD_UPDATE_HOOKS,_OOB_PROP_UPDATE_HOOKS, _OOB_ATTR_UPDATE_HOOKS - global _OOB_CUSTOM_UPDATE_HOOKS, _OOB_NDB_UPDATE_HOOKS - if entity == "field" and name in _OOB_FIELD_UPDATE_HOOKS: - del _OOB_FIELD_UPDATE_HOOKS[hid][name] - elif entity == "property" and name in _OOB_PROP_UPDATE_HOOKS: - del _OOB_PROP_UPDATE_HOOKS[hid][name] - elif entity == "db" and name in _OOB_ATTR_UPDATE_HOOKS: - del _OOB_ATTR_UPDATE_HOOKS[hid][name] - elif entity == "ndb" and name in _OOB_NDB_UPDATE_HOOKS: - del _OOB_NDB_UPDATE_HOOKS[hid][name] - elif entity == "custom" and name in _OOB_CUSTOM_UPDATE_HOOKS: - del _OOB_CUSTOM_UPDATE_HOOKS[hid][name] - else: - return None + #print "get_prop_cache", hid, propname, _PROP_CACHE.get(hid, None) + return _PROP_CACHE[hid].get(propname, None) -def call_ndb_hooks(obj, attrname, value): - """ - No caching is done of ndb here, but - we use this as a way to call OOB hooks. - """ - hid = hashid(obj) +def set_prop_cache(obj, propname, propvalue): + "Set property cache" + hid = hashid(obj, "-%s" % propname) if hid: - oob_hook = _OOB_NDB_UPDATE_HOOKS[hid].get(attrname) - if oob_hook: - oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2]) + #print "set_prop_cache", propname, propvalue + _PROP_CACHE[hid][propname] = propvalue + #_PROP_CACHE.set(hid, propvalue) -def call_custom_hooks(obj, attrname, value): - """ - Custom handler for developers adding their own oob hooks, e.g. to - custom typeclass properties. - """ - hid = hashid(obj) - if hid: - oob_hook = _OOB_CUSTOM_UPDATE_HOOKS[hid].get(attrname) - if oob_hook: - oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2]) +def del_prop_cache(obj, propname): + "Delete element from property cache" + hid = hashid(obj, "-%s" % propname) + if hid and propname in _PROP_CACHE[hid]: + del _PROP_CACHE[hid][propname] + #_PROP_CACHE.delete(hid) - -if _ENABLE_LOCAL_CACHES: - - # Cache stores - _ATTR_CACHE = defaultdict(dict) - _FIELD_CACHE = defaultdict(dict) +def flush_prop_cache(): + "Clear property cache" + global _PROP_CACHE _PROP_CACHE = defaultdict(dict) + #_PROP_CACHE.clear() - def get_cache_sizes(): - """ - Get cache sizes, expressed in number of objects and memory size in MB - """ - global _ATTR_CACHE, _FIELD_CACHE, _PROP_CACHE +#_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE +## oob helper functions +# OOB hooks (OOB not yet functional, don't use yet) +#_OOB_FIELD_UPDATE_HOOKS = defaultdict(dict) +#_OOB_PROP_UPDATE_HOOKS = defaultdict(dict) +#_OOB_ATTR_UPDATE_HOOKS = defaultdict(dict) +#_OOB_NDB_UPDATE_HOOKS = defaultdict(dict) +#_OOB_CUSTOM_UPDATE_HOOKS = defaultdict(dict) +# +#_OOB_HANDLER = None # set by oob handler when it initializes +#def register_oob_update_hook(obj,name, entity="field"): +# """ +# Register hook function to be called when field/property/db/ndb is updated. +# Given function will be called with function(obj, entityname, newvalue, *args, **kwargs) +# entity - one of "field", "property", "db", "ndb" or "custom" +# """ +# hid = hashid(obj) +# if hid: +# if entity == "field": +# global _OOB_FIELD_UPDATE_HOOKS +# _OOB_FIELD_UPDATE_HOOKS[hid][name] = True +# return +# elif entity == "property": +# global _OOB_PROP_UPDATE_HOOKS +# _OOB_PROP_UPDATE_HOOKS[hid][name] = True +# elif entity == "db": +# global _OOB_ATTR_UPDATE_HOOKS +# _OOB_ATTR_UPDATE_HOOKS[hid][name] = True +# elif entity == "ndb": +# global _OOB_NDB_UPDATE_HOOKS +# _OOB_NDB_UPDATE_HOOKS[hid][name] = True +# elif entity == "custom": +# global _OOB_CUSTOM_UPDATE_HOOKS +# _OOB_CUSTOM_UPDATE_HOOKS[hid][name] = True +# else: +# return None +# +#def unregister_oob_update_hook(obj, name, entity="property"): +# """ +# Un-register a report hook +# """ +# hid = hashid(obj) +# if hid: +# global _OOB_FIELD_UPDATE_HOOKS,_OOB_PROP_UPDATE_HOOKS, _OOB_ATTR_UPDATE_HOOKS +# global _OOB_CUSTOM_UPDATE_HOOKS, _OOB_NDB_UPDATE_HOOKS +# if entity == "field" and name in _OOB_FIELD_UPDATE_HOOKS: +# del _OOB_FIELD_UPDATE_HOOKS[hid][name] +# elif entity == "property" and name in _OOB_PROP_UPDATE_HOOKS: +# del _OOB_PROP_UPDATE_HOOKS[hid][name] +# elif entity == "db" and name in _OOB_ATTR_UPDATE_HOOKS: +# del _OOB_ATTR_UPDATE_HOOKS[hid][name] +# elif entity == "ndb" and name in _OOB_NDB_UPDATE_HOOKS: +# del _OOB_NDB_UPDATE_HOOKS[hid][name] +# elif entity == "custom" and name in _OOB_CUSTOM_UPDATE_HOOKS: +# del _OOB_CUSTOM_UPDATE_HOOKS[hid][name] +# else: +# return None +# +#def call_ndb_hooks(obj, attrname, value): +# """ +# No caching is done of ndb here, but +# we use this as a way to call OOB hooks. +# """ +# hid = hashid(obj) +# if hid: +# oob_hook = _OOB_NDB_UPDATE_HOOKS[hid].get(attrname) +# if oob_hook: +# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2]) +# +#def call_custom_hooks(obj, attrname, value): +# """ +# Custom handler for developers adding their own oob hooks, e.g. to +# custom typeclass properties. +# """ +# hid = hashid(obj) +# if hid: +# oob_hook = _OOB_CUSTOM_UPDATE_HOOKS[hid].get(attrname) +# if oob_hook: +# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2]) +# +# - attr_n = sum(len(dic) for dic in _ATTR_CACHE.values()) - attr_mb = sum(sum(getsizeof(obj) for obj in dic.values()) for dic in _ATTR_CACHE.values()) / 1024.0 +# # old cache system +# +# if _ENABLE_LOCAL_CACHES: +# # Cache stores +# _ATTR_CACHE = defaultdict(dict) +# _FIELD_CACHE = defaultdict(dict) +# _PROP_CACHE = defaultdict(dict) +# +# +# def get_cache_sizes(): +# """ +# Get cache sizes, expressed in number of objects and memory size in MB +# """ +# global _ATTR_CACHE, _FIELD_CACHE, _PROP_CACHE +# +# attr_n = sum(len(dic) for dic in _ATTR_CACHE.values()) +# attr_mb = sum(sum(getsizeof(obj) for obj in dic.values()) for dic in _ATTR_CACHE.values()) / 1024.0 +# +# field_n = sum(len(dic) for dic in _FIELD_CACHE.values()) +# field_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _FIELD_CACHE.values()) / 1024.0 +# +# prop_n = sum(len(dic) for dic in _PROP_CACHE.values()) +# prop_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _PROP_CACHE.values()) / 1024.0 +# +# return (attr_n, attr_mb), (field_n, field_mb), (prop_n, prop_mb) +# +# # on-object database field cache +# def get_field_cache(obj, name): +# "On-model Cache handler." +# global _FIELD_CACHE +# hid = hashid(obj) +# if hid: +# try: +# return _FIELD_CACHE[hid][name] +# except KeyError: +# val = _GA(obj, "db_%s" % name) +# _FIELD_CACHE[hid][name] = val +# return val +# return _GA(obj, "db_%s" % name) +# +# def set_field_cache(obj, name, val): +# "On-model Cache setter. Also updates database." +# _SA(obj, "db_%s" % name, val) +# _GA(obj, "save")() +# hid = hashid(obj) +# if hid: +# global _FIELD_CACHE +# _FIELD_CACHE[hid][name] = val +# # oob hook functionality +# if _OOB_FIELD_UPDATE_HOOKS[hid].get(name): +# _OOB_HANDLER.update(hid, name, val) +# +# def del_field_cache(obj, name): +# "On-model cache deleter" +# hid = hashid(obj) +# _SA(obj, "db_%s" % name, None) +# _GA(obj, "save")() +# if hid: +# try: +# del _FIELD_CACHE[hid][name] +# except KeyError: +# pass +# if _OOB_FIELD_UPDATE_HOOKS[hid].get(name): +# _OOB_HANDLER.update(hid, name, None) +# +# def flush_field_cache(obj=None): +# "On-model cache resetter" +# hid = hashid(obj) +# global _FIELD_CACHE +# if hid: +# try: +# del _FIELD_CACHE[hashid(obj)] +# except KeyError, e: +# pass +# else: +# # clean cache completely +# _FIELD_CACHE = defaultdict(dict) +# +# # on-object property cache (unrelated to database) +# # Note that the get/set_prop_cache handler do not actually +# # get/set the property "on" the object but only reads the +# # value to/from the cache. This is intended to be used +# # with a get/setter property on the object. +# +# def get_prop_cache(obj, name, default=None): +# "On-model Cache handler." +# global _PROP_CACHE +# hid = hashid(obj) +# if hid: +# try: +# val = _PROP_CACHE[hid][name] +# except KeyError: +# return default +# _PROP_CACHE[hid][name] = val +# return val +# return default +# +# def set_prop_cache(obj, name, val): +# "On-model Cache setter. Also updates database." +# hid = hashid(obj) +# if hid: +# global _PROP_CACHE +# _PROP_CACHE[hid][name] = val +# # oob hook functionality +# oob_hook = _OOB_PROP_UPDATE_HOOKS[hid].get(name) +# if oob_hook: +# oob_hook[0](obj.typeclass, name, val, *oob_hook[1], **oob_hook[2]) +# +# +# def del_prop_cache(obj, name): +# "On-model cache deleter" +# try: +# del _PROP_CACHE[hashid(obj)][name] +# except KeyError: +# pass +# def flush_prop_cache(obj=None): +# "On-model cache resetter" +# hid = hashid(obj) +# global _PROP_CACHE +# if hid: +# try: +# del _PROP_CACHE[hid] +# except KeyError,e: +# pass +# else: +# # clean cache completely +# _PROP_CACHE = defaultdict(dict) +# +# # attribute cache +# +# def get_attr_cache(obj, attrname): +# """ +# Attribute cache store +# """ +# return _ATTR_CACHE[hashid(obj)].get(attrname, None) +# +# def set_attr_cache(obj, attrname, attrobj): +# """ +# Cache an attribute object +# """ +# hid = hashid(obj) +# if hid: +# global _ATTR_CACHE +# _ATTR_CACHE[hid][attrname] = attrobj +# # oob hook functionality +# oob_hook = _OOB_ATTR_UPDATE_HOOKS[hid].get(attrname) +# if oob_hook: +# oob_hook[0](obj.typeclass, attrname, attrobj.value, *oob_hook[1], **oob_hook[2]) +# +# def del_attr_cache(obj, attrname): +# """ +# Remove attribute from cache +# """ +# global _ATTR_CACHE +# try: +# _ATTR_CACHE[hashid(obj)][attrname].no_cache = True +# del _ATTR_CACHE[hashid(obj)][attrname] +# except KeyError: +# pass +# +# def flush_attr_cache(obj=None): +# """ +# Flush the attribute cache for this object. +# """ +# global _ATTR_CACHE +# if obj: +# for attrobj in _ATTR_CACHE[hashid(obj)].values(): +# attrobj.no_cache = True +# del _ATTR_CACHE[hashid(obj)] +# else: +# # clean cache completely +# for objcache in _ATTR_CACHE.values(): +# for attrobj in objcache.values(): +# attrobj.no_cache = True +# _ATTR_CACHE = defaultdict(dict) +# +# +# def flush_obj_caches(obj=None): +# "Clean all caches on this object" +# flush_field_cache(obj) +# flush_prop_cache(obj) +# flush_attr_cache(obj) +# - field_n = sum(len(dic) for dic in _FIELD_CACHE.values()) - field_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _FIELD_CACHE.values()) / 1024.0 - - prop_n = sum(len(dic) for dic in _PROP_CACHE.values()) - prop_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _PROP_CACHE.values()) / 1024.0 - - return (attr_n, attr_mb), (field_n, field_mb), (prop_n, prop_mb) - - # on-object database field cache - def get_field_cache(obj, name): - "On-model Cache handler." - global _FIELD_CACHE - hid = hashid(obj) - if hid: - try: - return _FIELD_CACHE[hid][name] - except KeyError: - val = _GA(obj, "db_%s" % name) - _FIELD_CACHE[hid][name] = val - return val - return _GA(obj, "db_%s" % name) - - def set_field_cache(obj, name, val): - "On-model Cache setter. Also updates database." - _SA(obj, "db_%s" % name, val) - _GA(obj, "save")() - hid = hashid(obj) - if hid: - global _FIELD_CACHE - _FIELD_CACHE[hid][name] = val - # oob hook functionality - if _OOB_FIELD_UPDATE_HOOKS[hid].get(name): - _OOB_HANDLER.update(hid, name, val) - - def del_field_cache(obj, name): - "On-model cache deleter" - hid = hashid(obj) - _SA(obj, "db_%s" % name, None) - _GA(obj, "save")() - if hid: - try: - del _FIELD_CACHE[hid][name] - except KeyError: - pass - if _OOB_FIELD_UPDATE_HOOKS[hid].get(name): - _OOB_HANDLER.update(hid, name, None) - - def flush_field_cache(obj=None): - "On-model cache resetter" - hid = hashid(obj) - global _FIELD_CACHE - if hid: - del _FIELD_CACHE[hashid(obj)] - else: - # clean cache completely - _FIELD_CACHE = defaultdict(dict) - - # on-object property cache (unrelated to database) - # Note that the get/set_prop_cache handler do not actually - # get/set the property "on" the object but only reads the - # value to/from the cache. This is intended to be used - # with a get/setter property on the object. - - def get_prop_cache(obj, name, default=None): - "On-model Cache handler." - global _PROP_CACHE - hid = hashid(obj) - if hid: - try: - val = _PROP_CACHE[hid][name] - except KeyError: - return default - _PROP_CACHE[hid][name] = val - return val - return default - - def set_prop_cache(obj, name, val): - "On-model Cache setter. Also updates database." - hid = hashid(obj) - if hid: - global _PROP_CACHE - _PROP_CACHE[hid][name] = val - # oob hook functionality - oob_hook = _OOB_PROP_UPDATE_HOOKS[hid].get(name) - if oob_hook: - oob_hook[0](obj.typeclass, name, val, *oob_hook[1], **oob_hook[2]) - - - def del_prop_cache(obj, name): - "On-model cache deleter" - try: - del _PROP_CACHE[hashid(obj)][name] - except KeyError: - pass - def flush_prop_cache(obj=None): - "On-model cache resetter" - hid = hashid(obj) - global _PROP_CACHE - if hid: - del _PROP_CACHE[hashid(obj)] - else: - # clean cache completely - _PROP_CACHE = defaultdict(dict) - - # attribute cache - - def get_attr_cache(obj, attrname): - """ - Attribute cache store - """ - return _ATTR_CACHE[hashid(obj)].get(attrname, None) - - def set_attr_cache(obj, attrname, attrobj): - """ - Cache an attribute object - """ - hid = hashid(obj) - if hid: - global _ATTR_CACHE - _ATTR_CACHE[hid][attrname] = attrobj - # oob hook functionality - oob_hook = _OOB_ATTR_UPDATE_HOOKS[hid].get(attrname) - if oob_hook: - oob_hook[0](obj.typeclass, attrname, attrobj.value, *oob_hook[1], **oob_hook[2]) - - def del_attr_cache(obj, attrname): - """ - Remove attribute from cache - """ - global _ATTR_CACHE - try: - _ATTR_CACHE[hashid(obj)][attrname].no_cache = True - del _ATTR_CACHE[hashid(obj)][attrname] - except KeyError: - pass - - def flush_attr_cache(obj=None): - """ - Flush the attribute cache for this object. - """ - global _ATTR_CACHE - if obj: - for attrobj in _ATTR_CACHE[hashid(obj)].values(): - attrobj.no_cache = True - del _ATTR_CACHE[hashid(obj)] - else: - # clean cache completely - for objcache in _ATTR_CACHE.values(): - for attrobj in objcache.values(): - attrobj.no_cache = True - _ATTR_CACHE = defaultdict(dict) - - -else: +#else: # 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): - pass - # these should get oob handlers when oob is implemented. - def get_prop_cache(obj, name, default=None): - return None - def set_prop_cache(obj, name, val): - pass - def del_prop_cache(obj, name): - pass - def flush_prop_cache(obj=None): - pass - def get_attr_cache(obj, attrname): - return None - def set_attr_cache(obj, attrname, attrobj): - pass - def del_attr_cache(obj, attrname): - pass - def flush_attr_cache(obj=None): - pass +#def flush_field_cache(obj=None): +# pass +# these should get oob handlers when oob is implemented. +#def get_prop_cache(obj, name, default=None): +# return None +#def set_prop_cache(obj, name, val): +# pass +#def del_prop_cache(obj, name): +# pass +#def flush_prop_cache(obj=None): +# pass +#def get_attr_cache(obj, attrname): +# return None +#def set_attr_cache(obj, attrname, attrobj): +# pass +#def del_attr_cache(obj, attrname): +# pass +#def flush_attr_cache(obj=None): +# pass diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py index dc0326fe78..b49de392ca 100644 --- a/src/server/initial_setup.py +++ b/src/server/initial_setup.py @@ -7,13 +7,14 @@ Everything starts at handle_setup() """ import django -from django.contrib.auth.models import User from django.core import management from django.conf import settings +from django.contrib.auth import get_user_model from src.server.models import ServerConfig from src.help.models import HelpEntry from src.utils import create + from django.utils.translation import ugettext as _ def create_config_values(): @@ -23,11 +24,20 @@ def create_config_values(): ServerConfig.objects.conf("site_name", settings.SERVERNAME) ServerConfig.objects.conf("idle_timeout", settings.IDLE_TIMEOUT) -def get_god_user(): +def get_god_player(): """ - Returns the initially created 'god' User object. + Creates the god user. """ - return User.objects.get(id=1) + PlayerDB = get_user_model() + try: + god_player = PlayerDB.objects.get(id=1) + except PlayerDB.DoesNotExist: + txt = "\n\nNo superuser exists yet. The superuser is the 'owner' account on the" + txt += "\nEvennia server. Create a new superuser using the command" + txt += "\n\n python manage.py createsuperuser" + txt += "\n\nFollow the prompts, then restart the server." + raise Exception(txt) + return god_player def create_objects(): """ @@ -38,22 +48,23 @@ def create_objects(): # Set the initial User's account object's username on the #1 object. # This object is pure django and only holds name, email and password. - god_user = get_god_user() + god_player = get_god_player() # Create a Player 'user profile' object to hold eventual - # mud-specific settings for the bog standard User object. This is - # accessed by user.get_profile() and can also store attributes. - # It also holds mud permissions, but for a superuser these - # have no effect anyhow. - character_typeclass = settings.BASE_CHARACTER_TYPECLASS + # mud-specific settings for the PlayerDB object. + player_typeclass = settings.BASE_PLAYER_TYPECLASS - # Create the Player object as well as the in-game god-character - # for user #1. We can't set location and home yet since nothing + # run all creation hooks on god_player (we must do so manually since the manage.py command does not) + god_player.typeclass_path = player_typeclass + god_player.basetype_setup() + god_player.at_player_creation() + god_player.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all()") + + # Create the in-game god-character for player #1. We can't set location and home yet since nothing # exists. Also, all properties (name, email, password, is_superuser) # is inherited from the user so we don't specify it again here. - - god_player = create.create_player(god_user.username, None, None, user=god_user) - god_character = create.create_object(character_typeclass, key=god_user.username) + character_typeclass = settings.BASE_CHARACTER_TYPECLASS + god_character = create.create_object(character_typeclass, key=god_player.username) god_character.id = 1 god_character.db.desc = _('This is User #1.') @@ -121,7 +132,7 @@ def create_channels(): return # connect the god user to all these channels by default. - goduser = get_god_user() + goduser = get_god_player() from src.comms.models import PlayerChannelConnection PlayerChannelConnection.objects.create_connection(goduser, pchan) PlayerChannelConnection.objects.create_connection(goduser, ichan) diff --git a/src/server/migrations/0002_fix_config_value.py b/src/server/migrations/0002_fix_config_value.py index 129b08e752..a5da54880d 100644 --- a/src/server/migrations/0002_fix_config_value.py +++ b/src/server/migrations/0002_fix_config_value.py @@ -27,6 +27,8 @@ class Migration(DataMigration): conf.save() except utils.DatabaseError: # this will happen if we start the db from scratch (in which case this migration fix is not needed) + db.commit_transaction() + db.start_transaction() pass diff --git a/src/server/migrations/0003_add_tmpattr.py b/src/server/migrations/0003_add_tmpattr.py new file mode 100644 index 0000000000..19b8019fd9 --- /dev/null +++ b/src/server/migrations/0003_add_tmpattr.py @@ -0,0 +1,48 @@ +# -*- 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 model 'TmpAttribute' + db.create_table(u'server_tmpattribute', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_value', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_obj_id', self.gf('django.db.models.fields.IntegerField')(null=True)), + ('db_obj_type', self.gf('django.db.models.fields.CharField')(max_length=10, null=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(editable=True, auto_now_add=False)), + )) + db.send_create_signal('server', ['TmpAttribute']) + + + def backwards(self, orm): + # Deleting model 'TmpAttribute' + db.delete_table(u'server_tmpattribute') + + + models = { + u'server.serverconfig': { + 'Meta': {'object_name': 'ServerConfig'}, + 'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'db_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'server.tmpattribute': { + 'Meta': {'object_name': 'TmpAttribute'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'db_obj_type': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'db_date_created':('django.db.models.fields.DateTimeField',[],{'editable':'True', 'auto_now_add':'True'}), + } + } + + complete_apps = ['server'] diff --git a/src/server/migrations/0004_store_all_attrs.py b/src/server/migrations/0004_store_all_attrs.py new file mode 100644 index 0000000000..39e2343e4c --- /dev/null +++ b/src/server/migrations/0004_store_all_attrs.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models +#from src.utils.dbserialize import to_pickle, from_pickle + +class Migration(DataMigration): + "Store all attributes in a temporary table" + depends_on = (('objects', '0020_remove_old_attr_value_field'), + ('players','0019_remove_old_attr_value_field'), + ('scripts','0012_remove_old_attr_value_field')) + no_dry_run = True + def forwards(self, orm): + "Write your forwards methods here." + # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." + + # store ObjectAttributes + for attrobj in orm['objects.ObjAttribute'].objects.all(): + #value = from_pickle(attrobj.db_value, db_obj=attrobj) + new_attr = orm['server.TmpAttribute'](db_key=attrobj.db_key, + db_value=attrobj.db_value, + db_lock_storage=attrobj.db_lock_storage, + db_obj_id=attrobj.db_obj.id, + db_obj_type="objectdb", + db_date_created=attrobj.db_date_created) + new_attr.save() + #new_attr.db_value = to_pickle(value) + #new_attr.save() + + # store PlayerAttributes + for attrobj in orm['players.PlayerAttribute'].objects.all(): + #value = from_pickle(attrobj.db_value, db_obj=attrobj) + new_attr = orm['server.TmpAttribute'](db_key=attrobj.db_key, + db_value=attrobj.db_value, + db_lock_storage=attrobj.db_lock_storage, + db_obj_id=attrobj.db_obj.id, + db_obj_type="playerdb", + db_date_created=attrobj.db_date_created) + new_attr.save() + #new_attr.db_value = to_pickle(value) + #new_attr.save() + + # store ScriptAttributes + for attrobj in orm['scripts.ScriptAttribute'].objects.all(): + #value = from_pickle(attrobj.db_value, db_obj=attrobj) + new_attr = orm['server.TmpAttribute'](db_key=attrobj.db_key, + db_value=attrobj.db_value, + db_lock_storage=attrobj.db_lock_storage, + db_obj_id=attrobj.db_obj.id, + db_obj_type="scriptdb", + db_date_created=attrobj.db_date_created) + new_attr.save() + #new_attr.db_value = to_pickle(value) + #new_attr.save() + + def backwards(self, orm): + "Write your backwards methods here." + + 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'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.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'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_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'objects.objectdb': { + 'Meta': {'object_name': 'ObjectDB'}, + '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'objects.objectnick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'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_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'players.playerdb': { + 'Meta': {'object_name': 'PlayerDB'}, + '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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'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_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['scripts.ScriptDB']"}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'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_index': 'True'}), + '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_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'server.serverconfig': { + 'Meta': {'object_name': 'ServerConfig'}, + 'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'db_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'server.tmpattribute': { + 'Meta': {'object_name': 'TmpAttribute'}, + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'editable':'True','auto_now_add': 'False', '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_obj_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'db_obj_type': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['objects', 'players', 'scripts', 'server'] + symmetrical = True diff --git a/src/server/migrations/0005_auto__del_tmpattribute.py b/src/server/migrations/0005_auto__del_tmpattribute.py new file mode 100644 index 0000000000..7eab5ae376 --- /dev/null +++ b/src/server/migrations/0005_auto__del_tmpattribute.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + depends_on = (('typeclasses', '0002_resave_attrs'),) + + def forwards(self, orm): + # Deleting model 'TmpAttribute' + db.delete_table(u'server_tmpattribute') + + + def backwards(self, orm): + # Adding model 'TmpAttribute' + db.create_table(u'server_tmpattribute', ( + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_obj_id', self.gf('django.db.models.fields.IntegerField')(null=True)), + ('db_obj_type', self.gf('django.db.models.fields.CharField')(max_length=10, null=True)), + ('db_value', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=False, editable=True, blank=True)), + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('server', ['TmpAttribute']) + + + models = { + u'server.serverconfig': { + 'Meta': {'object_name': 'ServerConfig'}, + 'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'db_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['server'] diff --git a/src/server/models.py b/src/server/models.py index 4bb11c1bf1..da4ae08016 100644 --- a/src/server/models.py +++ b/src/server/models.py @@ -48,9 +48,6 @@ class ServerConfig(SharedMemoryModel): objects = ServerConfigManager() - # used by Attributes eventually storing this safely - _db_model_name = "serverconfig" - # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using # normal python operations (without having to remember to save() diff --git a/src/server/portal/__init__.py b/src/server/portal/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/server/mccp.py b/src/server/portal/mccp.py similarity index 97% rename from src/server/mccp.py rename to src/server/portal/mccp.py index 9cf7b34d5d..2e6aa77cd3 100644 --- a/src/server/mccp.py +++ b/src/server/portal/mccp.py @@ -2,7 +2,7 @@ MCCP - Mud Client Compression Protocol -The implements the MCCP v2 telnet protocol as per +This implements the MCCP v2 telnet protocol as per http://tintin.sourceforge.net/mccp/. MCCP allows for the server to compress data when sending to supporting clients, reducing bandwidth by 70-90%.. The compression is done using Python's builtin zlib diff --git a/src/server/msdp.py b/src/server/portal/msdp.py similarity index 100% rename from src/server/msdp.py rename to src/server/portal/msdp.py diff --git a/src/server/mssp.py b/src/server/portal/mssp.py similarity index 100% rename from src/server/mssp.py rename to src/server/portal/mssp.py diff --git a/src/server/portal.py b/src/server/portal/portal.py similarity index 84% rename from src/server/portal.py rename to src/server/portal/portal.py index b871bd434e..f35ae4e6db 100644 --- a/src/server/portal.py +++ b/src/server/portal/portal.py @@ -9,17 +9,19 @@ by game/evennia.py). """ import sys import os +from src.server.webserver import EvenniaReverseProxyResource + if os.name == 'nt': # For Windows batchfile we need an extra path insertion here. - sys.path.insert(0, os.path.dirname(os.path.dirname( - os.path.dirname(os.path.abspath(__file__))))) + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname( + os.path.dirname(os.path.abspath(__file__)))))) from twisted.application import internet, service from twisted.internet import protocol, reactor -from twisted.web import server, static +from twisted.web import server from django.conf import settings from src.utils.utils import get_evennia_version, mod_import, make_iter -from src.server.sessionhandler import PORTAL_SESSIONS +from src.server.portal.portalsessionhandler import PORTAL_SESSIONS PORTAL_SERVICES_PLUGIN_MODULES = [mod_import(module) for module in make_iter(settings.PORTAL_SERVICES_PLUGIN_MODULES)] @@ -55,7 +57,8 @@ WEBCLIENT_ENABLED = settings.WEBCLIENT_ENABLED AMP_HOST = settings.AMP_HOST AMP_PORT = settings.AMP_PORT -AMP_ENABLED = AMP_HOST and AMP_PORT +AMP_INTERFACE = settings.AMP_INTERFACE +AMP_ENABLED = AMP_HOST and AMP_PORT and AMP_INTERFACE #------------------------------------------------------------ @@ -156,6 +159,8 @@ if AMP_ENABLED: from src.server import amp + print ' amp (to Server): %s' % AMP_PORT + factory = amp.AmpClientFactory(PORTAL) amp_client = internet.TCPClient(AMP_HOST, AMP_PORT, factory) amp_client.setName('evennia_amp') @@ -168,7 +173,7 @@ if TELNET_ENABLED: # Start telnet game connections - from src.server import telnet + from src.server.portal import telnet for interface in TELNET_INTERFACES: if ":" in interface: @@ -192,7 +197,7 @@ if SSL_ENABLED: # Start SSL game connection (requires PyOpenSSL). - from src.server import ssl + from src.server.portal import ssl for interface in SSL_INTERFACES: if ":" in interface: @@ -218,7 +223,7 @@ if SSH_ENABLED: # Start SSH game connections. Will create a keypair in evennia/game if necessary. - from src.server import ssh + from src.server.portal import ssh for interface in SSH_INTERFACES: if ":" in interface: @@ -240,29 +245,9 @@ if SSH_ENABLED: if WEBSERVER_ENABLED: - # Start a django-compatible webserver. + # Start a reverse proxy to relay data to the Server-side webserver - from twisted.python import threadpool - from src.server.webserver import DjangoWebRoot, WSGIWebServer - - # start a thread pool and define the root url (/) as a wsgi resource - # recognized by Django - threads = threadpool.ThreadPool() - web_root = DjangoWebRoot(threads) - # point our media resources to url /media - web_root.putChild("media", static.File(settings.MEDIA_ROOT)) - - webclientstr = "" - if WEBCLIENT_ENABLED: - # create ajax client processes at /webclientdata - from src.server.webclient import WebClient - webclient = WebClient() - webclient.sessionhandler = PORTAL_SESSIONS - web_root.putChild("webclientdata", webclient) - - webclientstr = "/client" - - web_site = server.Site(web_root, logPath=settings.HTTP_LOG_FILE) + from twisted.web import proxy for interface in WEBSERVER_INTERFACES: if ":" in interface: @@ -271,14 +256,23 @@ if WEBSERVER_ENABLED: ifacestr = "" if interface != '0.0.0.0' or len(WEBSERVER_INTERFACES) > 1: ifacestr = "-%s" % interface - for port in WEBSERVER_PORTS: - pstring = "%s:%s" % (ifacestr, port) - # create the webserver - webserver = WSGIWebServer(threads, port, web_site, interface=interface) - webserver.setName('EvenniaWebServer%s' % pstring) - PORTAL.services.addService(webserver) + for proxyport, serverport in WEBSERVER_PORTS: + pstring = "%s:%s<->%s" % (ifacestr, proxyport, serverport) + web_root = EvenniaReverseProxyResource('127.0.0.1', serverport, '') + webclientstr = "" + if WEBCLIENT_ENABLED: + # create ajax client processes at /webclientdata + from src.server.portal.webclient import WebClient + webclient = WebClient() + webclient.sessionhandler = PORTAL_SESSIONS + web_root.putChild("webclientdata", webclient) + webclientstr = "/client" - print " webserver%s%s: %s" % (webclientstr, ifacestr, port) + web_root = server.Site(web_root, logPath=settings.HTTP_LOG_FILE) + proxy_service = internet.TCPServer(proxyport, web_root, interface=interface) + proxy_service.setName('EvenniaWebProxy%s' % pstring) + PORTAL.services.addService(proxy_service) + print " webproxy%s%s:%s (<-> %s)" % (webclientstr, ifacestr, proxyport, serverport) for plugin_module in PORTAL_SERVICES_PLUGIN_MODULES: # external plugin services to start @@ -286,7 +280,6 @@ for plugin_module in PORTAL_SERVICES_PLUGIN_MODULES: print '-' * 50 # end of terminal output - if os.name == 'nt': # Windows only: Set PID file manually f = open(os.path.join(settings.GAME_DIR, 'portal.pid'), 'w') diff --git a/src/server/portal/portalsessionhandler.py b/src/server/portal/portalsessionhandler.py new file mode 100644 index 0000000000..04228933f8 --- /dev/null +++ b/src/server/portal/portalsessionhandler.py @@ -0,0 +1,167 @@ +""" +Sessionhandler for portal sessions +""" +import time +from src.server.sessionhandler import SessionHandler, PCONN, PDISCONN + +#------------------------------------------------------------ +# Portal-SessionHandler class +#------------------------------------------------------------ +class PortalSessionHandler(SessionHandler): + """ + This object holds the sessions connected to the portal at any time. + It is synced with the server's equivalent SessionHandler over the AMP + connection. + + Sessions register with the handler using the connect() method. This + will assign a new unique sessionid to the session and send that sessid + to the server using the AMP connection. + + """ + + def __init__(self): + """ + Init the handler + """ + self.portal = None + self.sessions = {} + self.latest_sessid = 0 + self.uptime = time.time() + self.connection_time = 0 + + def at_server_connection(self): + """ + Called when the Portal establishes connection with the + Server. At this point, the AMP connection is already + established. + """ + self.connection_time = time.time() + + def connect(self, session): + """ + Called by protocol at first connect. This adds a not-yet authenticated session + using an ever-increasing counter for sessid. + """ + self.latest_sessid += 1 + sessid = self.latest_sessid + session.sessid = sessid + sessdata = session.get_sync_data() + self.sessions[sessid] = session + # sync with server-side + self.portal.amp_protocol.call_remote_ServerAdmin(sessid, + operation=PCONN, + data=sessdata) + def disconnect(self, session): + """ + Called from portal side when the connection is closed from the portal side. + """ + sessid = session.sessid + if sessid in self.sessions: + del self.sessions[sessid] + del session + # tell server to also delete this session + self.portal.amp_protocol.call_remote_ServerAdmin(sessid, + operation=PDISCONN) + + def server_disconnect(self, sessid, reason=""): + """ + Called by server to force a disconnect by sessid + """ + session = self.sessions.get(sessid, None) + if session: + session.disconnect(reason) + if sessid in self.sessions: + # in case sess.disconnect doesn't delete it + del self.sessions[sessid] + del session + + def server_disconnect_all(self, reason=""): + """ + Called by server when forcing a clean disconnect for everyone. + """ + for session in self.sessions.values(): + session.disconnect(reason) + del session + self.sessions = {} + + def server_logged_in(self, sessid, data): + "The server tells us that the session has been authenticated. Updated it." + sess = self.get_session(sessid) + sess.load_sync_data(data) + + def server_session_sync(self, serversessions): + """ + Server wants to save data to the portal, maybe because it's about to shut down. + We don't overwrite any sessions here, just update them in-place and remove + any that are out of sync (which should normally not be the case) + + serversessions - dictionary {sessid:{property:value},...} describing the properties + to sync on all sessions + """ + to_save = [sessid for sessid in serversessions if sessid in self.sessions] + to_delete = [sessid for sessid in self.sessions if sessid not in to_save] + # save protocols + for sessid in to_save: + self.sessions[sessid].load_sync_data(serversessions[sessid]) + # disconnect out-of-sync missing protocols + for sessid in to_delete: + self.server_disconnect(sessid) + + def count_loggedin(self, include_unloggedin=False): + """ + Count loggedin connections, alternatively count all connections. + """ + return len(self.get_sessions(include_unloggedin=include_unloggedin)) + + def session_from_suid(self, suid): + """ + Given a session id, retrieve the session (this is primarily + intended to be called by web clients) + """ + return [sess for sess in self.get_sessions(include_unloggedin=True) + if hasattr(sess, 'suid') and sess.suid == suid] + + def data_in(self, session, string="", data=""): + """ + Called by portal sessions for relaying data coming + in from the protocol to the server. data is + serialized before passed on. + """ + #print "portal_data_in:", string + self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid, + msg=string, + data=data) + def announce_all(self, message): + """ + Send message to all connection sessions + """ + for session in self.sessions.values(): + session.data_out(message) + + def data_out(self, sessid, string="", data=""): + """ + Called by server for having the portal relay messages and data + to the correct session protocol. + """ + session = self.sessions.get(sessid, None) + if session: + session.data_out(string, data=data) + + def oob_data_in(self, session, data): + """ + OOB (Out-of-band) data Portal -> Server + """ + print "portal_oob_data_in:", data + self.portal.amp_protocol.call_remote_OOBPortal2Server(session.sessid, + data=data) + + def oob_data_out(self, sessid, data): + """ + OOB (Out-of-band) data Server -> Portal + """ + print "portal_oob_data_out:", data + session = self.sessions.get(sessid, None) + if session: + session.oob_data_out(data) + +PORTAL_SESSIONS = PortalSessionHandler() diff --git a/src/server/ssh.py b/src/server/portal/ssh.py similarity index 100% rename from src/server/ssh.py rename to src/server/portal/ssh.py diff --git a/src/server/ssl.py b/src/server/portal/ssl.py similarity index 98% rename from src/server/ssl.py rename to src/server/portal/ssl.py index b3064731e3..238d3bfd8b 100644 --- a/src/server/ssl.py +++ b/src/server/portal/ssl.py @@ -11,7 +11,7 @@ except ImportError: print " SSL_ENABLED requires PyOpenSSL." sys.exit(5) -from src.server.telnet import TelnetProtocol +from src.server.portal.telnet import TelnetProtocol class SSLProtocol(TelnetProtocol): """ diff --git a/src/server/telnet.py b/src/server/portal/telnet.py similarity index 98% rename from src/server/telnet.py rename to src/server/portal/telnet.py index 27e446e56d..0812d305f7 100644 --- a/src/server/telnet.py +++ b/src/server/portal/telnet.py @@ -10,8 +10,8 @@ sessions etc. import re from twisted.conch.telnet import Telnet, StatefulTelnetProtocol, IAC, LINEMODE from src.server.session import Session -from src.server import ttype, mssp -from src.server.mccp import Mccp, mccp_compress, MCCP +from src.server.portal import ttype, mssp +from src.server.portal.mccp import Mccp, mccp_compress, MCCP from src.utils import utils, ansi, logger _RE_N = re.compile(r"\{n$") diff --git a/src/server/ttype.py b/src/server/portal/ttype.py similarity index 100% rename from src/server/ttype.py rename to src/server/portal/ttype.py diff --git a/src/server/webclient.py b/src/server/portal/webclient.py similarity index 98% rename from src/server/webclient.py rename to src/server/portal/webclient.py index afdbd49f2c..746d20d749 100644 --- a/src/server/webclient.py +++ b/src/server/portal/webclient.py @@ -63,11 +63,11 @@ class WebClient(resource.Resource): self.requests = {} self.databuffer = {} - def getChild(self, path, request): - """ - This is the place to put dynamic content. - """ - return self + #def getChild(self, path, request): + # """ + # This is the place to put dynamic content. + # """ + # return self def _responseFailed(self, failure, suid, request): "callback if a request is lost/timed out" diff --git a/src/server/server.py b/src/server/server.py index f25de51fb6..b7e8f6a281 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -14,7 +14,7 @@ if os.name == 'nt': # For Windows batchfile we need an extra path insertion here. sys.path.insert(0, os.path.dirname(os.path.dirname( os.path.dirname(os.path.abspath(__file__))))) - +from twisted.web import server, static from twisted.application import internet, service from twisted.internet import reactor, defer import django @@ -30,6 +30,12 @@ from src.utils.utils import get_evennia_version, mod_import, make_iter from src.comms import channelhandler from src.server.sessionhandler import SESSIONS +# setting up server-side field cache + +from django.db.models.signals import pre_save +from src.server.caches import field_pre_save +pre_save.connect(field_pre_save, dispatch_uid="fieldcache") + _SA = object.__setattr__ if os.name == 'nt': @@ -57,10 +63,15 @@ AMP_HOST = settings.AMP_HOST AMP_PORT = settings.AMP_PORT AMP_INTERFACE = settings.AMP_INTERFACE +WEBSERVER_PORTS = settings.WEBSERVER_PORTS +WEBSERVER_INTERFACES = settings.WEBSERVER_INTERFACES + # server-channel mappings +WEBSERVER_ENABLED = settings.WEBSERVER_ENABLED and WEBSERVER_PORTS and WEBSERVER_INTERFACES IMC2_ENABLED = settings.IMC2_ENABLED IRC_ENABLED = settings.IRC_ENABLED RSS_ENABLED = settings.RSS_ENABLED +WEBCLIENT_ENABLED = settings.WEBCLIENT_ENABLED #------------------------------------------------------------ @@ -145,7 +156,7 @@ class Evennia(object): #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): # 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 == 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)] @@ -325,7 +336,7 @@ if AMP_ENABLED: ifacestr = "" if AMP_INTERFACE != '127.0.0.1': ifacestr = "-%s" % AMP_INTERFACE - print ' amp (to Portal)%s:%s' % (ifacestr, AMP_PORT) + print ' amp (to Portal)%s: %s' % (ifacestr, AMP_PORT) from src.server import amp @@ -334,6 +345,30 @@ if AMP_ENABLED: amp_service.setName("EvenniaPortal") EVENNIA.services.addService(amp_service) +if WEBSERVER_ENABLED: + + # Start a django-compatible webserver. + + from twisted.python import threadpool + from src.server.webserver import DjangoWebRoot, WSGIWebServer + + # start a thread pool and define the root url (/) as a wsgi resource + # recognized by Django + threads = threadpool.ThreadPool(minthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[0]), + maxthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[1])) + web_root = DjangoWebRoot(threads) + # point our media resources to url /media + web_root.putChild("media", static.File(settings.MEDIA_ROOT)) + web_site = server.Site(web_root, logPath=settings.HTTP_LOG_FILE) + + for proxyport, serverport in WEBSERVER_PORTS: + # create the webserver (we only need the port for this) + webserver = WSGIWebServer(threads, serverport, web_site, interface='127.0.0.1') + webserver.setName('EvenniaWebServer%s' % serverport) + EVENNIA.services.addService(webserver) + + print " webserver: %s" % serverport + if IRC_ENABLED: # IRC channel connections diff --git a/src/server/serversession.py b/src/server/serversession.py index 49493311f8..24ba73cae1 100644 --- a/src/server/serversession.py +++ b/src/server/serversession.py @@ -77,17 +77,16 @@ class ServerSession(Session): player - the player associated with the session """ self.player = player - self.user = player.user - self.uid = self.user.id - self.uname = self.user.username + self.uid = self.player.id + self.uname = self.player.username self.logged_in = True self.conn_time = time.time() self.puid = None self.puppet = None # Update account's last login time. - self.user.last_login = datetime.now() - self.user.save() + self.player.last_login = datetime.now() + self.player.save() def at_disconnect(self): """ @@ -97,7 +96,7 @@ class ServerSession(Session): sessid = self.sessid player = self.player _GA(player.dbobj, "unpuppet_object")(sessid) - uaccount = _GA(player.dbobj, "user") + uaccount = player.dbobj uaccount.last_login = datetime.now() uaccount.save() # calling player hook diff --git a/src/server/sessionhandler.py b/src/server/sessionhandler.py index 34ca786ec8..6554279d31 100644 --- a/src/server/sessionhandler.py +++ b/src/server/sessionhandler.py @@ -380,167 +380,4 @@ class ServerSessionHandler(SessionHandler): """ self.server.amp_protocol.call_remote_OOBServer2Portal(session.sessid, data=data) - -#------------------------------------------------------------ -# Portal-SessionHandler class -#------------------------------------------------------------ - -class PortalSessionHandler(SessionHandler): - """ - This object holds the sessions connected to the portal at any time. - It is synced with the server's equivalent SessionHandler over the AMP - connection. - - Sessions register with the handler using the connect() method. This - will assign a new unique sessionid to the session and send that sessid - to the server using the AMP connection. - - """ - - def __init__(self): - """ - Init the handler - """ - self.portal = None - self.sessions = {} - self.latest_sessid = 0 - self.uptime = time.time() - self.connection_time = 0 - - def at_server_connection(self): - """ - Called when the Portal establishes connection with the - Server. At this point, the AMP connection is already - established. - """ - self.connection_time = time.time() - - def connect(self, session): - """ - Called by protocol at first connect. This adds a not-yet authenticated session - using an ever-increasing counter for sessid. - """ - self.latest_sessid += 1 - sessid = self.latest_sessid - session.sessid = sessid - sessdata = session.get_sync_data() - self.sessions[sessid] = session - # sync with server-side - self.portal.amp_protocol.call_remote_ServerAdmin(sessid, - operation=PCONN, - data=sessdata) - def disconnect(self, session): - """ - Called from portal side when the connection is closed from the portal side. - """ - sessid = session.sessid - if sessid in self.sessions: - del self.sessions[sessid] - del session - # tell server to also delete this session - self.portal.amp_protocol.call_remote_ServerAdmin(sessid, - operation=PDISCONN) - - def server_disconnect(self, sessid, reason=""): - """ - Called by server to force a disconnect by sessid - """ - session = self.sessions.get(sessid, None) - if session: - session.disconnect(reason) - if sessid in self.sessions: - # in case sess.disconnect doesn't delete it - del self.sessions[sessid] - del session - - def server_disconnect_all(self, reason=""): - """ - Called by server when forcing a clean disconnect for everyone. - """ - for session in self.sessions.values(): - session.disconnect(reason) - del session - self.sessions = {} - - def server_logged_in(self, sessid, data): - "The server tells us that the session has been authenticated. Updated it." - sess = self.get_session(sessid) - sess.load_sync_data(data) - - def server_session_sync(self, serversessions): - """ - Server wants to save data to the portal, maybe because it's about to shut down. - We don't overwrite any sessions here, just update them in-place and remove - any that are out of sync (which should normally not be the case) - - serversessions - dictionary {sessid:{property:value},...} describing the properties - to sync on all sessions - """ - to_save = [sessid for sessid in serversessions if sessid in self.sessions] - to_delete = [sessid for sessid in self.sessions if sessid not in to_save] - # save protocols - for sessid in to_save: - self.sessions[sessid].load_sync_data(serversessions[sessid]) - # disconnect out-of-sync missing protocols - for sessid in to_delete: - self.server_disconnect(sessid) - - def count_loggedin(self, include_unloggedin=False): - """ - Count loggedin connections, alternatively count all connections. - """ - return len(self.get_sessions(include_unloggedin=include_unloggedin)) - - def session_from_suid(self, suid): - """ - Given a session id, retrieve the session (this is primarily - intended to be called by web clients) - """ - return [sess for sess in self.get_sessions(include_unloggedin=True) - if hasattr(sess, 'suid') and sess.suid == suid] - - def data_in(self, session, string="", data=""): - """ - Called by portal sessions for relaying data coming - in from the protocol to the server. data is - serialized before passed on. - """ - #print "portal_data_in:", string - self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid, - msg=string, - data=data) - def announce_all(self, message): - """ - Send message to all connection sessions - """ - for session in self.sessions.values(): - session.data_out(message) - - def data_out(self, sessid, string="", data=""): - """ - Called by server for having the portal relay messages and data - to the correct session protocol. - """ - session = self.sessions.get(sessid, None) - if session: - session.data_out(string, data=data) - - def oob_data_in(self, session, data): - """ - OOB (Out-of-band) data Portal -> Server - """ - print "portal_oob_data_in:", data - self.portal.amp_protocol.call_remote_OOBPortal2Server(session.sessid, - data=data) - - def oob_data_out(self, sessid, data): - """ - OOB (Out-of-band) data Server -> Portal - """ - print "portal_oob_data_out:", data - session = self.sessions.get(sessid, None) - if session: - session.oob_data_out(data) - SESSIONS = ServerSessionHandler() -PORTAL_SESSIONS = PortalSessionHandler() diff --git a/src/server/webserver.py b/src/server/webserver.py index 9daf5d8b20..fdea83bb99 100644 --- a/src/server/webserver.py +++ b/src/server/webserver.py @@ -11,10 +11,13 @@ application. a great example/aid on how to do this.) """ +import urlparse +from urllib import quote as urlquote from twisted.web import resource, http -from twisted.python import threadpool from twisted.internet import reactor from twisted.application import service, internet +from twisted.web.proxy import ReverseProxyResource +from twisted.web.server import NOT_DONE_YET from twisted.web.wsgi import WSGIResource from django.core.handlers.wsgi import WSGIHandler @@ -44,6 +47,36 @@ class HTTPChannelWithXForwardedFor(http.HTTPChannel): http.HTTPFactory.protocol = HTTPChannelWithXForwardedFor +class EvenniaReverseProxyResource(ReverseProxyResource): + def getChild(self, path, request): + """ + Create and return a proxy resource with the same proxy configuration + as this one, except that its path also contains the segment given by + C{path} at the end. + """ + return EvenniaReverseProxyResource( + self.host, self.port, self.path + '/' + urlquote(path, safe=""), + self.reactor) + + + def render(self, request): + """ + Render a request by forwarding it to the proxied server. + """ + # RFC 2616 tells us that we can omit the port if it's the default port, + # but we have to provide it otherwise + request.content.seek(0, 0) + qs = urlparse.urlparse(request.uri)[4] + if qs: + rest = self.path + '?' + qs + else: + rest = self.path + clientFactory = self.proxyClientFactoryClass( + request.method, rest, request.clientproto, + request.getAllHeaders(), request.content.read(), request) + self.reactor.connectTCP(self.host, self.port, clientFactory) + return NOT_DONE_YET + # # Website server resource # diff --git a/src/settings_default.py b/src/settings_default.py index 068709af83..02e1235620 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -44,13 +44,21 @@ WEBSERVER_ENABLED = True # attacks. It defaults to allowing all. In production, make # sure to change this to your actual host addresses/IPs. ALLOWED_HOSTS = ["*"] -# A list of ports the Evennia webserver listens on -WEBSERVER_PORTS = [8000] +# The webserver sits behind a Portal proxy. This is a list +# of tuples (proxyport,serverport) used. The proxyports are what +# the Portal proxy presents to the world. The serverports are +# the internal ports the proxy uses to forward data to the Server-side +# webserver (these should not be publicly open) +WEBSERVER_PORTS = [(8000, 5001)] # Interface addresses to listen to. If 0.0.0.0, listen to all. WEBSERVER_INTERFACES = ['0.0.0.0'] # IP addresses that may talk to the server in a reverse proxy configuration, # like NginX. UPSTREAM_IPS = ['127.0.0.1'] +# The webserver uses threadpool for handling requests. This will scale +# with server load. Set the minimum and maximum number of threads it +# may use as (min, max) (must be > 0) +WEBSERVER_THREADPOOL_LIMITS = (1, 20) # Start the evennia ajax client on /webclient # (the webserver must also be running) WEBCLIENT_ENABLED = True @@ -151,13 +159,6 @@ DATABASES = { 'HOST':'', 'PORT':'' }} -# Engine Config style for Django versions < 1.2 only. See above. -DATABASE_ENGINE = 'sqlite3' -DATABASE_NAME = os.path.join(GAME_DIR, 'evennia.db3') -DATABASE_USER = '' -DATABASE_PASSWORD = '' -DATABASE_HOST = '' -DATABASE_PORT = '' ###################################################################### # Evennia pluggable modules @@ -479,6 +480,7 @@ INSTALLED_APPS = ( 'django.contrib.admindocs', 'django.contrib.flatpages', 'src.server', + 'src.typeclasses', 'src.players', 'src.objects', 'src.comms', @@ -488,7 +490,8 @@ INSTALLED_APPS = ( 'src.web.website',) # The user profile extends the User object with more functionality; # This should usually not be changed. -AUTH_PROFILE_MODULE = "players.PlayerDB" +AUTH_USER_MODEL = "players.PlayerDB" +#AUTH_PROFILE_MODULE = "players.PlayerDB" # Use a custom test runner that just tests Evennia-specific apps. TEST_RUNNER = 'src.utils.test_utils.EvenniaTestSuiteRunner' diff --git a/src/typeclasses/managers.py b/src/typeclasses/managers.py index 4ca3453d51..f40cbbb011 100644 --- a/src/typeclasses/managers.py +++ b/src/typeclasses/managers.py @@ -5,11 +5,13 @@ all Attributes and TypedObjects). """ from functools import update_wrapper from django.db import models +from django.db.models import Q from src.utils import idmapper from src.utils.utils import make_iter from src.utils.dbserialize import to_pickle __all__ = ("AttributeManager", "TypedObjectManager") +_GA = object.__getattribute__ # Managers @@ -48,28 +50,168 @@ class AttributeManager(models.Manager): def exists(self,*args, **kwargs): return super(AttributeManager, self).exists(*args, **kwargs) - def attr_namesearch(self, searchstr, obj, exact_match=True): + def get_attrs_on_obj(self, searchstr, obj, exact_match=True): """ - Searches the object's attributes for name matches. + Searches the object's attributes for attribute key matches. searchstr: (str) A string to search for. """ # Retrieve the list of attributes for this object. - if exact_match: - return self.filter(db_obj=obj).filter( - db_key__iexact=searchstr) - else: - return self.filter(db_obj=obj).filter( - db_key__icontains=searchstr) - def attr_valuesearch(self, searchstr, obj=None): + if exact_match: + return _GA("obj", "db_attributes").filter(db_key__iexact=searchstr) + else: + return _GA("obj", "db_attributes").filter(db_key__icontains=searchstr) + + def attr_namesearch(self, *args, **kwargs): + "alias wrapper for backwards compatability" + return self.get_attrs_on_obj(*args, **kwargs) + + def get_attr_by_value(self, searchstr, obj=None): """ - Searches for Attributes with a given value on obj + Searches obj for Attributes with a given value. + searchstr - value to search for. This may be any suitable object. + obj - limit to a given object instance + + If no restraint is given, all Attributes on all types of objects + will be searched. It's highly recommended to at least + supply the objclass argument (DBObject, DBScript or DBPlayer) + to restrict this lookup. """ if obj: - return self.filter(db_obj=obj, db_value=searchstr) + return _GA(obj, "db_attributes").filter(db_value=searchstr) return self.filter(db_value=searchstr) + def attr_valuesearch(self, *args, **kwargs): + "alias wrapper for backwards compatability" + return self.get_attr_by_value(self, *args, **kwargs) + +# +# LiteAttributeManager +# + +class LiteAttributeManager(models.Manager): + """ + Manager methods for LiteAttributes + """ + def get_lattrs_on_obj(self, obj, search_key=None, category=None): + """ + Get all lattrs 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() + return _GA(obj, "db_liteattributes").filter(cat_cands & key_cands) + else: + return list(_GA(obj, "db_liteattributes").all()) + + def get_lattr(self, search_key=None, category=None): + """ + Search and return all liteattrs matching any combination of + the search criteria. + search_key (string) - the lattr identifier + category (string) - the lattr 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() + return list(self.filter(key_cands & cat_cands)) + + def get_lattr_data(self, obj=None, search_key=None, category=None): + """ + Retrieve data from found lattrs in an efficient way. Returns a list of data + matching the search criterions + """ + 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 obj: + query = _GA(obj, "db_liteattributes").filter(key_cands & cat_cands).prefetch_related("db_data") + else: + query = self.filter(key_cands & cat_cands).prefetch_related("db_data") + return [q.db_data for q in query] + + def create_lattr(self, key, category=None, data=None, obj=None): + """ + Create a LiteAttribute. This makes sure the create case-insensitive keys. + """ + + lattr = self.objects.create(db_key=key.lower().strip(), + db_category=category.lower().strip() if category!=None else None, + db_data=str(data) if data!=None else None) + lattr.save() + if obj: + obj.db_liteattributes.add(lattr) + return lattr + +# +# TagManager +# + +class TagManager(models.Manager): + """ + Extra manager methods for Tags + """ + def get_tags_on_obj(self, obj, key=None, category=None): + """ + Get all tags on obj, optionally limited by key and/or category + """ + 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, key=None, category=None): + """ + Search and return all tags matching any combination of + the search criteria. + search_key (string) - the tag identifier + category (string) - the tag category + + 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=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 key and category: + return tags[0] if tags else None + else: + return list(tags) + + 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 + key (string) - the tag identifier + category (string) - the tag category + """ + 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) + + def create_tag(self, key=None, category=None, data=None): + """ + Create a tag. This makes sure the create case-insensitive tags. + Note that if the exact same tag configuration (key+category) + exists, it will be re-used. A data keyword will overwrite existing + data on a tag (it is not part of what makes the tag unique). + + """ + data = str(data) if data!=None else None + + tag = self.get_tag(key=key, category=category) + if tag and data != None: + tag.db_data = data + tag.save() + elif not tag: + 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 + # # helper functions for the TypedObjectManager. # diff --git a/src/typeclasses/migrations/0001_initial.py b/src/typeclasses/migrations/0001_initial.py new file mode 100644 index 0000000000..bc6777daab --- /dev/null +++ b/src/typeclasses/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# -*- 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 model 'Attribute' + db.create_table(u'typeclasses_attribute', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)), + ('db_value', self.gf('src.utils.picklefield.PickledObjectField')(null=True)), + ('db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + )) + db.send_create_signal(u'typeclasses', ['Attribute']) + + + def backwards(self, orm): + # Deleting model 'Attribute' + db.delete_table(u'typeclasses_attribute') + + + models = { + 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 = ['typeclasses'] \ No newline at end of file diff --git a/src/typeclasses/migrations/0002_resave_attrs.py b/src/typeclasses/migrations/0002_resave_attrs.py new file mode 100644 index 0000000000..355d1cd2b9 --- /dev/null +++ b/src/typeclasses/migrations/0002_resave_attrs.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + +user_orm_label = '%s.%s' % (User._meta.app_label, User._meta.object_name) +user_model_label = '%s.%s' % (User._meta.app_label, User._meta.module_name) +user_ptr_name = '%s_ptr' % User._meta.object_name.lower() + +class Migration(DataMigration): + depends_on = (('server', '0004_store_all_attrs'), + ('objects', '0021_auto__del_objattribute'), + ('players', '0020_auto__del_playerattribute'), + ('scripts', '0013_auto__del_scriptattribute')) + no_dry_run=True + def forwards(self, orm): + "Write your forwards methods here." + # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." + + for tmpattr in orm['server.TmpAttribute'].objects.all(): + typ = tmpattr.db_obj_type + dbid = tmpattr.db_obj_id + if typ == 'objectdb': + try: + dbobj = orm['objects.ObjectDB'].objects.get(id=dbid) + except: + print "could not find objid %i" % dbid + continue + elif typ == 'playerdb': + try: + dbobj = orm['players.PlayerDB'].objects.get(id=dbid) + except: + print "could not find objid %i" % dbid + continue + elif typ == 'scriptdb': + try: + dbobj = orm['scripts.ScriptDB'].objects.get(id=dbid) + except: + print "could not find objid %i" % dbid + continue + else: + print "Wrong object type to store on: %s" % typ + continue + dbattr = orm['typeclasses.Attribute'](db_key=tmpattr.db_key, + db_value=tmpattr.db_value, + db_lock_storage=tmpattr.db_lock_storage, + db_date_created=tmpattr.db_date_created) + + dbattr.save() + dbobj.db_attributes.add(dbattr) + + + def backwards(self, orm): + "Write your backwards methods here." + raise RuntimeError("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'}) + }, + user_model_label: { + 'Meta': {'object_name': User.__name__, 'db_table': "'%s'" % User._meta.db_table}, + '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'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'server.serverconfig': { + 'Meta': {'object_name': 'ServerConfig'}, + 'db_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'db_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'server.tmpattribute': { + 'Meta': {'object_name': 'TmpAttribute'}, + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_obj_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'db_obj_type': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'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'objects.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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'objects.objectnick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'}), + 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': "orm['%s']" % user_orm_label, 'unique': 'True'}) + }, + u'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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_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_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['server', 'typeclasses', 'objects', 'scripts', 'players'] + symmetrical = True diff --git a/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py b/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py new file mode 100644 index 0000000000..01a4f29685 --- /dev/null +++ b/src/typeclasses/migrations/0003_auto__add_liteattribute__add_index_liteattribute_db_key_db_category__a.py @@ -0,0 +1,81 @@ +# -*- 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 model 'LiteAttribute' + db.create_table(u'typeclasses_liteattribute', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('db_category', self.gf('django.db.models.fields.CharField')(max_length=64, null=True, blank=True)), + ('db_data', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'typeclasses', ['LiteAttribute']) + + # Adding index on 'LiteAttribute', fields ['db_key', 'db_category'] + db.create_index(u'typeclasses_liteattribute', ['db_key', 'db_category']) + + # Adding model 'Tag' + db.create_table(u'typeclasses_tag', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, null=True)), + ('db_category', self.gf('django.db.models.fields.CharField')(max_length=64, null=True)), + ('db_data', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + )) + db.send_create_signal(u'typeclasses', ['Tag']) + + # Adding unique constraint on 'Tag', fields ['db_key', 'db_category'] + db.create_unique(u'typeclasses_tag', ['db_key', 'db_category']) + + # Adding index on 'Tag', fields ['db_key', 'db_category'] + db.create_index(u'typeclasses_tag', ['db_key', 'db_category']) + + + def backwards(self, orm): + # Removing index on 'Tag', fields ['db_key', 'db_category'] + db.delete_index(u'typeclasses_tag', ['db_key', 'db_category']) + + # Removing unique constraint on 'Tag', fields ['db_key', 'db_category'] + db.delete_unique(u'typeclasses_tag', ['db_key', 'db_category']) + + # Removing index on 'LiteAttribute', fields ['db_key', 'db_category'] + db.delete_index(u'typeclasses_liteattribute', ['db_key', 'db_category']) + + # Deleting model 'LiteAttribute' + db.delete_table(u'typeclasses_liteattribute') + + # Deleting model 'Tag' + db.delete_table(u'typeclasses_tag') + + + models = { + 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 = ['typeclasses'] \ No newline at end of file diff --git a/src/typeclasses/migrations/0004_copy_nicks_to_liteattrs_aliases_to_tags.py b/src/typeclasses/migrations/0004_copy_nicks_to_liteattrs_aliases_to_tags.py new file mode 100644 index 0000000000..80ae81d88c --- /dev/null +++ b/src/typeclasses/migrations/0004_copy_nicks_to_liteattrs_aliases_to_tags.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models, IntegrityError + + +class Migration(DataMigration): + + depends_on = (("objects", "0022_add_db_liteattributes_db_tags"), + ("players", "0025_auto__add_db_liteattributes_db_tags")) + + def forwards(self, orm): + "Write your forwards methods here." + # Note: Don't use "from appname.models import ModelName". + # Use orm.ModelName to refer to models in this application, + # and orm['appname.ModelName'] for models in other applications. + + # Each alias and nick is its own case. By default, this function starts + # in a transaction, so we'll close that and make our own transactions. + + for alias in orm['objects.Alias'].objects.all(): + # convert all Aliases to tags + try: + tag = orm.Tag.objects.get(db_key=alias.db_key, db_category="object_alias") + except orm.Tag.DoesNotExist: + tag = orm.Tag(db_key=alias.db_key, db_category="object_alias", db_data=None) + tag.save() + obj = alias.db_obj + obj.db_tags.add(tag) + # convert all nicks to LiteAttrs + for nick in orm['objects.ObjectNick'].objects.all(): + lattr = orm.LiteAttribute(db_key=nick.db_nick, db_category="object_nick_%s" % nick.db_type, db_data=nick.db_real) + lattr.save() + obj = nick.db_obj + obj.db_liteattributes.add(lattr) + for nick in orm['players.PlayerNick'].objects.all(): + lattr = orm.LiteAttribute(db_key=nick.db_nick, db_category="player_nick_%s" % nick.db_type, db_data=nick.db_real) + lattr.save() + obj = nick.db_obj + obj.db_liteattributes.add(lattr) + + def backwards(self, orm): + "Write your backwards methods here." + + 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.alias': { + 'Meta': {'object_name': 'Alias'}, + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['objects.ObjectDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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'objects.objectnick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'}), + 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'players.playernick': { + 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'}, + 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}), + 'db_real': ('django.db.models.fields.TextField', [], {}), + 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 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 = ['objects', 'scripts', 'players', 'typeclasses'] + symmetrical = True diff --git a/src/typeclasses/migrations/__init__.py b/src/typeclasses/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 931b0e812e..1d3c1daa28 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -34,20 +34,24 @@ import sys import traceback #from collections import defaultdict -from django.db import models, IntegrityError +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.server.caches import get_field_cache, set_field_cache, del_field_cache -from src.server.caches import get_attr_cache, set_attr_cache, del_attr_cache -from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache, flush_attr_cache -from src.server.caches import call_ndb_hooks +from src.server.caches import get_attr_cache, set_attr_cache +from src.server.caches import get_prop_cache, set_prop_cache, flush_attr_cache + +from django.db.models.signals import m2m_changed +from src.server.caches import post_attr_update + +#from src.server.caches import call_ndb_hooks from src.server.models import ServerConfig from src.typeclasses import managers from src.locks.lockhandler import LockHandler from src.utils import logger, utils -from src.utils.utils import make_iter, is_iter, to_unicode, to_str +from src.utils.utils import make_iter, is_iter, to_str from src.utils.dbserialize import to_pickle, from_pickle from src.utils.picklefield import PickledObjectField @@ -59,8 +63,7 @@ _CTYPEGET = ContentType.objects.get _GA = object.__getattribute__ _SA = object.__setattr__ _DA = object.__delattr__ -#_PLOADS = pickle.loads -#_PDUMPS = pickle.dumps + #------------------------------------------------------------ # @@ -68,7 +71,6 @@ _DA = object.__delattr__ # #------------------------------------------------------------ - class Attribute(SharedMemoryModel): """ Abstract django model. @@ -85,34 +87,22 @@ class Attribute(SharedMemoryModel): mode - which type of data is stored in attribute lock_storage - perm strings obj - which object the attribute is defined on - date_created - when the attribute was created - value - the data stored in the attribute - what is actually stored in the field is a dict + date_created - when the attribute was created. + value - the data stored in the attribute, in pickled form + using wrappers to be able to store/retrieve models. - {type : nodb|dbobj|dbiter, - data : } - - where type is info for the loader, telling it if holds a single - dbobject (dbobj), have to do a full scan for dbrefs (dbiter) or - if it is a normal Python structure without any dbobjs inside it - and can thus return it without further action (nodb). """ # # Attribute Database Model setup # - # - # These databse fields are all set using their corresponding properties, + # These database fields are all set using their corresponding properties, # named same as the field, but withtout the db_* prefix. - db_key = models.CharField('key', max_length=255, db_index=True) # access through the value property - db_value = PickledObjectField('value2', null=True) + db_value = PickledObjectField('value', null=True) # Lock storage db_lock_storage = models.TextField('locks', blank=True) - # references the object the attribute is linked to (this is set - # by each child class to this abstact class) - db_obj = None # models.ForeignKey("RefencedObject") # time stamp db_date_created = models.DateTimeField('date_created', editable=False, auto_now_add=True) @@ -129,9 +119,9 @@ class Attribute(SharedMemoryModel): class Meta: "Define Django meta options" - abstract = True verbose_name = "Evennia Attribute" + # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using # normal python operations (without having to remember to save() @@ -242,10 +232,10 @@ class Attribute(SharedMemoryModel): # def __str__(self): - return smart_str("%s(%s)" % (self.key, self.id)) + return smart_str("%s(%s)" % (_GA(self, "db_key", _GA(self, "id")))) def __unicode__(self): - return u"%s(%s)" % (self.key, self.id) + return u"%s(%s)" % (_GA(self, "db_key", _GA(self, "id"))) def access(self, accessing_obj, access_type='read', default=False): """ @@ -262,53 +252,208 @@ class Attribute(SharedMemoryModel): """ pass - #------------------------------------------------------------ # -# Nicks +# LiteAttributes # #------------------------------------------------------------ -class TypeNick(SharedMemoryModel): - """ - This model holds whichever alternate names this object - has for OTHER objects, but also for arbitrary strings, - channels, players etc. Setting a nick does not affect - the nicknamed object at all (as opposed to Aliases above), - and only this object will be able to refer to the nicknamed - object by the given nick. - - The default nick types used by Evennia are: - inputline (default) - match against all input - player - match against player searches - obj - match against object searches - channel - used to store own names for channels +class LiteAttribute(models.Model): """ - db_nick = models.CharField('nickname',max_length=255, db_index=True, help_text='the alias') - db_real = models.TextField('realname', help_text='the original string to match and replace.') - db_type = models.CharField('nick type',default="inputline", max_length=16, null=True, blank=True, - help_text="the nick type describes when the engine tries to do nick-replacement. Common options are 'inputline','player','obj' and 'channel'. Inputline checks everything being inserted, whereas the other cases tries to replace in various searches or when posting to channels.") - db_obj = None #models.ForeignKey("ObjectDB") + This specialized model is a middle-road between a Tag + and an Attribute. A LiteAttribute is smaller, less complex + to search than an Attribute (its key is indexed together with its + category) but can only hold strings in its db_value property whereas + an Attribute can hold arbitrary data. A LiteAttribute is also not + kept in memory in the same way as Attributes and has no inherent + concept of access restrictions which makes it unsuitable for modification + by untrusted users. + + The difference between Liteattrs and Tags are that liteattrs are + not shared/unique but are created separately for each object holding them. + + LiteAttributes are accessed through the db_liteattributes many2many field on + Typed Objects. + + + The main default use of the LiteAttribute is to implement Nick replacement. + In this case the category determines when the replacement is to be checked. + The key value is the input to replace and the data value holds the replacement + text. + + The default nick category types used by Evennia are: + nick_inputline (default) - match against all input + nick_player - match against player searches + nick_obj - match against object searches + nick_channel - used to store own names for channels + + """ + db_key = models.CharField('key', max_length=255, help_text='name if liteattribute') + db_category = models.CharField('category', max_length=64, null=True, blank=True, help_text="liteattribute category") + db_data = models.TextField('data', help_text='holds string data') + + objects = managers.LiteAttributeManager() class Meta: "Define Django meta options" - abstract = True - verbose_name = "Nickname" - unique_together = ("db_nick", "db_type", "db_obj") + verbose_name = "Lite Attribute" + index_together = (("db_key", "db_category"),) + def __unicode__(self): + return u"%s" % self.db_key + def __str__(self): + return str(self.db_key) -class TypeNickHandler(object): +#------------------------------------------------------------ +# +# Tags +# +#------------------------------------------------------------ + +class Tag(models.Model): """ - Handles nick access and setting. Accessed through ObjectDB.nicks + Tags are quick markers for objects in-game. An typeobject + can have any number of tags, stored via its db_tags property. + Tagging similar objects will make it easier to quickly locate the + group later (such as when implementing zones). The main advantage + of tagging as opposed to using Attributes is speed; a tag is very + limited in what data it can hold, and the tag key+category is + indexed for efficient lookup in the database. Tags are shared between + objects - a new tag is only created if the key+category combination + did not previously exist, making them unsuitable for storing + object-related data (for this a LiteAttribute or a full Attribute + should be used). + The 'db_data' field is intended as a documentation + field for the tag itself, such as to document what this tag+category + stands for and display that in a web interface or similar. + + The main default use for Tags is to implement Aliases for objects. + this uses the 'aliases' tag category, which is also checked by the + default search functions of Evennia to allow quick searches by alias. """ + db_key = models.CharField('key', max_length=255, null=True, help_text="tag identifier") + db_category = models.CharField('category', max_length=64, null=True, help_text="tag category") + db_data = models.TextField('data', null=True, blank=True, help_text="optional data field with extra information. This is not searched for.") - NickClass = TypeNick + objects = managers.TagManager() + class Meta: + "Define Django meta options" + verbose_name = "Tag" + unique_together =(('db_key', 'db_category'),) + index_together = (('db_key', 'db_category'),) + def __unicode__(self): + return u"%s" % self.db_key + def __str__(self): + return str(self.db_key) - def __init__(self, obj): + +# +# Helper handlers +# + +class TagHandler(object): + """ + Generic tag-handler. Accessed via TypedObject.tags. + """ + def __init__(self, obj, category_prefix=""): """ - This handler allows for accessing and setting nicks - - on-the-fly replacements for various text input passing through - this object (most often a Character) + Tags are stored internally in the TypedObject.db_tags m2m field + using the category + """ + self.obj = obj + self.prefix = category_prefix.strip().lower() if category_prefix else "" + + def add(self, tag, category=None, data=None): + "Add a new tag to the handler" + for tag in make_iter(tag): + tag = tag.strip().lower() if tag!=None else None + category = "%s%s" % (self.prefix, category.strip.lower()) if category!=None else None + data = str(data) if data!=None else None + # this will only create tag if no matches existed beforehand (it will overload + # data on an existing tag since that is not considered part of making the tag unique) + tagobj = Tag.objects.create_tag(key=tag, category=category, data=data) + self.obj.db_tags.add(tagobj) + + def remove(self, tag, category=None): + "Remove a tag from the handler" + for tag in make_iter(tag): + tag = tag.strip().lower() if tag!=None else None + category = "%s%s" % (self.prefix, category.strip.lower()) if category!=None else None + #TODO This does not delete the tag object itself. Maybe it should do that when no + # objects reference the tag anymore? + tagobj = self.obj.db_tags.filter(db_key=tag, db_category=category) + if tagobj: + self.obj.remove(tagobj[0]) + def clear(self): + "Remove all tags from the handler" + self.obj.db_tags.clear() + + def all(self): + "Get all tags in this handler" + return [p[0] for p in self.obj.db_tags.all().values_list("db_key")] + + def __str__(self): + return ",".join(self.all()) + def __unicode(self): + return u",".join(self.all()) + + + +class AliasHandler(object): + """ + Handles alias access and setting. Accessed through TypedObject.aliases. + """ + def __init__(self, obj, category_prefix="object_"): + """ + Aliases are alternate names for an entity. + Implements the alias handler, using Tags for storage and + the _alias tag category. It is available + as TypedObjects.aliases. + """ + self.obj = obj + self.category = "%salias" % category_prefix + + def add(self, alias): + "Add a new nick to the handler" + 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) + self.obj.db_tags.add(aliasobj) + + def remove(self, alias): + "Remove alias from handler." + for alias in make_iter(alias): + aliasobj = self.obj.filter(db_key__iexact=alias.strip(), category=self.category) + #TODO note that this doesn't delete the tag itself. We might want to do this when no object + # uses it anymore ... + self.obj.db_tags.remove(aliasobj) + def clear(self): + "Clear all aliases from handler" + self.obj.db_tags.remove(self.obj.filter(categery=self.category)) + + def all(self): + "Get all aliases in this handler" + 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()) + def __unicode(self): + return u",".join(self.all()) + + +class NickHandler(object): + """ + Handles nick access and setting. Accessed through TypedObject.nicks. + """ + + def __init__(self, obj, category_prefix="object_"): + """ + Nicks are alternate names an entity as of ANOTHER entity. The + engine will auto-replace nicks under circumstances dictated + by the nick category. It uses LiteAttributes for storage. The default nick types used by Evennia are: @@ -317,67 +462,89 @@ class TypeNickHandler(object): obj - match against object searches channel - used to store own names for channels - You can define other nicktypes by using the add() method of - this handler and set nick_type to whatever you want. It's then - up to you to somehow make use of this nick_type in your game - (such as for a "recog" system). - + These are all stored interally using categories + nick_inputline etc. """ 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(): return - nick = nick.strip() - real = realname.strip() - query = self.NickClass.objects.filter(db_obj=self.obj, db_nick__iexact=nick, db_type__iexact=nick_type) - if query.count(): - old_nick = query[0] - old_nick.db_real = real - old_nick.save() - else: - new_nick = self.NickClass(db_nick=nick, db_real=real, db_type=nick_type, db_obj=self.obj) - new_nick.save() - def delete(self, nick, nick_type="inputline"): - "Removes a previously stored nick" - nick = nick.strip() - query = self.NickClass.objects.filter(db_obj=self.obj, db_nick__iexact=nick, db_type__iexact=nick_type) - if query.count(): - # remove the found nick(s) - query.delete() - def get(self, nick=None, nick_type="inputline", obj=None): - """ - Retrieves a given nick (with a specified nick_type) on an object. If no nick is given, returns a list - of all nicks on the object, or the empty list. - Defaults to searching the current object. - """ - if not obj: - # defaults to the current object - obj = self.obj - if nick: - query = self.NickClass.objects.filter(db_obj=obj, db_nick__iexact=nick, db_type__iexact=nick_type) - query = query.values_list("db_real", flat=True) + for nick in make_iter(nick): + nick = nick.strip() + real = realname + 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(): - return query[0] + old_nick = query[0] + old_nick.db_data = real + old_nick.save() else: - return nick - else: - return self.NickClass.objects.filter(db_obj=obj) - def has(self, nick, nick_type="inputline", obj=None): - """ - Returns true/false if this nick and nick_type is defined on the given - object or not. If no obj is given, default to the current object the - handler is defined on. + new_nick = LiteAttribute(db_key=nick, db_category=nick_type, db_data=real) + new_nick.save() + self.obj.db_liteattributes.add(new_nick) + def remove(self, key, category="inputline"): + "Removes a previously stored nick" + for nick in make_iter(key): + nick = nick.strip() + 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) + self.obj.db_liteattributes.remove(query[0]) + + def delete(self, *args, **kwargs): + "alias wrapper" + self.remove(*args, **kwargs) + + def get(self, key=None, category="inputline"): """ - if not obj: - obj = self.obj - return self.NickClass.objects.filter(db_obj=obj, db_nick__iexact=nick, db_type__iexact=nick_type).count() + 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 + original input or default if given + If no nick 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()) + 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 [p[0] for p in self.obj.db_nicks.filter(db_category=self.category).values_list("db_key")] + + #------------------------------------------------------------ @@ -411,33 +578,43 @@ class TypedObject(SharedMemoryModel): # TypedObject Database Model setup # # - # These databse fields are all set using their corresponding properties, - # named same as the field, but withtou the db_* prefix. + # These databse fields are all accessed and set using their corresponding properties, + # named same as the field, but without the db_* prefix (no separate save() call is needed) - # Main identifier of the object, for searching. Can also - # be referenced as 'name'. + # Main identifier of the object, for searching. Is accessed with self.key or self.name db_key = models.CharField('key', max_length=255, db_index=True) - # This is the python path to the type class this object is tied to - # (the type class is what defines what kind of Object this is) - db_typeclass_path = models.CharField('typeclass', max_length=255, null=True, help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") - # Creation date + # This is the python path to the type class this object is tied to the type class is what defines what kind of Object this is) + db_typeclass_path = models.CharField('typeclass', max_length=255, null=True, + help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") + # Creation date. This is not changed once the object is created. db_date_created = models.DateTimeField('creation date', editable=False, auto_now_add=True) # Permissions (access these through the 'permissions' property) - db_permissions = models.CharField('permissions', max_length=255, blank=True, help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Character objects use 'Players' by default. Most other objects don't have any permissions.") + db_permissions = models.CharField('permissions', max_length=255, blank=True, + help_text="a comma-separated list of text strings checked by in-game locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Character objects use 'Players' by default. Most other objects don't have any permissions.") # Lock storage - db_lock_storage = models.TextField('locks', blank=True, help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.") + db_lock_storage = models.TextField('locks', blank=True, + help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.") + # many2many relationships + db_attributes = models.ManyToManyField(Attribute, null=True, + help_text='attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).') + db_liteattributes = models.ManyToManyField(LiteAttribute, null=True, + help_text='liteattributes on this object. A LiteAttribute holds a key, a category and a string field for simple lookups.') + db_tags = models.ManyToManyField(Tag, null=True, + help_text='tags on this object. Tags are simple string markers to identify, group and alias objects.') # Database manager objects = managers.TypedObjectManager() - # object cache and flags + # quick on-object typeclass cache for speed _cached_typeclass = None # lock handler self.locks def __init__(self, *args, **kwargs): "We must initialize the parent first - important!" - SharedMemoryModel.__init__(self, *args, **kwargs) - self.locks = LockHandler(self) + super(SharedMemoryModel, self).__init__(*args, **kwargs) + #SharedMemoryModel.__init__(self, *args, **kwargs) + _SA(self, "dbobj", self) # this allows for self-reference + _SA(self, "locks", LockHandler(self)) class Meta: """ @@ -447,6 +624,7 @@ class TypedObject(SharedMemoryModel): verbose_name = "Evennia Database Object" ordering = ['-db_date_created', 'id', 'db_typeclass_path', 'db_key'] + # wrapper # Wrapper properties to easily set database fields. These are # @property decorators that allows to access these fields using # normal python operations (without having to remember to save() @@ -459,7 +637,8 @@ class TypedObject(SharedMemoryModel): #@property def __key_get(self): "Getter. Allows for value = self.key" - return get_field_cache(self, "key") + return _GA(self, "db_key") + #return get_field_cache(self, "key") #@key.setter def __key_set(self, value): "Setter. Allows for self.key = value" @@ -470,54 +649,44 @@ class TypedObject(SharedMemoryModel): raise Exception("Cannot delete objectdb key!") key = property(__key_get, __key_set, __key_del) - # name property (wraps db_key too - alias to self.key) - #@property - def __name_get(self): - "Getter. Allows for value = self.name" - return get_field_cache(self, "key") - #@name.setter - def __name_set(self, value): - "Setter. Allows for self.name = value" - set_field_cache(self, "key", value) - #@name.deleter - def __name_del(self): - "Deleter. Allows for del self.name" - raise Exception("Cannot delete name!") + # name property (alias to self.key) + def __name_get(self): return self.key + def __name_set(self, value): self.key = value + def __name_del(self): raise Exception("Cannot delete name") name = property(__name_get, __name_set, __name_del) - # typeclass_path property + # typeclass_path property - we manage this separately. #@property - def __typeclass_path_get(self): - "Getter. Allows for value = self.typeclass_path" - return get_field_cache(self, "typeclass_path") - #@typeclass_path.setter - def __typeclass_path_set(self, value): - "Setter. Allows for self.typeclass_path = value" - set_field_cache(self, "typeclass_path", value) - _SA(self, "_cached_typeclass", None) - #@typeclass_path.deleter - def __typeclass_path_del(self): - "Deleter. Allows for del self.typeclass_path" - self.db_typeclass_path = "" - self.save() - del_field_cache(self, "typeclass_path") - _SA(self, "_cached_typeclass", None) - typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del) + #def __typeclass_path_get(self): + # "Getter. Allows for value = self.typeclass_path" + # return _GA(self, "db_typeclass_path") + ##@typeclass_path.setter + #def __typeclass_path_set(self, value): + # "Setter. Allows for self.typeclass_path = value" + # _SA(self, "db_typeclass_path", value) + # update_fields = ["db_typeclass_path"] if _GA(self, "_get_pk_val")(_GA(self, "_meta")) is not None else None + # _GA(self, "save")(update_fields=update_fields) + ##@typeclass_path.deleter + #def __typeclass_path_del(self): + # "Deleter. Allows for del self.typeclass_path" + # self.db_typeclass_path = "" + # _GA(self, "save")(update_fields=["db_typeclass_path"]) + #typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del) # date_created property #@property - def __date_created_get(self): - "Getter. Allows for value = self.date_created" - return get_field_cache(self, "date_created") - #@date_created.setter - def __date_created_set(self, value): - "Setter. Allows for self.date_created = value" - raise Exception("Cannot change date_created!") - #@date_created.deleter - def __date_created_del(self): - "Deleter. Allows for del self.date_created" - raise Exception("Cannot delete date_created!") - date_created = property(__date_created_get, __date_created_set, __date_created_del) + #def __date_created_get(self): + # "Getter. Allows for value = self.date_created" + # return get_field_cache(self, "date_created") + ##@date_created.setter + #def __date_created_set(self, value): + # "Setter. Allows for self.date_created = value" + # raise Exception("Cannot change date_created!") + ##@date_created.deleter + #def __date_created_del(self): + # "Deleter. Allows for del self.date_created" + # raise Exception("Cannot delete date_created!") + #date_created = property(__date_created_get, __date_created_set, __date_created_del) # permissions property #@property @@ -542,18 +711,18 @@ class TypedObject(SharedMemoryModel): # lock_storage property (wraps db_lock_storage) #@property - def __lock_storage_get(self): - "Getter. Allows for value = self.lock_storage" - return get_field_cache(self, "lock_storage") - #@lock_storage.setter - def __lock_storage_set(self, value): - """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()""" - set_field_cache(self, "lock_storage", value) - #@lock_storage.deleter - def __lock_storage_del(self): - "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" - logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) - lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del) + #def __lock_storage_get(self): + # "Getter. Allows for value = self.lock_storage" + # return get_field_cache(self, "lock_storage") + ##@lock_storage.setter + #def __lock_storage_set(self, value): + # """Saves the lock_storage. This is usually not called directly, but through self.lock()""" + # set_field_cache(self, "lock_storage", value) + ##@lock_storage.deleter + #def __lock_storage_del(self): + # "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" + # logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) + #lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del) @@ -565,17 +734,15 @@ class TypedObject(SharedMemoryModel): # these are identifiers for fast Attribute access and caching _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS - _attribute_class = Attribute # replaced by relevant attribute class for child - _db_model_name = "typeclass" # used by attributes to safely store objects def __eq__(self, other): return other and hasattr(other, 'dbid') and self.dbid == other.dbid def __str__(self): - return smart_str("%s" % self.key) + return smart_str("%s" % _GA(self, "db_key")) def __unicode__(self): - return u"%s" % self.key + return u"%s" % _GA(self, "db_key") def __getattribute__(self, propname): """ @@ -588,6 +755,9 @@ class TypedObject(SharedMemoryModel): try: return _GA(self, propname) except AttributeError: + if propname.startswith('_'): + # don't relay private/special varname lookups to the typeclass + raise AttributeError("private property %s not found on db model (typeclass not searched)." % propname) # check if the attribute exists on the typeclass instead # (we make sure to not incur a loop by not triggering the # typeclass' __getattribute__, since that one would @@ -917,10 +1087,10 @@ class TypedObject(SharedMemoryModel): # # - # Fully persistent attributes. You usually access these + # Fully attr_obj attributes. You usually access these # through the obj.db.attrname method. - # Helper methods for persistent attributes + # Helper methods for attr_obj attributes def has_attribute(self, attribute_name): """ @@ -929,10 +1099,9 @@ class TypedObject(SharedMemoryModel): attribute_name: (str) The attribute's name. """ if not get_attr_cache(self, attribute_name): - attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name) - if attrib_obj: - set_attr_cache(self, attribute_name, attrib_obj[0]) + attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) + if attr_obj: + set_attr_cache(self, attribute_name, attr_obj[0]) else: return False return True @@ -950,46 +1119,38 @@ class TypedObject(SharedMemoryModel): below to perform access-checked modification of attributes. Lock types checked by secureattr are 'attrread','attredit','attrcreate'. """ - attrib_obj = get_attr_cache(self, attribute_name) - if not attrib_obj: - attrclass = _GA(self, "_attribute_class") - # check if attribute already exists. - attrib_obj = attrclass.objects.filter( - db_obj=self, db_key__iexact=attribute_name) - if attrib_obj: - # use old attribute - attrib_obj = attrib_obj[0] + attr_obj = get_attr_cache(self, attribute_name) + if not attr_obj: + # check if attribute already exists + attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) + if attr_obj: + # re-use old attribute object + attr_obj = attr_obj[0] + set_attr_cache(self, attribute_name, attr_obj) # renew cache else: - # no match; create new attribute - attrib_obj = attrclass(db_key=attribute_name, db_obj=self) + # no old attr available; create new (caches automatically) + attr_obj = Attribute(db_key=attribute_name) + attr_obj.save() # important + _GA(self, "db_attributes").add(attr_obj) if lockstring: - attrib_obj.locks.add(lockstring) - # re-set an old attribute value - try: - attrib_obj.value = new_value - except IntegrityError: - # this can happen if the cache was stale and the database object is - # missing. If so we need to clean self.hashid from the cache - flush_attr_cache(self) - self.delete() - raise IntegrityError("Attribute could not be saved - object %s was deleted from database." % self.key) - set_attr_cache(self, attribute_name, attrib_obj) + attr_obj.locks.add(lockstring) + # we shouldn't need to fear stale objects, the signalling should catch all cases + attr_obj.value = new_value def get_attribute_obj(self, attribute_name, default=None): """ Get the actual attribute object named attribute_name """ - attrib_obj = get_attr_cache(self, attribute_name) - if not attrib_obj: - attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name) - if not attrib_obj: + attr_obj = get_attr_cache(self, attribute_name) + if not attr_obj: + attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) + if not attr_obj: return default - set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here - return attrib_obj[0] - return attrib_obj + attr_obj = attr_obj[0] # query evaluated here + set_attr_cache(self, attribute_name, attr_obj) + return attr_obj - def get_attribute(self, attribute_name, default=None): + def get_attribute(self, attribute_name, default=None, raise_exception=False): """ Returns the value of an attribute on an object. You may need to type cast the returned value from this function since the attribute @@ -997,75 +1158,44 @@ class TypedObject(SharedMemoryModel): attribute_name: (str) The attribute's name. default: What to return if no attribute is found + raise_exception (bool) - raise an exception if no object exists instead of returning default. """ - attrib_obj = get_attr_cache(self, attribute_name) - if not attrib_obj: - attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name) - if not attrib_obj: + attr_obj = get_attr_cache(self, attribute_name) + if not attr_obj: + attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) + if not attr_obj: + if raise_exception: + raise AttributeError return default - set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here - return attrib_obj[0].value - return attrib_obj.value + attr_obj = attr_obj[0] # query is evaluated here + set_attr_cache(self, attribute_name, attr_obj) + 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. - """ - attrib_obj = get_attr_cache(self, attribute_name) - if not attrib_obj: - attrib_obj = _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name) - if not attrib_obj: - raise AttributeError - set_attr_cache(self, attribute_name, attrib_obj[0]) #query is first evaluated here - return attrib_obj[0].value - return attrib_obj.value - - def del_attribute(self, attribute_name): + def del_attribute(self, attribute_name, raise_exception=False): """ Removes an attribute entirely. attribute_name: (str) The attribute's name. + raise_exception (bool) - raise exception if attribute to delete + could not be found """ attr_obj = get_attr_cache(self, attribute_name) - if attr_obj: - del_attr_cache(self, attribute_name) - attr_obj.delete() - else: - try: - _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name)[0].delete() - except IndexError: - pass - - def del_attribute_raise(self, attribute_name): - """ - Removes and attribute. Raises AttributeError if - attribute is not found. - - attribute_name: (str) The attribute's name. - """ - attr_obj = get_attr_cache(self, attribute_name) - if attr_obj: - del_attr_cache(self, attribute_name) - attr_obj.delete() - else: - try: - _GA(self, "_attribute_class").objects.filter( - db_obj=self, db_key__iexact=attribute_name)[0].delete() - except IndexError: - pass - raise AttributeError + if not attr_obj: + attr_obj = _GA(self, "db_attributes").filter(db_key__iexact=attribute_name) + attr_obj = attr_obj[0] if attr_obj else None + if not attr_obj: + if raise_exception: + raise AttributeError + return + # the post-remove cache signal will auto-delete the attribute as well, + # don't call attr_obj.delete() after this. + self.db_attributes.remove(attr_obj) def get_all_attributes(self): """ Returns all attributes defined on the object. """ - return list(_GA(self,"_attribute_class").objects.filter(db_obj=self)) + return list(_GA(self, "db_attributes").all()) def attr(self, attribute_name=None, value=None, delete=False): """ @@ -1191,12 +1321,12 @@ class TypedObject(SharedMemoryModel): db = property(__db_get, __db_set, __db_del) # - # NON-PERSISTENT storage methods + # NON-attr_obj storage methods # def nattr(self, attribute_name=None, value=None, delete=False): """ - This is the equivalence of self.attr but for non-persistent + This is the equivalence of self.attr but for non-attr_obj stores. Will not raise error but return None. """ if attribute_name == None: @@ -1222,7 +1352,7 @@ class TypedObject(SharedMemoryModel): #@property def __ndb_get(self): """ - A non-persistent store (ndb: NonDataBase). Everything stored + A non-attr_obj store (ndb: NonDataBase). Everything stored to this is guaranteed to be cleared when a server is shutdown. Syntax is same as for the _get_db_holder() method and property, e.g. obj.ndb.attr = value etc. @@ -1231,7 +1361,7 @@ class TypedObject(SharedMemoryModel): return self._ndb_holder except AttributeError: class NdbHolder(object): - "Holder for storing non-persistent attributes." + "Holder for storing non-attr_obj attributes." def get_all(self): return [val for val in self.__dict__.keys() if not val.startswith('_')] @@ -1244,7 +1374,7 @@ class TypedObject(SharedMemoryModel): return None def __setattr__(self, key, value): # hook the oob handler here - call_ndb_hooks(self, key, value) + #call_ndb_hooks(self, key, value) _SA(self, key, value) self._ndb_holder = NdbHolder() return self._ndb_holder @@ -1273,11 +1403,6 @@ class TypedObject(SharedMemoryModel): """ return self.locks.check(accessing_obj, access_type=access_type, default=default) - def has_perm(self, accessing_obj, access_type): - "Alias to access" - logger.log_depmsg("has_perm() is deprecated. Use access() instead.") - return self.access(accessing_obj, access_type) - def check_permstring(self, permstring): """ This explicitly checks if we hold particular permission without involving @@ -1309,3 +1434,7 @@ class TypedObject(SharedMemoryModel): as a new Typeclass instance. """ self.__class__.flush_cached_instance(self) + + +# connect to attribute cache signal +m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through) diff --git a/src/typeclasses/typeclass.py b/src/typeclasses/typeclass.py index 13640d1414..8bd1c2854b 100644 --- a/src/typeclasses/typeclass.py +++ b/src/typeclasses/typeclass.py @@ -168,7 +168,7 @@ class TypeClass(object): log_trace("This is probably due to an unsafe reload.") return # ignore delete try: - dbobj.del_attribute_raise(propname) + dbobj.del_attribute(propname, raise_exception=True) except AttributeError: string = "Object: '%s' not found on %s(#%s), nor on its typeclass %s." raise AttributeError(string % (propname, dbobj, diff --git a/src/utils/create.py b/src/utils/create.py index 0eae842304..3772538b08 100644 --- a/src/utils/create.py +++ b/src/utils/create.py @@ -22,7 +22,6 @@ Models covered: Players """ from django.conf import settings -from django.contrib.auth.models import User from django.db import IntegrityError from src.utils.idmapper.models import SharedMemoryModel from src.utils import utils, logger @@ -130,7 +129,7 @@ def create_object(typeclass, key=None, location=None, if locks: new_object.locks.add(locks) if aliases: - new_object.aliases = aliases + new_object.aliases.add(aliases) # perform a move_to in order to display eventual messages. if home: @@ -387,49 +386,32 @@ channel = create_channel # Player creation methods # -def create_player(name, email, password, - user=None, +def create_player(key, email, password, typeclass=None, is_superuser=False, locks=None, permissions=None, - player_dbobj=None, report_to=None): + report_to=None): """ - This creates a new player, handling the creation of the User - object and its associated Player object. + This creates a new player. - If player_dbobj is given, this player object is used instead of - creating a new one. This is called by the admin interface since it - needs to create the player object in order to relate it automatically - to the user. + key - the player's name. This should be unique. + email - email on valid addr@addr.domain form. + password - password in cleartext + is_superuser - wether or not this player is to be a superuser + locks - lockstring + permission - list of permissions + report_to - an object with a msg() method to report errors to. If + not given, errors will be logged. - If create_character is - True, a game player object with the same name as the User/Player will - also be created. Its typeclass and base properties can also be given. - - Returns the new game character, or the Player obj if no - character is created. For more info about the typeclass argument, - see create_objects() above. - - Note: if user is supplied, it will NOT be modified (args name, email, - passw and is_superuser will be ignored). Change those properties - directly on the User instead. - - If no permissions are given (None), the default permission group - as defined in settings.PERMISSION_PLAYER_DEFAULT will be - assigned. If permissions are given, no automatic assignment will - occur. + Will return the Player-typeclass or None/raise Exception if the + Typeclass given failed to load. Concerning is_superuser: - A superuser should have access to everything - in the game and on the server/web interface. The very first user - created in the database is always a superuser (that's using - django's own creation, not this one). Usually only the server admin should need to be superuser, all other access levels can be handled with more fine-grained - permissions or groups. - Since superuser overrules all permissions, we don't - set any in this case. + permissions or groups. A superuser bypasses all lock checking + operations and is thus not suitable for play-testing the game. """ global _PlayerDB, _Player @@ -440,48 +422,28 @@ def create_player(name, email, password, if not email: email = "dummy@dummy.com" - if user: - new_user = user - email = user.email - - if user: - conflict_check = User.objects.filter(username__iexact=user.username) - conflict_check = len(conflict_check) > 1 - else: - conflict_check = User.objects.filter(username__iexact=name) - - if conflict_check: - raise ValueError("A user with this name already exists.") - - if not user: - if is_superuser: - new_user = User.objects.create_superuser(name, email, password) - else: - new_user = User.objects.create_user(name, email, password) + if _PlayerDB.objects.filter(username__iexact=key): + raise ValueError("A Player with this name already exists.") try: + + # create the correct Player object + if is_superuser: + new_db_player = _PlayerDB.objects.create_superuser(key, email, password) + else: + new_db_player = _PlayerDB.objects.create_user(key, email, password) + if not typeclass: typeclass = settings.BASE_PLAYER_TYPECLASS elif isinstance(typeclass, _PlayerDB): - # this is already an objectdb instance, extract its typeclass + # this is an PlayerDB instance, extract its typeclass path typeclass = typeclass.typeclass.path elif isinstance(typeclass, _Player) or utils.inherits_from(typeclass, _Player): - # this is already an object typeclass, extract its path + # this is Player object typeclass, extract its path typeclass = typeclass.path - if player_dbobj: - try: - _GA(player_dbobj, "dbobj") - new_db_player = player_dbobj.dbobj - except AttributeError: - new_db_player = player_dbobj - # use the typeclass from this object - typeclass = new_db_player.typeclass_path - else: - new_user = User.objects.get(username=new_user.username) - new_db_player = _PlayerDB(db_key=name, user=new_user) - new_db_player.save() - # assign the typeclass - typeclass = utils.to_unicode(typeclass) - new_db_player.typeclass_path = typeclass + + # assign the typeclass + typeclass = utils.to_unicode(typeclass) + new_db_player.typeclass_path = typeclass # this will either load the typeclass or the default one new_player = new_db_player.typeclass @@ -500,34 +462,27 @@ def create_player(name, email, password, # call hook method (may override default permissions) new_player.at_player_creation() - print # custom given arguments potentially overrides the hook if permissions: new_player.permissions = permissions elif not new_player.permissions: new_player.permissions = settings.PERMISSION_PLAYER_DEFAULT - if locks: new_player.locks.add(locks) - return new_player + except Exception: - # a failure in creating the character - if not user: - # in there was a failure we clean up everything we can - logger.log_trace() - try: - new_user.delete() - except Exception: - pass - try: - new_player.delete() - except Exception: - pass - try: - del new_player - except Exception: - pass + # a failure in creating the player; we try to clean + # up as much as we can + logger.log_trace() + try: + new_player.delete() + except Exception: + pass + try: + del new_player + except Exception: + pass raise # alias diff --git a/src/utils/dbserialize.py b/src/utils/dbserialize.py index b1d7682bf1..44c1d36a1d 100644 --- a/src/utils/dbserialize.py +++ b/src/utils/dbserialize.py @@ -28,13 +28,10 @@ except ImportError: from django.db import transaction from django.core.exceptions import ObjectDoesNotExist from django.contrib.contenttypes.models import ContentType +from src.server.models import ServerConfig from src.utils.utils import to_str, uses_database from src.utils import logger - - - - __all__ = ("to_pickle", "from_pickle", "do_pickle", "do_unpickle") PICKLE_PROTOCOL = 2 @@ -47,13 +44,21 @@ _FROM_MODEL_MAP = None _TO_MODEL_MAP = None _TO_TYPECLASS = lambda o: hasattr(o, 'typeclass') and o.typeclass or o _IS_PACKED_DBOBJ = lambda o: type(o) == tuple and len(o) == 4 and o[0] == '__packed_dbobj__' -_TO_DATESTRING = lambda o: _GA(o, "db_date_created").strftime("%Y:%m:%d-%H:%M:%S:%f") -if uses_database("mysql"): - from src.server.models import ServerConfig - mysql_version = ServerConfig.objects.get_mysql_db_version() - if mysql_version < '5.6.4': - # mysql <5.6.4 don't support millisecond precision - _TO_DATESTRING = lambda o: _GA(o, "db_date_created").strftime("%Y:%m:%d-%H:%M:%S:000000") +if uses_database("mysql") and ServerConfig.objects.get_mysql_db_version() < '5.6.4': + # mysql <5.6.4 don't support millisecond precision + _DATESTRING = "%Y:%m:%d-%H:%M:%S:000000" +else: + _DATESTRING = "%Y:%m:%d-%H:%M:%S:%f" + +def _TO_DATESTRING(obj): + "this will only be called with valid database objects. Returns datestring on correct form." + try: + return _GA(obj, "db_date_created").strftime(_DATESTRING) + except AttributeError: + # this can happen if object is not yet saved - no datestring is then set + obj.save() + return _GA(obj, "db_date_created").strftime(_DATESTRING) + def _init_globals(): "Lazy importing to avoid circular import issues" diff --git a/src/utils/idmapper/base.py b/src/utils/idmapper/base.py index d56948c57f..ad17defb7c 100755 --- a/src/utils/idmapper/base.py +++ b/src/utils/idmapper/base.py @@ -7,41 +7,40 @@ leave caching unexpectedly (no use if WeakRefs). Also adds cache_size() for monitoring the size of the cache. """ -import os +import os, threading +#from twisted.internet import reactor +#from twisted.internet.threads import blockingCallFromThread +from twisted.internet.reactor import callFromThread +from django.core.exceptions import ObjectDoesNotExist from django.db.models.base import Model, ModelBase -from django.db.models.signals import post_save, pre_delete, \ - post_syncdb +from django.db.models.signals import post_save, pre_delete, post_syncdb +from src.utils.utils import dbref, get_evennia_pids from manager import SharedMemoryManager +_FIELD_CACHE_GET = None +_FIELD_CACHE_SET = None +_GA = object.__getattribute__ +_SA = object.__setattr__ +_DA = object.__delattr__ + + # determine if our current pid is different from the server PID (i.e. # if we are in a subprocess or not) from src import PROC_MODIFIED_OBJS -def _get_pids(): - """ - Get the PID (Process ID) by trying to access - an PID file. - """ - from django.conf import settings - server_pidfile = os.path.join(settings.GAME_DIR, 'server.pid') - portal_pidfile = os.path.join(settings.GAME_DIR, 'portal.pid') - server_pid, portal_pid = None, None - if os.path.exists(server_pidfile): - f = open(server_pidfile, 'r') - server_pid = f.read() - f.close() - if os.path.exists(portal_pidfile): - f = open(portal_pidfile, 'r') - portal_pid = f.read() - f.close() - if server_pid and portal_pid: - return int(server_pid), int(portal_pid) - return None, None -_SELF_PID = os.getpid() -_SERVER_PID = None -_PORTAL_PID = None -_IS_SUBPROCESS = False +# get info about the current process and thread + +_SELF_PID = os.getpid() +_SERVER_PID, _PORTAL_PID = get_evennia_pids() +_IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and not _SELF_PID in (_SERVER_PID, _PORTAL_PID) +_IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread" + +#_SERVER_PID = None +#_PORTAL_PID = None +# #global _SERVER_PID, _PORTAL_PID, _IS_SUBPROCESS, _SELF_PID +# if not _SERVER_PID and not _PORTAL_PID: +# _IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and not _SELF_PID in (_SERVER_PID, _PORTAL_PID) class SharedMemoryModelBase(ModelBase): # CL: upstream had a __new__ method that skipped ModelBase's __new__ if @@ -68,13 +67,81 @@ class SharedMemoryModelBase(ModelBase): if cached_instance is None: cached_instance = new_instance() cls.cache_instance(cached_instance) - return cached_instance + def _prepare(cls): cls.__instance_cache__ = {} #WeakValueDictionary() super(SharedMemoryModelBase, cls)._prepare() + def __init__(cls, *args, **kwargs): + """ + Field shortcut creation: + Takes field names db_* and creates property wrappers named without the db_ prefix. So db_key -> key + This wrapper happens on the class level, so there is no overhead when creating objects. If a class + already has a wrapper of the given name, the automatic creation is skipped. Note: Remember to + document this auto-wrapping in the class header, this could seem very much like magic to the user otherwise. + """ + super(SharedMemoryModelBase, cls).__init__(*args, **kwargs) + def create_wrapper(cls, fieldname, wrappername): + "Helper method to create property wrappers with unique names (must be in separate call)" + def _get(cls, fname): + "Wrapper for getting database field" + value = _GA(cls, fieldname) + if type(value) in (basestring, int, float, bool): + return value + elif hasattr(value, "typeclass"): + return _GA(value, "typeclass") + return value + + def _set(cls, fname, value): + "Wrapper for setting database field" + if hasattr(value, "dbobj"): + value = _GA(value, "dbobj") + elif isinstance(value, basestring) and (value.isdigit() or value.startswith("#")): + # we also allow setting using dbrefs, if so we try to load the matching object. + # (we assume the object is of the same type as the class holding the field, if + # not a custom handler must be used for that field) + dbid = dbref(value, reqhash=False) + if dbid: + try: + value = cls._default_manager.get(id=dbid) + except ObjectDoesNotExist: + # maybe it is just a name + pass + #print "_set wrapper:", fname, value, type(value), cls._get_pk_val(cls._meta) + _SA(cls, fname, value) + # only use explicit update_fields in save if we actually have a + # primary key assigned already (won't be when first creating object) + update_fields = [fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None + _GA(cls, "save")(update_fields=update_fields) + + def _del(cls, fname): + "Wrapper for clearing database field - sets it to None" + _SA(cls, fname, None) + update_fields = [fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None + _GA(cls, "save")(update_fields=update_fields) + + # create class wrappers + fget = lambda cls: _get(cls, fieldname) + fset = lambda cls, val: _set(cls, fieldname, val) + fdel = lambda cls: _del(cls, fieldname) + doc = "Wraps setting, saving and deleting the %s field." % fieldname + type(cls).__setattr__(cls, wrappername, property(fget, fset, fdel, doc)) + + # exclude some models that should not auto-create wrapper fields + if cls.__name__ in ("ServerConfig", "TypeNick"): + return + # dynamically create the wrapper properties for all fields not already handled + for field in cls._meta.fields: + fieldname = field.name + if not fieldname.startswith("db_"): + continue + wrappername = fieldname == "id" and "dbid" or fieldname.replace("db_", "") + if not hasattr(cls, wrappername): + # makes sure not to overload manually created wrappers on the model + #print "wrapping %s -> %s" % (fieldname, wrappername) + create_wrapper(cls, fieldname, wrappername) class SharedMemoryModel(Model): # CL: setting abstract correctly to allow subclasses to inherit the default @@ -116,6 +183,13 @@ class SharedMemoryModel(Model): return result _get_cache_key = classmethod(_get_cache_key) + def _flush_cached_by_key(cls, key): + try: + del cls.__instance_cache__[key] + except KeyError: + pass + _flush_cached_by_key = classmethod(_flush_cached_by_key) + def get_cached_instance(cls, id): """ Method to retrieve a cached instance by pk value. Returns None when not found @@ -138,13 +212,6 @@ class SharedMemoryModel(Model): return cls.__instance_cache__.values() get_all_cached_instances = classmethod(get_all_cached_instances) - def _flush_cached_by_key(cls, key): - try: - del cls.__instance_cache__[key] - except KeyError: - pass - _flush_cached_by_key = classmethod(_flush_cached_by_key) - def flush_cached_instance(cls, instance): """ Method to flush an instance from the cache. The instance will always be flushed from the cache, @@ -158,15 +225,22 @@ class SharedMemoryModel(Model): flush_instance_cache = classmethod(flush_instance_cache) def save(cls, *args, **kwargs): - "overload spot for saving" - global _SERVER_PID, _PORTAL_PID, _IS_SUBPROCESS, _SELF_PID - if not _SERVER_PID and not _PORTAL_PID: - _SERVER_PID, _PORTAL_PID = _get_pids() - _IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and (_SERVER_PID != _SELF_PID) and (_PORTAL_PID != _SELF_PID) + "save method tracking process/thread issues" + if _IS_SUBPROCESS: - #print "storing in PROC_MODIFIED_OBJS:", cls.db_key, cls.id + # we keep a store of objects modified in subprocesses so + # we know to update their caches in the central process PROC_MODIFIED_OBJS.append(cls) - super(SharedMemoryModel, cls).save(*args, **kwargs) + + if _IS_MAIN_THREAD: + # in main thread - normal operation + super(SharedMemoryModel, cls).save(*args, **kwargs) + else: + # in another thread; make sure to save in reactor thread + def _save_callback(cls, *args, **kwargs): + super(SharedMemoryModel, cls).save(*args, **kwargs) + #blockingCallFromThread(reactor, _save_callback, cls, *args, **kwargs) + callFromThread(_save_callback, cls, *args, **kwargs) # Use a signal so we make sure to catch cascades. def flush_cache(**kwargs): diff --git a/src/utils/picklefield.py b/src/utils/picklefield.py index bcb513c819..dc33464ee3 100644 --- a/src/utils/picklefield.py +++ b/src/utils/picklefield.py @@ -217,14 +217,8 @@ class PickledObjectField(_get_subfield_superclass()): raise TypeError('Lookup type %s is not supported.' % lookup_type) # The Field model already calls get_db_prep_value before doing the # actual lookup, so all we need to do is limit the lookup types. - try: - return super(PickledObjectField, self).get_db_prep_lookup( - lookup_type, value, connection=connection, prepared=prepared) - except TypeError: - # Try not to break on older versions of Django, where the - # `connection` and `prepared` parameters are not available. - return super(PickledObjectField, self).get_db_prep_lookup( - lookup_type, value) + return super(PickledObjectField, self).get_db_prep_lookup( + lookup_type, value, connection=connection, prepared=prepared) # South support; see http://south.aeracode.org/docs/tutorial/part4.html#simple-inheritance diff --git a/src/utils/search.py b/src/utils/search.py index a7abbc2354..032c6241d1 100644 --- a/src/utils/search.py +++ b/src/utils/search.py @@ -16,11 +16,11 @@ the database model and call its 'objects' property. Also remember that all commands in this file return lists (also if there is only one match) unless noted otherwise. -Example: To reach the search method 'get_object_with_user' +Example: To reach the search method 'get_object_with_player' in src/objects/managers.py: > from src.objects.models import ObjectDB -> match = Object.objects.get_object_with_user(...) +> match = Object.objects.get_object_with_player(...) """ diff --git a/src/utils/utils.py b/src/utils/utils.py index a10d1b473a..c072c36002 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -287,22 +287,20 @@ def pypath_to_realpath(python_path, file_ending='.py'): def dbref(dbref, reqhash=True): """ - Converts/checks if input is a valid dbref Valid forms of dbref - (database reference number) are either a string '#N' or - an integer N. Output is the integer part. + Converts/checks if input is a valid dbref. + If reqhash is set, only input strings on the form '#N', where N is an integer + is accepted. Otherwise strings '#N', 'N' and integers N are all accepted. + Output is the integer part. """ - if reqhash and not (isinstance(dbref, basestring) and dbref.startswith("#")): - return None - if isinstance(dbref, basestring): + if reqhash: + return (int(dbref.lstrip('#')) if (isinstance(dbref, basestring) and + dbref.startswith("#") and + dbref.lstrip('#').isdigit()) + else None) + elif isinstance(dbref, basestring): dbref = dbref.lstrip('#') - try: - dbref = int(dbref) - if dbref < 1: - return None - except Exception: - return None - return dbref - return None + return int(dbref) if dbref.isdigit() else None + return dbref if isinstance(dbref, int) else None def to_unicode(obj, encoding='utf-8', force_string=False): """ @@ -467,9 +465,9 @@ def delay(delay=2, retval=None, callback=None): """ Delay the return of a value. Inputs: - to_return (any) - this will be returned by this function after a delay delay (int) - the delay in seconds - callback (func(r)) - if given, this will be called with the to_return after delay seconds + retval (any) - this will be returned by this function after a delay + callback (func(retval)) - if given, this will be called with retval after delay seconds Returns: deferred that will fire with to_return after delay seconds """ @@ -901,3 +899,28 @@ def format_table(table, extra_space=1): for icol, col in enumerate(table)]) return ftable +def get_evennia_pids(): + """ + Get the currently valids PIDs (Process IDs) of the Portal and Server + by trying to access an PID file. This can be used to determine if we + are in a subprocess by something like + + self_pid = os.getpid() + server_pid, portal_pid = get_evennia_pids() + is_subprocess = self_pid not in (server_pid, portal_pid) + + """ + server_pidfile = os.path.join(settings.GAME_DIR, 'server.pid') + portal_pidfile = os.path.join(settings.GAME_DIR, 'portal.pid') + server_pid, portal_pid = None, None + if os.path.exists(server_pidfile): + f = open(server_pidfile, 'r') + server_pid = f.read() + f.close() + if os.path.exists(portal_pidfile): + f = open(portal_pidfile, 'r') + portal_pid = f.read() + f.close() + if server_pid and portal_pid: + return int(server_pid), int(portal_pid) + return None, None diff --git a/src/web/backends.py b/src/web/backends.py index 21c5f9a100..6365d9e904 100644 --- a/src/web/backends.py +++ b/src/web/backends.py @@ -1,5 +1,5 @@ from django.contrib.auth.backends import ModelBackend -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model class CaseInsensitiveModelBackend(ModelBackend): """ @@ -7,6 +7,7 @@ class CaseInsensitiveModelBackend(ModelBackend): generally expected. This backend supports case insensitive username authentication. """ def authenticate(self, username=None, password=None): + User = get_user_model() try: user = User.objects.get(username__iexact=username) if user.check_password(password): diff --git a/src/web/news/models.py b/src/web/news/models.py index 02819644f6..d89d3362df 100755 --- a/src/web/news/models.py +++ b/src/web/news/models.py @@ -1,11 +1,13 @@ # # This module implements a simple news entry system -# for the evennia website. One needs to use the -# admin interface to add/edit/delete entries. +# for the evennia website. One needs to use the +# admin interface to add/edit/delete entries. # from django.db import models -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model + +User = get_user_model() class NewsTopic(models.Model): """ @@ -13,8 +15,8 @@ class NewsTopic(models.Model): """ name = models.CharField(max_length=75, unique=True) description = models.TextField(blank=True) - icon = models.ImageField(upload_to='newstopic_icons', - default='newstopic_icons/default.png', + icon = models.ImageField(upload_to='newstopic_icons', + default='newstopic_icons/default.png', blank=True, help_text="Image for the news topic.") def __str__(self): @@ -35,7 +37,7 @@ class NewsEntry(models.Model): body = models.TextField() topic = models.ForeignKey(NewsTopic, related_name='newstopic') date_posted = models.DateTimeField(auto_now_add=True) - + def __str__(self): return self.title diff --git a/src/web/news/urls.py b/src/web/news/urls.py index 10c891d42c..09c4a3b6fe 100755 --- a/src/web/news/urls.py +++ b/src/web/news/urls.py @@ -1,9 +1,9 @@ """ -This structures the url tree for the news application. +This structures the url tree for the news application. It is imported from the root handler, game.web.urls.py. """ -from django.conf.urls.defaults import * +from django.conf.urls import * urlpatterns = patterns('src.web.news.views', (r'^show/(?P\d+)/$', 'show_news'), diff --git a/src/web/templates/prosimii/index.html b/src/web/templates/prosimii/index.html index c4b9d377bc..ff98d70eb0 100644 --- a/src/web/templates/prosimii/index.html +++ b/src/web/templates/prosimii/index.html @@ -58,7 +58,7 @@

Recently Connected

    {% for player in players_connected_recent %} -
  • {{player.user.username}} -- {{player.user.last_login|timesince}} ago
  • +
  • {{player.username}} -- {{player.last_login|timesince}} ago
  • {% endfor %}

diff --git a/src/web/templates/prosimii/registration/login.html b/src/web/templates/prosimii/registration/login.html index 94e312e1cd..4497a9aaa8 100644 --- a/src/web/templates/prosimii/registration/login.html +++ b/src/web/templates/prosimii/registration/login.html @@ -13,7 +13,8 @@ Login

Your username and password didn't match. Please try again.

{% endif %} -
+ + {% csrf_token %} diff --git a/src/web/urls.py b/src/web/urls.py index bbe83633d6..5ca3bf8a41 100755 --- a/src/web/urls.py +++ b/src/web/urls.py @@ -6,7 +6,7 @@ # http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3 # -from django.conf.urls.defaults import * +from django.conf.urls import * from django.conf import settings from django.contrib import admin from django.views.generic import RedirectView @@ -17,12 +17,12 @@ from django.db.models.loading import cache as model_cache if not model_cache.loaded: model_cache.get_models() -# loop over all settings.INSTALLED_APPS and execute code in +# loop over all settings.INSTALLED_APPS and execute code in # files named admin.py in each such app (this will add those # models to the admin site) admin.autodiscover() -# Setup the root url tree from / +# Setup the root url tree from / urlpatterns = patterns('', # User Authentication @@ -36,11 +36,11 @@ urlpatterns = patterns('', # Page place-holder for things that aren't implemented yet. url(r'^tbi/', 'src.web.website.views.to_be_implemented'), - + # Admin interface url(r'^admin/doc/', include('django.contrib.admindocs.urls')), url(r'^admin/', include(admin.site.urls)), - + # favicon url(r'^favicon\.ico$', RedirectView.as_view(url='/media/images/favicon.ico')), diff --git a/src/web/webclient/urls.py b/src/web/webclient/urls.py index 93702a0673..03f2595d2e 100644 --- a/src/web/webclient/urls.py +++ b/src/web/webclient/urls.py @@ -1,6 +1,6 @@ """ -This structures the (simple) structure of the -webpage 'application'. +This structures the (simple) structure of the +webpage 'application'. """ from django.conf.urls import * diff --git a/src/web/webclient/views.py b/src/web/webclient/views.py index e9ac9910a3..3d097b6935 100644 --- a/src/web/webclient/views.py +++ b/src/web/webclient/views.py @@ -1,19 +1,25 @@ """ -This contains a simple view for rendering the webclient +This contains a simple view for rendering the webclient page and serve it eventual static content. """ -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response, redirect from django.template import RequestContext from django.conf import settings from src.server.sessionhandler import SESSIONS def webclient(request): """ - Webclient page template loading. - """ + Webclient page template loading. + """ + + # analyze request to find which port we are on + if int(request.META["SERVER_PORT"]) == 8000: + # we relay webclient to the portal port + print "Called from port 8000!" + #return redirect("http://localhost:8001/webclient/", permanent=True) # as an example we send the number of connected players to the template pagevars = {'num_players_connected': SESSIONS.player_count()} diff --git a/src/web/website/urls.py b/src/web/website/urls.py index b12603afe1..8bb4bd811e 100644 --- a/src/web/website/urls.py +++ b/src/web/website/urls.py @@ -1,9 +1,9 @@ """ -This structures the (simple) structure of the -webpage 'application'. +This structures the (simple) structure of the +webpage 'application'. """ -from django.conf.urls.defaults import * +from django.conf.urls import * urlpatterns = patterns('src.web.website.views', (r'^$', 'page_index'),