Run migrations! Made Channel model also accept ObjectDB subscriptions.
This commit is contained in:
parent
d63db77eb4
commit
94778f1c44
4 changed files with 193 additions and 27 deletions
|
|
@ -58,44 +58,78 @@ class DefaultChannel(ChannelDB):
|
||||||
|
|
||||||
# helper methods, for easy overloading
|
# helper methods, for easy overloading
|
||||||
|
|
||||||
def has_connection(self, player):
|
def has_connection(self, subscriber):
|
||||||
"""
|
"""
|
||||||
Checks so this player is actually listening
|
Checks so this player is actually listening
|
||||||
to this channel.
|
to this channel.
|
||||||
"""
|
|
||||||
if hasattr(player, "player"):
|
|
||||||
player = player.player
|
|
||||||
return player in self.db_subscriptions.all()
|
|
||||||
|
|
||||||
def connect(self, player):
|
Args:
|
||||||
"Connect the user to this channel. This checks access."
|
subscriber (Player or Object): Entity to check.
|
||||||
if hasattr(player, "player"):
|
|
||||||
player = player.player
|
Returns:
|
||||||
|
has_sub (bool): Whether the subscriber is subscribing to
|
||||||
|
this channel or not.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This will first try Player subscribers and only try Object
|
||||||
|
if the Player fails.
|
||||||
|
|
||||||
|
"""
|
||||||
|
has_sub = self.subscriptions.has(subscriber)
|
||||||
|
if not has_sub and hasattr(subscriber, "player"):
|
||||||
|
# it's common to send an Object when we
|
||||||
|
# by default only allow Players to subscribe.
|
||||||
|
has_sub = self.subscriptions.has(subscriber.player)
|
||||||
|
return has_sub
|
||||||
|
|
||||||
|
|
||||||
|
def connect(self, subscriber):
|
||||||
|
"""
|
||||||
|
Connect the user to this channel. This checks access.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
subscriber (Player or Object): the entity to subscribe
|
||||||
|
to this channel.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
success (bool): Whether or not the addition was
|
||||||
|
successful.
|
||||||
|
|
||||||
|
"""
|
||||||
# check access
|
# check access
|
||||||
if not self.access(player, 'listen'):
|
if not self.access(subscriber, 'listen'):
|
||||||
return False
|
return False
|
||||||
# pre-join hook
|
# pre-join hook
|
||||||
connect = self.pre_join_channel(player)
|
connect = self.pre_join_channel(subscriber)
|
||||||
if not connect:
|
if not connect:
|
||||||
return False
|
return False
|
||||||
# subscribe
|
# subscribe
|
||||||
self.db_subscriptions.add(player)
|
self.subscriptions.add(subscriber)
|
||||||
# post-join hook
|
# post-join hook
|
||||||
self.post_join_channel(player)
|
self.post_join_channel(subscriber)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def disconnect(self, player):
|
def disconnect(self, subscriber):
|
||||||
"Disconnect user from this channel."
|
"""
|
||||||
if hasattr(player, "player"):
|
Disconnect entity from this channel.
|
||||||
player = player.player
|
|
||||||
|
Args:
|
||||||
|
subscriber (Player of Object): the
|
||||||
|
entity to disconnect.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
success (bool): Whether or not the removal was
|
||||||
|
successful.
|
||||||
|
|
||||||
|
"""
|
||||||
# pre-disconnect hook
|
# pre-disconnect hook
|
||||||
disconnect = self.pre_leave_channel(player)
|
disconnect = self.pre_leave_channel(subscriber)
|
||||||
if not disconnect:
|
if not disconnect:
|
||||||
return False
|
return False
|
||||||
# disconnect
|
# disconnect
|
||||||
self.db_subscriptions.remove(player)
|
self.subscriptions.remove(subscriber)
|
||||||
# post-disconnect hook
|
# post-disconnect hook
|
||||||
self.post_leave_channel(player)
|
self.post_leave_channel(subscriber)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def access(self, accessing_obj, access_type='listen', default=False):
|
def access(self, accessing_obj, access_type='listen', default=False):
|
||||||
|
|
@ -133,17 +167,17 @@ class DefaultChannel(ChannelDB):
|
||||||
|
|
||||||
def distribute_message(self, msg, online=False):
|
def distribute_message(self, msg, online=False):
|
||||||
"""
|
"""
|
||||||
Method for grabbing all listeners that a message should be sent to on
|
Method for grabbing all listeners that a message should be
|
||||||
this channel, and sending them a message.
|
sent to on this channel, and sending them a message.
|
||||||
"""
|
"""
|
||||||
# get all players connected to this channel and send to them
|
# get all players connected to this channel and send to them
|
||||||
for player in self.db_subscriptions.all():
|
for entity in self.subscriptions.all():
|
||||||
try:
|
try:
|
||||||
# note our addition of the from_channel keyword here. This could be checked
|
# note our addition of the from_channel keyword here. This could be checked
|
||||||
# by a custom player.msg() to treat channel-receives differently.
|
# by a custom player.msg() to treat channel-receives differently.
|
||||||
player.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
entity.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
||||||
except AttributeError, e:
|
except AttributeError, e:
|
||||||
logger.log_trace("%s\nCannot send msg to player '%s'." % (e, player))
|
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
||||||
|
|
||||||
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
||||||
persistent=False, online=False, emit=False, external=False):
|
persistent=False, online=False, emit=False, external=False):
|
||||||
|
|
|
||||||
|
|
@ -283,11 +283,16 @@ class ChannelDBManager(TypedObjectManager):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_subscriptions(self, player):
|
def get_subscriptions(self, entity):
|
||||||
"""
|
"""
|
||||||
Return all channels a given player is subscribed to
|
Return all channels a given player is subscribed to
|
||||||
"""
|
"""
|
||||||
return player.subscription_set.all()
|
clsname = entity.__dbclass__.__name__
|
||||||
|
if clsname == "PlayerDB":
|
||||||
|
return entity.subscription_set.all()
|
||||||
|
if clsname == "ObjectDB":
|
||||||
|
return entity.object_subscription_set.all()
|
||||||
|
return []
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def channel_search(self, ostring, exact=True):
|
def channel_search(self, ostring, exact=True):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('objects', '0004_auto_20150118_1622'),
|
||||||
|
('comms', '0005_auto_20150223_1517'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='channeldb',
|
||||||
|
name='db_object_subscriptions',
|
||||||
|
field=models.ManyToManyField(related_name='object_subscription_set', null=True, verbose_name=b'subscriptions', to='objects.ObjectDB', db_index=True),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -349,6 +349,105 @@ class TempMsg(object):
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
||||||
|
class SubscriptionHandler(object):
|
||||||
|
"""
|
||||||
|
This handler manages subscriptions to the
|
||||||
|
channel and hides away which type of entity is
|
||||||
|
subscribing (Player or Object)
|
||||||
|
"""
|
||||||
|
def __init__(self, obj):
|
||||||
|
"""
|
||||||
|
Initialize the handler
|
||||||
|
|
||||||
|
Attr:
|
||||||
|
obj (ChannelDB): The channel the handler sits on.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.obj = obj
|
||||||
|
|
||||||
|
def has(self, entity):
|
||||||
|
"""
|
||||||
|
Check if the given entity subscribe to this channel
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity (str, Player or Object): The entity to return. If
|
||||||
|
a string, it assumed to be the key or the #dbref
|
||||||
|
of the entity.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
subscriber (Player, Object or None): The given
|
||||||
|
subscriber.
|
||||||
|
|
||||||
|
"""
|
||||||
|
clsname = entity.__dbclass__.__name__
|
||||||
|
if clsname == "PlayerDB":
|
||||||
|
return entity in self.obj.db_subscriptions.all()
|
||||||
|
elif clsname == "ObjectDB":
|
||||||
|
return entity in self.obj.db_object_subscriptions.all()
|
||||||
|
|
||||||
|
|
||||||
|
def add(self, entity):
|
||||||
|
"""
|
||||||
|
Subscribe an entity to this channel.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity (Player, Object or list): The entity or
|
||||||
|
list of entities to subscribe to this channel.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
No access-checking is done here, this must have
|
||||||
|
been done before calling this method. Also
|
||||||
|
no hooks will be called.
|
||||||
|
|
||||||
|
"""
|
||||||
|
for subscriber in make_iter(entity):
|
||||||
|
if subscriber:
|
||||||
|
clsname = subscriber.__dbclass__.__name__
|
||||||
|
# chooses the right type
|
||||||
|
if clsname == "ObjectDB":
|
||||||
|
self.obj.db_object_subscriptions.add(subscriber)
|
||||||
|
elif clsname == "PlayerDB":
|
||||||
|
self.obj.db_subscriptions.add(subscriber)
|
||||||
|
|
||||||
|
def remove(self, entity):
|
||||||
|
"""
|
||||||
|
Remove a subecriber from the channel.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity (Player, Object or list): The entity or
|
||||||
|
entities to un-subscribe from the channel.
|
||||||
|
|
||||||
|
"""
|
||||||
|
for subscriber in make_iter(entity):
|
||||||
|
if subscriber:
|
||||||
|
clsname = subscriber.__dbclass__.__name__
|
||||||
|
# chooses the right type
|
||||||
|
if clsname == "PlayerDB":
|
||||||
|
self.obj.db_subscriptions.remove(entity)
|
||||||
|
elif clsname == "ObjectDB":
|
||||||
|
self.obj.db_object_subscriptions.remove(entity)
|
||||||
|
|
||||||
|
def all(self):
|
||||||
|
"""
|
||||||
|
Get all subscriptions to this channel.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
subscribers (list): The subscribers. This
|
||||||
|
may be a mix of Players and Objects!
|
||||||
|
|
||||||
|
"""
|
||||||
|
return list(self.obj.db_subscriptions.all()) + \
|
||||||
|
list(self.obj.db_object_subscriptions.all())
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
"""
|
||||||
|
Remove all subscribers from channel.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.obj.db_subscriptions.clear()
|
||||||
|
self.obj.db_object_subscriptions.clear()
|
||||||
|
|
||||||
|
|
||||||
class ChannelDB(TypedObject):
|
class ChannelDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
This is the basis of a comm channel, only implementing
|
This is the basis of a comm channel, only implementing
|
||||||
|
|
@ -364,6 +463,9 @@ class ChannelDB(TypedObject):
|
||||||
db_subscriptions = models.ManyToManyField("players.PlayerDB",
|
db_subscriptions = models.ManyToManyField("players.PlayerDB",
|
||||||
related_name="subscription_set", null=True, verbose_name='subscriptions', db_index=True)
|
related_name="subscription_set", null=True, verbose_name='subscriptions', db_index=True)
|
||||||
|
|
||||||
|
db_object_subscriptions = models.ManyToManyField("objects.ObjectDB",
|
||||||
|
related_name="object_subscription_set", null=True, verbose_name='subscriptions', db_index=True)
|
||||||
|
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = managers.ChannelDBManager()
|
objects = managers.ChannelDBManager()
|
||||||
|
|
||||||
|
|
@ -377,3 +479,7 @@ class ChannelDB(TypedObject):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Channel '%s' (%s)" % (self.key, self.db.desc)
|
return "Channel '%s' (%s)" % (self.key, self.db.desc)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def subscriptions(self):
|
||||||
|
return SubscriptionHandler(self)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue