Finally transition away from those horrid channel attributes for tracking channel memberships. We'll see about doing away with them altogether if it's possible efficiently.

NOTE: MAKE SURE YOU SYNCDB. A new model was added to track channel memberships.
This commit is contained in:
Greg Taylor 2009-06-04 03:42:19 +00:00
parent acbfa1be6a
commit d29c6340fc
4 changed files with 86 additions and 52 deletions

View file

@ -12,7 +12,7 @@ class CommChannel(models.Model):
""" """
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
ansi_name = models.CharField(max_length=255) ansi_name = models.CharField(max_length=255)
owner = models.ForeignKey(Object, related_name="chan_owner") owner = models.ForeignKey(Object, related_name="channel_owner_set")
description = models.CharField(max_length=80, blank=True, null=True) description = models.CharField(max_length=80, blank=True, null=True)
is_joined_by_default = models.BooleanField(default=False) is_joined_by_default = models.BooleanField(default=False)
req_grp = models.ManyToManyField(Group, blank=True, null=True) req_grp = models.ManyToManyField(Group, blank=True, null=True)
@ -91,6 +91,19 @@ class CommChannel(models.Model):
Returns a default channel alias for the channel if none is provided. Returns a default channel alias for the channel if none is provided.
""" """
return self.name[:3].lower() return self.name[:3].lower()
class CommChannelMembership(models.Model):
"""
Used to track which channels an Object is listening to.
"""
channel = models.ForeignKey(CommChannel, related_name="membership_set")
listener = models.ForeignKey(Object, related_name="channel_membership_set")
user_alias = models.CharField(max_length=10)
comtitle = models.CharField(max_length=25, blank=True)
is_listening = models.BooleanField(default=True)
def __str__(self):
return "%s: %s" % (self.channel.name, self.listener.name)
class CommChannelMessage(models.Model): class CommChannelMessage(models.Model):
""" """

View file

