2003-03-12 07:26:59 +01:00
#!/usr/bin/env python
###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
2003-03-26 09:39:50 +01:00
"""
Handles relaying between networks .
"""
2003-10-05 14:56:56 +02:00
import plugins
2003-03-12 07:26:59 +01:00
2003-03-27 09:17:51 +01:00
import re
2003-10-22 07:15:19 +02:00
import sys
2003-06-22 18:17:33 +02:00
import time
2003-03-27 09:17:51 +01:00
2003-04-20 01:51:11 +02:00
import conf
2003-08-12 21:10:27 +02:00
import debug
2003-06-22 18:17:33 +02:00
import utils
2003-03-26 09:39:50 +01:00
import irclib
2003-04-20 02:10:53 +02:00
import drivers
2003-03-26 09:39:50 +01:00
import ircmsgs
import ircutils
2003-03-12 07:26:59 +01:00
import privmsgs
import callbacks
2003-03-26 09:39:50 +01:00
2003-08-27 18:25:43 +02:00
example = utils . wrapLines ( """
2003-08-26 14:45:08 +02:00
< jemfinch > @load Relay
< supybot > jemfinch : The operation succeeded .
< jemfinch > @startrelay freenode
< supybot > jemfinch : The operation succeeded .
< jemfinch > @relayconnect oftc irc . oftc . net
< supybot > jemfinch : The operation succeeded .
< jemfinch > @relayjoin #sourcereview
< supybot > jemfinch : The operation succeeded .
< supybot > supybot ( supybot ! ~ supybot @ 65.24 .59 .168 ) has joined on oftc
< jemfinch > howdy , folks : )
< supybot > jemfinch ( jemfinch ! ~ jfincher @dhcp065 - 024 - 059 - 168. columbus . rr . com ) has joined on oftc
< jemfinch > @list Relay
< supybot > jemfinch : relaycolor , relayconnect , relaydisconnect , relayjoin , relaynames , relaypart , relaysay , relaywhois , startrelay
< jemfinch > @relaynames
< supybot > jemfinch : oftc : supybot , jemfinch , sweede , Strike , GnuVince
< jemfinch > @relaycolor 0
< supybot > jemfinch : The operation succeeded .
< jemfinch > @relaycolor 1
< supybot > jemfinch : The operation succeeded .
< jemfinch > @relaycolor 2
< supybot > jemfinch : The operation succeeded .
< jemfinch > @relaycolor 3
< supybot > jemfinch : relaycolor < 0 , 1 , 2 >
< jemfinch > @relaywhois GnuVince
< supybot > jemfinch : Vincent Foley ( ~ vince @modemcable216 .89 - 202 - 24. mtl . mc . videotron . ca ) has been online since 08 : 37 PM , August 24 , 2003 ( idle for 1 day , 10 hours , 21 minutes , and 3 seconds ) and is on #sourcereview and @#hackcanada
2003-08-27 18:25:43 +02:00
""" )
2003-08-26 14:45:08 +02:00
2003-04-08 09:15:45 +02:00
def configure ( onStart , afterConnect , advanced ) :
import socket
from questions import expect , anything , something , yn
onStart . append ( ' load Relay ' )
startNetwork = anything ( ' What is the name of the network you \' re ' \
' connecting to first? ' )
2003-10-21 06:09:48 +02:00
onStart . append ( ' relay start %s ' % startNetwork )
2003-04-08 09:15:45 +02:00
while yn ( ' Do you want to connect to another network for relaying? ' ) == ' y ' :
network = anything ( ' What is the name of the network you want to ' \
' connect to? ' )
server = ' '
while not server :
server = anything ( ' What server does that network use? ' )
try :
print ' Looking up %s ' % server
ip = socket . gethostbyname ( server )
print ' Found %s ( %s ) ' % ( server , ip )
except socket . error :
print ' Sorry, but I couldn \' t find that server. '
server = ' '
if yn ( ' Does that server require you to connect on a port other than '
' the default port for IRC (6667)? ' ) == ' y ' :
port = ' '
while not port :
port = anything ( ' What port is that? ' )
try :
int ( port )
except ValueError :
print ' Sorry, but that isn \' t a valid port. '
port = ' '
server = ' : ' . join ( ( server , port ) )
2003-10-21 06:09:48 +02:00
onStart . append ( ' relay connect %s %s ' % ( network , server ) )
2003-04-08 09:15:45 +02:00
channel = anything ( ' What channel would you like to relay between? ' )
2003-10-22 11:14:49 +02:00
afterConnect . append ( ' relay join %s ' % utils . dqrepr ( channel ) )
2003-04-08 09:15:45 +02:00
while yn ( ' Would like to relay between any more channels? ' ) == ' y ' :
channel = anything ( ' What channel? ' )
2003-10-21 06:09:48 +02:00
afterConnect . append ( ' relay join %s ' % channel )
2003-08-22 22:58:58 +02:00
if yn ( ' Would you like to use color to distinguish between nicks? ' ) == ' y ' :
2003-10-21 06:09:48 +02:00
afterConnect . append ( ' relay color 2 ' )
2003-08-20 18:26:23 +02:00
2003-04-08 09:15:45 +02:00
2003-03-28 02:26:37 +01:00
class Relay ( callbacks . Privmsg ) :
2003-10-22 07:15:19 +02:00
priority = sys . maxint
2003-03-26 09:39:50 +01:00
def __init__ ( self ) :
callbacks . Privmsg . __init__ ( self )
2003-03-27 09:24:22 +01:00
self . ircs = { }
2003-10-21 09:19:53 +02:00
self . _color = 0
self . _whois = { }
2003-03-26 09:39:50 +01:00
self . started = False
2003-04-09 19:49:55 +02:00
self . ircstates = { }
2003-09-05 20:53:09 +02:00
self . lastmsg = { }
2003-08-29 10:15:07 +02:00
self . channels = ircutils . IrcSet ( )
2003-03-27 09:24:22 +01:00
self . abbreviations = { }
2003-08-23 07:04:41 +02:00
self . originalIrc = None
2003-08-20 18:26:23 +02:00
2003-09-22 13:17:10 +02:00
def __call__ ( self , irc , msg ) :
2003-09-23 21:39:48 +02:00
if self . started :
try :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
self . ircstates [ irc ] . addMsg ( irc , self . lastmsg [ irc ] )
finally :
self . lastmsg [ irc ] = msg
callbacks . Privmsg . __call__ ( self , irc , msg )
2003-08-20 18:26:23 +02:00
2003-08-23 07:04:41 +02:00
def die ( self ) :
for irc in self . abbreviations :
if irc != self . originalIrc :
irc . callbacks [ : ] = [ ]
irc . die ( )
2003-08-23 14:12:04 +02:00
def do376 ( self , irc , msg ) :
if self . channels :
irc . queueMsg ( ircmsgs . joins ( self . channels ) )
2003-09-30 17:21:02 +02:00
do377 = do376
do422 = do376
2003-08-23 14:12:04 +02:00
2003-10-21 06:09:48 +02:00
def start ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" <network abbreviation for current server>
This command is necessary to start the Relay plugin ; the
< network abbreviation > is the abbreviation that the network the
bot is currently connected to should be shown as to other networks .
For instance , if the network abbreviation is ' oftc ' , then when
relaying messages from that network to other networks , the users
will show up as ' user@oftc ' .
"""
2003-08-25 08:48:28 +02:00
if isinstance ( irc , irclib . Irc ) :
realIrc = irc
else :
realIrc = irc . getRealIrc ( )
2003-08-23 07:04:41 +02:00
self . originalIrc = realIrc
2003-03-27 09:24:22 +01:00
abbreviation = privmsgs . getArgs ( args )
self . ircs [ abbreviation ] = realIrc
self . abbreviations [ realIrc ] = abbreviation
2003-09-05 20:53:09 +02:00
self . ircstates [ realIrc ] = irclib . IrcState ( )
self . lastmsg [ realIrc ] = ircmsgs . ping ( ' this is just a fake message ' )
2003-03-27 09:24:22 +01:00
self . started = True
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
start = privmsgs . checkCapability ( start , ' owner ' )
2003-03-26 09:39:50 +01:00
2003-10-21 06:09:48 +02:00
def connect ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" <network abbreviation> <domain:port> (port defaults to 6667)
2003-08-20 18:26:23 +02:00
2003-04-06 11:17:38 +02:00
Connects to another network at < domain : port > . The network
abbreviation < network abbreviation > is used when relaying messages from
that network to other networks .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-03-27 09:24:22 +01:00
abbreviation , server = privmsgs . getArgs ( args , needed = 2 )
2003-08-25 08:48:28 +02:00
if isinstance ( irc , irclib . Irc ) :
realIrc = irc
else :
realIrc = irc . getRealIrc ( )
2003-03-27 09:24:22 +01:00
if ' : ' in server :
( server , port ) = server . split ( ' : ' )
port = int ( port )
2003-03-26 09:39:50 +01:00
else :
2003-03-27 09:24:22 +01:00
port = 6667
2003-08-23 06:42:04 +02:00
newIrc = irclib . Irc ( irc . nick , callbacks = realIrc . callbacks )
2003-08-26 18:40:31 +02:00
newIrc . state . history = realIrc . state . history
2003-04-20 01:51:11 +02:00
driver = drivers . newDriver ( ( server , port ) , newIrc )
2003-04-20 02:00:37 +02:00
newIrc . driver = driver
2003-03-27 09:24:22 +01:00
self . ircs [ abbreviation ] = newIrc
self . abbreviations [ newIrc ] = abbreviation
2003-09-05 20:53:09 +02:00
self . ircstates [ newIrc ] = irclib . IrcState ( )
self . lastmsg [ newIrc ] = ircmsgs . ping ( ' this is just a fake message ' )
2003-03-27 09:24:22 +01:00
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
connect = privmsgs . checkCapability ( connect , ' owner ' )
2003-03-26 09:39:50 +01:00
2003-10-21 06:09:48 +02:00
def disconnect ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" <network>
Disconnects and ceases to relay to and from the network represented by
the network abbreviation < network > .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-03-27 09:24:22 +01:00
network = privmsgs . getArgs ( args )
otherIrc = self . ircs [ network ]
2003-10-25 01:15:04 +02:00
otherIrc . driver . die ( )
world . ircs . remove ( otherIrc )
2003-03-28 02:36:00 +01:00
del self . ircs [ network ]
2003-03-31 11:22:48 +02:00
del self . abbreviations [ otherIrc ]
2003-03-28 02:26:37 +01:00
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
disconnect = privmsgs . checkCapability ( disconnect , ' owner ' )
2003-03-26 09:39:50 +01:00
2003-10-21 06:09:48 +02:00
def join ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" <channel>
Starts relaying between the channel < channel > on all networks . If on a
network the bot isn ' t in <channel>, he ' ll join . This commands is
required even if the bot is in the channel on both networks ; he won ' t
2003-10-21 06:09:48 +02:00
relay between those channels unless he ' s told to oin both
2003-04-06 11:17:38 +02:00
channels .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-03-27 09:24:22 +01:00
channel = privmsgs . getArgs ( args )
2003-04-11 22:42:21 +02:00
self . channels . add ( ircutils . toLower ( channel ) )
2003-03-27 09:24:22 +01:00
for otherIrc in self . ircs . itervalues ( ) :
if channel not in otherIrc . state . channels :
otherIrc . queueMsg ( ircmsgs . join ( channel ) )
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
join = privmsgs . checkCapability ( join , ' owner ' )
2003-03-26 09:39:50 +01:00
2003-10-21 06:09:48 +02:00
def part ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" <channel>
Ceases relaying between the channel < channel > on all networks . The bot
will part from the channel on all networks in which it is on the
channel .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-03-27 09:24:22 +01:00
channel = privmsgs . getArgs ( args )
2003-04-11 22:42:21 +02:00
self . channels . remove ( ircutils . toLower ( channel ) )
2003-03-27 09:24:22 +01:00
for otherIrc in self . ircs . itervalues ( ) :
if channel in otherIrc . state . channels :
otherIrc . queueMsg ( ircmsgs . part ( channel ) )
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
part = privmsgs . checkCapability ( part , ' owner ' )
2003-03-26 09:39:50 +01:00
2003-10-21 06:09:48 +02:00
def say ( self , irc , msg , args ) :
2003-08-07 10:20:23 +02:00
""" <network> [<channel>] <text>
Says < text > on < channel > ( using the current channel if unspecified )
on < network > .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-08-07 10:20:23 +02:00
if not args :
2003-10-21 06:09:48 +02:00
raise callbacks . ArgumentError
2003-08-07 10:20:23 +02:00
network = args . pop ( 0 )
channel = privmsgs . getChannel ( msg , args )
text = privmsgs . getArgs ( args )
if network not in self . ircs :
irc . error ( msg , ' I \' m not currently on %s . ' % network )
return
if channel not in self . channels :
irc . error ( msg , ' I \' m not currently relaying to %s . ' % channel )
return
self . ircs [ network ] . queueMsg ( ircmsgs . privmsg ( channel , text ) )
2003-10-21 06:09:48 +02:00
say = privmsgs . checkCapability ( say , ' admin ' )
2003-08-07 10:20:23 +02:00
2003-10-21 06:09:48 +02:00
def names ( self , irc , msg , args ) :
2003-04-06 11:17:38 +02:00
""" [<channel>] (only if not sent in the channel itself.)
The < channel > argument is only necessary if the message isn ' t sent on
the channel itself . Returns the nicks of the people in the channel on
the various networks the bot is connected to .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-08-25 08:48:28 +02:00
if isinstance ( irc , irclib . Irc ) :
realIrc = irc
else :
2003-03-27 22:28:15 +01:00
realIrc = irc . getRealIrc ( )
2003-03-27 22:14:28 +01:00
channel = privmsgs . getChannel ( msg , args )
if channel not in self . channels :
2003-04-02 12:07:06 +02:00
irc . error ( msg , ' I \' m not relaying %s . ' % channel )
2003-03-27 22:14:28 +01:00
return
users = [ ]
for ( abbreviation , otherIrc ) in self . ircs . iteritems ( ) :
2003-03-27 22:28:15 +01:00
if abbreviation != self . abbreviations [ realIrc ] :
2003-03-27 22:18:49 +01:00
Channel = otherIrc . state . channels [ channel ]
2003-03-27 22:21:20 +01:00
usersS = ' , ' . join ( [ s for s in Channel . users if s . strip ( ) != ' ' ] )
2003-07-23 07:29:16 +02:00
users . append ( ' %s : %s ' % ( ircutils . bold ( abbreviation ) , usersS ) )
2003-03-27 22:14:28 +01:00
irc . reply ( msg , ' ; ' . join ( users ) )
2003-06-22 18:17:33 +02:00
2003-10-21 06:09:48 +02:00
def whois ( self , irc , msg , args ) :
2003-06-22 18:17:33 +02:00
""" <nick>@<network>
Returns the WHOIS response < network > gives for < nick > .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-06-22 18:17:33 +02:00
nickAtNetwork = privmsgs . getArgs ( args )
2003-08-25 08:48:28 +02:00
if isinstance ( irc , irclib . Irc ) :
realIrc = irc
else :
realIrc = irc . getRealIrc ( )
2003-08-12 10:48:16 +02:00
try :
( nick , network ) = nickAtNetwork . split ( ' @ ' , 1 )
2003-09-29 07:34:02 +02:00
if not ircutils . isNick ( nick ) :
irc . error ( msg , ' %s is not an IRC nick. ' % nick )
return
2003-08-23 14:12:04 +02:00
nick = ircutils . toLower ( nick )
2003-08-12 10:48:16 +02:00
except ValueError :
2003-08-25 08:48:28 +02:00
if len ( self . abbreviations ) == 2 :
# If there are only two networks being relayed, we can safely
# pick the *other* one.
nick = ircutils . toLower ( nickAtNetwork )
for ( keyIrc , net ) in self . abbreviations . iteritems ( ) :
if keyIrc != realIrc :
network = net
else :
raise callbacks . ArgumentError
2003-06-22 18:17:33 +02:00
if network not in self . ircs :
irc . error ( msg , ' I \' m not on that network. ' )
return
otherIrc = self . ircs [ network ]
2003-08-21 18:31:37 +02:00
otherIrc . queueMsg ( ircmsgs . whois ( nick , nick ) )
2003-10-21 09:19:53 +02:00
self . _whois [ ( otherIrc , nick ) ] = ( irc , msg , { } )
2003-06-22 18:17:33 +02:00
2003-10-21 06:09:48 +02:00
def color ( self , irc , msg , args ) :
2003-08-21 13:19:32 +02:00
""" <0,1,2>
0 turns coloring of nicks / angle brackets off entirely . 1 colors the
nicks , but not the angle brackets . 2 colors both .
"""
2003-09-23 20:59:22 +02:00
if not self . started :
2003-10-21 06:09:48 +02:00
irc . error ( msg , ' You must use the start command first. ' )
2003-09-23 20:59:22 +02:00
return
2003-08-21 13:19:32 +02:00
try :
2003-08-21 13:49:42 +02:00
color = int ( privmsgs . getArgs ( args ) )
2003-08-21 13:19:32 +02:00
if color != 0 and color != 1 and color != 2 :
raise callbacks . ArgumentError
2003-10-21 09:19:53 +02:00
self . _color = color
2003-08-21 13:19:32 +02:00
except ValueError :
raise callbacks . ArgumentError
irc . reply ( msg , conf . replySuccess )
2003-10-21 06:09:48 +02:00
color = privmsgs . checkCapability ( color , ' admin ' )
2003-08-21 13:19:32 +02:00
2003-06-22 18:17:33 +02:00
def do311 ( self , irc , msg ) :
if not isinstance ( irc , irclib . Irc ) :
2003-08-12 10:48:16 +02:00
irc = irc . getRealIrc ( )
2003-08-23 14:12:04 +02:00
nick = ircutils . toLower ( msg . args [ 1 ] )
2003-10-21 09:19:53 +02:00
if ( irc , nick ) not in self . _whois :
2003-06-22 18:17:33 +02:00
return
else :
2003-10-21 09:19:53 +02:00
self . _whois [ ( irc , nick ) ] [ - 1 ] [ msg . command ] = msg
2003-06-22 18:17:33 +02:00
do312 = do311
do317 = do311
do319 = do311
2003-08-20 18:26:23 +02:00
2003-06-22 18:17:33 +02:00
def do318 ( self , irc , msg ) :
if not isinstance ( irc , irclib . Irc ) :
2003-07-23 03:45:48 +02:00
irc = irc . getRealIrc ( )
2003-08-23 14:12:04 +02:00
nick = ircutils . toLower ( msg . args [ 1 ] )
2003-10-21 09:19:53 +02:00
if ( irc , nick ) not in self . _whois :
2003-06-22 18:17:33 +02:00
return
2003-10-21 09:19:53 +02:00
( replyIrc , replyMsg , d ) = self . _whois [ ( irc , nick ) ]
2003-08-12 10:48:16 +02:00
hostmask = ' @ ' . join ( d [ ' 311 ' ] . args [ 2 : 4 ] )
2003-08-21 18:31:37 +02:00
user = d [ ' 311 ' ] . args [ - 1 ]
2003-08-26 18:40:31 +02:00
if ' 319 ' in d :
channels = d [ ' 319 ' ] . args [ - 1 ] . split ( )
2003-10-28 15:08:11 +01:00
ops = [ ]
voices = [ ]
normal = [ ]
halfops = [ ]
for channel in channels :
if channel . startswith ( ' @ ' ) :
ops . append ( channel [ : - 1 ] )
elif channel . startswith ( ' % ' ) :
halfops . append ( channel [ : - 1 ] )
elif channel . startswith ( ' + ' ) :
voices . append ( channel [ : - 1 ] )
else :
normal . append ( channel )
L = [ ]
if ops :
L . append ( ' is an op on %s ' % utils . commaAndify ( ops ) )
if halfops :
L . append ( ' is a halfop on %s ' % utils . commaAndify ( halfops ) )
if voices :
L . append ( ' is voiced on %s ' % utils . commaAndify ( voices ) )
if L :
L . append ( ' is also on %s ' % utils . commaAndify ( normal ) )
else :
L . append ( ' is on %s ' % utils . commaAndify ( normal ) )
2003-08-12 10:48:16 +02:00
else :
2003-10-28 15:08:11 +01:00
L = [ ' isn \' t on any non-secret channels ' ]
channels = utils . commaAndify ( L )
2003-08-12 10:48:16 +02:00
if ' 317 ' in d :
idle = utils . timeElapsed ( d [ ' 317 ' ] . args [ 2 ] )
2003-08-26 13:15:15 +02:00
signon = time . strftime ( conf . humanTimestampFormat ,
time . localtime ( float ( d [ ' 317 ' ] . args [ 3 ] ) ) )
2003-08-12 10:48:16 +02:00
else :
2003-08-21 18:31:37 +02:00
idle = ' <unknown> '
signon = ' <unknown> '
2003-10-16 12:58:31 +02:00
if ' 312 ' in d :
server = d [ ' 312 ' ] . args [ 2 ]
else :
server = ' <unknown> '
s = ' %s ( %s ) has been on server %s since %s (idle for %s ) and %s . ' % \
( user , hostmask , server , signon , idle , channels )
2003-06-22 18:17:33 +02:00
replyIrc . reply ( replyMsg , s )
2003-10-21 09:19:53 +02:00
del self . _whois [ ( irc , nick ) ]
2003-08-20 18:26:23 +02:00
2003-08-26 19:55:30 +02:00
def do402 ( self , irc , msg ) :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
nick = ircutils . toLower ( msg . args [ 1 ] )
2003-10-21 09:19:53 +02:00
if ( irc , nick ) not in self . _whois :
2003-08-26 19:55:30 +02:00
return
2003-10-21 09:19:53 +02:00
( replyIrc , replyMsg , d ) = self . _whois [ ( irc , nick ) ]
2003-08-26 19:55:30 +02:00
s = ' There is no %s on %s . ' % ( nick , self . abbreviations [ irc ] )
replyIrc . reply ( replyMsg , s )
2003-08-28 18:31:56 +02:00
do401 = do402
2003-08-15 07:41:51 +02:00
def _formatPrivmsg ( self , nick , network , msg ) :
2003-07-23 07:29:16 +02:00
# colorize nicks
2003-10-21 09:19:53 +02:00
if self . _color > = 1 :
2003-08-21 13:19:32 +02:00
nick = ircutils . mircColor ( nick , * ircutils . canonicalColor ( nick ) )
2003-10-21 09:19:53 +02:00
if self . _color > = 2 :
2003-08-21 13:19:32 +02:00
colors = ircutils . canonicalColor ( nick , shift = 4 )
2003-03-27 09:17:51 +01:00
if ircmsgs . isAction ( msg ) :
2003-10-21 09:19:53 +02:00
if self . _color > = 2 :
2003-08-21 13:19:32 +02:00
t = ircutils . mircColor ( ' * ' , * colors )
else :
t = ' * '
2003-08-15 07:41:51 +02:00
s = ' %s %s @ %s %s ' % ( t , nick , network , ircmsgs . unAction ( msg ) )
2003-03-27 09:17:51 +01:00
else :
2003-10-21 09:19:53 +02:00
if self . _color > = 2 :
2003-08-21 13:19:32 +02:00
lt = ircutils . mircColor ( ' < ' , * colors )
gt = ircutils . mircColor ( ' > ' , * colors )
else :
lt = ' < '
gt = ' > '
2003-08-15 07:41:51 +02:00
s = ' %s %s @ %s %s %s ' % ( lt , nick , network , gt , msg . args [ 1 ] )
2003-08-12 10:48:16 +02:00
return s
2003-03-27 09:17:51 +01:00
2003-10-10 08:10:50 +02:00
def _sendToOthers ( self , irc , msg ) :
assert msg . command == ' PRIVMSG '
for otherIrc in self . ircs . itervalues ( ) :
if otherIrc != irc :
if msg . args [ 0 ] in otherIrc . state . channels :
otherIrc . queueMsg ( msg )
2003-03-26 09:39:50 +01:00
def doPrivmsg ( self , irc , msg ) :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
if self . started and ircutils . isChannel ( msg . args [ 0 ] ) :
channel = msg . args [ 0 ]
2003-03-27 21:10:10 +01:00
if channel not in self . channels :
return
2003-03-26 09:39:50 +01:00
abbreviation = self . abbreviations [ irc ]
2003-03-27 09:17:51 +01:00
s = self . _formatPrivmsg ( msg . nick , abbreviation , msg )
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-03-26 09:39:50 +01:00
def doJoin ( self , irc , msg ) :
if self . started :
2003-03-27 10:14:00 +01:00
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
2003-03-27 21:32:49 +01:00
channel = msg . args [ 0 ]
if channel not in self . channels :
return
2003-03-26 09:39:50 +01:00
abbreviation = self . abbreviations [ irc ]
2003-04-30 16:49:09 +02:00
s = ' %s ( %s ) has joined on %s ' % ( msg . nick , msg . prefix , abbreviation )
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-03-26 09:39:50 +01:00
def doPart ( self , irc , msg ) :
if self . started :
2003-03-27 10:14:00 +01:00
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
2003-03-27 21:32:49 +01:00
channel = msg . args [ 0 ]
if channel not in self . channels :
return
2003-03-26 09:39:50 +01:00
abbreviation = self . abbreviations [ irc ]
2003-04-30 16:49:09 +02:00
s = ' %s ( %s ) has left on %s ' % ( msg . nick , msg . prefix , abbreviation )
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-03-26 09:39:50 +01:00
2003-03-31 09:04:23 +02:00
def doMode ( self , irc , msg ) :
if self . started :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
channel = msg . args [ 0 ]
2003-10-10 08:10:50 +02:00
if channel not in self . channels :
return
abbreviation = self . abbreviations [ irc ]
s = ' mode change by %s on %s : %s ' % \
( msg . nick , abbreviation , ' ' . join ( msg . args [ 1 : ] ) )
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-09-03 20:42:52 +02:00
def doKick ( self , irc , msg ) :
if self . started :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
channel = msg . args [ 0 ]
2003-10-10 08:10:50 +02:00
if channel not in self . channels :
return
abbrev = self . abbreviations [ irc ]
if len ( msg . args ) == 3 :
2003-10-18 01:08:27 +02:00
s = ' %s was kicked by %s on %s ( %s ) ' % \
( msg . args [ 1 ] , msg . nick , abbrev , msg . args [ 2 ] )
2003-10-10 08:10:50 +02:00
else :
2003-10-18 01:08:27 +02:00
s = ' %s was kicked by %s on %s ' % \
( msg . args [ 1 ] , msg . nick , abbrev )
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-08-20 18:26:23 +02:00
2003-03-31 09:04:23 +02:00
def doNick ( self , irc , msg ) :
if self . started :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
2003-03-31 11:22:48 +02:00
newNick = msg . args [ 0 ]
2003-08-12 10:48:16 +02:00
network = self . abbreviations [ irc ]
s = ' nick change by %s to %s on %s ' % ( msg . nick , newNick , network )
2003-03-31 11:22:48 +02:00
for channel in self . channels :
if newNick in irc . state . channels [ channel ] . users :
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
def doTopic ( self , irc , msg ) :
if self . started :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
2003-10-10 15:37:23 +02:00
if msg . nick == irc . nick :
return
2003-10-10 08:10:50 +02:00
newTopic = msg . args [ 1 ]
network = self . abbreviations [ irc ]
s = ' topic change by %s on %s : %s ' % ( msg . nick , network , newTopic )
m = ircmsgs . privmsg ( msg . args [ 0 ] , s )
self . _sendToOthers ( irc , m )
2003-04-01 09:09:36 +02:00
def doQuit ( self , irc , msg ) :
if self . started :
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
network = self . abbreviations [ irc ]
2003-06-22 18:17:33 +02:00
if msg . args :
2003-04-30 16:49:09 +02:00
s = ' %s has quit %s ( %s ) ' % ( msg . nick , network , msg . args [ 0 ] )
2003-04-01 09:09:36 +02:00
else :
2003-04-30 16:49:09 +02:00
s = ' %s has quit %s . ' % ( msg . nick , network )
2003-04-01 09:09:36 +02:00
for channel in self . channels :
2003-04-09 21:11:00 +02:00
if msg . nick in self . ircstates [ irc ] . channels [ channel ] . users :
2003-10-10 08:10:50 +02:00
m = ircmsgs . privmsg ( channel , s )
self . _sendToOthers ( irc , m )
2003-08-20 18:26:23 +02:00
2003-03-27 09:17:51 +01:00
def outFilter ( self , irc , msg ) :
2003-03-31 11:22:48 +02:00
if not self . started :
return msg
2003-03-27 10:14:00 +01:00
if not isinstance ( irc , irclib . Irc ) :
irc = irc . getRealIrc ( )
2003-03-27 09:17:51 +01:00
if msg . command == ' PRIVMSG ' :
abbreviations = self . abbreviations . values ( )
2003-03-27 09:56:34 +01:00
rPrivmsg = re . compile ( r ' <[^@]+@(?: %s )> ' % ' | ' . join ( abbreviations ) )
2003-06-05 23:03:22 +02:00
rAction = re . compile ( r ' \ * [^/]+@(?: %s ) ' % ' | ' . join ( abbreviations ) )
2003-08-12 10:48:16 +02:00
text = ircutils . unColor ( msg . args [ 1 ] )
if not ( rPrivmsg . match ( text ) or \
rAction . match ( text ) or \
' has left on ' in text or \
' has joined on ' in text or \
' has quit ' in text or \
2003-10-19 16:45:14 +02:00
' was kicked by ' in text or \
2003-08-12 10:48:16 +02:00
text . startswith ( ' mode change ' ) or \
2003-10-10 08:10:50 +02:00
text . startswith ( ' nick change ' ) or \
text . startswith ( ' topic change ' ) ) :
2003-03-27 09:17:51 +01:00
channel = msg . args [ 0 ]
2003-03-28 06:36:59 +01:00
if channel in self . channels :
abbreviation = self . abbreviations [ irc ]
s = self . _formatPrivmsg ( irc . nick , abbreviation , msg )
for otherIrc in self . ircs . itervalues ( ) :
if otherIrc != irc :
if channel in otherIrc . state . channels :
otherIrc . queueMsg ( ircmsgs . privmsg ( channel , s ) )
2003-09-06 04:10:55 +02:00
elif msg . command == ' TOPIC ' and len ( msg . args ) > 1 :
2003-03-28 06:36:59 +01:00
( channel , topic ) = msg . args
if channel in self . channels :
2003-03-27 09:24:22 +01:00
for otherIrc in self . ircs . itervalues ( ) :
2003-03-27 09:17:51 +01:00
if otherIrc != irc :
2003-03-28 08:10:23 +01:00
if otherIrc . state . getTopic ( channel ) != topic :
otherIrc . queueMsg ( ircmsgs . topic ( channel , topic ) )
2003-08-20 18:26:23 +02:00
2003-03-27 09:26:36 +01:00
return msg
2003-03-27 09:17:51 +01:00
2003-03-26 09:39:50 +01:00
Class = Relay
2003-08-20 18:26:23 +02:00
2003-03-24 09:41:19 +01:00
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: