A bot's say_to message gets passed to message callbacks (and subsequently parsers) now by default and can be disabled by specifying callback=False in the say_to call. Added links module, for relaying channels of the same specified link name. Relays own messages as well as across networks.

This commit is contained in:
Josh K 2018-12-04 08:25:11 -05:00
parent cceb2515eb
commit adcb11debf
5 changed files with 83 additions and 14 deletions

15
bot.py
View File

@ -75,6 +75,7 @@ def parser():
""" """
message parser decorator. message parser decorator.
decorated function gets passed con, dst, nick, msg on each privmsg decorated function gets passed con, dst, nick, msg on each privmsg
by default, bot's own messages are caught by parsers too
""" """
def __deco__( func ): def __deco__( func ):
mod = add_module( func.__module__ ) mod = add_module( func.__module__ )
@ -142,7 +143,8 @@ def _on_priv_message( con, dst, nick, msg ):
# message split into words, first word is command rest are parms list # message split into words, first word is command rest are parms list
pfx = bcfg['bot']['prefix'] pfx = bcfg['bot']['prefix']
strp_msg = msg.lstrip() strp_msg = msg.lstrip()
if strp_msg[0 : len( pfx )] == pfx: # if prefixed and not from self
if strp_msg[0 : len( pfx )] == pfx and nick != bcfg['user']['nick']:
msg_words = strp_msg.split() msg_words = strp_msg.split()
cmd = msg_words[0][len( pfx ):].lower() cmd = msg_words[0][len( pfx ):].lower()
parms = msg_words[1:] parms = msg_words[1:]
@ -163,12 +165,11 @@ def _on_priv_message( con, dst, nick, msg ):
parms, {'con':con,'dst':dst,'nick':nick} ) ) parms, {'con':con,'dst':dst,'nick':nick} ) )
break break
# callback registered parsers, not for self messages though # callback registered parsers, self messages too by default
if nick != bcfg['user']['nick']: #if nick != bcfg['user']['nick']:
# call each registered parser for v in _MOD_MAP.values():
for v in _MOD_MAP.values(): for p in v['parsers']:
for p in v['parsers']: p( con, dst, nick, msg )
p( con, dst, nick, msg )
# core commands # core commands

View File

@ -10,7 +10,7 @@
owner = "slipyx" owner = "slipyx"
# nick, user, and real name of bot # nick, user, and real name of bot
nick = "dustbot" nick = "dustbotomize"
user = "dust" user = "dust"
name = "Me Mow" name = "Me Mow"
@ -19,11 +19,11 @@ name = "Me Mow"
## ##
[bot] [bot]
# command prefix # command prefix
prefix = ";" prefix = "::"
# list of module names to import from modules package # list of module names to import from modules package
# additions are imported on bot reload # any additions made are imported on bot reload
modules = ['misc','qdb'] modules = ['misc','qdb','links']
## ##
## networks/servers config ## networks/servers config
@ -33,7 +33,7 @@ modules = ['misc','qdb']
name = "Tilde" name = "Tilde"
# host and port of server to connect to # host and port of server to connect to
host = "irc.tilde.chat" host = "team.tilde.chat"
port = 6697 port = 6697
# optional list of channels to join upon connecting # optional list of channels to join upon connecting

62
modules/links.py Normal file
View File

