From c7f32f904dcc23fda9000568439d0f0ed40ad2fe Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Fri, 25 May 2007 03:24:23 +0000 Subject: [PATCH] Lots of re-arranging of the comsys and near completion of comsys player commands. I'm going to halt further progres on this long enough for me to take a second look at my code and re-factor some things, then go on to work on some of the lesser-used commands. New in this revision: on, off, last, who for channels (pub who, etc.). Make sure you nuke all of your comsys-related tables and re-sync. --- apps/objects/models.py | 7 +- cmdhandler.py | 24 ++++- commands_comsys.py | 15 +-- functions_comsys.py | 225 ++++++++++++++++++++++++++++++++++++++--- functions_db.py | 2 +- session.py | 53 +--------- 6 files changed, 249 insertions(+), 77 deletions(-) diff --git a/apps/objects/models.py b/apps/objects/models.py index 4fa5556fbf..0b6679a83f 100755 --- a/apps/objects/models.py +++ b/apps/objects/models.py @@ -745,7 +745,7 @@ class CommChannel(models.Model): Returns the channel's header text, or what is shown before each channel message. """ - return ansi.parse_ansi(self.header) + return ansi.parse_ansi(self.ansi_name) def get_owner(self): """ @@ -780,9 +780,8 @@ class CommChannelMessage(models.Model): A single logged channel message. """ channel = models.ForeignKey(CommChannel, related_name="msg_channel") - sender = models.ForeignKey(Object, related_name="msg_sender", blank=True, null=True) message = models.CharField(maxlength=255) - date_sent = models.DateField(editable=False, auto_now_add=True) + date_sent = models.DateTimeField(editable=False, auto_now_add=True) def __str__(self): return "%s: %s" % (self.sender.name, self.message) @@ -791,7 +790,7 @@ class CommChannelMessage(models.Model): ordering = ['-date_sent'] class Admin: - list_display = ('channel', 'sender', 'message') + list_display = ('channel', 'message') import functions_db import functions_general diff --git a/cmdhandler.py b/cmdhandler.py index 7165bf7566..3c38d398aa 100755 --- a/cmdhandler.py +++ b/cmdhandler.py @@ -9,6 +9,7 @@ import commands_unloggedin import cmdtable import functions_db import functions_general +import functions_comsys """ This is the command processing module. It is instanced once in the main @@ -95,9 +96,28 @@ def handle(cdat): parsed_input['splitted'][1] = parsed_input['splitted'][1][1:] parsed_input['root_cmd'] = 'pose' # Channel alias match. - elif session.has_user_channel(parsed_input['root_cmd'], alias_search=True, return_muted=False): - cname = session.channels_subscribed.get(parsed_input['root_cmd'])[0] + elif functions_comsys.plr_has_channel(session, + parsed_input['root_cmd'], + alias_search=True, + return_muted=True): + + calias = parsed_input['root_cmd'] + cname = functions_comsys.plr_cname_from_alias(session, calias) cmessage = ' '.join(parsed_input['splitted'][1:]) + + if cmessage == "who": + functions_comsys.msg_cwho(session, cname) + return + elif cmessage == "on": + functions_comsys.plr_chan_on(session, calias) + return + elif cmessage == "off": + functions_comsys.plr_chan_off(session, calias) + return + elif cmessage == "last": + functions_comsys.msg_chan_hist(session, cname) + return + second_arg = "%s=%s" % (cname, cmessage) parsed_input['splitted'] = ["@cemit/sendername", second_arg] parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet'] diff --git a/commands_comsys.py b/commands_comsys.py index bf4f868e0b..d1e5415ba0 100644 --- a/commands_comsys.py +++ b/commands_comsys.py @@ -1,13 +1,14 @@ -import settings +import os import time + +import settings import functions_general import functions_db import functions_help import functions_comsys -import defines_global as global_defines +import defines_global import session_mgr import ansi -import os """ Comsys command module. Pretty much every comsys command should go here for now. @@ -52,7 +53,7 @@ def cmd_addcom(cdat): chan_name_parsed = name_matches[0].get_name() session.msg("You join %s, with an alias of %s." % \ (chan_name_parsed, chan_alias)) - session.set_user_channel(chan_alias, chan_name_parsed, True) + functions_comsys.plr_set_channel(session, chan_alias, chan_name_parsed, True) # Announce the user's joining. join_msg = "[%s] %s has joined the channel." % \ @@ -83,7 +84,7 @@ def cmd_delcom(cdat): chan_name = session.channels_subscribed[chan_alias][0] session.msg("You have left %s." % (chan_name,)) - session.del_user_channel(chan_alias) + functions_comsys.plr_del_channel(session, chan_alias) # Announce the user's leaving. leave_msg = "[%s] %s has left the channel." % \ @@ -160,7 +161,6 @@ def cmd_cdestroy(cdat): session.msg("Channel %s destroyed." % (name_matches[0],)) name_matches.delete() - def cmd_cset(cdat): """ @cset @@ -237,6 +237,9 @@ def cmd_cemit(cdat): final_cmessage = cmessage else: if "sendername" in switches: + if not functions_comsys.plr_has_channel(session, cname_parsed, return_muted=False): + session.msg("You must be on %s to do that." % (cname_parsed,)) + return final_cmessage = "[%s] %s: %s" % (cname_parsed, pobject.get_name(show_dbref=False), cmessage) else: if not pobject.user_has_perm("objects.emit_commchannel"): diff --git a/functions_comsys.py b/functions_comsys.py index b97b851b66..5d13024346 100644 --- a/functions_comsys.py +++ b/functions_comsys.py @@ -1,24 +1,207 @@ -from apps.objects.models import CommChannel +import cPickle as pickle +import time +import datetime + +from apps.objects.models import CommChannel, CommChannelMessage import session_mgr import ansi """ Comsys functions. """ +def plr_get_cdict(session): + """ + Returns the users's channel subscription dictionary. Use this instead of + directly referring to the session object. + + session: (SessionProtocol) Reference to a player session. + """ + return session.channels_subscribed + +def plr_listening_channel(session, cstr, alias_search=False): + """ + Returns a player's listening status for a channel. + + session: (SessionProtocol) Reference to a player session. + cstr: (str) The channel name or alias (depending on alias_search). + alias_search: (bool) If true, search by alias. Else search by full name. + """ + return plr_has_channel(session, cstr, alias_search=alias_search, + return_muted=False) + +def plr_cname_from_alias(session, calias): + """ + Returns a channel name given a channel alias. + + session: (SessionProtocol) Reference to a player session. + calias: (str) The channel alias. + """ + return plr_get_cdict(session).get(calias, None)[0] + +def plr_chan_off(session, calias): + """ + Turn a channel off for a player. + + session: (SessionProtocol) Reference to a player session. + calias: (str) The channel alias. + """ + if not plr_listening_channel(session, calias, alias_search=True): + session.msg("You're already not listening to that channel.") + return + else: + cname = plr_cname_from_alias(session, calias) + cobj = get_cobj_from_name(cname) + plr_set_channel_listening(session, calias, False) + session.msg("You have left %s." % (cname,)) + send_cmessage(cname, "%s %s has left the channel." % (cobj.get_header(), + session.get_pobject().get_name(show_dbref=False))) + +def plr_chan_on(session, calias): + """ + Turn a channel on for a player. + + session: (SessionProtocol) Reference to a player session. + calias: (str) The channel alias. + """ + plr_listening = plr_listening_channel(session, calias, alias_search=True) + if plr_listening: + session.msg("You're already listening to that channel.") + return + else: + cname = plr_cname_from_alias(session, calias) + cobj = get_cobj_from_name(cname) + send_cmessage(cname, "%s %s has joined the channel." % (cobj.get_header(), + session.get_pobject().get_name(show_dbref=False))) + plr_set_channel_listening(session, calias, True) + session.msg("You have joined %s." % (cname,)) + +def plr_has_channel(session, cname, alias_search=False, return_muted=False): + """ + Is this session subscribed to the named channel? + + session: (SessionProtocol) Reference to a player session. + cname: (str) The channel name or alias (depending on alias_search) + alias_search: (bool) If False, search by full name. Else search by alias. + return_muted: (bool) Take the user's enabling/disabling of the channel + into consideration? + """ + has_channel = False + + if alias_search: + # Search by aliases only. + cdat = plr_get_cdict(session).get(cname, False) + # No key match, fail immediately. + if not cdat: + return False + + # If channel status is taken into consideration, see if the user + # has the channel muted or not. + if return_muted: + return True + else: + return cdat[1] + + else: + # Search by complete channel name. + chan_list = plr_get_cdict(session).values() + for chan in chan_list: + # Check for a name match + if cname == chan[0]: + has_channel = True + + # If channel status is taken into consideration, see if the user + # has the channel muted or not. + if return_muted is False and not chan[1]: + has_channel = False + break + + return has_channel + +def plr_set_channel_listening(session, alias, listening): + """ + Add a channel to a session's channel list. + + session: (SessionProtocol) A reference to the player session. + alias: (str) The channel alias. + listening: (bool) A True or False value to determine listening status. + """ + plr_get_cdict(session).get(alias)[1] = listening + plr_pickle_channels(session) + +def plr_set_channel(session, alias, cname, listening): + """ + Set a channels alias, name, and listening status in one go, or add the + channel if it doesn't already exist on a user's list. + + session: (SessionProtocol) A reference to the player session. + alias: (str) The channel alias (also the key in the user's cdict) + cname: (str) Desired channel name to set. + listening: (bool) A True or False value to determine listening status. + """ + plr_get_cdict(session)[alias] = [cname, listening] + plr_pickle_channels(session) + +def plr_pickle_channels(session): + """ + Save the player's channel list to the CHANLIST attribute. + + session: (SessionProtocol) A reference to the player session. + """ + session.get_pobject().set_attribute("CHANLIST", pickle.dumps(plr_get_cdict(session))) + +def plr_del_channel(session, alias): + """ + Remove a channel from a session's channel list. + + session: (SessionProtocol) A reference to the player session. + alias: (str) The channel alias (also the key in the user's cdict) + """ + del plr_get_cdict(session)[alias] + +def msg_chan_hist(session, channel_name): + """ + Sends a listing of subscribers to a channel given a channel name. + + session: (SessionProtocol) A reference to the player session. + channel_name: (str) The channel's full name. + """ + cobj = get_cobj_from_name(channel_name) + hist_list = CommChannelMessage.objects.filter(channel=cobj).order_by('date_sent') + for entry in hist_list: + delta_days = datetime.datetime.now() - entry.date_sent + days_elapsed = delta_days.days + if days_elapsed > 0: + time_str = entry.date_sent.strftime("%m.%d / %H:%M") + else: + time_str = entry.date_sent.strftime("%H:%M") + session.msg("[%s] %s" % (time_str, entry.message)) + +def msg_cwho(session, channel_name): + """ + Sends a listing of subscribers to a channel given a channel name. + + session: (SessionProtocol) A reference to the player session. + channel_name: (str) The channel's full name. + """ + session.msg("--- Users Listening to %s ---" % (channel_name,)) + for plr_sess in get_cwho_list(channel_name): + session.msg(plr_sess.get_pobject().get_name(show_dbref=False)) + session.msg("--- End Channel Listeners ---") + def get_cwho_list(channel_name, return_muted=False): - """ - Get all users on a channel. + """ + Get all users on a channel. - channel_name: (string) The name of the channel. - return_muted: (bool) Return those who have the channel muted if True. - """ - sess_list = session_mgr.get_session_list() - result_list = [] - for sess in sess_list: - if sess.has_user_channel(channel_name, return_muted): - result_list.append(sess) + channel_name: (string) The name of the channel. + return_muted: (bool) Return those who have the channel muted if True. + """ + sess_list = session_mgr.get_session_list() + result_list = [] + for sess in sess_list: + if plr_has_channel(sess, channel_name, return_muted): + result_list.append(sess) - return result_list + return result_list def send_cmessage(channel_name, message): """ @@ -29,6 +212,16 @@ def send_cmessage(channel_name, message): """ for user in get_cwho_list(channel_name, return_muted=False): user.msg(message) + + chan_message = CommChannelMessage() + + try: + chan_message.channel = get_cobj_from_name(channel_name) + except: + functions_general.log_errmsg("send_cmessage(): Can't find channel: %s" %(channel_name,)) + + chan_message.message = message + chan_message.save() def get_all_channels(): """ @@ -36,6 +229,12 @@ def get_all_channels(): """ return CommChannel.objects.all() +def get_cobj_from_name(cname): + """ + Returns the channel's object when given a name. + """ + return CommChannel.objects.get(name=cname) + def create_channel(cdat): """ Create a new channel. cdat is a dictionary that contains the following keys. @@ -60,4 +259,4 @@ def cname_search(search_text, exact=False): if exact: return CommChannel.objects.filter(name__iexact=search_text) else: - return CommChannel.objects.filter(name__istartswith=search_text) \ No newline at end of file + return CommChannel.objects.filter(name__istartswith=search_text) diff --git a/functions_db.py b/functions_db.py index 08055d104b..8c8b70fdeb 100644 --- a/functions_db.py +++ b/functions_db.py @@ -316,4 +316,4 @@ def create_user(cdat, uname, email, password): # Activate the player's session and set them loose. session.login(user) print 'Registration: %s' % (session,) - session.push("Welcome to %s, %s.\n\r" % (gameconf.get_configvalue('site_name'), session.get_pobject().get_name(show_dbref=False),)) + session.msg("Welcome to %s, %s.\n\r" % (gameconf.get_configvalue('site_name'), session.get_pobject().get_name(show_dbref=False),)) diff --git a/session.py b/session.py index 7e013eb287..0acee9d7fa 100755 --- a/session.py +++ b/session.py @@ -60,57 +60,8 @@ class SessionProtocol(StatefulTelnetProtocol): """ Execute this when a client abruplty loses their connection. """ - print "DISCONNECT:", reason.getErrorMessage() - - def has_user_channel(self, cname, alias_search=False, return_muted=False): - """ - Is this session subscribed to the named channel? - return_muted: (bool) Take the user's enabling/disabling of the channel - into consideration? - """ - has_channel = False - - if alias_search: - # Search by aliases only. - cdat = self.channels_subscribed.get(cname, False) - # No key match, fail immediately. - if not cdat: - return False - - # If channel status is taken into consideration, see if the user - # has the channel muted or not. - if return_muted: - return cdat[1] - else: - return True - else: - # Search by complete channel name. - chan_list = self.channels_subscribed.values() - for chan in chan_list: - # Check for a name match - if cname == chan[0]: - has_channel = True - - # If channel status is taken into consideration, see if the user - # has the channel muted or not. - if return_muted is False and not chan[1]: - has_channel = False - break - - return has_channel - - def set_user_channel(self, alias, cname, listening): - """ - Add a channel to a session's channel list. - """ - self.channels_subscribed[alias] = [cname, listening] - self.get_pobject().set_attribute("CHANLIST", pickle.dumps(self.channels_subscribed)) - - def del_user_channel(self, alias): - """ - Remove a channel from a session's channel list. - """ - del self.channels_subscribed[alias] + functions_general.log_infomsg('Disconnect: %s' % (self,)) + functions_general.log_infomsg('Sessions active: %d' % (len(session_mgr.get_session_list()),)) def load_user_channels(self): """