change calling convention

This commit is contained in:
Ryan Hitchman 2010-02-01 21:42:34 -07:00
parent 8c68bbd128
commit 1dd86babc2
13 changed files with 202 additions and 202 deletions

View File

@ -1,43 +1,44 @@
import thread
import traceback
class Input(object):
class Input(dict):
def __init__(self, conn, raw, prefix, command, params,
nick, user, host, paraml, msg):
chan = paraml[0].lower()
if chan == conn.nick: # is a PM
chan = nick
def __init__(self, conn, raw, prefix, command,
params, nick, user, host, paraml, msg):
self.conn = conn # irc object
self.server = conn.server # hostname of server
self.raw = raw # unprocessed line of text
self.prefix = prefix # usually hostmask
self.command = command # PRIVMSG, JOIN, etc.
self.params = params
self.nick = nick
self.user = user # user@host
self.host = host
self.paraml = paraml # params[-1] without the :
self.msg = msg
self.chan = paraml[0].lower()
if self.chan == conn.nick: # is a PM
self.chan = nick
def say(msg):
conn.msg(chan, msg)
def say(self, msg):
self.conn.msg(self.chan, msg)
def reply(msg):
conn.msg(chan, nick + ': ' + msg)
def reply(self, msg):
self.say(self.nick + ': ' + msg)
def pm(msg):
conn.msg(nick, msg)
def pm(self, msg):
self.conn.msg(self.nick, msg)
dict.__init__(self, conn=conn, raw=raw, prefix=prefix, command=command,
params=params, nick=nick, user=user, host=host,
paraml=paraml, msg=msg, server=conn.server, chan=chan,
say=say, reply=reply, pm=pm, bot=bot)
self.__dict__ = self # permits attribute access to values
def run(func, input):
ac = func.func_code.co_argcount
if ac == 2:
out = func(bot, input)
elif ac == 1:
out = func(input.inp)
args = func._skybot_args
if args:
if 'db' in args:
input['db'] = get_db_connection(input['server'])
if 0 in args:
out = func(input['inp'], **input)
else:
kw = dict((key, input[key]) for key in args if key in input)
out = func(input['inp'], **kw)
else:
out = func(input['inp'])
if out is not None:
input.reply(unicode(out))
input['reply'](unicode(out))
def main(conn, out):

View File

@ -2,7 +2,7 @@ from util import hook
#Scaevolus: factormystic if you commit a re-enabled goonsay I'm going to revoke your commit access
#@hook.command
def goonsay(bot, input):
input.say(' __________ /')
input.say('(--[. ]-[ .] /')
input.say('(_______o__)')
def goonsay(inp, say=None):
say(' __________ /')
say('(--[. ]-[ .] /')
say('(_______o__)')

View File

@ -1,7 +1,7 @@
from util import hook
@hook.command
def help(bot, input):
def help(inp, bot=None, pm=None):
".help [command] -- gives a list of commands/help for a command"
funcs = {}
@ -10,8 +10,8 @@ def help(bot, input):
if func.__doc__ is not None:
funcs[csig[1]] = func
if not input.inp:
input.pm('available commands: ' + ' '.join(sorted(funcs)))
if not inp:
pm('available commands: ' + ' '.join(sorted(funcs)))
else:
if input.inp in funcs:
input.pm(funcs[input.inp].__doc__)
if inp in funcs:
pm(funcs[inp].__doc__)

View File

@ -6,25 +6,25 @@ socket.setdefaulttimeout(5) # global setting
#autorejoin channels
@hook.event('KICK')
def rejoin(bot, input):
if input.paraml[1] == input.conn.nick:
if input.paraml[0] in input.conn.channels:
input.conn.join(input.paraml[0])
def rejoin(inp, paraml=[], conn=None):
if paraml[1] == conn.nick:
if paraml[0].lower() in conn.channels:
conn.join(paraml[0])
#join channels when invited
@hook.event('INVITE')
def invite(bot, input):
if input.command == 'INVITE':
input.conn.join(input.inp)
def invite(inp, command='', conn=None):
if command == 'INVITE':
conn.join(inp)
#join channels when server says hello & identify bot
@hook.event('004')
def onjoin(bot, input):
for channel in input.conn.channels:
input.conn.join(channel)
def onjoin(inp, conn=None):
for channel in conn.channels:
conn.join(channel)
nickserv_password = input.conn.conf.get('nickserv_password', '')
nickserv_name = input.conn.conf.get('nickserv_name', 'nickserv')
nickserv_command = input.conn.conf.get('nickserv_command', 'IDENTIFY %s')
nickserv_password = conn.conf.get('nickserv_password', '')
nickserv_name = conn.conf.get('nickserv_name', 'nickserv')
nickserv_command = conn.conf.get('nickserv_command', 'IDENTIFY %s')
if nickserv_password:
input.conn.msg(nickserv_name, nickserv_command % nickserv_password)
conn.msg(nickserv_name, nickserv_command % nickserv_password)

