Add search, make encyclopedia more general, misc fixes

This commit is contained in:
Dennis Kaarsemaker
2006-09-28 14:35:24 +02:00
parent 4b5931194b
commit 9a1d60918f
8 changed files with 94 additions and 44 deletions

View File

@ -171,7 +171,7 @@ class Bantracker(callbacks.Plugin):
def doQuit(self, irc, msg): def doQuit(self, irc, msg):
for (channel, chan) in self.lastStates[irc].channels.iteritems(): for (channel, chan) in self.lastStates[irc].channels.iteritems():
if msg.nick in chan.users: if msg.nick in chan.users:
self.doLog(irc, channel, '*** %s has quit IRC\n' % msg.nick) self.doLog(irc, channel, '*** %s has quit IRC (%s)\n' % (msg.nick, msg.args[0]))
def outFilter(self, irc, msg): def outFilter(self, irc, msg):
# Gotta catch my own messages *somehow* :) # Gotta catch my own messages *somehow* :)

View File

@ -327,7 +327,7 @@ class Bugtracker(callbacks.PluginRegexp):
def oopsSnarfer(self, irc, msg, match): def oopsSnarfer(self, irc, msg, match):
r"OOPS-(?P<oopsid>\d*[A-Z]\d+)" r"OOPS-(?P<oopsid>\d*[A-Z]\d+)"
oopsid = match.group(1) oopsid = match.group(1)
irc.reply("https://chinstrap.ubuntu.com/~jamesh/oops.cgi/%s" % oopsid, prefixNick=False) irc.reply("https://devpad.canonical.com/~jamesh/oops.cgi/%s" % oopsid, prefixNick=False)
def get_tracker(self,snarfurl,sfdata): def get_tracker(self,snarfurl,sfdata):
for t in self.db.keys(): for t in self.db.keys():

View File

@ -28,8 +28,7 @@ __contributors__ = {}
__url__ = '' # 'http://supybot.com/Members/yourname/Factoid plugin/download' __url__ = '' # 'http://supybot.com/Members/yourname/Factoid plugin/download'
import config import config
import plugin reload(config)
reload(plugin) # In case we're being reloaded.
import plugin_ng import plugin_ng
reload(plugin_ng) reload(plugin_ng)
# Add more reloads here if you add third-party modules and want them to be # Add more reloads here if you add third-party modules and want them to be
@ -38,7 +37,6 @@ reload(plugin_ng)
if world.testing: if world.testing:
import test import test
Class = plugin.Class
Class = plugin_ng.Class Class = plugin_ng.Class
configure = config.configure configure = config.configure

View File

@ -23,6 +23,14 @@ Encyclopedia = conf.registerPlugin('Encyclopedia')
# registry.Boolean(False, """Help for someConfigVariableName.""")) # registry.Boolean(False, """Help for someConfigVariableName."""))
conf.registerChannelValue(Encyclopedia, 'database', conf.registerChannelValue(Encyclopedia, 'database',
registry.String('', 'Name of database to use')) registry.String('', 'Name of database to use'))
conf.registerGlobalValue(Encyclopedia, 'packagelookup',
registry.Boolean(True, "Whether to look up packages"))
conf.registerChannelValue(Encyclopedia, 'fallbackdb',
registry.String('ubuntu', 'Fallback database'))
conf.registerGlobalValue(Encyclopedia, 'fallbackchannel',
registry.String('#ubuntu', 'Fallback channel'))
conf.registerGlobalValue(Encyclopedia, 'relaychannel',
registry.String('#ubuntu-ops', 'Relay channel for unauthorized edits'))
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

View File

@ -47,25 +47,43 @@ except:
con = sqlite.connect('/home/dennis/ubugtu/data/facts/%s.db' % database) con = sqlite.connect('/home/dennis/ubugtu/data/facts/%s.db' % database)
cur = con.cursor() cur = con.cursor()
cur.execute("""SELECT COUNT(*) FROM facts WHERE value NOT LIKE '<alias>%%'""") if 'search' not in form:
num = cur.fetchall()[0][0] cur.execute("""SELECT COUNT(*) FROM facts WHERE value NOT LIKE '<alias>%%'""")
npages = int(ceil(num / float(NUM_PER_PAGE))) num = cur.fetchall()[0][0]
out('&middot;') npages = int(ceil(num / float(NUM_PER_PAGE)))
for i in range(npages): out('&middot;')
out(' <a href="factoids.cgi?db=%s&order=%s&page=%s">%d</a> &middot;' % (database, order_by, i, i+1)) for i in range(npages):
out('<br />Order by<br />&middot;') out(' <a href="factoids.cgi?db=%s&order=%s&page=%s">%d</a> &middot;' % (database, order_by, i, i+1))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'name ASC', page, 'Name +')) out('<br />Order by<br />&middot;')
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'name DESC', page, 'Name -')) out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'name ASC', page, 'Name +'))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'popularity ASC', page, 'Popularity +')) out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'name DESC', page, 'Name -'))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'popularity DESC', page, 'Popularity -')) out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'popularity ASC', page, 'Popularity +'))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'added ASC', page, 'Date added +')) out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'popularity DESC', page, 'Popularity -'))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'added DESC', page, 'Date added -')) out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'added ASC', page, 'Date added +'))
out(' <a href="factoids.cgi?db=%s&order=%s&page=%d">%s</a> &middot;' % (database, 'added DESC', page, 'Date added -'))
out('<table cellspacing="0"><tr><th>Factoid</th><th>Value</th><th>Author</th></tr>') out('<table cellspacing="0"><tr><th>Factoid</th><th>Value</th><th>Author</th></tr>')
cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE value NOT LIKE '<alias>%%' AND name NOT LIKE '%%-also' ORDER BY %s LIMIT %d, %d" % (order_by, page*NUM_PER_PAGE, NUM_PER_PAGE)) if 'search' in form:
factoids = cur.fetchall() keys = form['search'].value.split()[:5]
ret = {}
for k in keys:
k = k.replace("'","\'")
cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE name LIKE '%%%s%%' OR VAlUE LIKE '%%%s%%'" % (k, k))
res = cur.fetchall()
for r in res:
r0 = r[0]
try:
ret[r][1] += 1
except:
ret[r0] = (r, 1)
keys = sorted(ret.keys(), lambda x, y: cmp(ret[x][1], ret[y][1]))
factoids = []
for k in keys[:50]:
factoids.append(ret[k][0])
else:
cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE value NOT LIKE '<alias>%%' AND name NOT LIKE '%%-also' ORDER BY %s LIMIT %d, %d" % (order_by, page*NUM_PER_PAGE, NUM_PER_PAGE))
factoids = cur.fetchall()
i = 0 i = 0
for f in factoids: for f in factoids:
f = list(f) f = list(f)

View File

@ -127,13 +127,17 @@ div.log {
More help: <a href="http://wiki.ubuntu.com/">wiki.ubuntu.com</a> &middot; More help: <a href="http://wiki.ubuntu.com/">wiki.ubuntu.com</a> &middot;
<a href="http://help.ubuntu.com/">help.ubuntu.com</a><br /> <a href="http://help.ubuntu.com/">help.ubuntu.com</a><br />
More factoids: <a href="factoids.cgi?db=ubuntu">Ubuntu</a> &middot; More factoids: <a href="factoids.cgi?db=ubuntu">Ubuntu</a> &middot;
<a href="factoids.cgi?db=buntudot">buntudot</a> <a href="factoids.cgi?db=buntudot">buntudot</a> &middot;
<a href="factoids.cgi?db=gnewsense">GNewSense</a><br />
<form action="/factoids.cgi" method="GET"><input class="input" type="text" name="search" />
<input class="input" type="submit" value="Search"></form>
<p> <p>
%s %s
</p> </p>
<p> <p>
<a href="ubuntu.db">Ubuntu factoid database file</a><br /> <a href="ubuntu.db">Ubuntu factoid database file</a><br />
<a href="buntudot.db">Buntudot factoid database file</a><br /> <a href="buntudot.db">Buntudot factoid database file</a><br />
<a href="gnewsense.db">GNewSense factoid database file</a><br />
&copy;2006 Dennis Kaarsemaker &copy;2006 Dennis Kaarsemaker
</p> </p>
</div> </div>

View File

@ -18,14 +18,12 @@ from email import FeedParser
import re, os, fcntl, time import re, os, fcntl, time
apt_pkg.init() apt_pkg.init()
fallback = ('ubuntu', '#ubuntu')
datadir = '/home/dennis/ubugtu/data/facts' datadir = '/home/dennis/ubugtu/data/facts'
aptdir = '/home/dennis/ubugtu/data/apt' aptdir = '/home/dennis/ubugtu/data/apt'
relaychannel = '#ubuntu-ops'
distros = ('dapper','breezy','edgy','hoary','warty','dapper-commercial','dapper-seveas','breezy-seveas','dapper-imbrandon','edgy-imbrandon') distros = ('dapper','breezy','edgy','hoary','warty','dapper-commercial','dapper-seveas','breezy-seveas','dapper-imbrandon','edgy-imbrandon')
# Keep 'earchistros' in search order!
searchdistros = ('dapper','dapper-commercial','dapper-seveas','dapper-imbrandon')
defaultdistro = 'dapper' defaultdistro = 'dapper'
# Keep 'searchistros' in search order!
searchdistros = ('dapper','dapper-commercial','dapper-seveas','dapper-imbrandon')
# Simple wrapper class for factoids # Simple wrapper class for factoids
class Factoid: class Factoid:
@ -127,28 +125,29 @@ class Encyclopedia(callbacks.Plugin):
# XXX these 3 belong in a different plugin, but hey # XXX these 3 belong in a different plugin, but hey
if text.lower()[:4] in ('info','seen','find'): if text.lower()[:4] in ('info','seen','find'):
text = text.lower() text = text.lower()
if text.startswith('info '): if self.registryValue('packagelookup'):
irc.reply(pkginfo(text[5:].strip())) if text.startswith('info '):
return queue(irc, target, pkginfo(text[5:].strip()))
if text.startswith('find '): return
irc.reply(findpkg(text[5:].strip())) if text.startswith('find '):
return queue(irc, target, findpkg(text[5:].strip()))
if text.startswith('seen '): return
self.seens[text[5:].strip()] = (target, time.time()) if text.startswith('seen '):
queue(irc, 'seenserv', "seen %s" % text[5:].strip()) self.seens[text[5:].strip()] = (target, time.time())
return queue(irc, 'seenserv', "seen %s" % text[5:].strip())
return
# Factoid manipulation # Factoid manipulation
db = self.registryValue('database',channel) db = self.registryValue('database',channel)
if not db: if not db:
db,channel = fallback db,channel = self.registryValue('fallbackdb'), self.registryValue('fallbackchannel')
if channel not in self.databases: if channel not in self.databases:
self.databases[channel] = sqlite.connect(os.path.join(datadir, '%s.db' % db)) self.databases[channel] = sqlite.connect(os.path.join(datadir, '%s.db' % db))
self.databases[channel].name = db self.databases[channel].name = db
db = self.databases[channel] db = self.databases[channel]
if text.lower().startswith('search '): if text.lower().startswith('search '):
irc.reply(searchfactoid(text[7:].strip().lower())) irc.reply(searchfactoid(db, text[7:].strip().lower()))
return return
do_new = False do_new = False
if text.lower().startswith('forget '): if text.lower().startswith('forget '):
@ -165,7 +164,7 @@ class Encyclopedia(callbacks.Plugin):
text = text.replace('is <sed>','=~',1) text = text.replace('is <sed>','=~',1)
if ' is ' in text and '=~' not in text: if ' is ' in text and '=~' not in text:
do_new = True do_new = True
if text.lower().startswith('no '): if text.lower()[:3] in ('no ','no,'):
do_new = False do_new = False
text = text[3:].strip() text = text[3:].strip()
if text.startswith('is '): if text.startswith('is '):
@ -186,8 +185,8 @@ class Encyclopedia(callbacks.Plugin):
if '=~' in text: if '=~' in text:
# Editing # Editing
if not capab(msg.prefix, 'editfactoids'): if not capab(msg.prefix, 'editfactoids'):
irc.queueMsg(ircmsgs.privmsg(relaychannel, "In %s, %s said: %s" % (msg.args[0], msg.nick, msg.args[1]))) irc.queueMsg(ircmsgs.privmsg(self.registryValue('relaychannel'), "In %s, %s said: %s" % (msg.args[0], msg.nick, msg.args[1])))
irc.reply("Your edit request has been forwarded to #ubuntu-ops. Thank you for your attention to detail",private=True) irc.reply("Your edit request has been forwarded to %s. Thank you for your attention to detail",self.registryValue('relaychannel'),private=True)
lfd = open('/home/dennis/public_html/botlogs/lock','a') lfd = open('/home/dennis/public_html/botlogs/lock','a')
fcntl.lockf(lfd, fcntl.LOCK_EX) fcntl.lockf(lfd, fcntl.LOCK_EX)
fd = open('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a') fd = open('/home/dennis/public_html/botlogs/%s.log' % datetime.date.today().strftime('%Y-%m-%d'),'a')
@ -318,9 +317,12 @@ class Encyclopedia(callbacks.Plugin):
break break
else: else:
if not replied: if not replied:
i = pkginfo(text) if self.registryValue('packagelookup'):
if not i.startswith('Package'): i = pkginfo(text)
queue(irc, target, i) if not i.startswith('Package'):
queue(irc, target, i)
else:
irc.reply("Sorry, I don't know anything about %s - try searching on http://bots.ubuntulinux.nl/factoids.cgi" % text)
else: else:
irc.reply("Sorry, I don't know anything about %s - try searching on http://bots.ubuntulinux.nl/factoids.cgi" % text) irc.reply("Sorry, I don't know anything about %s - try searching on http://bots.ubuntulinux.nl/factoids.cgi" % text)
for key in ('channel_secondary', 'global_secondary'): for key in ('channel_secondary', 'global_secondary'):
@ -486,6 +488,22 @@ def get_factoids(db, name, channel, resolve = True, info = False):
factoids.channel_secondary = factoid_info(db, factoids.channel_secondary, channel) factoids.channel_secondary = factoid_info(db, factoids.channel_secondary, channel)
return factoids return factoids
def searchfactoid(db, factoid):
keys = factoid.split()[:5]
cur = db.cursor()
ret = {}
for k in keys:
k = k.replace("'","\'")
cur.execute("SELECT name FROM facts WHERE name LIKE '%%%s%%' OR VAlUE LIKE '%%%s%%'" % (k, k))
res = cur.fetchall()
for r in res:
r = r[0]
try:
ret[r] += 1
except:
ret[r] = 1
return 'Found: %s' % ','.join(sorted(ret.keys(), lambda x, y: cmp(ret[x], ret[y]))[:10])
def factoid_info(db,factoid,channel): def factoid_info(db,factoid,channel):
if factoid: if factoid:
if not factoid.value.startswith('<alias>'): if not factoid.value.startswith('<alias>'):

View File

@ -207,6 +207,10 @@ class Webcal(callbacks.Plugin):
now = wrap(now, [additional('text')]) now = wrap(now, [additional('text')])
time = now time = now
def subscribe(self, irc, msg, args, meeting):
print meeting
subscribe = wrap(subscribe, ['text'])
# Warn people that you manage the topic # Warn people that you manage the topic
def doTopic(self, irc, msg): def doTopic(self, irc, msg):
if not self.registryValue('doTopic'): if not self.registryValue('doTopic'):