3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-30 14:49:28 +01:00

core, fantasy: redo handling of noticed and/or private replies

New behaviour for command responses in general: FANTASY commands reply in channel as PRIVMSG, while all commands sent in PM reply as private notices.

- The old irc.called_by is now irc.called_in (PLACE last command was called)
- irc.called_by is now used to store the CALLER of the last command
- notice=True/False toggle is dropped from ServiceBot.call_cmd()
- New private=True/False option added to ServiceBot.reply() and irc.reply(), which controls whether replies should be sent privately or not.
This commit is contained in:
James Lu 2016-06-30 18:22:45 -07:00
parent 14f569fd7c
commit 02405c36b5
4 changed files with 32 additions and 15 deletions

View File

@ -104,9 +104,10 @@ class Irc():
self.pseudoclient = None
self.lastping = time.time()
# Internal variable to set the place the last command was called (in PM
# Internal variable to set the place and caller of the last command (in PM
# or in a channel), used by fantasy command support.
self.called_by = None
self.called_in = None
# Intialize the server, channel, and user indexes to be populated by
# our protocol module. For the server index, we can add ourselves right
@ -460,9 +461,21 @@ class Irc():
cmd = 'PYLINK_SELF_PRIVMSG'
self.callHooks([source, cmd, {'target': target, 'text': text}])
def reply(self, text, notice=False, source=None):
def reply(self, text, notice=False, source=None, private=False, force_privmsg_in_private=False):
"""Replies to the last caller in the right context (channel or PM)."""
self.msg(self.called_by, text, notice=notice, source=source)
# Private reply is enabled, or the caller was originally a PM
if private or self.called_in in self.users:
if not force_privmsg_in_private:
# For private replies, the default is to override the notice=True/False argument,
# and send replies as notices regardless. This is standard behaviour for most
# IRC services, but can be disabled if force_privmsg_in_private is given.
notice = True
target = self.called_by
else:
target = self.called_in
self.msg(self.called_in, text, notice=notice, source=source)
def toLower(self, text):
"""Returns a lowercase representation of text based on the IRC object's

View File

@ -53,7 +53,7 @@ def handle_fantasy(irc, source, command, args):
text = orig_text[len(prefix):]
# Finally, call the bot command and loop to the next bot.
sbot.call_cmd(irc, source, text, called_by=channel, notice=False)
sbot.call_cmd(irc, source, text, called_in=channel)
continue
utils.add_hook(handle_fantasy, 'PRIVMSG')

View File

@ -96,9 +96,9 @@ def remote(irc, source, args):
irc.reply('No text entered!')
return
# Force remoteirc.called_by to something private in order to prevent
# Force remoteirc.called_in to something private in order to prevent
# accidental information leakage from replies.
remoteirc.called_by = remoteirc.pseudoclient.uid
remoteirc.called_in = remoteirc.called_by = remoteirc.pseudoclient.uid
# Set PyLink's identification to admin.
remoteirc.pseudoclient.identified = "<PyLink networks.remote override>"

View File

@ -147,6 +147,10 @@ def getDatabaseName(dbname):
return dbname
class ServiceBot():
"""
PyLink IRC Service class.
"""
def __init__(self, name, default_help=True, default_request=False, default_list=True,
nick=None, ident=None, manipulatable=False, extra_channels=collections.defaultdict(set),
desc=None):
@ -190,6 +194,9 @@ class ServiceBot():
self.add_cmd(self.listcommands, 'list')
def spawn(self, irc=None):
"""
Spawns instances of this service on all connected networks.
"""
# Spawn the new service by calling the PYLINK_NEW_SERVICE hook,
# which is handled by coreplugin.
if irc is None:
@ -198,25 +205,22 @@ class ServiceBot():
else:
raise NotImplementedError("Network specific plugins not supported yet.")
def reply(self, irc, text):
"""Replies to a message using the right service UID."""
def reply(self, irc, text, notice=False, private=False):
"""Replies to a message as the service in question."""
servuid = self.uids.get(irc.name)
if not servuid:
log.warning("(%s) Possible desync? UID for service %s doesn't exist!", irc.name, self.name)
return
irc.reply(text, notice=self.use_notice, source=servuid)
irc.reply(text, notice=notice, source=servuid, private=private)
def call_cmd(self, irc, source, text, called_by=None, notice=True):
def call_cmd(self, irc, source, text, called_in=None):
"""
Calls a PyLink bot command. source is the caller's UID, and text is the
full, unparsed text of the message.
"""
irc.called_by = called_by or source
# Store this globally so other commands don't have to worry about whether
# we're preferring notices.
self.use_notice = notice
irc.called_in = called_in or source
irc.called_by = source
cmd_args = text.strip().split(' ')
cmd = cmd_args[0].lower()