mirror of
https://github.com/evennia/evennia.git
synced 2026-04-01 05:27:17 +02:00
Add working unit tests for new channel command
This commit is contained in:
parent
e8e60d48d5
commit
2021f8ca15
7 changed files with 309 additions and 134 deletions
|
|
@ -304,18 +304,18 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
"""
|
||||
try:
|
||||
|
||||
@inlineCallbacks
|
||||
def _get_channel_cmdset(account_or_obj):
|
||||
"""
|
||||
Helper-method; Get channel-cmdsets
|
||||
"""
|
||||
# Create cmdset for all account's available channels
|
||||
try:
|
||||
channel_cmdset = yield CHANNELHANDLER.get_cmdset(account_or_obj)
|
||||
returnValue([channel_cmdset])
|
||||
except Exception:
|
||||
_msg_err(caller, _ERROR_CMDSETS)
|
||||
raise ErrorReported(raw_string)
|
||||
# @inlineCallbacks
|
||||
# def _get_channel_cmdset(account_or_obj):
|
||||
# """
|
||||
# Helper-method; Get channel-cmdsets
|
||||
# """
|
||||
# # Create cmdset for all account's available channels
|
||||
# try:
|
||||
# channel_cmdset = yield CHANNELHANDLER.get_cmdset(account_or_obj)
|
||||
# returnValue([channel_cmdset])
|
||||
# except Exception:
|
||||
# _msg_err(caller, _ERROR_CMDSETS)
|
||||
# raise ErrorReported(raw_string)
|
||||
|
||||
@inlineCallbacks
|
||||
def _get_local_obj_cmdsets(obj):
|
||||
|
|
@ -406,13 +406,13 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
||||
]
|
||||
cmdsets += local_obj_cmdsets
|
||||
if not current.no_channels:
|
||||
# also objs may have channels
|
||||
channel_cmdsets = yield _get_channel_cmdset(obj)
|
||||
cmdsets += channel_cmdsets
|
||||
if not current.no_channels:
|
||||
channel_cmdsets = yield _get_channel_cmdset(account)
|
||||
cmdsets += channel_cmdsets
|
||||
# if not current.no_channels:
|
||||
# # also objs may have channels
|
||||
# channel_cmdsets = yield _get_channel_cmdset(obj)
|
||||
# cmdsets += channel_cmdsets
|
||||
# if not current.no_channels:
|
||||
# channel_cmdsets = yield _get_channel_cmdset(account)
|
||||
# cmdsets += channel_cmdsets
|
||||
|
||||
elif callertype == "account":
|
||||
# we are calling the command from the account level
|
||||
|
|
@ -430,11 +430,11 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
||||
]
|
||||
cmdsets += local_obj_cmdsets
|
||||
if not current.no_channels:
|
||||
# also objs may have channels
|
||||
cmdsets += yield _get_channel_cmdset(obj)
|
||||
if not current.no_channels:
|
||||
cmdsets += yield _get_channel_cmdset(account)
|
||||
# if not current.no_channels:
|
||||
# # also objs may have channels
|
||||
# cmdsets += yield _get_channel_cmdset(obj)
|
||||
# if not current.no_channels:
|
||||
# cmdsets += yield _get_channel_cmdset(account)
|
||||
|
||||
elif callertype == "object":
|
||||
# we are calling the command from the object level
|
||||
|
|
@ -448,9 +448,9 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
cmdset for cmdset in local_obj_cmdsets if cmdset.key != "ExitCmdSet"
|
||||
]
|
||||
cmdsets += yield local_obj_cmdsets
|
||||
if not current.no_channels:
|
||||
# also objs may have channels
|
||||
cmdsets += yield _get_channel_cmdset(obj)
|
||||
# if not current.no_channels:
|
||||
# # also objs may have channels
|
||||
# cmdsets += yield _get_channel_cmdset(obj)
|
||||
else:
|
||||
raise Exception("get_and_merge_cmdsets: callertype %s is not valid." % callertype)
|
||||
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ class AccountCmdSet(CmdSet):
|
|||
|
||||
# Comm commands
|
||||
self.add(comms.CmdChannel())
|
||||
# self.add(comms.CmdChannels())
|
||||
self.add(comms.CmdAddCom())
|
||||
self.add(comms.CmdDelCom())
|
||||
self.add(comms.CmdAllCom())
|
||||
self.add(comms.CmdChannels())
|
||||
self.add(comms.CmdCdestroy())
|
||||
self.add(comms.CmdChannelCreate())
|
||||
self.add(comms.CmdClock())
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ __all__ = (
|
|||
"CmdAddCom",
|
||||
"CmdDelCom",
|
||||
"CmdAllCom",
|
||||
#"CmdChannels",
|
||||
"CmdChannels",
|
||||
"CmdCdestroy",
|
||||
"CmdCBoot",
|
||||
"CmdCemit",
|
||||
|
|
@ -60,10 +60,10 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
channel/list
|
||||
channel/all
|
||||
channel/history channelname [= index]
|
||||
channel/sub channelname [= alias]
|
||||
channel/sub channelname [= alias[;alias...]]
|
||||
channel/unsub channelname[,channelname, ...]
|
||||
channel/alias channelname = alias
|
||||
channel/unalias channelname = alias
|
||||
channel/alias channelname = alias[;alias...]
|
||||
channel/unalias alias
|
||||
channel/mute channelname[,channelname,...]
|
||||
channel/unmute channelname[,channelname,...]
|
||||
channel/create channelname;alias;alias:typeclass [= description]
|
||||
|
|
@ -87,6 +87,10 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
"list", "all", "history", "sub", "unsub", "mute", "unmute", "alias", "unalias",
|
||||
"create", "destroy", "desc", "lock", "unlock", "boot", "ban", "unban", "who",)
|
||||
|
||||
# note - changing this will invalidate existing aliases in db
|
||||
channel_msg_nick_alias = "{alias} $1"
|
||||
channel_msg_nick_replacement = "channel {channelname} = $1"
|
||||
|
||||
def search_channel(self, channelname, exact=False):
|
||||
"""
|
||||
Helper function for searching for a single channel with some error
|
||||
|
|
@ -181,6 +185,11 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
if channel.has_connection(caller):
|
||||
return False, f"Already listening to channel {channel.key}."
|
||||
result = channel.connect(caller)
|
||||
|
||||
key_and_aliases = [channel.key.lower()] + [alias.lower() for alias in channel.aliases.all()]
|
||||
for key_or_alias in key_and_aliases:
|
||||
self.add_alias(channel, key_or_alias)
|
||||
|
||||
return result, "" if result else f"Were not allowed to subscribe to channel {channel.key}"
|
||||
|
||||
def unsub_from_channel(self, channel):
|
||||
|
|
@ -201,46 +210,87 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
if not channel.has_connection(caller):
|
||||
return False, f"Not listening to channel {channel.key}."
|
||||
# clear nicks
|
||||
chkey = channel.key
|
||||
for nick in [
|
||||
nick
|
||||
for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
|
||||
if nick and nick.pk and nick.value[3].lower() == chkey
|
||||
]:
|
||||
nick.delete()
|
||||
for key_or_alias in self.get_channel_aliases(channel):
|
||||
self.remove_alias(key_or_alias)
|
||||
result = channel.disconnect(caller)
|
||||
return result, "" if result else f"Could not unsubscribe from channel {channel.key}"
|
||||
|
||||
def add_alias(self, channel, alias):
|
||||
def add_alias(self, channel, alias, **kwargs):
|
||||
"""
|
||||
Add a new alias for the user to use with this channel.
|
||||
Add a new alias (nick) for the user to use with this channel.
|
||||
|
||||
Args:
|
||||
channel (Channel): The channel to alias.
|
||||
alias (str): The personal alias to use for this channel.
|
||||
**kwargs: If given, passed into nicks.add.
|
||||
|
||||
Note:
|
||||
We add two nicks - one is a plain `alias -> channel.key` that
|
||||
we need to be able to reference this channel easily. The other
|
||||
is a templated nick to easily be able to send messages to the
|
||||
channel without needing to give the full `channel` command. The
|
||||
structure of this nick is given by `self.channel_msg_nick_alias`
|
||||
and `self.channel_msg_nick_replacement`. By default it maps
|
||||
`alias <msg> -> channel <channelname> = <msg>`, so that you can
|
||||
for example just write `pub Hello` to send a message.
|
||||
|
||||
The alias created is `alias $1 -> channel channel = $1`, to allow
|
||||
for sending to channel using the main channel command.
|
||||
|
||||
"""
|
||||
self.caller.nicks.add(alias, channel.key, category="channel")
|
||||
chan_key = channel.key.lower()
|
||||
msg_alias = self.channel_msg_nick_alias.format(alias=alias)
|
||||
msg_replacement = self.channel_msg_nick_replacement.format(channelname=chan_key)
|
||||
|
||||
def remove_alias(self, alias):
|
||||
if chan_key != alias:
|
||||
self.caller.nicks.add(alias, chan_key, category="channel", **kwargs)
|
||||
self.caller.nicks.add(msg_alias, msg_replacement, category="channel", **kwargs)
|
||||
|
||||
def remove_alias(self, alias, **kwargs):
|
||||
"""
|
||||
Remove an alias from a given channel.
|
||||
Remove an alias from a channel.
|
||||
|
||||
Args:
|
||||
alias (str, optional): The alias to remove, or `None` for all.
|
||||
alias (str, optional): The alias to remove.
|
||||
The channel will be reverse-determined from the
|
||||
alias, if it exists.
|
||||
|
||||
Returns:
|
||||
bool, str: True, None if removal succeeded. If False,
|
||||
the second part is an error string.
|
||||
**kwargs: If given, passed into nicks.get/add.
|
||||
|
||||
Note:
|
||||
This will remove two nicks - the plain channel alias and the templated
|
||||
nick used for easily sending messages to the channel.
|
||||
|
||||
"""
|
||||
caller = self.caller
|
||||
channame = caller.nicks.get(key=alias, category="channel")
|
||||
if channame:
|
||||
caller.nicks.remove(key=alias, category="channel")
|
||||
if caller.nicks.get(alias, category="channel", **kwargs):
|
||||
msg_alias = self.channel_msg_nick_alias.format(alias=alias)
|
||||
caller.nicks.remove(alias, category="channel", **kwargs)
|
||||
caller.nicks.remove(msg_alias, category="channel", **kwargs)
|
||||
return True, ""
|
||||
return False, "No such alias was defined."
|
||||
|
||||
def get_channel_aliases(self, channel):
|
||||
"""
|
||||
Get a user's aliases for a given channel. The user is retrieved
|
||||
through self.caller.
|
||||
|
||||
Args:
|
||||
channel (Channel): The channel to act on.
|
||||
|
||||
Returns:
|
||||
list: A list of zero, one or more alias-strings.
|
||||
|
||||
"""
|
||||
chan_key = channel.key.lower()
|
||||
nicktuples = self.caller.nicks.get(category="channel", return_tuple=True)
|
||||
if nicktuples:
|
||||
return [tup[2] for tup in nicktuples if tup[3].lower() == chan_key]
|
||||
return []
|
||||
|
||||
def mute_channel(self, channel):
|
||||
"""
|
||||
Temporarily mute a channel.
|
||||
|
|
@ -419,12 +469,13 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
nick.delete()
|
||||
channel.disconnect(target)
|
||||
reason = f" Reason: {reason}" if reason else ""
|
||||
target.msg(f"You were booted from channel {channel.key} by {caller.key}.{reason}")
|
||||
target.msg(f"You were booted from channel {channel.key} by {self.caller.key}.{reason}")
|
||||
if not quiet:
|
||||
channel.msg(f"{target.key} was booted from channel by {caller.key}.{reason}")
|
||||
channel.msg(f"{target.key} was booted from channel by {self.caller.key}.{reason}")
|
||||
|
||||
logger.log_sec(f"Channel Boot: {target} (Channel: {channel}, "
|
||||
f"Reason: {reason}, Caller: {caller}")
|
||||
f"Reason: {reason.strip()}, Caller: {self.caller}")
|
||||
return True, ""
|
||||
|
||||
def ban_user(self, channel, target, quiet=False, reason=""):
|
||||
"""
|
||||
|
|
@ -442,7 +493,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
the second part is an error string.
|
||||
|
||||
"""
|
||||
boot_user(self.caller, channel, target, quiet=quiet, reason=reason)
|
||||
self.boot_user(channel, target, quiet=quiet, reason=reason)
|
||||
if channel.ban(target):
|
||||
return True, ""
|
||||
return False, f"{target} is already banned from this channel."
|
||||
|
|
@ -508,6 +559,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
name = subscriber.get_display_name(caller)
|
||||
conditions = ("muted" if subscriber in mute_list else "",
|
||||
"offline" if subscriber not in online_list else "")
|
||||
conditions = (cond for cond in conditions if cond)
|
||||
cond_text = "(" + ", ".join(conditions) + ")" if conditions else ""
|
||||
who_list.append(f"{name}{cond_text}")
|
||||
|
||||
|
|
@ -547,8 +599,6 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
EvTable: Table to display.
|
||||
|
||||
"""
|
||||
caller = self.caller
|
||||
|
||||
comtable = self.styled_table(
|
||||
"|wchannel|n",
|
||||
"|wmy aliases|n",
|
||||
|
|
@ -558,14 +608,12 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
)
|
||||
|
||||
for chan in subscribed:
|
||||
clower = chan.key.lower()
|
||||
nicks = caller.nicks.get(category="channel", return_obj=True)
|
||||
my_aliases = ", ".join(self.get_channel_aliases(chan))
|
||||
comtable.add_row(
|
||||
*("{}{}".format(
|
||||
chan.key,
|
||||
"({})".format(",".join(chan.aliases.all())) if chan.aliases.all() else ""),
|
||||
",".join(nick.db_key for nick in make_iter(nicks)
|
||||
if nick and nick.value[3].lower() == clower),
|
||||
chan.key,
|
||||
"({})".format(",".join(chan.aliases.all())) if chan.aliases.all() else ""),
|
||||
my_aliases,
|
||||
chan.db.desc))
|
||||
return comtable
|
||||
|
||||
|
|
@ -593,9 +641,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
channels = subscribed + available
|
||||
|
||||
for chan in channels:
|
||||
clower = chan.key.lower()
|
||||
nicks = caller.nicks.get(category="channel", return_obj=True)
|
||||
nicks = nicks or []
|
||||
my_aliases = ", ".join(self.get_channel_aliases(chan))
|
||||
if chan not in subscribed:
|
||||
substatus = "|rNo|n"
|
||||
elif caller in chan.mutelist:
|
||||
|
|
@ -607,8 +653,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
"{}{}".format(
|
||||
chan.key,
|
||||
"({})".format(",".join(chan.aliases.all())) if chan.aliases.all() else ""),
|
||||
",".join(nick.db_key for nick in make_iter(nicks)
|
||||
if nick.value[3].lower() == clower),
|
||||
my_aliases,
|
||||
str(chan.locks),
|
||||
chan.db.desc))
|
||||
comtable.reformat_column(0, width=9)
|
||||
|
|
@ -666,6 +711,20 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
self.msg(err)
|
||||
return
|
||||
|
||||
if 'unalias' in switches:
|
||||
# remove a personal alias (no channel needed)
|
||||
alias = self.rhs
|
||||
if not alias:
|
||||
self.msg("Specify the alias to remove as channel/unalias <alias>")
|
||||
return
|
||||
success, err = self.remove_alias(alias)
|
||||
if success:
|
||||
self.msg(f"Removed your channel alias '{alias}'.")
|
||||
else:
|
||||
self.msg(err)
|
||||
return
|
||||
|
||||
|
||||
channels = []
|
||||
for channel_name in channel_names:
|
||||
# find a channel by fuzzy-matching. This also checks
|
||||
|
|
@ -691,7 +750,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
# inspect a given channel
|
||||
subscribed, available = self.list_channels()
|
||||
if channel in subscribed:
|
||||
table = self.display_subbed_channels[channel]
|
||||
table = self.display_subbed_channels([channel])
|
||||
self.msg(
|
||||
"\n|wSubscribed to Channel|n "
|
||||
f"(use |w/all|n to see all available)\n{table}")
|
||||
|
|
@ -717,11 +776,16 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'sub' in switches:
|
||||
# subscribe to a channel
|
||||
aliases = set(alias.strip().lower() for alias in self.rhs.split(";"))
|
||||
success, err = self.sub_to_channel(channel)
|
||||
if success:
|
||||
for alias in aliases:
|
||||
self.add_alias(channel, alias)
|
||||
alias_txt = ', '.join(aliases)
|
||||
alias_txt = f" using alias(es) {alias_txt}" if aliases else ''
|
||||
self.msg("You are now subscribed "
|
||||
f"to the channel {channel.key}. Use /alias to "
|
||||
"be able to use different names to refer to the channel.")
|
||||
f"to the channel {channel.key}{alias_txt}. Use /alias to "
|
||||
"add additional aliases for referring to the channel.")
|
||||
else:
|
||||
self.msg(err)
|
||||
return
|
||||
|
|
@ -746,19 +810,6 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
self.msg(f"Added/updated your alias '{alias}' for channel {channel.key}.")
|
||||
return
|
||||
|
||||
if 'unalias' in switches:
|
||||
# remove a personal alias for a channel
|
||||
alias = self.rhs
|
||||
if not alias:
|
||||
self.msg("Specify the alias to remove as channel/unalias channelname = alias")
|
||||
return
|
||||
success, err = self.remove_alias(channel, alias)
|
||||
if success:
|
||||
self.msg(f"Removed your alias '{alias}' for channel {channel.key}")
|
||||
else:
|
||||
self.msg(err)
|
||||
return
|
||||
|
||||
if 'mute' in switches:
|
||||
# mute a given channel
|
||||
success, err = self.mute_channel(channel)
|
||||
|
|
@ -798,18 +849,33 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
"Aborted."
|
||||
)
|
||||
|
||||
if 'desc' in switches:
|
||||
# set channel description
|
||||
desc = self.rhs.strip()
|
||||
|
||||
if not channel.access(caller, "control"):
|
||||
self.msg("You can only change description of channels you control.")
|
||||
return
|
||||
|
||||
if not desc:
|
||||
self.msg("Usage: /desc channel = description")
|
||||
return
|
||||
|
||||
self.set_desc(channel, desc)
|
||||
self.msg("Updated channel description.")
|
||||
|
||||
if 'lock' in switches:
|
||||
# add a lockstring to channel
|
||||
lockstring = self.rhs.strip()
|
||||
|
||||
if not lockstring:
|
||||
self.msg("Usage: channel/lock channelname = lockstring")
|
||||
return
|
||||
|
||||
if not channel.access(caller, "control"):
|
||||
self.msg("You need 'control'-access to change locks on this channel.")
|
||||
return
|
||||
|
||||
if not lockstring:
|
||||
self.msg("Usage: channel/lock channelname = lockstring")
|
||||
return
|
||||
|
||||
success, err = self.set_lock(channel, self.rhs)
|
||||
if success:
|
||||
caller.msg("Added/updated lock on channel.")
|
||||
|
|
@ -829,9 +895,9 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("You need 'control'-access to change locks on this channel.")
|
||||
return
|
||||
|
||||
success, err = self.set_lock(channel, self.rhs)
|
||||
success, err = self.unset_lock(channel, self.rhs)
|
||||
if success:
|
||||
caller.msg("Removed lock on channel.")
|
||||
caller.msg("Removed lock from channel.")
|
||||
else:
|
||||
caller.msg(f"Could not remove lock: {err}")
|
||||
return
|
||||
|
|
@ -848,12 +914,12 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
for chan in channels:
|
||||
|
||||
if not chan.access(caller, "admin"):
|
||||
self.msg("You need 'control'-access to boot a user from {chan.key}.")
|
||||
if not chan.access(caller, "control"):
|
||||
self.msg(f"You need 'control'-access to boot a user from {chan.key}.")
|
||||
return
|
||||
|
||||
# the target must be a member of all given channels
|
||||
target = self.search(target_str, candidates=chan.subscriptions.all())
|
||||
target = caller.search(target_str, candidates=chan.subscriptions.all())
|
||||
if not target:
|
||||
caller.msg(f"Cannot boot '{target_str}' - not in channel {chan.key}.")
|
||||
return
|
||||
|
|
@ -867,10 +933,12 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(f"Cannot boot {target.key} from channel {chan.key}: {err}")
|
||||
|
||||
channames = ", ".join(chan.key for chan in channels)
|
||||
reasonwarn = (". Also note that your reason will be echoed to the channel"
|
||||
if reason else '')
|
||||
ask_yes_no(
|
||||
caller,
|
||||
f"Are you sure you want to boot user {target.key} from "
|
||||
f"channel(s) {channames} (make sure name/channels are correct) "
|
||||
f"channel(s) {channames} (make sure name/channels are correct{reasonwarn}). "
|
||||
"{yesno}?",
|
||||
_boot_user,
|
||||
"Aborted.",
|
||||
|
|
@ -885,7 +953,7 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
# view bans for channels
|
||||
|
||||
if not channel.access(caller, "control"):
|
||||
self.msg("You need 'control'-access to view bans on channel {channel.key}")
|
||||
self.msg(f"You need 'control'-access to view bans on channel {channel.key}")
|
||||
return
|
||||
|
||||
bans = ["Channel bans "
|
||||
|
|
@ -899,7 +967,12 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
for chan in channels:
|
||||
# the target must be a member of all given channels
|
||||
target = self.search(target_str, candidates=chan.subscriptions.all())
|
||||
if not chan.access(caller, "control"):
|
||||
caller.msg(f"You don't have access to ban users on channel {chan.key}")
|
||||
return
|
||||
|
||||
target = caller.search(target_str, candidates=chan.subscriptions.all())
|
||||
|
||||
if not target:
|
||||
caller.msg(f"Cannot ban '{target_str}' - not in channel {chan.key}.")
|
||||
return
|
||||
|
|
@ -908,26 +981,57 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
for chan in channels:
|
||||
success, err = self.ban_user(chan, target, quiet=False, reason=reason)
|
||||
if success:
|
||||
caller.msg(f"Banned {target.key} from channel {chan.key}.")
|
||||
self.msg(f"Banned {target.key} from channel {chan.key}.")
|
||||
else:
|
||||
caller.msg(f"Cannot boot {target.key} from channel {chan.key}: {err}")
|
||||
self.msg(f"Cannot boot {target.key} from channel {chan.key}: {err}")
|
||||
|
||||
channames = ", ".join(chan.key for chan in channels)
|
||||
reasonwarn = (". Also note that your reason will be echoed to the channel"
|
||||
if reason else '')
|
||||
ask_yes_no(
|
||||
caller,
|
||||
f"Are you sure you want to ban user {target.key} from "
|
||||
f"channel(s) {channames} (make sure name/channels are correct) "
|
||||
f"channel(s) {channames} (make sure name/channels are correct{reasonwarn}) "
|
||||
"{yesno}?",
|
||||
_ban_user,
|
||||
"Aborted.",
|
||||
)
|
||||
return
|
||||
|
||||
if 'unban' in switches:
|
||||
# unban a previously banned user from channel
|
||||
target_str = self.rhs.strip()
|
||||
|
||||
if not target_str:
|
||||
self.msg("Usage: channel[,channel,...] = user")
|
||||
return
|
||||
|
||||
banlists = []
|
||||
for chan in channels:
|
||||
# the target must be a member of all given channels
|
||||
if not chan.access(caller, "control"):
|
||||
caller.msg(f"You don't have access to unban users on channel {chan.key}")
|
||||
return
|
||||
banlists.extend(chan.banlist)
|
||||
|
||||
target = caller.search(target_str, candidates=banlists)
|
||||
if not target:
|
||||
self.msg("Could not find a banned user '{target_str}' in given channel(s).")
|
||||
return
|
||||
|
||||
for chan in channels:
|
||||
success, err = self.unban_user(channel, target)
|
||||
if success:
|
||||
self.msg(f"Un-banned {target_str} from channel {chan.key}")
|
||||
else:
|
||||
self.msg(err)
|
||||
return
|
||||
|
||||
if "who" in switches:
|
||||
# view who's a member of a channel
|
||||
|
||||
who_list = [f"Subscribed to {channel.key}:"]
|
||||
who_list.expand(self.channel_list_who(channel))
|
||||
who_list.extend(self.channel_list_who(channel))
|
||||
caller.msg("\n".join(who_list))
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -247,6 +247,12 @@ class CommandTest(EvenniaTest):
|
|||
except InterruptCommand:
|
||||
pass
|
||||
|
||||
for inp in inputs:
|
||||
# if there are any inputs left, we may have a non-generator
|
||||
# input to handle (get_input/ask_yes_no that uses a separate
|
||||
# cmdset rather than a yield
|
||||
caller.execute_cmd(inp)
|
||||
|
||||
# At this point the mocked .msg methods on each receiver will have
|
||||
# stored all calls made to them (that's a basic function of the Mock
|
||||
# class). We will not extract them and compare to what we expected to
|
||||
|
|
@ -1662,14 +1668,15 @@ class TestCommsChannel(CommandTest):
|
|||
self.channel.connect(self.char1)
|
||||
|
||||
def tearDown(self):
|
||||
self.channel.delete()
|
||||
if self.channel.pk:
|
||||
self.channel.delete()
|
||||
|
||||
# test channel command
|
||||
def test_channel__noarg(self):
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"",
|
||||
"Usage"
|
||||
"Channel subscriptions"
|
||||
)
|
||||
|
||||
def test_channel__msg(self):
|
||||
|
|
@ -1712,7 +1719,10 @@ class TestCommsChannel(CommandTest):
|
|||
"/sub testchannel",
|
||||
"You are now subscribed"
|
||||
)
|
||||
self.assertTrue(self.char1 in self.channel.subscriptions)
|
||||
self.assertTrue(self.char1 in self.channel.subscriptions.all())
|
||||
alias_msg = comms.CmdChannel.channel_msg_nick_alias.format(alias='testchannel')
|
||||
self.assertEqual(self.char1.nicks.get(alias_msg, category="channel"),
|
||||
"channel testchannel = $1")
|
||||
|
||||
def test_channel__unsub(self):
|
||||
self.call(
|
||||
|
|
@ -1720,32 +1730,40 @@ class TestCommsChannel(CommandTest):
|
|||
"/unsub testchannel",
|
||||
"You un-subscribed"
|
||||
)
|
||||
self.assertFalse(self.char1 in self.channel.subscriptions)
|
||||
self.assertFalse(self.char1 in self.channel.subscriptions.all())
|
||||
|
||||
def test_channel__alias(self):
|
||||
def test_channel__alias__unalias(self):
|
||||
"""Add and then remove a channel alias"""
|
||||
# add alias
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/alias testchannel = foo",
|
||||
""
|
||||
"Added/updated your alias 'foo' for channel testchannel."
|
||||
)
|
||||
self.assertEqual(self.chan1.aliases.get('foo'), "")
|
||||
self.assertEqual(
|
||||
self.char1.nicks.get('foo $1', category="channel"), "channel testchannel = $1")
|
||||
|
||||
def test_channel__unalias(self):
|
||||
|
||||
self.chan1.aliases.add("foo", "", "channel")
|
||||
# use alias
|
||||
self.channel.msg = Mock()
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"foo = test message",
|
||||
"")
|
||||
self.channel.msg.assert_called_with("test message", senders=self.char1)
|
||||
|
||||
# remove alias
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/unalias testchannel = foo",
|
||||
""
|
||||
"Removed your channel alias 'foo'"
|
||||
)
|
||||
self.assertEqual(self.chan1.aliases.get('foo'), None)
|
||||
self.assertEqual(self.char1.nicks.get('foo $1', category="channel"), None)
|
||||
|
||||
def test_channel__mute(self):
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/mute testchannel",
|
||||
""
|
||||
"Muted channel testchannel"
|
||||
)
|
||||
self.assertTrue(self.char1 in self.channel.mutelist)
|
||||
|
||||
|
|
@ -1755,7 +1773,7 @@ class TestCommsChannel(CommandTest):
|
|||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/unmute testchannel = Char1",
|
||||
""
|
||||
"Un-muted channel testchannel"
|
||||
)
|
||||
self.assertFalse(self.char1 in self.channel.mutelist)
|
||||
|
||||
|
|
@ -1763,51 +1781,96 @@ class TestCommsChannel(CommandTest):
|
|||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/create testchannel2",
|
||||
""
|
||||
"Created (and joined) new channel"
|
||||
)
|
||||
|
||||
def test_channel__destroy(self):
|
||||
self.channel.msg = Mock()
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/create testchannel2",
|
||||
""
|
||||
"/destroy testchannel = delete reason",
|
||||
"Are you sure you want to delete channel ",
|
||||
inputs=['Yes']
|
||||
)
|
||||
self.channel.msg.assert_called_with(
|
||||
"delete reason", bypass_mute=True, senders=self.char1)
|
||||
|
||||
def test_channel__desc(self):
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/desc testchannel = Another description",
|
||||
""
|
||||
"Updated channel description."
|
||||
)
|
||||
|
||||
def test_channel__lock(self):
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/lock testchannel = foo:bar()",
|
||||
""
|
||||
"/lock testchannel = foo:false()",
|
||||
"Added/updated lock on channel"
|
||||
)
|
||||
self.assertEqual(self.channel.locks.all(), [])
|
||||
self.assertEqual(self.channel.locks.get('foo'), 'foo:false()')
|
||||
|
||||
def test_channel__unlock(self):
|
||||
self.channel.locks.add("foo:bar()")
|
||||
self.channel.locks.add("foo:true()")
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/unlock testchannel = foo:bar()",
|
||||
""
|
||||
"/unlock testchannel = foo",
|
||||
"Removed lock from channel"
|
||||
)
|
||||
self.assertEqual(self.channel.locks.all(), [])
|
||||
self.assertEqual(self.channel.locks.get('foo'), '')
|
||||
|
||||
def test_channel__boot(self):
|
||||
pass
|
||||
self.channel.connect(self.char2)
|
||||
self.assertTrue(self.char2 in self.channel.subscriptions.all())
|
||||
self.channel.msg = Mock()
|
||||
self.char2.msg = Mock()
|
||||
|
||||
def test_channel__ban(self):
|
||||
pass
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/boot testchannel = Char2 : Booting from channel!",
|
||||
"Are you sure ",
|
||||
inputs=["Yes"]
|
||||
)
|
||||
self.channel.msg.assert_called_with(
|
||||
"Char2 was booted from channel by Char. Reason: Booting from channel!")
|
||||
self.char2.msg.assert_called_with(
|
||||
"You were booted from channel testchannel by Char. Reason: Booting from channel!")
|
||||
|
||||
def test_channel__ban__unban(self):
|
||||
"""Test first ban and then unban"""
|
||||
|
||||
# ban
|
||||
self.channel.connect(self.char2)
|
||||
self.assertTrue(self.char2 in self.channel.subscriptions.all())
|
||||
self.channel.msg = Mock()
|
||||
self.char2.msg = Mock()
|
||||
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/ban testchannel = Char2 : Banning from channel!",
|
||||
"Are you sure ",
|
||||
inputs=["Yes"]
|
||||
)
|
||||
self.channel.msg.assert_called_with(
|
||||
"Char2 was booted from channel by Char. Reason: Banning from channel!")
|
||||
self.char2.msg.assert_called_with(
|
||||
"You were booted from channel testchannel by Char. Reason: Banning from channel!")
|
||||
self.assertTrue(self.char2 in self.channel.banlist)
|
||||
|
||||
# unban
|
||||
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/unban testchannel = Char2",
|
||||
"Un-banned Char2 from channel testchannel"
|
||||
)
|
||||
self.assertFalse(self.char2 in self.channel.banlist)
|
||||
|
||||
def test_channel__who(self):
|
||||
self.call(
|
||||
comms.CmdChannel(),
|
||||
"/who testchannel",
|
||||
""
|
||||
"Subscribed to testchannel:\nChar"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
banlist = self.banlist
|
||||
if target not in banlist:
|
||||
banlist.append(target)
|
||||
self.db.ban_list = banlist
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
@ -226,9 +227,10 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase):
|
|||
bool: True if unbanning was successful, False if target was not
|
||||
previously banned.
|
||||
"""
|
||||
banlist = self.banlist
|
||||
if target not in banlist:
|
||||
banlist.append(target)
|
||||
banlist = list(self.banlist)
|
||||
if target in banlist:
|
||||
banlist = [banned for banned in banlist if banned != target]
|
||||
self.db.ban_list = banlist
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -1405,6 +1405,11 @@ class NickHandler(AttributeHandler):
|
|||
a string.
|
||||
kwargs (any, optional): These are passed on to `AttributeHandler.get`.
|
||||
|
||||
Returns:
|
||||
str or tuple: The nick replacement string or nick tuple.
|
||||
|
||||
|
||||
|
||||
"""
|
||||
if return_tuple or "return_obj" in kwargs:
|
||||
return super().get(key=key, category=category, **kwargs)
|
||||
|
|
@ -1431,10 +1436,10 @@ class NickHandler(AttributeHandler):
|
|||
kwargs (any, optional): These are passed on to `AttributeHandler.get`.
|
||||
|
||||
"""
|
||||
if category == "channel":
|
||||
nick_regex, nick_template = initialize_nick_templates(key + " $1", replacement + " $1")
|
||||
else:
|
||||
nick_regex, nick_template = initialize_nick_templates(key, replacement)
|
||||
# if category == "channel":
|
||||
# nick_regex, nick_template = initialize_nick_templates(key + " $1", replacement + " $1")
|
||||
# else:
|
||||
nick_regex, nick_template = initialize_nick_templates(key, replacement)
|
||||
super().add(key, (nick_regex, nick_template, key, replacement), category=category, **kwargs)
|
||||
|
||||
def remove(self, key, category="inputline", **kwargs):
|
||||
|
|
|
|||
|
|
@ -1678,11 +1678,12 @@ class CmdYesNoQuestion(Command):
|
|||
|
||||
# cleanup
|
||||
self._clean()
|
||||
except Exception:
|
||||
except Exception as err:
|
||||
# make sure to clean up cmdset if something goes wrong
|
||||
caller.msg("|rError in ask_yes_no. Choice not confirmed (report to admin)|n")
|
||||
logger.log_trace("Error in ask_yes_no")
|
||||
self._clean()
|
||||
raise
|
||||
|
||||
|
||||
class YesNoQuestionCmdSet(CmdSet):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue