diff --git a/src/comms/comms.py b/src/comms/comms.py index 8bfdb35dc1..8ed3e945ef 100644 --- a/src/comms/comms.py +++ b/src/comms/comms.py @@ -5,6 +5,7 @@ See objects.objects for more information on Typeclassing. """ from src.typeclasses.models import TypeclassBase from src.comms.models import Msg, TempMsg, ChannelDB +from src.comms.managers import ChannelManager from src.utils import logger from src.utils.utils import make_iter @@ -15,6 +16,7 @@ class Channel(ChannelDB): types of communication channels. """ __metaclass__ = TypeclassBase + objects = ChannelManager() # helper methods, for easy overloading diff --git a/src/comms/managers.py b/src/comms/managers.py index b2cbce4e5d..1823a42794 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -4,7 +4,8 @@ These managers handles the from django.db import models from django.db.models import Q -from src.typeclasses.managers import TypedObjectManager, returns_typeclass_list, returns_typeclass +from src.typeclasses.managers import (TypedObjectManager, TypeclassManager, + returns_typeclass_list, returns_typeclass) _GA = object.__getattribute__ _PlayerDB = None @@ -251,7 +252,7 @@ class MsgManager(models.Manager): # Channel manager # -class ChannelManager(TypedObjectManager): +class ChannelDBManager(TypedObjectManager): """ This ChannelManager implements methods for searching and manipulating Channels directly from the database. @@ -373,6 +374,9 @@ class ChannelManager(TypedObjectManager): for a in channel.aliases.all()]] return channels +class ChannelManager(ChannelDBManager, TypeclassManager): + pass + # # PlayerChannelConnection manager diff --git a/src/comms/models.py b/src/comms/models.py index a56c665ad5..6b12da2c3c 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -22,7 +22,7 @@ be able to delete connections on the fly). from datetime import datetime from django.conf import settings from django.db import models -from src.typeclasses.models import TypedObject, TagHandler, AttributeHandler, AliasHandler +from src.typeclasses.models import TypedObject from src.utils.idmapper.models import SharedMemoryModel from src.comms import managers from src.comms.managers import identify_object @@ -356,7 +356,7 @@ class ChannelDB(TypedObject): related_name="subscription_set", null=True, verbose_name='subscriptions', db_index=True) # Database manager - objects = managers.ChannelManager() + objects = managers.ChannelDBManager() _typeclass_paths = settings.CHANNEL_TYPECLASS_PATHS _default_typeclass_path = settings.BASE_CHANNEL_TYPECLASS or "src.comms.comms.Channel" diff --git a/src/objects/__init__.py b/src/objects/__init__.py index 4931eaa394..2cdc469ceb 100644 --- a/src/objects/__init__.py +++ b/src/objects/__init__.py @@ -6,7 +6,7 @@ Also, the initiated object manager is available as src.objects.manager. """ -from src.objects.objects import * +#from src.objects.objects import * from src.objects.models import ObjectDB manager = ObjectDB.objects diff --git a/src/objects/manager.py b/src/objects/manager.py index ac5c80d621..2be80ac064 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -5,7 +5,7 @@ from itertools import chain from django.db.models import Q from django.conf import settings from django.db.models.fields import exceptions -from src.typeclasses.managers import TypedObjectManager +from src.typeclasses.managers import TypedObjectManager, TypeclassManager from src.typeclasses.managers import returns_typeclass, returns_typeclass_list from src.utils import utils from src.utils.utils import to_unicode, is_iter, make_iter, string_partial_matching @@ -22,7 +22,7 @@ _ATTR = None _AT_MULTIMATCH_INPUT = utils.variable_from_module(*settings.SEARCH_AT_MULTIMATCH_INPUT.rsplit('.', 1)) -class ObjectManager(TypedObjectManager): +class ObjectDBManager(TypedObjectManager): """ This ObjectManager implementes methods for searching and manipulating Objects directly from the database. @@ -413,3 +413,6 @@ class ObjectManager(TypedObjectManager): """ self.filter(db_sessid__isnull=False).update(db_sessid=None) + +class ObjectManager(ObjectDBManager, TypeclassManager): + pass diff --git a/src/objects/models.py b/src/objects/models.py index e53354f506..5a2b6ceeb7 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -20,7 +20,7 @@ from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from src.typeclasses.models import TypedObject, NickHandler -from src.objects.manager import ObjectManager +from src.objects.manager import ObjectDBManager from src.players.models import PlayerDB from src.commands.cmdsethandler import CmdSetHandler from src.commands import cmdhandler @@ -171,7 +171,7 @@ class ObjectDB(TypedObject): help_text="optional python path to a cmdset class.") # Database manager - objects = ObjectManager() + objects = ObjectDBManager() # caches for quick lookups of typeclass loading. _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS diff --git a/src/objects/objects.py b/src/objects/objects.py index cb43ee9609..a90c25b923 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -17,6 +17,7 @@ they control by simply linking to a new object's user property. from django.conf import settings from src.typeclasses.models import TypeclassBase +from src.objects.manager import ObjectTypeclassManager from src.objects.models import ObjectDB from src.commands import cmdset, command from src.utils.logger import log_depmsg @@ -39,6 +40,7 @@ class Object(ObjectDB): """ __metaclass__ = TypeclassBase + objects = ObjectTypeclassManager() # __init__ is only defined here in order to present docstring to API. def __init__(self, *args, **kwargs): diff --git a/src/players/__init__.py b/src/players/__init__.py index b49e80468c..a448c50b40 100644 --- a/src/players/__init__.py +++ b/src/players/__init__.py @@ -7,7 +7,7 @@ Also, the initiated object manager is available as src.players.manager. """ -from src.players.player import * +#from src.players.player import * from src.players.models import PlayerDB manager = PlayerDB.objects diff --git a/src/players/manager.py b/src/players/manager.py index d7526c2943..67c72bd147 100644 --- a/src/players/manager.py +++ b/src/players/manager.py @@ -5,7 +5,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 src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager +from src.typeclasses.managers import (returns_typeclass_list, returns_typeclass, + TypedObjectManager, TypeclassManager) #from src.utils import logger __all__ = ("PlayerManager",) @@ -14,7 +15,7 @@ __all__ = ("PlayerManager",) # Player Manager # -class PlayerManager(TypedObjectManager, UserManager): +class PlayerDBManager(TypedObjectManager, UserManager): """ This PlayerManager implements methods for searching and manipulating Players directly from the database. @@ -149,3 +150,6 @@ class PlayerManager(TypedObjectManager, UserManager): if old_character and delete_old_character: old_character.delete() return True + +class PlayerManager(PlayerDBManager, TypeclassManager): + pass diff --git a/src/players/models.py b/src/players/models.py index 86d63831c5..90bef3c7a6 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -21,7 +21,7 @@ from django.db import models from django.contrib.auth.models import AbstractUser from django.utils.encoding import smart_str -from src.players import manager +from src.players.manager import PlayerDBManager from src.scripts.models import ScriptDB from src.typeclasses.models import (TypedObject, NickHandler) from src.scripts.scripthandler import ScriptHandler @@ -100,7 +100,7 @@ class PlayerDB(TypedObject, AbstractUser): db_is_bot = models.BooleanField(default=False, verbose_name="is_bot", help_text="Used to identify irc/imc2/rss bots") # Database manager - objects = manager.PlayerManager() + objects = PlayerDBManager() # caches for quick lookups _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS diff --git a/src/players/player.py b/src/players/player.py index 039b5dfba1..653c725c1e 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -14,6 +14,7 @@ instead for most things). import datetime from django.conf import settings from src.typeclasses.models import TypeclassBase +from src.players.manager import PlayerManager from src.players.models import PlayerDB from src.comms.models import ChannelDB from src.utils import logger @@ -28,6 +29,7 @@ class Player(PlayerDB): Base typeclass for all Players. """ __metaclass__ = TypeclassBase + objects = PlayerManager() def __init__(self, *args, **kwargs): """ diff --git a/src/scripts/manager.py b/src/scripts/manager.py index 1dc4b5f638..6c82077d4d 100644 --- a/src/scripts/manager.py +++ b/src/scripts/manager.py @@ -3,7 +3,7 @@ The custom manager for Scripts. """ from django.db.models import Q -from src.typeclasses.managers import TypedObjectManager +from src.typeclasses.managers import TypedObjectManager, TypeclassManager from src.typeclasses.managers import returns_typeclass_list from src.utils.utils import make_iter __all__ = ("ScriptManager",) @@ -12,7 +12,7 @@ _GA = object.__getattribute__ VALIDATE_ITERATION = 0 -class ScriptManager(TypedObjectManager): +class ScriptDBManager(TypedObjectManager): """ This Scriptmanager implements methods for searching and manipulating Scripts directly from the database. @@ -230,3 +230,6 @@ class ScriptManager(TypedObjectManager): new_script = create.create_script(typeclass, key=new_key, obj=new_obj, locks=new_locks, autostart=True) return new_script + +class ScriptManager(ScriptDBManager, TypeclassManager): + pass diff --git a/src/scripts/models.py b/src/scripts/models.py index 45347cff9a..c1717fc0b9 100644 --- a/src/scripts/models.py +++ b/src/scripts/models.py @@ -28,7 +28,7 @@ from django.conf import settings from django.db import models from django.core.exceptions import ObjectDoesNotExist from src.typeclasses.models import TypedObject -from src.scripts.manager import ScriptManager +from src.scripts.manager import ScriptDBManager from src.utils.utils import dbref, to_str __all__ = ("ScriptDB",) @@ -98,7 +98,7 @@ class ScriptDB(TypedObject): db_is_active = models.BooleanField('script active', default=False) # Database manager - objects = ScriptManager() + objects = ScriptDBManager() # caches for quick lookups _typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS diff --git a/src/scripts/scripts.py b/src/scripts/scripts.py index 4aa289481e..ec14aba91b 100644 --- a/src/scripts/scripts.py +++ b/src/scripts/scripts.py @@ -11,6 +11,7 @@ from django.conf import settings from src.typeclasses.models import TypeclassBase from django.utils.translation import ugettext as _ from src.scripts.models import ScriptDB +from src.scripts.manager import ScriptManager from src.comms import channelhandler from src.utils import logger @@ -114,6 +115,7 @@ class ScriptBase(ScriptDB): from the class 'Script' instead. """ __metaclass__ = TypeclassBase + objects = ScriptManager() def __eq__(self, other): """ diff --git a/src/typeclasses/managers.py b/src/typeclasses/managers.py index 1e389e39b2..42d6f3d26a 100644 --- a/src/typeclasses/managers.py +++ b/src/typeclasses/managers.py @@ -46,67 +46,6 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): # common methods for all typed managers. These are used # in other methods. Returns querysets. - def get(self, **kwargs): - """ - Overload the standard get. This will limit itself to only - return the current typeclass. - """ - kwargs.update({"db_typeclass_path":self.model.path}) - return super(TypedObjectManager, self).get(**kwargs) - - def filter(self, **kwargs): - """ - Overload of the standard filter function. This filter will - limit itself to only the current typeclass. - """ - kwargs.update({"db_typeclass_path":self.model.path}) - return super(TypedObjectManager, self).filter(**kwargs) - - def all(self, **kwargs): - """ - Overload method to return all matches, filtering for typeclass - """ - return super(TypedObjectManager, self).all(**kwargs).filter(db_typeclass_path=self.model.path) - - def _get_subclasses(self, cls): - """ - Recursively get all subclasses to a class - """ - all_subclasses = cls.__subclasses__() - for subclass in all_subclasses: - all_subclasses.extend(self._get_subclasses(subclass)) - return all_subclasses - - def get_family(self, **kwargs): - """ - Variation of get that not only returns the current - typeclass but also all subclasses of that typeclass. - """ - paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) - for cls in self._get_subclasses(self.model)] - kwargs.update({"db_typeclass_path__in":paths}) - return super(TypedObjectManager, self).get(**kwargs) - - def filter_family(self, **kwargs): - """ - Variation of filter that allows results both from typeclass - and from subclasses of typeclass - """ - # query, including all subclasses - paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) - for cls in self._get_subclasses(self.model)] - kwargs.update({"db_typeclass_path__in":paths}) - return super(TypedObjectManager, self).filter(**kwargs) - - def all_family(self, **kwargs): - """ - Return all matches, allowing matches from all subclasses of - the typeclass. - """ - paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) - for cls in self._get_subclasses(self.model)] - return super(TypedObjectManager, self).all(**kwargs).filter(db_typeclass_path__in=paths) - # Attribute manager methods def get_attribute(self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None): @@ -337,3 +276,68 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): query = query | Q(db_typeclass_path__exact=parent.path) # actually query the database return self.filter(query) + + +class TypeclassManager(TypedObjectManager): + def get(self, **kwargs): + """ + Overload the standard get. This will limit itself to only + return the current typeclass. + """ + kwargs.update({"db_typeclass_path":self.model.path}) + return super(TypedObjectManager, self).get(**kwargs) + + def filter(self, **kwargs): + """ + Overload of the standard filter function. This filter will + limit itself to only the current typeclass. + """ + kwargs.update({"db_typeclass_path":self.model.path}) + return super(TypedObjectManager, self).filter(**kwargs) + + def all(self, **kwargs): + """ + Overload method to return all matches, filtering for typeclass + """ + return super(TypedObjectManager, self).all(**kwargs).filter(db_typeclass_path=self.model.path) + + def _get_subclasses(self, cls): + """ + Recursively get all subclasses to a class + """ + all_subclasses = cls.__subclasses__() + for subclass in all_subclasses: + all_subclasses.extend(self._get_subclasses(subclass)) + return all_subclasses + + def get_family(self, **kwargs): + """ + Variation of get that not only returns the current + typeclass but also all subclasses of that typeclass. + """ + paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) + for cls in self._get_subclasses(self.model)] + kwargs.update({"db_typeclass_path__in":paths}) + return super(TypedObjectManager, self).get(**kwargs) + + def filter_family(self, **kwargs): + """ + Variation of filter that allows results both from typeclass + and from subclasses of typeclass + """ + # query, including all subclasses + paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) + for cls in self._get_subclasses(self.model)] + kwargs.update({"db_typeclass_path__in":paths}) + return super(TypedObjectManager, self).filter(**kwargs) + + def all_family(self, **kwargs): + """ + Return all matches, allowing matches from all subclasses of + the typeclass. + """ + paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__) + for cls in self._get_subclasses(self.model)] + return super(TypedObjectManager, self).all(**kwargs).filter(db_typeclass_path__in=paths) + +