View File

@ -164,6 +164,7 @@ set_abbrevs = {
'Zendikar': 'ZEN'}
rarity_abbrevs = {
'Land': 'L',
'Common': 'C',
'Uncommon': 'UC',
'Rare': 'R',

View File

@ -5,20 +5,20 @@ import time
from util import hook
def add_quote(conn, chan, nick, add_nick, msg):
def add_quote(db, chan, nick, add_nick, msg):
now = time.time()
conn.execute('''insert or fail into quote (chan, nick, add_nick,
db.execute('''insert or fail into quote (chan, nick, add_nick,
msg, time) values(?,?,?,?,?)''',
(chan, nick, add_nick, msg, now))
conn.commit()
db.commit()
def get_quotes_by_nick(conn, chan, nick):
return conn.execute("select time, nick, msg from quote where deleted!=1 "
def get_quotes_by_nick(db, chan, nick):
return db.execute("select time, nick, msg from quote where deleted!=1 "
"and chan=? and lower(nick)=lower(?) order by time",
(chan, nick)).fetchall()
def get_quotes_by_chan(conn, chan):
return conn.execute("select time, nick, msg from quote where deleted!=1 "
def get_quotes_by_chan(db, chan):
return db.execute("select time, nick, msg from quote where deleted!=1 "
"and chan=? order by time", (chan,)).fetchall()
@ -29,26 +29,24 @@ def format_quote(q, num, n_quotes):
@hook.command('q')
@hook.command
def quote(bot, input):
def quote(inp, nick='', chan='', db=None):
".q/.quote <nick/#chan> [#n]/.quote add <nick> <msg> -- gets " \
"random or [#n]th quote by <nick> or from <#chan>/adds quote"
conn = bot.get_db_connection(input.server)
conn.execute("create table if not exists quote"
db.execute("create table if not exists quote"
"(chan, nick, add_nick, msg, time real, deleted default 0, "
"primary key (chan, nick, msg))")
conn.commit()
db.commit()
try:
add = re.match(r"add\s+<?[^\w]?(\S+?)>?\s+(.*)", input.inp, re.I)
retrieve = re.match(r"(\S+)(?:\s+#?(-?\d+))?", input.inp)
chan = input.chan
add = re.match(r"add\s+<?[^\w]?(\S+?)>?\s+(.*)", inp, re.I)
retrieve = re.match(r"(\S+)(?:\s+#?(-?\d+))?", inp)
if add:
nick, msg = add.groups()
quoted_nick, msg = add.groups()
try:
add_quote(conn, chan, nick, input.nick, msg)
except conn.IntegrityError:
add_quote(db, chan, quoted_nick, nick, msg)
except db.IntegrityError:
return "message already stored, doing nothing."
return "quote added."
elif retrieve:
@ -57,9 +55,9 @@ def quote(bot, input):
by_chan = False
if select.startswith('#'):
by_chan = True
quotes = get_quotes_by_chan(conn, select)
quotes = get_quotes_by_chan(db, select)
else:
quotes = get_quotes_by_nick(conn, chan, select)
quotes = get_quotes_by_nick(db, chan, select)
n_quotes = len(quotes)
@ -83,5 +81,5 @@ def quote(bot, input):
else:
return quote.__doc__
finally:
conn.commit()
conn.close()
db.commit()
db.close()

View File

@ -5,34 +5,20 @@ skybot plugin for testing regular expressions
by Ipsum
'''
import thread
import codecs
import re
from util import hook
@hook.command('re')
def reg(bot, input):
".re <regex> <string> -- matches regular expression in given <string> (seperate regex and string by 2 spaces)"
def reg(inp):
".re <regex> <string> -- matches regular expression in given <string> "\
"(leave 2 spaces between)"
m = ""
if len(input.msg) < 3:
return reg.__doc__
query = input.inp.partition(" ")
if query[2] != "":
r = re.compile(query[0])
query = inp.split(" ", 1)
if not inp or len(query) != 2:
return reg.__doc__
return '|'.join(re.findall(query[0], query[1]))
matches = r.findall(query[2])
for match in matches:
m += match + "|"
return m.rstrip('|')
else:
return reg.__doc__

View File

@ -10,47 +10,41 @@ def seeninput(bot, input):
if input.command != 'PRIVMSG':
return
conn = db_connect(bot, input.server)
cursor = conn.cursor()
cursor.execute("insert or replace into seen(name, time, quote, chan)"
"values(?,?,?,?)", (input.nick.lower(), time.time(),
input.msg, input.chan))
conn.commit()
db = bot.get_db_connection(input.server)
db_init(db)
db.execute("insert or replace into seen(name, time, quote, chan)"
"values(?,?,?,?)", (input.nick.lower(), time.time(), input.msg,
input.chan))
db.commit()
@hook.command
def seen(bot, input):
def seen(inp, nick='', chan='', db=None):
".seen <nick> -- Tell when a nickname was last in active in irc"
if not input.inp:
if not inp:
return seen.__doc__
query = input.inp
if query.lower() == input.nick.lower():
if inp.lower() == nick.lower():
return "Have you looked in a mirror lately?"
conn = db_connect(bot, input.server)
cursor = conn.cursor()
db_init(db)
command = "select time, quote FROM seen WHERE name LIKE ? AND chan = ?"
cursor.execute(command, (query, input.chan))
results = cursor.fetchone()
last_seen = db.execute("select name, time, quote from seen where name"
" like ? and chan = ?", (inp, chan)).fetchone()
if results:
reltime = timesince.timesince(results[0])
if last_seen:
reltime = timesince.timesince(last_seen[1])
if last_seen[0] != inp.lower(): # for glob matching
inp = last_seen[0]
return '%s was last seen %s ago saying: %s' % \
(query, reltime, results[1])
(inp, reltime, last_seen[2])
else:
return "I've never seen %s" % query
return "I've never seen %s" % inp
def db_connect(bot, server):
def db_init(db):
"check to see that our db has the the seen table and return a connection."
conn = bot.get_db_connection(server)
conn.execute("create table if not exists seen(name, time, quote, chan, "
db.execute("create table if not exists seen(name, time, quote, chan, "
"primary key(name, chan))")
conn.commit()
return conn
db.commit()

View File

@ -7,12 +7,12 @@ import json
from util import hook
@hook.command
def suggest(bot, input):
def suggest(inp, inp_unstripped=''):
".suggest [#n] <phrase> -- gets a random/the nth suggested google search"
if not input.inp:
if not inp:
return suggest.__doc__
inp = input.inp_unstripped
inp = inp_unstripped
m = re.match('^#(\d+) (.+)$', inp)
if m:
num, inp = m.groups()

View File

@ -5,20 +5,24 @@ import time
from util import hook, timesince
def get_tells(conn, user_to, chan):
return conn.execute("select user_from, message, time from tell where"
def get_tells(db, user_to, chan):
return db.execute("select user_from, message, time from tell where"
" user_to=lower(?) and chan=? order by time",
(user_to.lower(), chan)).fetchall()
@hook.command(hook=r'(.*)', prefix=False)
@hook.tee
def tellinput(bot, input):
if 'showtells' in input.inp.lower():
if input.command != 'PRIVMSG':
return
if 'showtells' in input.msg.lower():
return
conn = db_connect(bot, input.server)
db = bot.get_db_connection(input.server)
db = db_init(db)
tells = get_tells(conn, input.nick, input.chan)
tells = get_tells(db, input.nick, input.chan)
if tells:
user_from, message, time = tells[0]
@ -28,72 +32,70 @@ def tellinput(bot, input):
if len(tells) > 1:
reply += " (+%d more, .showtells to view)" % (len(tells) - 1)
conn.execute("delete from tell where user_to=lower(?) and message=?",
db.execute("delete from tell where user_to=lower(?) and message=?",
(input.nick, message))
conn.commit()
return reply
db.commit()
input.reply(reply)
@hook.command
def showtells(bot, input):
def showtells(inp, nick='', chan='', pm=None, db=None):
".showtells -- view all pending tell messages (sent in PM)."
conn = db_connect(bot, input.server)
db_init(db)
tells = get_tells(conn, input.nick, input.chan)
tells = get_tells(db, nick, chan)
if not tells:
input.pm("You have no pending tells.")
pm("You have no pending tells.")
return
for tell in tells:
user_from, message, time = tell
reltime = timesince.timesince(time)
input.pm("%s said %s ago: %s" % (user_from, reltime, message))
pm("%s said %s ago: %s" % (user_from, reltime, message))
conn.execute("delete from tell where user_to=lower(?) and chan=?",
(input.nick, input.chan))
conn.commit()
db.execute("delete from tell where user_to=lower(?) and chan=?",
(nick, chan))
db.commit()
@hook.command
def tell(bot, input):
def tell(inp, nick='', chan='', db=None):
".tell <nick> <message> -- relay <message> to <nick> when <nick> is around"
query = input.inp.split(' ', 1)
query = inp.split(' ', 1)
if len(query) != 2 or not input.inp:
if not inp or len(query) != 2:
return tell.__doc__
user_to = query[0].lower()
message = query[1].strip()
user_from = input.nick
user_from = nick
if user_to == user_from.lower():
return "No."
conn = db_connect(bot, input.server)
db_init(db)
if conn.execute("select count() from tell where user_to=?",
if db.execute("select count() from tell where user_to=?",
(user_to,)).fetchone()[0] >= 5:
return "That person has too many things queued."
try:
conn.execute("insert into tell(user_to, user_from, message, chan,"
db.execute("insert into tell(user_to, user_from, message, chan,"
"time) values(?,?,?,?,?)", (user_to, user_from, message,
input.chan, time.time()))
conn.commit()
except conn.IntegrityError:
chan, time.time()))
db.commit()
except db.IntegrityError:
return "Message has already been queued."
return "I'll pass that along."
def db_connect(bot, server):
"check to see that our db has the tell table and return a connection."
conn = bot.get_db_connection(server)
conn.execute("create table if not exists tell"
def db_init(db):
"check to see that our db has the tell table and return a dbection."
db.execute("create table if not exists tell"
"(user_to, user_from, message, chan, time,"
"primary key(user_to, message))")
conn.commit()
db.commit()
return conn
return db

View File

@ -11,23 +11,23 @@ expiration_period_text = "24 hours"
ignored_urls = [urlnorm.normalize("http://google.com")]
def db_connect(bot, server):
"check to see that our db has the the seen table and return a connection."
conn = bot.get_db_connection(server)
conn.execute("create table if not exists urlhistory"
"check to see that our db has the the seen table and return a dbection."
db = bot.get_db_connection(server)
db.execute("create table if not exists urlhistory"
"(chan, url, nick, time)")
conn.commit()
return conn
db.commit()
return db
def insert_history(conn, chan, url, nick):
def insert_history(db, chan, url, nick):
now = time.time()
conn.execute("insert into urlhistory(chan, url, nick, time) "
db.execute("insert into urlhistory(chan, url, nick, time) "
"values(?,?,?,?)", (chan, url, nick, time.time()))
conn.commit()
db.commit()
def get_history(conn, chan, url):
conn.execute("delete from urlhistory where time < ?",
def get_history(db, chan, url):
db.execute("delete from urlhistory where time < ?",
(time.time() - expiration_period,))
nicks = conn.execute("select nick from urlhistory where "
nicks = db.execute("select nick from urlhistory where "
"chan=? and url=?", (chan, url)).fetchall()
return [x[0] for x in nicks]
@ -42,22 +42,22 @@ def ordinal(count):
return ["once", "twice", "%d times" % count][min(count, 3) - 1]
@hook.command(hook=r'(.*)', prefix=False)
def urlinput(bot, input):
m = url_re.search(input.msg.encode('utf8'))
def urlinput(inp, nick='', chan='', server='', reply=None, bot=None):
m = url_re.search(inp.encode('utf8'))
if not m:
return
# URL detected
conn = db_connect(bot, input.server)
db = db_connect(bot, server)
try:
url = urlnorm.normalize(m.group(0))
if url not in ignored_urls:
dupes = get_history(conn, input.chan, url)
insert_history(conn, input.chan, url, input.nick)
if dupes and input.nick not in dupes:
input.reply("That link has been posted " + ordinal(len(dupes))
dupes = get_history(db, chan, url)
insert_history(db, chan, url, nick)
if dupes and nick not in dupes:
reply("That link has been posted " + ordinal(len(dupes))
+ " in the past " + expiration_period_text + " by " +
get_nicklist(dupes))
finally:
conn.commit()
conn.close()
db.commit()
db.close()

View File

@ -1,6 +1,7 @@
import Queue
import inspect
import thread
import traceback
import Queue
def _isfunc(x):
if type(x) == type(_isfunc):
@ -8,11 +9,33 @@ def _isfunc(x):
return False
def _hook_add(func, add):
def _hook_add(func, add, name=''):
if not hasattr(func, '_skybot_hook'):
func._skybot_hook = []
func._skybot_hook.append(add)
if not hasattr(func, '_skybot_args'):
argspec = inspect.getargspec(func)
if name:
n_args = len(argspec.args)
if argspec.defaults:
n_args -= len(argspec.defaults)
if argspec.keywords:
n_args -= 1
if argspec.varargs:
n_args -= 1
if n_args != 1:
err = '%ss must take 1 non-keyword argument (%s)' % (name,
func.__name__)
raise ValueError(err)
args = []
if argspec.defaults:
end = bool(argspec.keywords) + bool(argspec.varargs)
args.extend(argspec.args[-len(argspec.defaults):
end if end else None])
if argspec.keywords:
args.append(0) # means kwargs present
func._skybot_args = args
def _make_sig(f):
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
@ -30,12 +53,9 @@ def command(func=None, hook=None, **kwargs):
args = {}
def command_wrapper(func):
if func.func_code.co_argcount not in (1, 2):
raise ValueError(
'commands must take 1 or 2 arguments: (inp) or (bot, input)')
args.setdefault('name', func.func_name)
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)], 'command')
return func
if hook is not None or kwargs or not _isfunc(func):
@ -53,12 +73,10 @@ def event(arg=None, **kwargs):
args = kwargs
def event_wrapper(func):
if func.func_code.co_argcount != 2:
raise ValueError('events must take 2 arguments: (bot, input)')
args['name'] = func.func_name
args['prefix'] = False
args.setdefault('events', '*')
_hook_add(func, ['event', (_make_sig(func), func, args)])
_hook_add(func, ['event', (_make_sig(func), func, args)], 'event')
return func
if _isfunc(arg):
@ -74,7 +92,7 @@ def tee(func, **kwargs):
if func.func_code.co_argcount != 2:
raise ValueError('tees must take 2 arguments: (bot, input)')
_hook_add(func, ['tee', (_make_sig(func), func, kwargs)])
func._iqueue = Queue.Queue()

View File

@ -7,20 +7,20 @@ from util import hook
@hook.command
def weather(bot, input):
def weather(inp, nick='', server='', reply=None, db=None):
".weather <location> [dontsave] -- queries the google weather API for weather data"
loc = input.inp
loc = inp
dontsave = loc.endswith(" dontsave")
if dontsave:
loc = loc[:-9].strip().lower()
conn = bot.get_db_connection(input.server)
conn.execute("create table if not exists weather(nick primary key, loc)")
db.execute("create table if not exists weather(nick primary key, loc)")
if not loc: # blank line
loc = conn.execute("select loc from weather where nick=lower(?)",
(input.nick,)).fetchone()
loc = db.execute("select loc from weather where nick=lower(?)",
(nick,)).fetchone()
if not loc:
return weather.__doc__
loc = loc[0]
@ -31,17 +31,17 @@ def weather(bot, input):
if w.find('problem_cause') is not None:
return "Couldn't fetch weather data for '%s', try using a zip or " \
"postal code." % input.inp
"postal code." % inp
info = dict((e.tag, e.get('data')) for e in w.find('current_conditions'))
info['city'] = w.find('forecast_information/city').get('data')
info['high'] = w.find('forecast_conditions/high').get('data')
info['low'] = w.find('forecast_conditions/low').get('data')
input.reply('%(city)s: %(condition)s, %(temp_f)sF/%(temp_c)sC (H:%(high)sF'\
reply('%(city)s: %(condition)s, %(temp_f)sF/%(temp_c)sC (H:%(high)sF'\
', L:%(low)sF), %(humidity)s, %(wind_condition)s.' % info)
if input.inp and not dontsave:
conn.execute("insert or replace into weather(nick, loc) values (?,?)",
(input.nick.lower(), loc))
conn.commit()
if inp and not dontsave:
db.execute("insert or replace into weather(nick, loc) values (?,?)",
(nick.lower(), loc))
db.commit()