diff --git a/.hgignore b/.hgignore index da631cd..5c7670e 100644 --- a/.hgignore +++ b/.hgignore @@ -3,3 +3,4 @@ syntax: glob *.pyc iambuttbot_password persist +pep8.py diff --git a/docs/bots b/docs/bots new file mode 100644 index 0000000..7181b80 --- /dev/null +++ b/docs/bots @@ -0,0 +1,26 @@ +Other bots we should "borrow" ideas from: + +supybot http://supybot.com/ + - horribly bloated plugin structure, each plugin has its own directory and 4 files (unit testing for plugins what) + +phenny http://inamidst.com/phenny/ + - inspiration for skybot, too much magic and not easy enough to change + +pyfibot http://code.google.com/p/pyfibot/ + - interesting, but lots of magic + +rbot http://linuxbrit.co.uk/rbot/ + - Ruby + - lots of plugins + +pyirc http://www.k-pdt.net/pyirc/ + - very simple, not multithreaded + - poor use of regexes, skybot has much better parsing, but it implements many more irc control godes + - can convert irc colors to vt100 escape codes -- should implement this + - autoreconnect + +pybot + - can handle multiple servers, but not multithreaded + - ugly modules + - too many external dependencies + - attempt at NLP diff --git a/plugins/babel.py b/plugins/babel.py index d993187..1b76c76 100644 --- a/plugins/babel.py +++ b/plugins/babel.py @@ -1,10 +1,8 @@ -import yaml import urllib import htmlentitydefs import re -import hook - +from util import hook, yaml ########### from http://effbot.org/zone/re-sub.htm#unescape-html ############# diff --git a/plugins/bf.py b/plugins/bf.py index a69e29a..761c04a 100644 --- a/plugins/bf.py +++ b/plugins/bf.py @@ -4,7 +4,8 @@ http://brainfuck.sourceforge.net/brain.py''' import re import random -import hook +from util import hook + BUFFER_SIZE = 5000 MAX_STEPS = 1000000 diff --git a/plugins/bible.py b/plugins/bible.py index 1ad479f..11fe18a 100644 --- a/plugins/bible.py +++ b/plugins/bible.py @@ -1,6 +1,6 @@ import urllib -import hook +from util import hook @hook.command('god') diff --git a/plugins/dice.py b/plugins/dice.py index 778db8a..6edb920 100644 --- a/plugins/dice.py +++ b/plugins/dice.py @@ -5,7 +5,8 @@ simulates dicerolls import re import random -import hook +from util import hook + whitespace_re = re.compile(r'\s+') valid_diceroll_re = re.compile(r'^[+-]?(\d+|\d*d\d+)([+-](\d+|\d*d\d+))*$') diff --git a/plugins/google.py b/plugins/google.py index 37c03bb..c87fcd2 100644 --- a/plugins/google.py +++ b/plugins/google.py @@ -1,8 +1,7 @@ -import yaml import urllib from lxml import html -import hook +from util import hook, yaml def api_get(kind, query): diff --git a/plugins/goonsay.py b/plugins/goonsay.py index 894e35e..688c6b9 100644 --- a/plugins/goonsay.py +++ b/plugins/goonsay.py @@ -1,4 +1,4 @@ -import hook +from util import hook #@hook.command diff --git a/plugins/hash.py b/plugins/hash.py index 3a1d069..f4f5956 100644 --- a/plugins/hash.py +++ b/plugins/hash.py @@ -1,6 +1,6 @@ import hashlib -import hook +from util import hook @hook.command diff --git a/plugins/iambuttbot.py b/plugins/iambuttbot.py index ca1423b..a793f8a 100644 --- a/plugins/iambuttbot.py +++ b/plugins/iambuttbot.py @@ -4,7 +4,8 @@ posts everything buttbot says to the iambuttbot twitter account """ import urllib -import hook + +from util import hook @hook.command(hook=r'(.*)', prefix=False, ignorebots=False) diff --git a/plugins/log.py b/plugins/log.py index 2bbb7b1..6a8d4c7 100644 --- a/plugins/log.py +++ b/plugins/log.py @@ -8,7 +8,8 @@ import codecs import time import re -import hook +from util import hook + lock = thread.allocate_lock() log_fds = {} # '%(net)s %(chan)s' : (filename, fd) diff --git a/plugins/misc.py b/plugins/misc.py index 5b433ef..a2f3030 100644 --- a/plugins/misc.py +++ b/plugins/misc.py @@ -1,4 +1,4 @@ -import hook +from util import hook @hook.event('KICK INVITE') diff --git a/plugins/profile.py b/plugins/profile.py index 0509f3d..b3b2c5c 100644 --- a/plugins/profile.py +++ b/plugins/profile.py @@ -1,6 +1,6 @@ # for crusty old rotor -import hook +from util import hook @hook.command diff --git a/plugins/pyexec.py b/plugins/pyexec.py index a986c02..431d386 100644 --- a/plugins/pyexec.py +++ b/plugins/pyexec.py @@ -1,7 +1,8 @@ import urllib import re -import hook +from util import hook + re_lineends = re.compile(r'[\r\n]*') diff --git a/plugins/remember.py b/plugins/remember.py index 5d5f99a..23fd1e3 100644 --- a/plugins/remember.py +++ b/plugins/remember.py @@ -6,7 +6,8 @@ import os import thread import codecs -import hook +from util import hook + lock = thread.allocate_lock() memory = {} diff --git a/plugins/seen.py b/plugins/seen.py index 0fe1fd8..5f3b348 100644 --- a/plugins/seen.py +++ b/plugins/seen.py @@ -2,11 +2,11 @@ import sqlite3 import datetime, time -import hook import os -from timesince import timesince -dbname = "skydb" +from util import hook, timesince + +dbname = "seen.db" def adapt_datetime(ts): return time.mktime(ts.timetuple()) @@ -18,18 +18,9 @@ def seeninput(bot,input): dbpath = os.path.join(bot.persist_dir, dbname) conn = dbconnect(dbpath) - cursor = conn.cursor() - command = "select count(name) from seen where name = ? and chan = ?" - cursor.execute(command, (input.nick,input.chan)) - - if(cursor.fetchone()[0] == 0): - command = "insert into seen(name, date, quote, chan) values(?,?,?,?)" - cursor.execute(command, (input.nick, datetime.datetime.now(), input.msg, input.chan)) - else: - command = "update seen set date=?, quote=? where name = ? and chan = ?" - cursor.execute(command, (datetime.datetime.now(), input.msg, input.nick, input.chan)) - + cursor.execute("insert or replace into seen(name, date, quote, chan) values(?,?,?,?)" + command, (input.nick, datetime.datetime.now(), input.msg, input.chan)) conn.commit() conn.close() @@ -66,7 +57,7 @@ def seen(bot, input): # check to see that our db has the the seen table, and return a connection. def dbconnect(db): conn = sqlite3.connect(db) - results = conn.execute("select count(*) from sqlite_master where name=?", ("seen" ,)).fetchone() + results = conn.execute("select count(*) from sqlite_master where name=?", ("seen",)).fetchone() if(results[0] == 0): conn.execute("create table if not exists "+ \ diff --git a/plugins/sieve.py b/plugins/sieve.py index 97e3f4e..218f53b 100644 --- a/plugins/sieve.py +++ b/plugins/sieve.py @@ -1,6 +1,6 @@ import re -import hook +from util import hook @hook.sieve diff --git a/plugins/tell.py b/plugins/tell.py index 8ca6c66..2082e57 100644 --- a/plugins/tell.py +++ b/plugins/tell.py @@ -1,10 +1,12 @@ " tell.py: written by sklnd in July 2009" -import datetime, time -import sqlite3 -import hook import os -from timesince import timesince +import time +import datetime +import sqlite3 + +from util import hook, timesince + dbname = "skydb" diff --git a/plugins/tinyurl.py b/plugins/tinyurl.py index ef34a42..dc868ae 100644 --- a/plugins/tinyurl.py +++ b/plugins/tinyurl.py @@ -1,7 +1,7 @@ import re import urllib2 -import hook +from util import hook tinyurl_re = re.compile(r'http://(?:www\.)?tinyurl.com/([A-Za-z0-9\-]+)', flags=re.IGNORECASE) diff --git a/plugins/twitter.py b/plugins/twitter.py index d9cb50b..2547d1d 100644 --- a/plugins/twitter.py +++ b/plugins/twitter.py @@ -6,7 +6,7 @@ retrieves most recent tweets import urllib from lxml import etree -import hook +from util import hook def unescape_xml(string): diff --git a/plugins/urbandictionary.py b/plugins/urbandictionary.py index 18abd83..a6b8ce1 100644 --- a/plugins/urbandictionary.py +++ b/plugins/urbandictionary.py @@ -1,7 +1,7 @@ from lxml import html import urllib -import hook +from util import hook @hook.command('u') diff --git a/plugins/util/__init__.py b/plugins/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/hook.py b/plugins/util/hook.py similarity index 100% rename from plugins/hook.py rename to plugins/util/hook.py diff --git a/lib/timesince.py b/plugins/util/timesince.py similarity index 100% rename from lib/timesince.py rename to plugins/util/timesince.py diff --git a/plugins/yaml/LICENSE b/plugins/util/yaml/LICENSE similarity index 100% rename from plugins/yaml/LICENSE rename to plugins/util/yaml/LICENSE diff --git a/plugins/yaml/PKG-INFO b/plugins/util/yaml/PKG-INFO similarity index 100% rename from plugins/yaml/PKG-INFO rename to plugins/util/yaml/PKG-INFO diff --git a/plugins/yaml/README b/plugins/util/yaml/README similarity index 100% rename from plugins/yaml/README rename to plugins/util/yaml/README diff --git a/plugins/yaml/__init__.py b/plugins/util/yaml/__init__.py similarity index 100% rename from plugins/yaml/__init__.py rename to plugins/util/yaml/__init__.py diff --git a/plugins/yaml/composer.py b/plugins/util/yaml/composer.py similarity index 100% rename from plugins/yaml/composer.py rename to plugins/util/yaml/composer.py diff --git a/plugins/yaml/constructor.py b/plugins/util/yaml/constructor.py similarity index 100% rename from plugins/yaml/constructor.py rename to plugins/util/yaml/constructor.py diff --git a/plugins/yaml/cyaml.py b/plugins/util/yaml/cyaml.py similarity index 100% rename from plugins/yaml/cyaml.py rename to plugins/util/yaml/cyaml.py diff --git a/plugins/yaml/dumper.py b/plugins/util/yaml/dumper.py similarity index 100% rename from plugins/yaml/dumper.py rename to plugins/util/yaml/dumper.py diff --git a/plugins/yaml/emitter.py b/plugins/util/yaml/emitter.py similarity index 100% rename from plugins/yaml/emitter.py rename to plugins/util/yaml/emitter.py diff --git a/plugins/yaml/error.py b/plugins/util/yaml/error.py similarity index 100% rename from plugins/yaml/error.py rename to plugins/util/yaml/error.py diff --git a/plugins/yaml/events.py b/plugins/util/yaml/events.py similarity index 100% rename from plugins/yaml/events.py rename to plugins/util/yaml/events.py diff --git a/plugins/yaml/loader.py b/plugins/util/yaml/loader.py similarity index 100% rename from plugins/yaml/loader.py rename to plugins/util/yaml/loader.py diff --git a/plugins/yaml/nodes.py b/plugins/util/yaml/nodes.py similarity index 100% rename from plugins/yaml/nodes.py rename to plugins/util/yaml/nodes.py diff --git a/plugins/yaml/parser.py b/plugins/util/yaml/parser.py similarity index 100% rename from plugins/yaml/parser.py rename to plugins/util/yaml/parser.py diff --git a/plugins/yaml/reader.py b/plugins/util/yaml/reader.py similarity index 100% rename from plugins/yaml/reader.py rename to plugins/util/yaml/reader.py diff --git a/plugins/yaml/representer.py b/plugins/util/yaml/representer.py similarity index 100% rename from plugins/yaml/representer.py rename to plugins/util/yaml/representer.py diff --git a/plugins/yaml/resolver.py b/plugins/util/yaml/resolver.py similarity index 100% rename from plugins/yaml/resolver.py rename to plugins/util/yaml/resolver.py diff --git a/plugins/yaml/scanner.py b/plugins/util/yaml/scanner.py similarity index 100% rename from plugins/yaml/scanner.py rename to plugins/util/yaml/scanner.py diff --git a/plugins/yaml/serializer.py b/plugins/util/yaml/serializer.py similarity index 100% rename from plugins/yaml/serializer.py rename to plugins/util/yaml/serializer.py diff --git a/plugins/yaml/tokens.py b/plugins/util/yaml/tokens.py similarity index 100% rename from plugins/yaml/tokens.py rename to plugins/util/yaml/tokens.py diff --git a/plugins/weather.py b/plugins/weather.py index 3481869..da4b33a 100644 --- a/plugins/weather.py +++ b/plugins/weather.py @@ -6,7 +6,8 @@ import thread import urllib from lxml import etree -import hook +from util import hook + lock = thread.allocate_lock() stalk = {} diff --git a/plugins/wikipedia.py b/plugins/wikipedia.py index e3b65c2..8c560ec 100644 --- a/plugins/wikipedia.py +++ b/plugins/wikipedia.py @@ -5,7 +5,8 @@ import urllib from lxml import etree import re -import hook +from util import hook + api_prefix = "http://en.wikipedia.org/w/api.php" search_url = api_prefix + "?action=opensearch&search=%s&format=xml" diff --git a/plugins/youtube.py b/plugins/youtube.py index fb99b4b..28ad6d8 100644 --- a/plugins/youtube.py +++ b/plugins/youtube.py @@ -2,9 +2,7 @@ import re from lxml import etree import locale -import hook - -locale.setlocale(locale.LC_ALL, "") +from util import hook def ytdata(id): diff --git a/plugins/youtube.py.orig b/plugins/youtube.py.orig new file mode 100644 index 0000000..c3d593c --- /dev/null +++ b/plugins/youtube.py.orig @@ -0,0 +1,43 @@ +import re +from lxml import etree +import locale + +import hook + +locale.setlocale(locale.LC_ALL, "") + + +def ytdata(id): + url = 'http://gdata.youtube.com/feeds/api/videos/' + id + x = etree.parse(url) + + # I can't figure out how to deal with schemas/namespaces properly :( + yt = '{http://gdata.youtube.com/schemas/2007}' + media = '{http://search.yahoo.com/mrss/}' + + rating = x.find('{http://schemas.google.com/g/2005}rating') + data = dict(rating.items()) + data['title'] = x.find('{http://www.w3.org/2005/Atom}title').text + data['views'] = locale.format('%d', int(x.find(yt + 'statistics').get( + 'viewCount')), 1) + length = int(x.find(media + 'group/' + yt + 'duration').get('seconds')) + data['length'] = '' + if length / 3600: # > 1 hour + data['length'] += str(length/3600) + 'h ' + if length / 60: # > 1 minute + data['length'] += str(length/60 % 60) + 'm ' + data['length'] += "%ds" % (length % 60) + + return data + +youtube_re = re.compile(r'.*youtube.*v=([-_a-z0-9]+)', flags=re.IGNORECASE) + + +@hook.command(hook=r'(.*)', prefix=False, ignore='chan:#cobol chan:#yospos') +def youtube(inp): + m = youtube_re.match(inp) + if m: + data = ytdata(m.group(1)) + return '\x02%(title)s\x02 - rated \x02%(average)s/%(max)s\x02 ' \ + '(%(numRaters)s) - views \x02%(views)s\x02 - length \x02' \ + '%(length)s\x02' % data