@ -3,7 +3,8 @@ Comsys command module.
""" """
import time import time
from django.conf import settings from django.conf import settings
import src.comsys from src import comsys
from src.channels.models import CommChannelMembership, CommChannel
from src import defines_global from src import defines_global
from src import ansi from src import ansi
from src.util import functions_general from src.util import functions_general
@ -36,24 +37,26 @@ def cmd_addcom(command):
chan_name = command_argument.strip() chan_name = command_argument.strip()
chan_alias = chan_name chan_alias = chan_name
if chan_alias in command.session.channels_subscribed: if source_object.channel_membership_set.filter(channel__name__iexact=chan_name):
source_object.emit_to("You are already on that channel.") source_object.emit_to("You are already on that channel.")
return return
name_matches = src.comsys.cname_search(chan_name, exact=True) try:
chan = CommChannel.objects.get(name__iexact=chan_name)
if name_matches: # This adds a CommChannelMembership object and a matching dict entry
chan_name_parsed = name_matches[0].get_name() # on the session's cdict.
comsys.plr_add_channel(source_object, chan_alias, chan)
# Let the player know everything went well.
source_object.emit_to("You join %s, with an alias of %s." % \ source_object.emit_to("You join %s, with an alias of %s." % \
(chan_name_parsed, chan_alias)) (chan.get_name(), chan_alias))
src.comsys.plr_set_channel(command.session, chan_alias,
chan_name_parsed, True)
# Announce the user's joining. # Announce the user's joining.
join_msg = "%s has joined the channel." % \ join_msg = "%s has joined the channel." % \
(source_object.get_name(show_dbref=False),) (source_object.get_name(show_dbref=False),)
src.comsys.send_cmessage(chan_name_parsed, join_msg) comsys.send_cmessage(chan, join_msg)
else: except CommChannel.DoesNotExist:
# Failed to match iexact on channel's 'name' attribute.
source_object.emit_to("Could not find channel %s." % chan_name) source_object.emit_to("Could not find channel %s." % chan_name)
GLOBAL_CMD_TABLE.add_command("addcom", cmd_addcom), GLOBAL_CMD_TABLE.add_command("addcom", cmd_addcom),
@ -73,18 +76,20 @@ def cmd_delcom(command):
source_object.emit_to("You must specify a channel alias.") source_object.emit_to("You must specify a channel alias.")
return return
if command.command_argument not in command.session.channels_subscribed: try:
membership = source_object.channel_membership_set.get(user_alias__iexact=command.command_argument)
except CommChannelMembership.DoesNotExist:
source_object.emit_to("You are not on that channel.") source_object.emit_to("You are not on that channel.")
return return
chan_name = command.session.channels_subscribed[command.command_argument][0] chan_name = membership.channel.get_name()
source_object.emit_to("You have left %s." % chan_name) source_object.emit_to("You have left %s." % chan_name)
src.comsys.plr_del_channel(command.session, command.command_argument) comsys.plr_del_channel(source_object, command.command_argument)
# Announce the user's leaving. # Announce the user's leaving.
leave_msg = "%s has left the channel." % \ leave_msg = "%s has left the channel." % \
(source_object.get_name(show_dbref=False),) (source_object.get_name(show_dbref=False),)
src.comsys.send_cmessage(chan_name, leave_msg) comsys.send_cmessage(chan_name, leave_msg)
GLOBAL_CMD_TABLE.add_command("delcom", cmd_delcom), GLOBAL_CMD_TABLE.add_command("delcom", cmd_delcom),
def cmd_comlist(command): def cmd_comlist(command):
@ -95,14 +100,16 @@ def cmd_comlist(command):
session = command.session session = command.session
source_object.emit_to("Alias Channel Status") source_object.emit_to("Alias Channel Status")
for chan in session.channels_subscribed: for membership in source_object.channel_membership_set.all():
if session.channels_subscribed[chan][1]: chan = membership.channel
if membership.is_listening:
chan_on = "On" chan_on = "On"
else: else:
chan_on = "Off" chan_on = "Off"
source_object.emit_to("%-9.9s %-19.19s %s" % source_object.emit_to("%-9.9s %-19.19s %s" % (membership.user_alias,
(chan, session.channels_subscribed[chan][0], chan_on)) chan.get_name(),
chan_on))
source_object.emit_to("-- End of comlist --") source_object.emit_to("-- End of comlist --")
GLOBAL_CMD_TABLE.add_command("comlist", cmd_comlist), GLOBAL_CMD_TABLE.add_command("comlist", cmd_comlist),
@ -136,7 +143,7 @@ def cmd_clist(command):
source_object = command.source_object source_object = command.source_object
source_object.emit_to("** Channel Owner Description") source_object.emit_to("** Channel Owner Description")
for chan in src.comsys.get_all_channels(): for chan in comsys.get_all_channels():
source_object.emit_to("%s%s %-15.14s%-22.15s%s" % source_object.emit_to("%s%s %-15.14s%-22.15s%s" %
('-', ('-',
'-', '-',
@ -159,7 +166,7 @@ def cmd_cdestroy(command):
source_object.emit_to("You must supply a name!") source_object.emit_to("You must supply a name!")
return return
name_matches = src.comsys.cname_search(cname, exact=True) name_matches = comsys.cname_search(cname, exact=True)
if not name_matches: if not name_matches:
source_object.emit_to("Could not find channel %s." % (cname,)) source_object.emit_to("Could not find channel %s." % (cname,))
@ -234,7 +241,7 @@ def cmd_cemit(command):
source_object.emit_to("You must provide a message to emit.") source_object.emit_to("You must provide a message to emit.")
return return
name_matches = src.comsys.cname_search(cname, exact=True) name_matches = comsys.cname_search(cname, exact=True)
if name_matches: if name_matches:
cname_parsed = name_matches[0].get_name() cname_parsed = name_matches[0].get_name()
else: else:
@ -252,7 +259,7 @@ def cmd_cemit(command):
show_channel_header = False show_channel_header = False
else: else:
if "sendername" in command.command_switches: if "sendername" in command.command_switches:
if not src.comsys.plr_has_channel(command.session, cname_parsed, if not comsys.plr_has_channel(command.session, cname_parsed,
return_muted=False): return_muted=False):
source_object.emit_to("You must be on %s to do that." % (cname_parsed,)) source_object.emit_to("You must be on %s to do that." % (cname_parsed,))
return return
@ -266,7 +273,7 @@ def cmd_cemit(command):
if not "quiet" in command.command_switches: if not "quiet" in command.command_switches:
source_object.emit_to("Sent - %s" % (name_matches[0],)) source_object.emit_to("Sent - %s" % (name_matches[0],))
src.comsys.send_cmessage(cname_parsed, final_cmessage, comsys.send_cmessage(cname_parsed, final_cmessage,
show_header=show_channel_header) show_header=show_channel_header)
if settings.IMC2_ENABLED: if settings.IMC2_ENABLED:
@ -311,7 +318,7 @@ def cmd_cwho(command):
source_object.emit_to("You must specify a channel name.") source_object.emit_to("You must specify a channel name.")
return return
name_matches = src.comsys.cname_search(channel_name, exact=True) name_matches = comsys.cname_search(channel_name, exact=True)
if name_matches: if name_matches:
# Check to make sure the user has permission to use @cwho. # Check to make sure the user has permission to use @cwho.
@ -319,7 +326,7 @@ def cmd_cwho(command):
is_controlled_by_plr = name_matches[0].controlled_by(source_object) is_controlled_by_plr = name_matches[0].controlled_by(source_object)
if is_controlled_by_plr or is_channel_admin: if is_controlled_by_plr or is_channel_admin:
src.comsys.msg_cwho(source_object, channel_name) comsys.msg_cwho(source_object, channel_name)
else: else:
source_object.emit_to("Permission denied.") source_object.emit_to("Permission denied.")
return return
@ -346,13 +353,13 @@ def cmd_ccreate(command):
source_object.emit_to("Permission denied.") source_object.emit_to("Permission denied.")
return return
name_matches = src.comsys.cname_search(cname, exact=True) name_matches = comsys.cname_search(cname, exact=True)
if name_matches: if name_matches:
source_object.emit_to("A channel with that name already exists.") source_object.emit_to("A channel with that name already exists.")
else: else:
# Create and set the object up. # Create and set the object up.
new_chan = src.comsys.create_channel(cname, source_object) new_chan = comsys.create_channel(cname, source_object)
source_object.emit_to("Channel %s created." % (new_chan.get_name(),)) source_object.emit_to("Channel %s created." % (new_chan.get_name(),))
GLOBAL_CMD_TABLE.add_command("@ccreate", cmd_ccreate, GLOBAL_CMD_TABLE.add_command("@ccreate", cmd_ccreate,
priv_tuple=("objects.add_commchannel")), priv_tuple=("objects.add_commchannel")),

View file

@ -4,7 +4,7 @@ Comsys functions.
import time import time
import datetime import datetime
from django.utils import simplejson from django.utils import simplejson
from src.channels.models import CommChannel, CommChannelMessage from src.channels.models import CommChannel, CommChannelMessage, CommChannelMembership
from src import session_mgr from src import session_mgr
from src import ansi from src import ansi
from src import logger from src import logger
@ -119,44 +119,48 @@ def plr_has_channel(session, cname, alias_search=False, return_muted=False):
def plr_set_channel_listening(session, alias, listening): def plr_set_channel_listening(session, alias, listening):
""" """
Add a channel to a session's channel list. Enables or disables listening on a particular channel.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
alias: (str) The channel alias. alias: (str) The channel alias.
listening: (bool) A True or False value to determine listening status. listening: (bool) A True or False value to determine listening status.
""" """
membership = session.pobject.channel_membership_set.get(user_alias=alias)
membership.is_listening = listening
membership.save()
plr_get_cdict(session).get(alias)[1] = listening plr_get_cdict(session).get(alias)[1] = listening
plr_jsondump_channels(session)
def plr_set_channel(session, alias, cname, listening): def plr_add_channel(source_object, alias, channel):
""" """
Set a channels alias, name, and listening status in one go, or add the Adds a player to a channel via a CommChannelMembership and sets the cached
channel if it doesn't already exist on a user's list. cdict value.
session: (SessionProtocol) A reference to the player session. source_object: (Object) Reference to the object that will be listening.
alias: (str) The channel alias (also the key in the user's cdict) alias: (str) The channel alias (also the key in the user's cdict)
cname: (str) Desired channel name to set. channel: (CommChannel) The channel object to add.
listening: (bool) A True or False value to determine listening status. listening: (bool) A True or False value to determine listening status.
""" """
plr_get_cdict(session)[alias] = [cname, listening] membership = CommChannelMembership(channel=channel, listener=source_object,
plr_jsondump_channels(session) user_alias=alias)
membership.save()
def plr_jsondump_channels(session):
"""
Save the player's channel list to the CHANLIST attribute.
session: (SessionProtocol) A reference to the player session. sessions = session_mgr.sessions_from_object(source_object)
""" for session in sessions:
session.get_pobject().set_attribute("__CHANLIST", simplejson.dumps(plr_get_cdict(session))) plr_get_cdict(session)[alias] = [channel.get_name(), True]
def plr_del_channel(session, alias): def plr_del_channel(source_object, alias):
""" """
Remove a channel from a session's channel list. Remove a channel from a session's channel list.
session: (SessionProtocol) A reference to the player session. source_object: (Object) Reference to the object that will be listening.
alias: (str) The channel alias (also the key in the user's cdict) alias: (str) The channel alias (also the key in the user's cdict)
""" """
del plr_get_cdict(session)[alias] membership = source_object.channel_membership_set.get(user_alias=alias)
membership.delete()
sessions = session_mgr.sessions_from_object(source_object)
for session in sessions:
del plr_get_cdict(session)[alias]
def msg_chan_hist(target_obj, channel_name): def msg_chan_hist(target_obj, channel_name):
""" """
@ -214,11 +218,12 @@ def load_object_channels(pobject):
""" """
Parse JSON dict of a user's channel list from their CHANLIST attribute. Parse JSON dict of a user's channel list from their CHANLIST attribute.
""" """
chan_list = pobject.get_attribute_value("__CHANLIST") membership_list = pobject.channel_membership_set.all()
if chan_list: for membership in membership_list:
sessions = session_mgr.sessions_from_object(pobject) sessions = session_mgr.sessions_from_object(pobject)
for session in sessions: for session in sessions:
session.channels_subscribed = simplejson.loads(chan_list) session.channels_subscribed[membership.user_alias] = [membership.channel.name,
membership.is_listening]
def send_cmessage(channel, message, show_header=True): def send_cmessage(channel, message, show_header=True):
""" """

View file

@ -36,6 +36,15 @@ def get_session_list(return_unlogged=False):
return session_list return session_list
else: else:
return [sess for sess in session_list if sess.is_loggedin()] return [sess for sess in session_list if sess.is_loggedin()]
def get_session_id_list(return_unlogged=False):
"""
Lists the connected session object ids.
"""
if return_unlogged:
return session_list
else:
return [sess.uid for sess in session_list if sess.is_loggedin()]
def disconnect_all_sessions(): def disconnect_all_sessions():
""" """