PEP8 compliance (only whitespace changes)

This commit is contained in:
Ryan Hitchman 2009-04-17 18:57:18 -06:00
parent 94d9fd22f0
commit 5ea26b8ff7
20 changed files with 122 additions and 63 deletions

15
bot.py
View File

@ -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

View File

@ -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
View File

@ -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:

View File

@ -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:

View File

@ -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]

View File

@ -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)] + '...'

View File

@ -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)

View File

@ -1,5 +1,6 @@
import hook import hook
#@hook.command #@hook.command
def goonsay(bot, input): def goonsay(bot, input):
bot.say(' __________ /') bot.say(' __________ /')

View File

@ -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()

View File

@ -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:

View File

@ -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:

View File

@ -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')

View File

@ -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

View File

@ -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]

View File

@ -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"

View File

@ -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()))

View File

@ -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):

View File

@ -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')

View File

@ -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:

View File

@ -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)