mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 18:47:16 +01:00
Start refactoring channels
This commit is contained in:
parent
9e2b7576b1
commit
48ebe5e3c2
2 changed files with 469 additions and 236 deletions
|
|
@ -945,6 +945,98 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
|||
self, raw_string, callertype="account", session=session, **kwargs
|
||||
)
|
||||
|
||||
# channel receive hooks
|
||||
|
||||
def at_pre_channel_msg(self, message, channel, senders=None, **kwargs):
|
||||
"""
|
||||
Called by `self.channel_msg` before sending a channel message to the
|
||||
user. This allows for customizing messages per-user and also to abort
|
||||
the receive on the receiver-level.
|
||||
|
||||
Args:
|
||||
message (str): The message sent to the channel.
|
||||
channel (Channel): The sending channel.
|
||||
senders (list, optional): Accounts or Objects acting as senders.
|
||||
For most normal messages, there is only a single sender. If
|
||||
there are no senders, this may be a broadcasting message.
|
||||
**kwargs: These are additional keywords passed into `channel_msg`.
|
||||
If `no_prefix=True` or `emit=True` are passed, the channel
|
||||
prefix will not be added (`[channelname]: ` by default)
|
||||
|
||||
Returns:
|
||||
str or None: Allows for customizing the message for this recipient.
|
||||
If returning `None` (or `False`) message-receiving is aborted.
|
||||
The returning string will be passed into `self.channel_msg`.
|
||||
|
||||
Notes:
|
||||
This support posing/emotes by starting channel-send with : or ;.
|
||||
|
||||
"""
|
||||
if senders:
|
||||
sender_string = ', '.join(sender.key for sender in senders)
|
||||
message_lstrip = message.lstrip()
|
||||
if message_lstrip.startswith((':', ';')):
|
||||
# this is a pose, should show as e.g. "User1 smiles to channel"
|
||||
spacing = "" if message_lstrip.startswith((':', '\'', ',')) else " "
|
||||
message = f"{sender_string}{spacing}{message_lstrip[1:]}"
|
||||
else:
|
||||
# normal message
|
||||
message = f"{sender_string}: {message}"
|
||||
|
||||
if not kwargs.get("no_prefix") or not kwargs.get("emit"):
|
||||
message = channel.channel_prefix() + message
|
||||
|
||||
return message
|
||||
|
||||
def channel_msg(self, message, channel, senders=None, **kwargs):
|
||||
"""
|
||||
This performs the actions of receiving a message to an un-muted
|
||||
channel.
|
||||
|
||||
Args:
|
||||
message (str): The message sent to the channel.
|
||||
channel (Channel): The sending channel.
|
||||
senders (list, optional): Accounts or Objects acting as senders.
|
||||
For most normal messages, there is only a single sender. If
|
||||
there are no senders, this may be a broadcasting message or
|
||||
similar.
|
||||
**kwargs: These are additional keywords originally passed into
|
||||
`Channel.msg`.
|
||||
|
||||
Notes:
|
||||
Before this, `Channel.at_before_msg` will fire, which offers a way
|
||||
to customize the message for the receiver on the channel-level.
|
||||
|
||||
"""
|
||||
# channel pre-msg hook
|
||||
message = self.at_pre_channel_msg(message, channel, senders=senders, **kwargs)
|
||||
if message in (None, False):
|
||||
return
|
||||
|
||||
# the actual sending
|
||||
self.msg(text=(message, {"from_channel": channel.id}),
|
||||
from_obj=senders, options={"from_channel": channel.id})
|
||||
|
||||
# channel post-msg hook
|
||||
self.at_post_channel_msg(message, channel, senders=senders, **kwargs)
|
||||
|
||||
def at_post_channel_msg(self, message, channel, senders=None, **kwargs):
|
||||
"""
|
||||
Called by `self.channel_msg` after message was received.
|
||||
|
||||
Args:
|
||||
message (str): The message sent to the channel.
|
||||
channel (Channel): The sending channel.
|
||||
senders (list, optional): Accounts or Objects acting as senders.
|
||||
For most normal messages, there is only a single sender. If
|
||||
there are no senders, this may be a broadcasting message.
|
||||
**kwargs: These are additional keywords passed into `channel_msg`.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
# search method
|
||||
|
||||
def search(
|
||||
self,
|
||||
searchdata,
|
||||
|
|
|
|||
|
|
@ -20,10 +20,33 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
This is the base class for all Channel Comms. Inherit from this to
|
||||
create different types of communication channels.
|
||||
|
||||
Class-level variables:
|
||||
- `send_to_online_only` (bool, default True) - if set, will only try to
|
||||
send to subscribers that are actually active. This is a useful optimization.
|
||||
- `log_to_file` (str, default `"channel_{channel_key}.log"`). This is the
|
||||
log file to which the channel history will be saved. The `{channel_key}` tag
|
||||
will be replaced by the key of the Channel. If an Attribute 'log_file'
|
||||
is set, this will be used instead. If this is None and no Attribute is found,
|
||||
no history will be saved.
|
||||
- `channel_prefix_string` (str, default `"[{channel_key} ]"`) - this is used
|
||||
as a simple template to get the channel prefix with `.channel_prefix()`.
|
||||
|
||||
"""
|
||||
|
||||
objects = ChannelManager()
|
||||
|
||||
# channel configuration
|
||||
|
||||
# only send to characters/accounts who has an active session (this is a
|
||||
# good optimization since people can still recover history separately).
|
||||
send_to_online_only = True
|
||||
# store log in log file. `channel_key tag will be replace with key of channel.
|
||||
# Will use log_file Attribute first, if given
|
||||
log_to_file = "channel_{channel_key}.log"
|
||||
# which prefix to use when showing were a message is coming from. Set to
|
||||
# None to disable and set this later.
|
||||
channel_prefix_string = "[{channel_key}] "
|
||||
|
||||
def at_first_save(self):
|
||||
"""
|
||||
Called by the typeclass system the very first time the channel
|
||||
|
|
@ -139,8 +162,8 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
|
||||
def unmute(self, subscriber, **kwargs):
|
||||
"""
|
||||
Removes an entity to the list of muted subscribers. A muted subscriber will no longer see channel messages,
|
||||
but may use channel commands.
|
||||
Removes an entity to the list of muted subscribers. A muted subscriber
|
||||
will no longer see channel messages, but may use channel commands.
|
||||
|
||||
Args:
|
||||
subscriber (Object or Account): The subscriber to unmute.
|
||||
|
|
@ -302,156 +325,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
|
||||
CHANNELHANDLER.update()
|
||||
|
||||
def message_transform(
|
||||
self, msgobj, emit=False, prefix=True, sender_strings=None, external=False, **kwargs
|
||||
):
|
||||
"""
|
||||
Generates the formatted string sent to listeners on a channel.
|
||||
|
||||
Args:
|
||||
msgobj (Msg): Message object to send.
|
||||
emit (bool, optional): In emit mode the message is not associated
|
||||
with a specific sender name.
|
||||
prefix (bool, optional): Prefix `msg` with a text given by `self.channel_prefix`.
|
||||
sender_strings (list, optional): Used by bots etc, one string per external sender.
|
||||
external (bool, optional): If this is an external sender or not.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
"""
|
||||
if sender_strings or external:
|
||||
body = self.format_external(msgobj, sender_strings, emit=emit)
|
||||
else:
|
||||
body = self.format_message(msgobj, emit=emit)
|
||||
if prefix:
|
||||
body = "%s%s" % (self.channel_prefix(msgobj, emit=emit), body)
|
||||
msgobj.message = body
|
||||
return msgobj
|
||||
|
||||
def distribute_message(self, msgobj, online=False, **kwargs):
|
||||
"""
|
||||
Method for grabbing all listeners that a message should be
|
||||
sent to on this channel, and sending them a message.
|
||||
|
||||
Args:
|
||||
msgobj (Msg or TempMsg): Message to distribute.
|
||||
online (bool): Only send to receivers who are actually online
|
||||
(not currently used):
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
Notes:
|
||||
This is also where logging happens, if enabled.
|
||||
|
||||
"""
|
||||
# get all accounts or objects connected to this channel and send to them
|
||||
if online:
|
||||
subs = self.subscriptions.online()
|
||||
else:
|
||||
subs = self.subscriptions.all()
|
||||
for entity in subs:
|
||||
# if the entity is muted, we don't send them a message
|
||||
if entity in self.mutelist:
|
||||
continue
|
||||
try:
|
||||
# note our addition of the from_channel keyword here. This could be checked
|
||||
# by a custom account.msg() to treat channel-receives differently.
|
||||
entity.msg(
|
||||
msgobj.message, from_obj=msgobj.senders, options={"from_channel": self.id}
|
||||
)
|
||||
except AttributeError as e:
|
||||
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
||||
|
||||
if msgobj.keep_log:
|
||||
# log to file
|
||||
logger.log_file(
|
||||
msgobj.message, self.attributes.get("log_file") or "channel_%s.log" % self.key
|
||||
)
|
||||
|
||||
def msg(
|
||||
self,
|
||||
msgobj,
|
||||
header=None,
|
||||
senders=None,
|
||||
sender_strings=None,
|
||||
keep_log=None,
|
||||
online=False,
|
||||
emit=False,
|
||||
external=False,
|
||||
):
|
||||
"""
|
||||
Send the given message to all accounts connected to channel. Note that
|
||||
no permission-checking is done here; it is assumed to have been
|
||||
done before calling this method. The optional keywords are not used if
|
||||
persistent is False.
|
||||
|
||||
Args:
|
||||
msgobj (Msg, TempMsg or str): If a Msg/TempMsg, the remaining
|
||||
keywords will be ignored (since the Msg/TempMsg object already
|
||||
has all the data). If a string, this will either be sent as-is
|
||||
(if persistent=False) or it will be used together with `header`
|
||||
and `senders` keywords to create a Msg instance on the fly.
|
||||
header (str, optional): A header for building the message.
|
||||
senders (Object, Account or list, optional): Optional if persistent=False, used
|
||||
to build senders for the message.
|
||||
sender_strings (list, optional): Name strings of senders. Used for external
|
||||
connections where the sender is not an account or object.
|
||||
When this is defined, external will be assumed. The list will be
|
||||
filtered so each sender-string only occurs once.
|
||||
keep_log (bool or None, optional): This allows to temporarily change the logging status of
|
||||
this channel message. If `None`, the Channel's `keep_log` Attribute will
|
||||
be used. If `True` or `False`, that logging status will be used for this
|
||||
message only (note that for unlogged channels, a `True` value here will
|
||||
create a new log file only for this message).
|
||||
online (bool, optional) - If this is set true, only messages people who are
|
||||
online. Otherwise, messages all accounts connected. This can
|
||||
make things faster, but may not trigger listeners on accounts
|
||||
that are offline.
|
||||
emit (bool, optional) - Signals to the message formatter that this message is
|
||||
not to be directly associated with a name.
|
||||
external (bool, optional): Treat this message as being
|
||||
agnostic of its sender.
|
||||
|
||||
Returns:
|
||||
success (bool): Returns `True` if message sending was
|
||||
successful, `False` otherwise.
|
||||
|
||||
"""
|
||||
senders = make_iter(senders) if senders else []
|
||||
if isinstance(msgobj, str):
|
||||
# given msgobj is a string - convert to msgobject (always TempMsg)
|
||||
msgobj = TempMsg(senders=senders, header=header, message=msgobj, channels=[self])
|
||||
# we store the logging setting for use in distribute_message()
|
||||
msgobj.keep_log = keep_log if keep_log is not None else self.db.keep_log
|
||||
|
||||
# start the sending
|
||||
msgobj = self.pre_send_message(msgobj)
|
||||
if not msgobj:
|
||||
return False
|
||||
if sender_strings:
|
||||
sender_strings = list(set(make_iter(sender_strings)))
|
||||
msgobj = self.message_transform(
|
||||
msgobj, emit=emit, sender_strings=sender_strings, external=external
|
||||
)
|
||||
self.distribute_message(msgobj, online=online)
|
||||
self.post_send_message(msgobj)
|
||||
return True
|
||||
|
||||
def tempmsg(self, message, header=None, senders=None):
|
||||
"""
|
||||
A wrapper for sending non-persistent messages.
|
||||
|
||||
Args:
|
||||
message (str): Message to send.
|
||||
header (str, optional): Header of message to send.
|
||||
senders (Object or list, optional): Senders of message to send.
|
||||
|
||||
"""
|
||||
self.msg(message, senders=senders, header=header, keep_log=False)
|
||||
|
||||
# hooks
|
||||
|
||||
def channel_prefix(self, msg=None, emit=False, **kwargs):
|
||||
def channel_prefix(self):
|
||||
"""
|
||||
Hook method. How the channel should prefix itself for users.
|
||||
|
||||
|
|
@ -465,111 +339,378 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
Returns:
|
||||
prefix (str): The created channel prefix.
|
||||
|
||||
"""
|
||||
return "" if emit else "[%s] " % self.key
|
||||
Notes:
|
||||
This is normally retrieved from the hooks on the receiver.
|
||||
|
||||
def format_senders(self, senders=None, **kwargs):
|
||||
"""
|
||||
Hook method. Function used to format a list of sender names.
|
||||
return self.channel_prefix_string.format(channel_key=self.key)
|
||||
|
||||
def at_pre_msg(self, message, **kwargs):
|
||||
"""
|
||||
Called before the starting of sending the message to a receiver. This
|
||||
is called before any hooks on the receiver itself. If this returns
|
||||
None/False, the sending will be aborted.
|
||||
|
||||
Args:
|
||||
senders (list): Sender object names.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
message (str): The message to send.
|
||||
**kwargs (any): Keywords passed on from `.msg`. This includes
|
||||
`senders`.
|
||||
|
||||
Returns:
|
||||
formatted_list (str): The list of names formatted appropriately.
|
||||
str, False or None: Any custom changes made to the message. If
|
||||
falsy, no message will be sent.
|
||||
|
||||
"""
|
||||
return message
|
||||
|
||||
def msg(self, message, senders=None, bypass_mute=False, **kwargs):
|
||||
"""
|
||||
Send message to channel, causing it to be distributed to all non-muted
|
||||
subscribed users of that channel.
|
||||
|
||||
Args:
|
||||
message (str): The message to send.
|
||||
senders (Object, Account or list, optional): If not given, there is
|
||||
no way to associate one or more senders with the message (like
|
||||
a broadcast message or similar).
|
||||
bypass_mute (bool, optional): If set, always send, regardless of
|
||||
individual mute-state of subscriber. This can be used for
|
||||
global announcements or warnings/alerts.
|
||||
**kwargs (any): This will be passed on to all hooks. Use `no_prefix`
|
||||
to exclude the channel prefix.
|
||||
|
||||
Notes:
|
||||
This function exists separately so that external sources
|
||||
can use it to format source names in the same manner as
|
||||
normal object/account names.
|
||||
The call hook calling sequence is:
|
||||
|
||||
- `msg = channel.at_pre_msg(message, **kwargs)` (aborts for all if return None)
|
||||
- `msg = receiver.at_pre_channel_msg(msg, channel, **kwargs)` (aborts for receiver if return None)
|
||||
- `receiver.at_channel_msg(msg, channel, **kwargs)`
|
||||
- `receiver.at_post_channel_msg(msg, channel, **kwargs)``
|
||||
Called after all receivers are processed:
|
||||
- `channel.at_post_all_msg(message, **kwargs)`
|
||||
|
||||
(where the senders/bypass_mute are embedded into **kwargs for
|
||||
later access in hooks)
|
||||
|
||||
"""
|
||||
if not senders:
|
||||
return ""
|
||||
return ", ".join(senders)
|
||||
|
||||
def pose_transform(self, msgobj, sender_string, **kwargs):
|
||||
"""
|
||||
Hook method. Detects if the sender is posing, and modifies the
|
||||
message accordingly.
|
||||
|
||||
Args:
|
||||
msgobj (Msg or TempMsg): The message to analyze for a pose.
|
||||
sender_string (str): The name of the sender/poser.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
Returns:
|
||||
string (str): A message that combines the `sender_string`
|
||||
component with `msg` in different ways depending on if a
|
||||
pose was performed or not (this must be analyzed by the
|
||||
hook).
|
||||
|
||||
"""
|
||||
pose = False
|
||||
message = msgobj.message
|
||||
message_start = message.lstrip()
|
||||
if message_start.startswith((":", ";")):
|
||||
pose = True
|
||||
message = message[1:]
|
||||
if not message.startswith((":", "'", ",")):
|
||||
if not message.startswith(" "):
|
||||
message = " " + message
|
||||
if pose:
|
||||
return "%s%s" % (sender_string, message)
|
||||
senders = make_iter(senders) if senders else []
|
||||
if self.send_to_online_only:
|
||||
receivers = self.subscriptions.online()
|
||||
else:
|
||||
return "%s: %s" % (sender_string, message)
|
||||
receivers = self.subscriptions.all()
|
||||
if not bypass_mute:
|
||||
receivers = receivers.exclude(id__in=[muted.id for muted in self.mutelist])
|
||||
|
||||
def format_external(self, msgobj, senders, emit=False, **kwargs):
|
||||
send_kwargs = {'senders': senders, 'bypass_mute': bypass_mute, **kwargs}
|
||||
|
||||
# pre-send hook
|
||||
message = self.at_pre_msg(message, **send_kwargs)
|
||||
if message in (None, False):
|
||||
return
|
||||
|
||||
for receiver in receivers:
|
||||
# send to each individual subscriber
|
||||
try:
|
||||
recv_msg = receiver.at_pre_channel_msg(message, self, **send_kwargs)
|
||||
if recv_msg in (None, False):
|
||||
continue
|
||||
receiver.channel_msg(recv_msg, self, **send_kwargs)
|
||||
receiver.at_post_channel_msg(recv_msg, **send_kwargs)
|
||||
|
||||
except Exception:
|
||||
logger.log_trace(f"Cannot send channel message to {receiver}.")
|
||||
|
||||
self.at_post_msg(self, message, **send_kwargs)
|
||||
|
||||
def at_post_msg(self, message, **kwargs):
|
||||
"""
|
||||
Hook method. Used for formatting external messages. This is
|
||||
needed as a separate operation because the senders of external
|
||||
messages may not be in-game objects/accounts, and so cannot
|
||||
have things like custom user preferences.
|
||||
This is called after sending to *all* valid recipients. It is normally
|
||||
used for logging/channel history.
|
||||
|
||||
Args:
|
||||
msgobj (Msg or TempMsg): The message to send.
|
||||
senders (list): Strings, one per sender.
|
||||
emit (bool, optional): A sender-agnostic message or not.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
Returns:
|
||||
transformed (str): A formatted string.
|
||||
message (str): The message sent.
|
||||
**kwargs (any): Keywords passed on from `msg`, including `senders`.
|
||||
|
||||
"""
|
||||
if emit or not senders:
|
||||
return msgobj.message
|
||||
senders = ", ".join(senders)
|
||||
return self.pose_transform(msgobj, senders)
|
||||
# save channel history to log file
|
||||
default_log_file = (self.log_to_file.format(channel_key=self.key)
|
||||
if self.log_to_file else None)
|
||||
log_file = self.attributes.get("log_file", default=default_log_file)
|
||||
if log_file:
|
||||
senders = ",".join(kwargs.get("senders", []))
|
||||
senders = f"{senders}: " if senders else ""
|
||||
message = f"{senders}{message}"
|
||||
logger.log_file(message, log_file)
|
||||
|
||||
def format_message(self, msgobj, emit=False, **kwargs):
|
||||
"""
|
||||
Hook method. Formats a message body for display.
|
||||
# def message_transform(
|
||||
# self, msgobj, emit=False, prefix=True, sender_strings=None, external=False, **kwargs
|
||||
# ):
|
||||
# """
|
||||
# Generates the formatted string sent to listeners on a channel.
|
||||
|
||||
Args:
|
||||
msgobj (Msg or TempMsg): The message object to send.
|
||||
emit (bool, optional): The message is agnostic of senders.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
# Args:
|
||||
# msgobj (Msg): Message object to send.
|
||||
# emit (bool, optional): In emit mode the message is not associated
|
||||
# with a specific sender name.
|
||||
# prefix (bool, optional): Prefix `msg` with a text given by `self.channel_prefix`.
|
||||
# sender_strings (list, optional): Used by bots etc, one string per external sender.
|
||||
# external (bool, optional): If this is an external sender or not.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
Returns:
|
||||
transformed (str): The formatted message.
|
||||
# """
|
||||
# if sender_strings or external:
|
||||
# body = self.format_external(msgobj, sender_strings, emit=emit)
|
||||
# else:
|
||||
# body = self.format_message(msgobj, emit=emit)
|
||||
# if prefix:
|
||||
# body = "%s%s" % (self.channel_prefix(msgobj, emit=emit), body)
|
||||
# msgobj.message = body
|
||||
# return msgobj
|
||||
|
||||
"""
|
||||
# We don't want to count things like external sources as senders for
|
||||
# the purpose of constructing the message string.
|
||||
senders = [sender for sender in msgobj.senders if hasattr(sender, "key")]
|
||||
if not senders:
|
||||
emit = True
|
||||
if emit:
|
||||
return msgobj.message
|
||||
else:
|
||||
senders = [sender.key for sender in msgobj.senders]
|
||||
senders = ", ".join(senders)
|
||||
return self.pose_transform(msgobj, senders)
|
||||
# def distribute_message(self, msgobj, online=False, **kwargs):
|
||||
# """
|
||||
# Method for grabbing all listeners that a message should be
|
||||
# sent to on this channel, and sending them a message.
|
||||
|
||||
# Args:
|
||||
# msgobj (Msg or TempMsg): Message to distribute.
|
||||
# online (bool): Only send to receivers who are actually online
|
||||
# (not currently used):
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Notes:
|
||||
# This is also where logging happens, if enabled.
|
||||
|
||||
# """
|
||||
# # get all accounts or objects connected to this channel and send to them
|
||||
# if online:
|
||||
# subs = self.subscriptions.online()
|
||||
# else:
|
||||
# subs = self.subscriptions.all()
|
||||
# for entity in subs:
|
||||
# # if the entity is muted, we don't send them a message
|
||||
# if entity in self.mutelist:
|
||||
# continue
|
||||
# try:
|
||||
# # note our addition of the from_channel keyword here. This could be checked
|
||||
# # by a custom account.msg() to treat channel-receives differently.
|
||||
# entity.msg(
|
||||
# msgobj.message, from_obj=msgobj.senders, options={"from_channel": self.id}
|
||||
# )
|
||||
# except AttributeError as e:
|
||||
# logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
||||
|
||||
# if msgobj.keep_log:
|
||||
# # log to file
|
||||
# logger.log_file(
|
||||
# msgobj.message, self.attributes.get("log_file") or "channel_%s.log" % self.key
|
||||
# )
|
||||
|
||||
# def msg(
|
||||
# self,
|
||||
# msgobj,
|
||||
# header=None,
|
||||
# senders=None,
|
||||
# sender_strings=None,
|
||||
# keep_log=None,
|
||||
# online=False,
|
||||
# emit=False,
|
||||
# external=False,
|
||||
# ):
|
||||
# """
|
||||
# Send the given message to all accounts connected to channel. Note that
|
||||
# no permission-checking is done here; it is assumed to have been
|
||||
# done before calling this method. The optional keywords are not used if
|
||||
# persistent is False.
|
||||
|
||||
# Args:
|
||||
# msgobj (Msg, TempMsg or str): If a Msg/TempMsg, the remaining
|
||||
# keywords will be ignored (since the Msg/TempMsg object already
|
||||
# has all the data). If a string, this will either be sent as-is
|
||||
# (if persistent=False) or it will be used together with `header`
|
||||
# and `senders` keywords to create a Msg instance on the fly.
|
||||
# header (str, optional): A header for building the message.
|
||||
# senders (Object, Account or list, optional): Optional if persistent=False, used
|
||||
# to build senders for the message.
|
||||
# sender_strings (list, optional): Name strings of senders. Used for external
|
||||
# connections where the sender is not an account or object.
|
||||
# When this is defined, external will be assumed. The list will be
|
||||
# filtered so each sender-string only occurs once.
|
||||
# keep_log (bool or None, optional): This allows to temporarily change the logging status of
|
||||
# this channel message. If `None`, the Channel's `keep_log` Attribute will
|
||||
# be used. If `True` or `False`, that logging status will be used for this
|
||||
# message only (note that for unlogged channels, a `True` value here will
|
||||
# create a new log file only for this message).
|
||||
# online (bool, optional) - If this is set true, only messages people who are
|
||||
# online. Otherwise, messages all accounts connected. This can
|
||||
# make things faster, but may not trigger listeners on accounts
|
||||
# that are offline.
|
||||
# emit (bool, optional) - Signals to the message formatter that this message is
|
||||
# not to be directly associated with a name.
|
||||
# external (bool, optional): Treat this message as being
|
||||
# agnostic of its sender.
|
||||
|
||||
# Returns:
|
||||
# success (bool): Returns `True` if message sending was
|
||||
# successful, `False` otherwise.
|
||||
|
||||
# """
|
||||
# senders = make_iter(senders) if senders else []
|
||||
# if isinstance(msgobj, str):
|
||||
# # given msgobj is a string - convert to msgobject (always TempMsg)
|
||||
# msgobj = TempMsg(senders=senders, header=header, message=msgobj, channels=[self])
|
||||
# # we store the logging setting for use in distribute_message()
|
||||
# msgobj.keep_log = keep_log if keep_log is not None else self.db.keep_log
|
||||
|
||||
# # start the sending
|
||||
# msgobj = self.pre_send_message(msgobj)
|
||||
|
||||
# if not msgobj:
|
||||
# return False
|
||||
# if sender_strings:
|
||||
# sender_strings = list(set(make_iter(sender_strings)))
|
||||
# msgobj = self.message_transform(
|
||||
# msgobj, emit=emit, sender_strings=sender_strings, external=external
|
||||
# )
|
||||
# self.distribute_message(msgobj, online=online)
|
||||
# self.post_send_message(msgobj)
|
||||
# return True
|
||||
|
||||
# def tempmsg(self, message, header=None, senders=None):
|
||||
# """
|
||||
# A wrapper for sending non-persistent messages.
|
||||
|
||||
# Args:
|
||||
# message (str): Message to send.
|
||||
# header (str, optional): Header of message to send.
|
||||
# senders (Object or list, optional): Senders of message to send.
|
||||
|
||||
# """
|
||||
# self.msg(message, senders=senders, header=header, keep_log=False)
|
||||
|
||||
# # hooks
|
||||
|
||||
# def channel_prefix(self, msg=None, emit=False, **kwargs):
|
||||
# """
|
||||
# Hook method. How the channel should prefix itself for users.
|
||||
|
||||
# Args:
|
||||
# msg (str, optional): Prefix text
|
||||
# emit (bool, optional): Switches to emit mode, which usually
|
||||
# means to not prefix the channel's info.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Returns:
|
||||
# prefix (str): The created channel prefix.
|
||||
|
||||
# """
|
||||
# return "" if emit else "[%s] " % self.key
|
||||
|
||||
# def format_senders(self, senders=None, **kwargs):
|
||||
# """
|
||||
# Hook method. Function used to format a list of sender names.
|
||||
|
||||
# Args:
|
||||
# senders (list): Sender object names.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Returns:
|
||||
# formatted_list (str): The list of names formatted appropriately.
|
||||
|
||||
# Notes:
|
||||
# This function exists separately so that external sources
|
||||
# can use it to format source names in the same manner as
|
||||
# normal object/account names.
|
||||
|
||||
# """
|
||||
# if not senders:
|
||||
# return ""
|
||||
# return ", ".join(senders)
|
||||
|
||||
# def pose_transform(self, msgobj, sender_string, **kwargs):
|
||||
# """
|
||||
# Hook method. Detects if the sender is posing, and modifies the
|
||||
# message accordingly.
|
||||
|
||||
# Args:
|
||||
# msgobj (Msg or TempMsg): The message to analyze for a pose.
|
||||
# sender_string (str): The name of the sender/poser.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Returns:
|
||||
# string (str): A message that combines the `sender_string`
|
||||
# component with `msg` in different ways depending on if a
|
||||
# pose was performed or not (this must be analyzed by the
|
||||
# hook).
|
||||
|
||||
# """
|
||||
# pose = False
|
||||
# message = msgobj.message
|
||||
# message_start = message.lstrip()
|
||||
# if message_start.startswith((":", ";")):
|
||||
# pose = True
|
||||
# message = message[1:]
|
||||
# if not message.startswith((":", "'", ",")):
|
||||
# if not message.startswith(" "):
|
||||
# message = " " + message
|
||||
# if pose:
|
||||
# return "%s%s" % (sender_string, message)
|
||||
# else:
|
||||
# return "%s: %s" % (sender_string, message)
|
||||
|
||||
# def format_external(self, msgobj, senders, emit=False, **kwargs):
|
||||
# """
|
||||
# Hook method. Used for formatting external messages. This is
|
||||
# needed as a separate operation because the senders of external
|
||||
# messages may not be in-game objects/accounts, and so cannot
|
||||
# have things like custom user preferences.
|
||||
|
||||
# Args:
|
||||
# msgobj (Msg or TempMsg): The message to send.
|
||||
# senders (list): Strings, one per sender.
|
||||
# emit (bool, optional): A sender-agnostic message or not.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Returns:
|
||||
# transformed (str): A formatted string.
|
||||
|
||||
# """
|
||||
# if emit or not senders:
|
||||
# return msgobj.message
|
||||
# senders = ", ".join(senders)
|
||||
# return self.pose_transform(msgobj, senders)
|
||||
|
||||
# def format_message(self, msgobj, emit=False, **kwargs):
|
||||
# """
|
||||
# Hook method. Formats a message body for display.
|
||||
|
||||
# Args:
|
||||
# msgobj (Msg or TempMsg): The message object to send.
|
||||
# emit (bool, optional): The message is agnostic of senders.
|
||||
# **kwargs (dict): Arbitrary, optional arguments for users
|
||||
# overriding the call (unused by default).
|
||||
|
||||
# Returns:
|
||||
# transformed (str): The formatted message.
|
||||
|
||||
# """
|
||||
# # We don't want to count things like external sources as senders for
|
||||
# # the purpose of constructing the message string.
|
||||
# senders = [sender for sender in msgobj.senders if hasattr(sender, "key")]
|
||||
# if not senders:
|
||||
# emit = True
|
||||
# if emit:
|
||||
# return msgobj.message
|
||||
# else:
|
||||
# senders = [sender.key for sender in msgobj.senders]
|
||||
# senders = ", ".join(senders)
|
||||
# return self.pose_transform(msgobj, senders)
|
||||
|
||||
def pre_join_channel(self, joiner, **kwargs):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue