PEP8 compliance (only whitespace changes)
This commit is contained in:
parent
94d9fd22f0
commit
5ea26b8ff7
15
bot.py
15
bot.py
|
@ -20,7 +20,9 @@ import yaml
|
||||||
|
|
||||||
os.chdir(sys.path[0]) # do stuff relative to the installation directory
|
os.chdir(sys.path[0]) # do stuff relative to the installation directory
|
||||||
|
|
||||||
|
|
||||||
class Bot(object):
|
class Bot(object):
|
||||||
|
|
||||||
def __init__(self, nick, channel, network):
|
def __init__(self, nick, channel, network):
|
||||||
self.nick = nick
|
self.nick = nick
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
|
@ -32,8 +34,9 @@ print 'Loading plugins'
|
||||||
|
|
||||||
plugin_mtimes = {}
|
plugin_mtimes = {}
|
||||||
|
|
||||||
|
|
||||||
def reload_plugins():
|
def reload_plugins():
|
||||||
|
|
||||||
if not hasattr(bot, 'plugs'):
|
if not hasattr(bot, 'plugs'):
|
||||||
bot.plugs = collections.defaultdict(lambda: [])
|
bot.plugs = collections.defaultdict(lambda: [])
|
||||||
|
|
||||||
|
@ -46,7 +49,7 @@ def reload_plugins():
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print ' error:', e
|
print ' error:', e
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# remove plugins already loaded from this filename
|
# remove plugins already loaded from this filename
|
||||||
for name, data in bot.plugs.iteritems():
|
for name, data in bot.plugs.iteritems():
|
||||||
bot.plugs[name] = filter(lambda x: x[0][0] != filename, data)
|
bot.plugs[name] = filter(lambda x: x[0][0] != filename, data)
|
||||||
|
@ -79,8 +82,10 @@ bot.persist_dir = os.path.abspath('persist')
|
||||||
|
|
||||||
print 'Running main loop'
|
print 'Running main loop'
|
||||||
|
|
||||||
|
|
||||||
class Input(object):
|
class Input(object):
|
||||||
def __init__(self, raw, prefix, command,
|
|
||||||
|
def __init__(self, raw, prefix, command,
|
||||||
params, nick, user, host, paraml, msg):
|
params, nick, user, host, paraml, msg):
|
||||||
self.raw = raw
|
self.raw = raw
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
@ -99,7 +104,9 @@ class Input(object):
|
||||||
else:
|
else:
|
||||||
self.chan = ""
|
self.chan = ""
|
||||||
|
|
||||||
|
|
||||||
class FakeBot(object):
|
class FakeBot(object):
|
||||||
|
|
||||||
def __init__(self, bot, input, func):
|
def __init__(self, bot, input, func):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.persist_dir = bot.persist_dir
|
self.persist_dir = bot.persist_dir
|
||||||
|
@ -131,7 +138,7 @@ class FakeBot(object):
|
||||||
self.say(unicode(out))
|
self.say(unicode(out))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
out = bot.irc.out.get(timeout=1)
|
out = bot.irc.out.get(timeout=1)
|
||||||
reload_plugins()
|
reload_plugins()
|
||||||
printed = False
|
printed = False
|
||||||
|
|
|
@ -2,6 +2,7 @@ import re
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.sieve
|
@hook.sieve
|
||||||
def sieve_suite(bot, input, func, args):
|
def sieve_suite(bot, input, func, args):
|
||||||
events = args.get('events', ['PRIVMSG'])
|
events = args.get('events', ['PRIVMSG'])
|
||||||
|
@ -14,9 +15,10 @@ def sieve_suite(bot, input, func, args):
|
||||||
|
|
||||||
hook = args.get('hook', r'(.*)')
|
hook = args.get('hook', r'(.*)')
|
||||||
args.setdefault('prefix', True)
|
args.setdefault('prefix', True)
|
||||||
|
|
||||||
if args.get('prefix', True):
|
if args.get('prefix', True):
|
||||||
hook = (r'^(?:[.!]|' if input.chan != input.nick else r'^(?:[.!]?|') + bot.nick +r'[:,]*\s*)' + hook
|
hook = (r'^(?:[.!]|' if input.chan != input.nick else r'^(?:[.!]?|') \
|
||||||
|
+ bot.nick +r'[:,]*\s*)' + hook
|
||||||
|
|
||||||
input.re = re.match(hook, input.msg, flags=re.I)
|
input.re = re.match(hook, input.msg, flags=re.I)
|
||||||
if input.re is None:
|
if input.re is None:
|
||||||
|
|
20
irc.py
20
irc.py
|
@ -1,13 +1,14 @@
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import thread
|
import thread
|
||||||
import asyncore
|
import asyncore
|
||||||
import asynchat
|
import asynchat
|
||||||
import Queue
|
import Queue
|
||||||
|
|
||||||
queue = Queue.Queue
|
queue = Queue.Queue
|
||||||
|
|
||||||
|
|
||||||
def decode(txt):
|
def decode(txt):
|
||||||
for codec in ('utf-8', 'iso-8859-1', 'shift_jis', 'cp1252'):
|
for codec in ('utf-8', 'iso-8859-1', 'shift_jis', 'cp1252'):
|
||||||
try:
|
try:
|
||||||
|
@ -16,8 +17,10 @@ def decode(txt):
|
||||||
continue
|
continue
|
||||||
return txt.decode('utf-8', 'ignore')
|
return txt.decode('utf-8', 'ignore')
|
||||||
|
|
||||||
|
|
||||||
class crlf_tcp(asynchat.async_chat):
|
class crlf_tcp(asynchat.async_chat):
|
||||||
"Handles tcp connections that consist of utf-8 lines ending with crlf"
|
"Handles tcp connections that consist of utf-8 lines ending with crlf"
|
||||||
|
|
||||||
def __init__(self, host, port):
|
def __init__(self, host, port):
|
||||||
asynchat.async_chat.__init__(self)
|
asynchat.async_chat.__init__(self)
|
||||||
self.set_terminator('\r\n')
|
self.set_terminator('\r\n')
|
||||||
|
@ -35,17 +38,17 @@ class crlf_tcp(asynchat.async_chat):
|
||||||
asyncore.loop()
|
asyncore.loop()
|
||||||
|
|
||||||
def handle_connect(self):
|
def handle_connect(self):
|
||||||
thread.start_new_thread(self.queue_read_loop,())
|
thread.start_new_thread(self.queue_read_loop, ())
|
||||||
|
|
||||||
def queue_read_loop(self):
|
def queue_read_loop(self):
|
||||||
while True:
|
while True:
|
||||||
line = self.oqueue.get().splitlines()[0][:500]
|
line = self.oqueue.get().splitlines()[0][:500]
|
||||||
print ">>> %r" % line
|
print ">>> %r" % line
|
||||||
self.push(line.encode('utf-8','replace')+'\r\n')
|
self.push(line.encode('utf-8', 'replace') + '\r\n')
|
||||||
|
|
||||||
def collect_incoming_data(self, data):
|
def collect_incoming_data(self, data):
|
||||||
self.buffer += data
|
self.buffer += data
|
||||||
|
|
||||||
def found_terminator(self):
|
def found_terminator(self):
|
||||||
line = self.buffer
|
line = self.buffer
|
||||||
self.iqueue.put(decode(line))
|
self.iqueue.put(decode(line))
|
||||||
|
@ -56,19 +59,20 @@ irc_noprefix_re = re.compile(r'()(.*?) (.*)')
|
||||||
irc_param_re = re.compile(r'(?:^|(?<= ))(:.*|[^ ]+)')
|
irc_param_re = re.compile(r'(?:^|(?<= ))(:.*|[^ ]+)')
|
||||||
irc_netmask_re = re.compile(r':?([^!@]*)!?([^@]*)@?(.*)')
|
irc_netmask_re = re.compile(r':?([^!@]*)!?([^@]*)@?(.*)')
|
||||||
|
|
||||||
|
|
||||||
class irc(object):
|
class irc(object):
|
||||||
"handles the IRC protocol"
|
"handles the IRC protocol"
|
||||||
#see the docs/ folder for more information on the protocol
|
#see the docs/ folder for more information on the protocol
|
||||||
|
|
||||||
def __init__(self, network, nick, port=6667):
|
def __init__(self, network, nick, port=6667):
|
||||||
self.conn = crlf_tcp(network, port)
|
self.conn = crlf_tcp(network, port)
|
||||||
thread.start_new_thread(self.conn.run,())
|
thread.start_new_thread(self.conn.run, ())
|
||||||
self.out = queue() #responses from the server are placed here
|
self.out = queue() #responses from the server are placed here
|
||||||
# format: [rawline, prefix, command, params,
|
# format: [rawline, prefix, command, params,
|
||||||
# nick, user, host, paramlist, msg]
|
# nick, user, host, paramlist, msg]
|
||||||
self.nick(nick)
|
self.nick(nick)
|
||||||
self.cmd("USER", ["skybot v0.01", "0", "bot"])
|
self.cmd("USER", ["skybot v0.01", "0", "bot"])
|
||||||
thread.start_new_thread(self.parse_loop,())
|
thread.start_new_thread(self.parse_loop, ())
|
||||||
|
|
||||||
def parse_loop(self):
|
def parse_loop(self):
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -4,8 +4,13 @@ import htmlentitydefs
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
########### from http://effbot.org/zone/re-sub.htm#unescape-html #############
|
########### from http://effbot.org/zone/re-sub.htm#unescape-html #############
|
||||||
|
|
||||||
|
|
||||||
def unescape(text):
|
def unescape(text):
|
||||||
|
|
||||||
def fixup(m):
|
def fixup(m):
|
||||||
text = m.group(0)
|
text = m.group(0)
|
||||||
if text[:2] == "&#":
|
if text[:2] == "&#":
|
||||||
|
@ -24,12 +29,15 @@ def unescape(text):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return text # leave as is
|
return text # leave as is
|
||||||
|
|
||||||
return re.sub("&#?\w+;", fixup, text)
|
return re.sub("&#?\w+;", fixup, text)
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
languages = 'ja fr de ko ru zh'.split();
|
languages = 'ja fr de ko ru zh'.split()
|
||||||
language_pairs = zip(languages[:-1], languages[1:])
|
language_pairs = zip(languages[:-1], languages[1:])
|
||||||
|
|
||||||
|
|
||||||
def goog_trans(text, slang, tlang):
|
def goog_trans(text, slang, tlang):
|
||||||
req_url = 'http://ajax.googleapis.com/ajax/services/language/translate' \
|
req_url = 'http://ajax.googleapis.com/ajax/services/language/translate' \
|
||||||
'?v=1.0&q=%s&langpair=%s'
|
'?v=1.0&q=%s&langpair=%s'
|
||||||
|
@ -38,10 +46,11 @@ def goog_trans(text, slang, tlang):
|
||||||
parsed = yaml.load(json)
|
parsed = yaml.load(json)
|
||||||
if not 200 <= parsed['responseStatus'] < 300:
|
if not 200 <= parsed['responseStatus'] < 300:
|
||||||
print parsed
|
print parsed
|
||||||
raise IOError, 'error with the translation server: %d: %s' % (
|
raise IOError('error with the translation server: %d: %s' % (
|
||||||
parsed['responseStatus'], '')
|
parsed['responseStatus'], ''))
|
||||||
return unescape(parsed['responseData']['translatedText'])
|
return unescape(parsed['responseData']['translatedText'])
|
||||||
|
|
||||||
|
|
||||||
def babel_gen(inp):
|
def babel_gen(inp):
|
||||||
for language in languages:
|
for language in languages:
|
||||||
inp = inp.encode('utf8')
|
inp = inp.encode('utf8')
|
||||||
|
@ -50,6 +59,7 @@ def babel_gen(inp):
|
||||||
print language, trans, inp
|
print language, trans, inp
|
||||||
yield language, trans, inp
|
yield language, trans, inp
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def babel(inp):
|
def babel(inp):
|
||||||
try:
|
try:
|
||||||
|
@ -57,6 +67,7 @@ def babel(inp):
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
return e
|
return e
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def babelext(inp):
|
def babelext(inp):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -9,12 +9,13 @@ import hook
|
||||||
BUFFER_SIZE = 5000
|
BUFFER_SIZE = 5000
|
||||||
MAX_STEPS = 1000000
|
MAX_STEPS = 1000000
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def bf(input):
|
def bf(input):
|
||||||
"""Runs a Brainfuck program."""
|
"""Runs a Brainfuck program."""
|
||||||
|
|
||||||
program = re.sub('[^][<>+-.,]', '', input)
|
program = re.sub('[^][<>+-.,]', '', input)
|
||||||
|
|
||||||
# create a dict of brackets pairs, for speed later on
|
# create a dict of brackets pairs, for speed later on
|
||||||
brackets={}
|
brackets={}
|
||||||
open_brackets=[]
|
open_brackets=[]
|
||||||
|
@ -34,12 +35,11 @@ def bf(input):
|
||||||
# now we can start interpreting
|
# now we can start interpreting
|
||||||
ip = 0 # instruction pointer
|
ip = 0 # instruction pointer
|
||||||
mp = 0 # memory pointer
|
mp = 0 # memory pointer
|
||||||
steps = 0
|
steps = 0
|
||||||
memory = [0] * BUFFER_SIZE #initial memory area
|
memory = [0] * BUFFER_SIZE #initial memory area
|
||||||
rightmost = 0
|
rightmost = 0
|
||||||
|
|
||||||
output = "" #we'll save the output here
|
output = "" #we'll save the output here
|
||||||
|
|
||||||
# the main program loop:
|
# the main program loop:
|
||||||
while ip < len(program):
|
while ip < len(program):
|
||||||
c = program[ip]
|
c = program[ip]
|
||||||
|
@ -53,7 +53,7 @@ def bf(input):
|
||||||
rightmost = mp
|
rightmost = mp
|
||||||
if mp >= len(memory):
|
if mp >= len(memory):
|
||||||
# no restriction on memory growth!
|
# no restriction on memory growth!
|
||||||
memory.extend([0]*BUFFER_SIZE)
|
memory.extend([0]*BUFFER_SIZE)
|
||||||
elif c == '<':
|
elif c == '<':
|
||||||
mp = mp - 1 % len(memory)
|
mp = mp - 1 % len(memory)
|
||||||
elif c == '.':
|
elif c == '.':
|
||||||
|
@ -61,18 +61,18 @@ def bf(input):
|
||||||
if len(output) > 500:
|
if len(output) > 500:
|
||||||
break
|
break
|
||||||
elif c == ',':
|
elif c == ',':
|
||||||
memory[mp] = random.randint(1,255)
|
memory[mp] = random.randint(1, 255)
|
||||||
elif c == '[':
|
elif c == '[':
|
||||||
if memory[mp] == 0:
|
if memory[mp] == 0:
|
||||||
ip = brackets[ip]
|
ip = brackets[ip]
|
||||||
elif c == ']':
|
elif c == ']':
|
||||||
if memory[mp] != 0:
|
if memory[mp] != 0:
|
||||||
ip = brackets[ip]
|
ip = brackets[ip]
|
||||||
|
|
||||||
ip += 1
|
ip += 1
|
||||||
steps += 1
|
steps += 1
|
||||||
if steps > MAX_STEPS:
|
if steps > MAX_STEPS:
|
||||||
output += "Maximum number of steps exceeded"
|
output += "Maximum number of steps exceeded"
|
||||||
break
|
break
|
||||||
|
|
||||||
return unicode(re.sub('[\r\n\x00]', '/', output), 'iso-8859-1')[:430]
|
return unicode(re.sub('[\r\n\x00]', '/', output), 'iso-8859-1')[:430]
|
||||||
|
|
|
@ -2,6 +2,7 @@ import urllib
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command('god')
|
@hook.command('god')
|
||||||
@hook.command
|
@hook.command
|
||||||
def bible(inp):
|
def bible(inp):
|
||||||
|
@ -14,7 +15,7 @@ def bible(inp):
|
||||||
text = urllib.urlopen(base_url + urllib.quote(inp)).read()
|
text = urllib.urlopen(base_url + urllib.quote(inp)).read()
|
||||||
|
|
||||||
text = ' '.join(text.split())
|
text = ' '.join(text.split())
|
||||||
|
|
||||||
if len(text) > 400:
|
if len(text) > 400:
|
||||||
text = text[:text.rfind(' ', 0, 400)] + '...'
|
text = text[:text.rfind(' ', 0, 400)] + '...'
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,22 @@ valid_diceroll_re = re.compile(r'^[+-]?(\d+|\d*d\d+)([+-](\d+|\d*d\d+))*$')
|
||||||
sign_re = re.compile(r'[+-]?(?:\d*d)?\d+')
|
sign_re = re.compile(r'[+-]?(?:\d*d)?\d+')
|
||||||
split_re = re.compile(r'([\d+-]*)d?(\d*)')
|
split_re = re.compile(r'([\d+-]*)d?(\d*)')
|
||||||
|
|
||||||
|
|
||||||
def nrolls(count, n):
|
def nrolls(count, n):
|
||||||
"roll an n-sided die count times"
|
"roll an n-sided die count times"
|
||||||
if n < 2: #it's a coin
|
if n < 2: #it's a coin
|
||||||
if count < 5000:
|
if count < 5000:
|
||||||
return sum(random.randint(0,1) for x in xrange(count))
|
return sum(random.randint(0, 1) for x in xrange(count))
|
||||||
else: #fake it
|
else: #fake it
|
||||||
return int(random.normalvariate(.5*count,(.75*count)**.5))
|
return int(random.normalvariate(.5*count, (.75*count)**.5))
|
||||||
else:
|
else:
|
||||||
if count < 5000:
|
if count < 5000:
|
||||||
return sum(random.randint(1,n) for x in xrange(count))
|
return sum(random.randint(1, n) for x in xrange(count))
|
||||||
else: #fake it
|
else: #fake it
|
||||||
return int(random.normalvariate(.5*(1+n)*count,
|
return int(random.normalvariate(.5*(1+n)*count,
|
||||||
(((n+1)*(2*n+1)/6.-(.5*(1+n))**2)*count)**.5))
|
(((n+1)*(2*n+1)/6.-(.5*(1+n))**2)*count)**.5))
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def dice(input):
|
def dice(input):
|
||||||
".dice <diceroll> - simulates dicerolls, e.g. .dice 2d20-d5+4 roll 2 " \
|
".dice <diceroll> - simulates dicerolls, e.g. .dice 2d20-d5+4 roll 2 " \
|
||||||
|
@ -43,7 +45,7 @@ def dice(input):
|
||||||
if side == "":
|
if side == "":
|
||||||
sum += int(count)
|
sum += int(count)
|
||||||
else:
|
else:
|
||||||
count = int(count) if count not in " +-" else 1
|
count = int(count) if count not in" +-" else 1
|
||||||
side = int(side)
|
side = int(side)
|
||||||
try:
|
try:
|
||||||
if count > 0:
|
if count > 0:
|
||||||
|
@ -52,5 +54,5 @@ def dice(input):
|
||||||
sum -= nrolls(abs(count), side)
|
sum -= nrolls(abs(count), side)
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
return "Thanks for overflowing a float, jerk >:["
|
return "Thanks for overflowing a float, jerk >:["
|
||||||
|
|
||||||
return str(sum)
|
return str(sum)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
#@hook.command
|
#@hook.command
|
||||||
def goonsay(bot, input):
|
def goonsay(bot, input):
|
||||||
bot.say(' __________ /')
|
bot.say(' __________ /')
|
||||||
|
|
|
@ -2,14 +2,17 @@ import hashlib
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def md5(input):
|
def md5(input):
|
||||||
return hashlib.md5(input).hexdigest()
|
return hashlib.md5(input).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def sha1(input):
|
def sha1(input):
|
||||||
return hashlib.sha1(input).hexdigest()
|
return hashlib.sha1(input).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def hash(input):
|
def hash(input):
|
||||||
return ', '.join(x + ": " + getattr(hashlib, x)(input).hexdigest()
|
return ', '.join(x + ": " + getattr(hashlib, x)(input).hexdigest()
|
||||||
|
|
|
@ -3,32 +3,37 @@ def _isfunc(x):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _hook_add(func, add):
|
def _hook_add(func, add):
|
||||||
if not hasattr(func, '_skybot_hook'):
|
if not hasattr(func, '_skybot_hook'):
|
||||||
func._skybot_hook = []
|
func._skybot_hook = []
|
||||||
func._skybot_hook.append(add)
|
func._skybot_hook.append(add)
|
||||||
|
|
||||||
|
|
||||||
def _make_sig(f):
|
def _make_sig(f):
|
||||||
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
|
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
|
||||||
|
|
||||||
|
|
||||||
def sieve(func):
|
def sieve(func):
|
||||||
if func.func_code.co_argcount != 4:
|
if func.func_code.co_argcount != 4:
|
||||||
raise ValueError, \
|
raise ValueError(
|
||||||
'sieves must take 4 arguments: (bot, input, func, args)'
|
'sieves must take 4 arguments: (bot, input, func, args)')
|
||||||
_hook_add(func, ['sieve', (_make_sig(func), func)])
|
_hook_add(func, ['sieve', (_make_sig(func), func)])
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def command(func=None, hook=None, **kwargs):
|
def command(func=None, hook=None, **kwargs):
|
||||||
args = {}
|
args = {}
|
||||||
|
|
||||||
def command_wrapper(func):
|
def command_wrapper(func):
|
||||||
if func.func_code.co_argcount not in (1, 2):
|
if func.func_code.co_argcount not in (1, 2):
|
||||||
raise ValueError, \
|
raise ValueError(
|
||||||
'commands must take 1 or 2 arguments: (inp) or (bot, input)'
|
'commands must take 1 or 2 arguments: (inp) or (bot, input)')
|
||||||
args.setdefault('name', func.func_name)
|
args.setdefault('name', func.func_name)
|
||||||
args.setdefault('hook', args['name'] + r'(?:\s+|$)(.*)')
|
args.setdefault('hook', args['name'] + r'(?:\s+|$)(.*)')
|
||||||
_hook_add(func, ['command', (_make_sig(func), func, args)])
|
_hook_add(func, ['command', (_make_sig(func), func, args)])
|
||||||
return func
|
return func
|
||||||
|
|
||||||
if hook is not None or kwargs or not _isfunc(func):
|
if hook is not None or kwargs or not _isfunc(func):
|
||||||
if func is not None:
|
if func is not None:
|
||||||
args['name'] = func
|
args['name'] = func
|
||||||
|
@ -39,18 +44,19 @@ def command(func=None, hook=None, **kwargs):
|
||||||
else:
|
else:
|
||||||
return command_wrapper(func)
|
return command_wrapper(func)
|
||||||
|
|
||||||
|
|
||||||
def event(arg=None, **kwargs):
|
def event(arg=None, **kwargs):
|
||||||
args = kwargs
|
args = kwargs
|
||||||
|
|
||||||
def event_wrapper(func):
|
def event_wrapper(func):
|
||||||
if func.func_code.co_argcount != 2:
|
if func.func_code.co_argcount != 2:
|
||||||
raise ValueError, \
|
raise ValueError('events must take 2 arguments: (bot, input)')
|
||||||
'events must take 2 arguments: (bot, input)'
|
|
||||||
args['name'] = func.func_name
|
args['name'] = func.func_name
|
||||||
args['prefix'] = False
|
args['prefix'] = False
|
||||||
args.setdefault('events', '*')
|
args.setdefault('events', '*')
|
||||||
_hook_add(func, ['event', (_make_sig(func), func, args)])
|
_hook_add(func, ['event', (_make_sig(func), func, args)])
|
||||||
return func
|
return func
|
||||||
|
|
||||||
if _isfunc(arg):
|
if _isfunc(arg):
|
||||||
return event_wrapper(arg, kwargs)
|
return event_wrapper(arg, kwargs)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -6,9 +6,10 @@ posts everything buttbot says to the iambuttbot twitter account
|
||||||
import urllib
|
import urllib
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook=r'(.*)', prefix=False, ignorebots=False)
|
@hook.command(hook=r'(.*)', prefix=False, ignorebots=False)
|
||||||
def iambuttbot(bot, input):
|
def iambuttbot(bot, input):
|
||||||
if input.nick.lower() != 'buttbot':
|
if input.nick.lower() != 'buttbot':
|
||||||
return
|
return
|
||||||
|
|
||||||
if '@' in input or '#' in input:
|
if '@' in input or '#' in input:
|
||||||
|
|
|
@ -16,13 +16,16 @@ log_fds = {} # '%(net)s %(chan)s' : (filename, fd)
|
||||||
|
|
||||||
timestamp_format = '%H:%M:%S'
|
timestamp_format = '%H:%M:%S'
|
||||||
|
|
||||||
|
|
||||||
def get_log_filename(dir, network, chan):
|
def get_log_filename(dir, network, chan):
|
||||||
return os.path.join(dir, 'log', gmtime('%Y'), network,
|
return os.path.join(dir, 'log', gmtime('%Y'), network,
|
||||||
gmtime('%%s.%m-%d.log') % chan).lower()
|
gmtime('%%s.%m-%d.log') % chan).lower()
|
||||||
|
|
||||||
|
|
||||||
def gmtime(format):
|
def gmtime(format):
|
||||||
return time.strftime(format, time.gmtime())
|
return time.strftime(format, time.gmtime())
|
||||||
|
|
||||||
|
|
||||||
def get_log_fd(dir, network, chan):
|
def get_log_fd(dir, network, chan):
|
||||||
fn = get_log_filename(dir, network, chan)
|
fn = get_log_filename(dir, network, chan)
|
||||||
cache_key = '%s %s' % (network, chan)
|
cache_key = '%s %s' % (network, chan)
|
||||||
|
@ -40,10 +43,11 @@ def get_log_fd(dir, network, chan):
|
||||||
|
|
||||||
return fd
|
return fd
|
||||||
|
|
||||||
|
|
||||||
@hook.event(ignorebots=False)
|
@hook.event(ignorebots=False)
|
||||||
def log(bot, input):
|
def log(bot, input):
|
||||||
".remember <word> <data> -- maps word to data in the memory"
|
".remember <word> <data> -- maps word to data in the memory"
|
||||||
with lock:
|
with lock:
|
||||||
fd = get_log_fd(bot.persist_dir, bot.network, 'raw')
|
fd = get_log_fd(bot.persist_dir, bot.network, 'raw')
|
||||||
fd.write(gmtime(timestamp_format) + ' ' + input.raw + '\n')
|
fd.write(gmtime(timestamp_format) + ' ' + input.raw + '\n')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.event('KICK INVITE')
|
@hook.event('KICK INVITE')
|
||||||
def rejoin(bot, input):
|
def rejoin(bot, input):
|
||||||
print input.command, input.inp
|
print input.command, input.inp
|
||||||
|
|
|
@ -5,10 +5,11 @@ import hook
|
||||||
|
|
||||||
re_lineends = re.compile(r'[\r\n]*')
|
re_lineends = re.compile(r'[\r\n]*')
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def py(input):
|
def py(input):
|
||||||
res = urllib.urlopen("http://eval.appspot.com/eval?statement=%s" %
|
res = urllib.urlopen("http://eval.appspot.com/eval?statement=%s" %
|
||||||
urllib.quote(input.strip(),safe='')).readlines()
|
urllib.quote(input.strip(), safe='')).readlines()
|
||||||
if len(res) == 0:
|
if len(res) == 0:
|
||||||
return
|
return
|
||||||
res[0] = re_lineends.split(res[0])[0]
|
res[0] = re_lineends.split(res[0])[0]
|
||||||
|
|
|
@ -13,48 +13,53 @@ import hook
|
||||||
lock = thread.allocate_lock()
|
lock = thread.allocate_lock()
|
||||||
memory = {}
|
memory = {}
|
||||||
|
|
||||||
|
|
||||||
def load_memory(filename, mtimes={}):
|
def load_memory(filename, mtimes={}):
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
return {}
|
return {}
|
||||||
mtime = os.stat(filename).st_mtime
|
mtime = os.stat(filename).st_mtime
|
||||||
if mtimes.get(filename, 0) != mtime:
|
if mtimes.get(filename, 0) != mtime:
|
||||||
mtimes[filename] = mtime
|
mtimes[filename] = mtime
|
||||||
return dict((x.split(None, 1)[0].lower(), x.strip()) for x in
|
return dict((x.split(None, 1)[0].lower(), x.strip()) for x in
|
||||||
codecs.open(filename, 'r', 'utf-8'))
|
codecs.open(filename, 'r', 'utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def save_memory(filename, memory):
|
def save_memory(filename, memory):
|
||||||
out = codecs.open(filename, 'w', 'utf-8')
|
out = codecs.open(filename, 'w', 'utf-8')
|
||||||
out.write('\n'.join(sorted(memory.itervalues())))
|
out.write('\n'.join(sorted(memory.itervalues())))
|
||||||
out.flush()
|
out.flush()
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
|
|
||||||
def make_filename(dir, chan):
|
def make_filename(dir, chan):
|
||||||
return os.path.join(dir, 'memory')
|
return os.path.join(dir, 'memory')
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def remember(bot, input):
|
def remember(bot, input):
|
||||||
".remember <word> <data> -- maps word to data in the memory"
|
".remember <word> <data> -- maps word to data in the memory"
|
||||||
with lock:
|
with lock:
|
||||||
filename = make_filename(bot.persist_dir, input.chan)
|
filename = make_filename(bot.persist_dir, input.chan)
|
||||||
memory.setdefault(filename, load_memory(filename))
|
memory.setdefault(filename, load_memory(filename))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
head, tail = input.inp.split(None, 1)
|
head, tail = input.inp.split(None, 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return remember.__doc__
|
return remember.__doc__
|
||||||
|
|
||||||
tail = tail.strip()
|
tail = tail.strip()
|
||||||
low = head.lower()
|
low = head.lower()
|
||||||
if low not in memory[filename]:
|
if low not in memory[filename]:
|
||||||
bot.reply("done.")
|
bot.reply("done.")
|
||||||
else:
|
else:
|
||||||
bot.reply('forgetting that "%s", remembering this instead.' %
|
bot.reply('forgetting that "%s", remembering this instead.' %
|
||||||
memory[filename][low])
|
memory[filename][low])
|
||||||
memory[filename][low] = input.inp.strip()
|
memory[filename][low] = input.inp.strip()
|
||||||
save_memory(filename, memory[filename])
|
save_memory(filename, memory[filename])
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def forget(bot, input):
|
def forget(bot, input):
|
||||||
".forget <word> -- forgets the mapping that word had"
|
".forget <word> -- forgets the mapping that word had"
|
||||||
with lock:
|
with lock:
|
||||||
filename = make_filename(bot.persist_dir, input.chan)
|
filename = make_filename(bot.persist_dir, input.chan)
|
||||||
|
@ -62,7 +67,7 @@ def forget(bot, input):
|
||||||
|
|
||||||
if not input.inp.strip():
|
if not input.inp.strip():
|
||||||
return forget.__doc__
|
return forget.__doc__
|
||||||
|
|
||||||
print input.inp
|
print input.inp
|
||||||
low = input.inp.strip().lower()
|
low = input.inp.strip().lower()
|
||||||
print repr(low)
|
print repr(low)
|
||||||
|
@ -74,6 +79,7 @@ def forget(bot, input):
|
||||||
del memory[filename][low]
|
del memory[filename][low]
|
||||||
save_memory(filename, memory[filename])
|
save_memory(filename, memory[filename])
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook='\?(.+)', prefix=False)
|
@hook.command(hook='\?(.+)', prefix=False)
|
||||||
def question(bot, input):
|
def question(bot, input):
|
||||||
"?<word> -- shows what data is associated with word"
|
"?<word> -- shows what data is associated with word"
|
||||||
|
|
|
@ -8,6 +8,7 @@ from lxml import etree
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def twitter(bot, input):
|
def twitter(bot, input):
|
||||||
".twitter <user> - gets most recent tweet from <user>"
|
".twitter <user> - gets most recent tweet from <user>"
|
||||||
|
@ -23,7 +24,7 @@ def twitter(bot, input):
|
||||||
|
|
||||||
if tweet.find('error') is not None:
|
if tweet.find('error') is not None:
|
||||||
return "can't find that username"
|
return "can't find that username"
|
||||||
|
|
||||||
tweet = tweet.find('status')
|
tweet = tweet.find('status')
|
||||||
bot.say(': '.join(tweet.find(x).text for x in
|
bot.say(': '.join(tweet.find(x).text for x in
|
||||||
'created_at user/screen_name text'.split()))
|
'created_at user/screen_name text'.split()))
|
||||||
|
|
|
@ -3,6 +3,7 @@ import urllib
|
||||||
|
|
||||||
import hook
|
import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command('u')
|
@hook.command('u')
|
||||||
@hook.command
|
@hook.command
|
||||||
def urban(inp):
|
def urban(inp):
|
||||||
|
|
|
@ -13,21 +13,24 @@ import hook
|
||||||
lock = thread.allocate_lock()
|
lock = thread.allocate_lock()
|
||||||
stalk = {}
|
stalk = {}
|
||||||
|
|
||||||
|
|
||||||
def load_stalk(filename, mtimes={}):
|
def load_stalk(filename, mtimes={}):
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
return {}
|
return {}
|
||||||
mtime = os.stat(filename).st_mtime
|
mtime = os.stat(filename).st_mtime
|
||||||
if mtimes.get(filename, 0) != mtime:
|
if mtimes.get(filename, 0) != mtime:
|
||||||
mtimes[filename] = mtime
|
mtimes[filename] = mtime
|
||||||
return dict(x.strip().split(None, 1) for x in
|
return dict(x.strip().split(None, 1) for x in
|
||||||
codecs.open(filename, 'r', 'utf-8'))
|
codecs.open(filename, 'r', 'utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def save_stalk(filename, houses):
|
def save_stalk(filename, houses):
|
||||||
out = codecs.open(filename, 'w', 'utf-8')
|
out = codecs.open(filename, 'w', 'utf-8')
|
||||||
out.write('\n'.join('%s %s' % x for x in sorted(houses.iteritems()))) #_heh_
|
out.write('\n'.join('%s %s' % x for x in sorted(houses.iteritems()))) #heh
|
||||||
out.flush()
|
out.flush()
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def weather(bot, input):
|
def weather(bot, input):
|
||||||
".weather <location> -- queries the google weather API for weather data"
|
".weather <location> -- queries the google weather API for weather data"
|
||||||
|
@ -37,7 +40,7 @@ def weather(bot, input):
|
||||||
if not stalk:
|
if not stalk:
|
||||||
with lock:
|
with lock:
|
||||||
stalk = load_stalk(filename)
|
stalk = load_stalk(filename)
|
||||||
|
|
||||||
nick = input.nick.lower()
|
nick = input.nick.lower()
|
||||||
loc = input.inp.strip().lower()
|
loc = input.inp.strip().lower()
|
||||||
if not loc: # blank line
|
if not loc: # blank line
|
||||||
|
@ -45,14 +48,14 @@ def weather(bot, input):
|
||||||
if not loc:
|
if not loc:
|
||||||
return weather.__doc__
|
return weather.__doc__
|
||||||
|
|
||||||
data = urllib.urlencode({'weather':loc.encode('utf-8')})
|
data = urllib.urlencode({'weather': loc.encode('utf-8')})
|
||||||
url = 'http://www.google.com/ig/api?' + data
|
url = 'http://www.google.com/ig/api?' + data
|
||||||
w = etree.parse(url).find('weather')
|
w = etree.parse(url).find('weather')
|
||||||
|
|
||||||
if w.find('problem_cause') is not None:
|
if w.find('problem_cause') is not None:
|
||||||
return "Couldn't fetch weather data for '%s', try using a zip or " \
|
return "Couldn't fetch weather data for '%s', try using a zip or " \
|
||||||
"postal code." % input.inp
|
"postal code." % input.inp
|
||||||
|
|
||||||
info = dict((e.tag, e.get('data')) for e in w.find('current_conditions'))
|
info = dict((e.tag, e.get('data')) for e in w.find('current_conditions'))
|
||||||
info['city'] = w.find('forecast_information/city').get('data')
|
info['city'] = w.find('forecast_information/city').get('data')
|
||||||
info['high'] = w.find('forecast_conditions/high').get('data')
|
info['high'] = w.find('forecast_conditions/high').get('data')
|
||||||
|
|
|
@ -12,11 +12,13 @@ search_url = api_prefix + "?action=opensearch&search=%s&format=xml"
|
||||||
|
|
||||||
paren_re = re.compile('\s*\(.*\)$')
|
paren_re = re.compile('\s*\(.*\)$')
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook='w(\s+.*|$)')
|
@hook.command(hook='w(\s+.*|$)')
|
||||||
@hook.command
|
@hook.command
|
||||||
def wiki(query):
|
def wiki(query):
|
||||||
'''.w/.wiki <phrase> -- gets first sentence of wikipedia article on <phrase>'''
|
'''.w/.wiki <phrase> -- gets first sentence of wikipedia ''' \
|
||||||
|
'''article on <phrase>'''
|
||||||
|
|
||||||
if not query.strip():
|
if not query.strip():
|
||||||
return wiki.__doc__
|
return wiki.__doc__
|
||||||
|
|
||||||
|
@ -33,19 +35,19 @@ def wiki(query):
|
||||||
return 'no results found'
|
return 'no results found'
|
||||||
|
|
||||||
def extract(item):
|
def extract(item):
|
||||||
return [item.find(ns + x).text for x in
|
return [item.find(ns + x).text for x in
|
||||||
('Text', 'Description', 'Url')]
|
('Text', 'Description', 'Url')]
|
||||||
|
|
||||||
title, desc, url = extract(items[0])
|
title, desc, url = extract(items[0])
|
||||||
|
|
||||||
if 'may refer to' in desc:
|
if 'may refer to' in desc:
|
||||||
title, desc, url = extract(items[1])
|
title, desc, url = extract(items[1])
|
||||||
|
|
||||||
title = paren_re.sub('', title)
|
title = paren_re.sub('', title)
|
||||||
|
|
||||||
if title.lower() not in desc.lower():
|
if title.lower() not in desc.lower():
|
||||||
desc = title + desc
|
desc = title + desc
|
||||||
|
|
||||||
desc = re.sub('\s+', ' ', desc).strip() #remove excess spaces
|
desc = re.sub('\s+', ' ', desc).strip() #remove excess spaces
|
||||||
|
|
||||||
if len(desc) > 300:
|
if len(desc) > 300:
|
||||||
|
|
|
@ -6,6 +6,7 @@ import hook
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, "")
|
locale.setlocale(locale.LC_ALL, "")
|
||||||
|
|
||||||
|
|
||||||
def ytdata(id):
|
def ytdata(id):
|
||||||
url = 'http://gdata.youtube.com/feeds/api/videos/' + id
|
url = 'http://gdata.youtube.com/feeds/api/videos/' + id
|
||||||
x = etree.parse(url)
|
x = etree.parse(url)
|
||||||
|
@ -31,6 +32,7 @@ def ytdata(id):
|
||||||
|
|
||||||
youtube_re = re.compile(r'.*youtube.*v=([-_a-z0-9]+)', flags=re.IGNORECASE)
|
youtube_re = re.compile(r'.*youtube.*v=([-_a-z0-9]+)', flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
#@hook.command(hook=r'(.*)', prefix=False)
|
#@hook.command(hook=r'(.*)', prefix=False)
|
||||||
def youtube(inp):
|
def youtube(inp):
|
||||||
m = youtube_re.match(inp)
|
m = youtube_re.match(inp)
|
||||||
|
|
Loading…
Reference in New Issue