mirror of https://github.com/nealey/firebot
169 lines
5.4 KiB
Python
Executable File
169 lines
5.4 KiB
Python
Executable File
#! /usr/bin/env python
|
|
|
|
import firebot
|
|
from finger import Finger
|
|
from procbot import ProcBot, Runner
|
|
import shorturl
|
|
import asyncore
|
|
import irc
|
|
import re
|
|
import os
|
|
import time
|
|
import socket
|
|
|
|
def esc(arg):
|
|
return "'" + arg.replace("'", r"'\''") + "'"
|
|
|
|
def lesc(args):
|
|
return [esc(arg) for arg in args]
|
|
|
|
class Arsenic(firebot.FireBot, ProcBot):
|
|
debug = False
|
|
bindings = []
|
|
ping_interval = 120
|
|
chatty = False # #x can't play nice
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
firebot.FireBot.__init__(self, *args, **kwargs)
|
|
self.seen = {}
|
|
self.lusers = {}
|
|
self.heartbeat_interval=0.01
|
|
self.lag = 0
|
|
self.whinecount = 0
|
|
|
|
def runcmd(self, sender, forum, addl, match):
|
|
command = match.group('command')
|
|
args = lesc(lesc(match.group('args').split(' ')))
|
|
argstr = ' '.join(args)
|
|
print argstr
|
|
Runner('%s %s' % (command, argstr),
|
|
lambda l,r: self.proc_cb('%s: ' % command, sender, forum, l, r))
|
|
bindings.append((re.compile(r"^(?P<command>whois) +(?P<args>.*)$"),
|
|
runcmd))
|
|
bindings.append((re.compile(r"^(?P<command>host) +(?P<args>.*)$"),
|
|
runcmd))
|
|
|
|
def rp(self, sender, forum, addl, match):
|
|
command = 'rp'
|
|
argstr = match.group('args')
|
|
Finger(('db.nic.lanl.gov', 5833),
|
|
argstr,
|
|
lambda l: self.proc_cb('%s: ' % command, sender, forum, l, 0))
|
|
bindings.append((re.compile(r"^(?P<command>rp) +(?P<args>.*)$"),
|
|
rp))
|
|
|
|
def finger(self, sender, forum, addl, match):
|
|
command = 'finger'
|
|
argstr = match.group('args')
|
|
Finger(('finger.lanl.gov', 79),
|
|
argstr,
|
|
lambda l: self.proc_cb('%s: ' % command, sender, forum, l, 0))
|
|
bindings.append((re.compile(r"^(?P<command>finger) +(?P<args>.*)$"),
|
|
finger))
|
|
|
|
def lag(self, sender, forum, addl, match):
|
|
forum.msg("My server lag is %.3f seconds." % self.lag)
|
|
bindings.append((re.compile(r"^\008[,: ]+ (what is the )?(server )?lag"),
|
|
lag))
|
|
|
|
def note(self, sender, forum, addl, match):
|
|
whom = match.group('whom')
|
|
what = match.group('what')
|
|
when = time.time()
|
|
key = '\013notes:%s' % whom
|
|
note = (when, sender.name(), what)
|
|
try:
|
|
n = self.db[key]
|
|
except KeyError:
|
|
n = []
|
|
n.append(note)
|
|
self.db[key] = n
|
|
forum.msg(self.gettext('okay', sender=sender.name()))
|
|
bindings.append((re.compile(r"^\008[:, ]+note (to )?(?P<whom>[^: ]+):? +(?P<what>.*)"),
|
|
note))
|
|
|
|
bindings.extend(firebot.FireBot.bindings)
|
|
|
|
##
|
|
## IRC protocol-level extensions
|
|
##
|
|
|
|
def add_luser(self, luser, channel):
|
|
# Keeps track of what users have been on what channels, and
|
|
# sends an invite to luser for every channel in which they're
|
|
# listed. If they're already in the channel, the server just
|
|
# sends back an error. This has the effect of letting people
|
|
# get back into invite-only channels after a disconnect.
|
|
who = luser.name()
|
|
self.lusers[channel.name()][who] = luser
|
|
for chan, l in self.lusers.iteritems():
|
|
if chan == channel.name():
|
|
continue
|
|
t = l.get(who)
|
|
if t and t.host == luser.host:
|
|
self.write(['INVITE', who, chan])
|
|
|
|
def cmd_join(self, sender, forum, addl):
|
|
if sender.name() == self.nick:
|
|
# If it was me, get a channel listing and beg for ops
|
|
self.write(['WHO', forum.name()])
|
|
forum.notice('If you op me, I will op everyone who joins this channel.')
|
|
self.lusers[forum.name()] = {}
|
|
else:
|
|
# Otherwise, add the user
|
|
self.add_luser(sender, forum)
|
|
forum.write(['MODE', forum.name(), '+o'], sender.name())
|
|
|
|
def cmd_352(self, sender, forum, addl):
|
|
# Response to WHO
|
|
forum = irc.Channel(self, addl[0])
|
|
who = irc.User(self, addl[4], addl[1], addl[2])
|
|
self.add_luser(who, forum)
|
|
|
|
def cmd_invite(self, sender, forum, addl):
|
|
# Join any channel to which we're invited
|
|
self.write('JOIN', forum.name())
|
|
|
|
def cmd_pong(self, sender, forum, addl):
|
|
now = time.time()
|
|
self.lag = now - float(addl[0])
|
|
|
|
def cmd_482(self, sender, forum, addl):
|
|
forum = self.recipient(addl[0])
|
|
self.whinecount += 1
|
|
if (self.whinecount == 2 or
|
|
self.whinecount == 4 or
|
|
self.whinecount == 8):
|
|
forum.notice("Just a reminder: I can't op anyone unless I'm opped myself.")
|
|
elif (self.whinecount == 16):
|
|
forum.notice("This is the last time I'm going to beg for ops. Puh-leaze?")
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import daemon
|
|
|
|
debug = True
|
|
|
|
if not debug:
|
|
# Become a daemon
|
|
log = file('arsenic.log', 'a')
|
|
daemon.daemon('arsenic.pid', log, log)
|
|
|
|
# Short URL server
|
|
us = shorturl.start(('', 0))
|
|
firebot.URLSERVER = (socket.gethostbyaddr(socket.gethostname())[0],
|
|
us.getsockname()[1])
|
|
|
|
NICK = ['arsenic']
|
|
INFO = "I'm a little printf, short and stdout"
|
|
|
|
l1 = Arsenic(('irc.lanl.gov', 6667),
|
|
NICK,
|
|
INFO,
|
|
["#x", "#csirt"],
|
|
ssl=False)
|
|
l1.debug = debug
|
|
|
|
irc.run_forever(0.01)
|