@ -0,0 +1,62 @@
# links/relays channels to a specified link name
# works cross network. all chans linked to same name are relayed
import asyncio
import bot
# globals
try:
_G
except NameError:
_G = {
'links': {} # strLinkName: [c,c]
}
async def link( c, lname ):
if lname not in _G['links'].keys(): _G['links'][lname] = []
if c not in _G['links'][lname]:
c['con'].say_to( c['dst'], '> Adding this chan to link named \'{}\'...'.format( lname ) )
_G['links'][lname].append( c )
else: c['con'].say_to( c['dst'], '> This chan is already linked to that name...' )
async def unlink( c, lname ):
if lname not in _G['links'].keys():
c['con'].say_to( c['dst'], '> Link name not found.' )
return
if c in _G['links'][lname]:
c['con'].say_to( c['dst'], '> Unlinking this chan from link named \'{}\'...'.format( lname ) )
_G['links'][lname].remove( c )
# if nothing else in link, remove name too
if not _G['links'][lname]: _G['links'].pop( lname, None )
else: c['con'].say_to( c['dst'], '> This chan is not linked to link name \'{}\'...'.format( lname ) )
@bot.parser()
def parse_linked_chat( con, chan, nick, msg ):
for lname in _G['links'].keys():
for c in _G['links'][lname]:
if con == c['con'] and chan == c['dst']:
for ctx in _G['links'][lname]:
if ctx['con'] != con or ctx['dst'] != chan:
# disable callback for recursion prevention!
ctx['con'].say_to( ctx['dst'], '[{}:{}] <{}> {}'.format(
lname, _G['links'][lname].index( c ) + 1, nick, msg ), callback=False )
break
@bot.command( 'link', True )
async def cmd_link( p, c ):
lname = ''
if p: lname = p[0].lower()
else:
c['con'].say_to( c['dst'], '> Please specify a link name.' )
return
await link( c, lname )
@bot.command( 'unlink', True )
async def cmd_unlink( p, c ):
lname = ''
if p: lname = p[0].lower()
else:
c['con'].say_to( c['dst'], '> Please specify a link name.' )
return
await unlink( c, lname )

View File

@ -48,6 +48,9 @@ async def get_quote( parms, ctx ):
con.say_to( dst, 'No QDB known by name \'{}\'!'.format( db_name ) ) con.say_to( dst, 'No QDB known by name \'{}\'!'.format( db_name ) )
return return
# implicit spam for tilde server
if sv_name == 'tilde': spam = True
con.say_to( dst, 'Grabbing a quote from QDB \'{}\'...'.format( db_name ) ) con.say_to( dst, 'Grabbing a quote from QDB \'{}\'...'.format( db_name ) )
req = requests.get( QDB_URLS[db_name] ) req = requests.get( QDB_URLS[db_name] )

View File

@ -167,7 +167,7 @@ class IrcProtocol( asyncio.Protocol ):
#if new in self.names: #if new in self.names:
self.names[new] = self.names.pop( name, [] ) self.names[new] = self.names.pop( name, [] )
#else: self.names[new] = [] #else: self.names[new] = []
#self.log( 'NICK {} changed to {} w/now: {}'.format( name, new, self.names[new] ) ) self.log( 'NICK {} changed to {} w/now: {}'.format( name, new, self.names[new] ) )
# callbacks # callbacks
def add_message_callback( self, cb ): def add_message_callback( self, cb ):
@ -195,10 +195,13 @@ class IrcProtocol( asyncio.Protocol ):
#if 'PONG' not in msg: self.log( '>> {}'.format( msg ) ) #if 'PONG' not in msg: self.log( '>> {}'.format( msg ) )
self._trans.write( bytes( msg[:510] + '\r\n', 'utf-8' ) ) self._trans.write( bytes( msg[:510] + '\r\n', 'utf-8' ) )
# helper func for sending a privmsg to specified destination # helper func for sending a privmsg to specified destination
def say_to( self, dst, msg ): # also passes on to callbacks by default if not disabled
def say_to( self, dst, msg, callback=True ):
msg = msg.replace( '\n', ' ' ).replace( '\r', '' ) msg = msg.replace( '\n', ' ' ).replace( '\r', '' )
self.log( '{} >> {}'.format( dst, msg ) ) self.log( '{} >> {}'.format( dst, msg ) )
self.send( 'PRIVMSG {} :{}'.format( dst, msg ) ) self.send( 'PRIVMSG {} :{}'.format( dst, msg ) )
if callback:
for cb in self._cb['message']: cb( self, dst, self.cfg['usr']['nick'], msg )
# create connection task # create connection task
async def do_connect( self, sv_cfg ): async def do_connect( self, sv_cfg ):