Add Infobot.update, which allows updating the is/are dbs with external Infobot

"fact packs".  Need to add threading so the bot isn't blocked while updating.
This commit is contained in:
James Vega 2004-12-29 20:34:19 +00:00
parent 4cd15d053a
commit ab0eff4eea
2 changed files with 58 additions and 14 deletions

View File

@ -55,6 +55,7 @@ import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs import supybot.privmsgs as privmsgs
import supybot.registry as registry import supybot.registry as registry
import supybot.webutils as webutils
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
@ -340,12 +341,12 @@ class SqliteInfobotDB(object):
def changeIs(self, channel, factoid, replacer): def changeIs(self, channel, factoid, replacer):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT value FROM isFacts WHERE key=%s""", factoid) cursor.execute("""SELECT value FROM isFacts WHERE key LIKE %s""", factoid)
if cursor.rowcount == 0: if cursor.rowcount == 0:
raise dbi.NoRecordError raise dbi.NoRecordError
old = cursor.fetchone()[0] old = cursor.fetchone()[0]
if replacer is not None: if replacer is not None:
cursor.execute("""UPDATE isFacts SET value=%s WHERE key=%s""", cursor.execute("""UPDATE isFacts SET value=%s WHERE key LIKE %s""",
replacer(old), factoid) replacer(old), factoid)
db.commit() db.commit()
self.incChanges() self.incChanges()
@ -353,7 +354,7 @@ class SqliteInfobotDB(object):
def getIs(self, channel, factoid): def getIs(self, channel, factoid):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT value FROM isFacts WHERE key=%s""", factoid) cursor.execute("""SELECT value FROM isFacts WHERE key LIKE %s""", factoid)
ret = cursor.fetchone()[0] ret = cursor.fetchone()[0]
self.incResponses() self.incResponses()
return ret return ret
@ -368,7 +369,7 @@ class SqliteInfobotDB(object):
def delIs(self, channel, factoid): def delIs(self, channel, factoid):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""DELETE FROM isFacts WHERE key=%s""", factoid) cursor.execute("""DELETE FROM isFacts WHERE key LIKE %s""", factoid)
if cursor.rowcount == 0: if cursor.rowcount == 0:
raise dbi.NoRecordError raise dbi.NoRecordError
db.commit() db.commit()
@ -377,18 +378,18 @@ class SqliteInfobotDB(object):
def hasIs(self, channel, factoid): def hasIs(self, channel, factoid):
(db, _) = self._getDb(channel) (db, _) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT * FROM isFacts WHERE key=%s""", factoid) cursor.execute("""SELECT * FROM isFacts WHERE key LIKE %s""", factoid)
return cursor.rowcount == 1 return cursor.rowcount == 1
def changeAre(self, channel, factoid, replacer): def changeAre(self, channel, factoid, replacer):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT value FROM areFacts WHERE key=%s""", factoid) cursor.execute("""SELECT value FROM areFacts WHERE key LIKE %s""", factoid)
if cursor.rowcount == 0: if cursor.rowcount == 0:
raise dbi.NoRecordError raise dbi.NoRecordError
old = cursor.fetchone()[0] old = cursor.fetchone()[0]
if replacer is not None: if replacer is not None:
cursor.execute("""UPDATE areFacts SET value=%s WHERE key=%s""", cursor.execute("""UPDATE areFacts SET value=%s WHERE key LIKE %s""",
replacer(old), factoid) replacer(old), factoid)
db.commit() db.commit()
self.incChanges() self.incChanges()
@ -396,7 +397,7 @@ class SqliteInfobotDB(object):
def getAre(self, channel, factoid): def getAre(self, channel, factoid):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT value FROM areFacts WHERE key=%s""", factoid) cursor.execute("""SELECT value FROM areFacts WHERE key LIKE %s""", factoid)
ret = cursor.fetchone()[0] ret = cursor.fetchone()[0]
self.incResponses() self.incResponses()
return ret return ret
@ -411,7 +412,7 @@ class SqliteInfobotDB(object):
def delAre(self, channel, factoid): def delAre(self, channel, factoid):
(db, filename) = self._getDb(channel) (db, filename) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""DELETE FROM areFacts WHERE key=%s""", factoid) cursor.execute("""DELETE FROM areFacts WHERE key LIKE %s""", factoid)
if cursor.rowcount == 0: if cursor.rowcount == 0:
raise dbi.NoRecordError raise dbi.NoRecordError
db.commit() db.commit()
@ -420,7 +421,7 @@ class SqliteInfobotDB(object):
def hasAre(self, channel, factoid): def hasAre(self, channel, factoid):
(db, _) = self._getDb(channel) (db, _) = self._getDb(channel)
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT * FROM areFacts WHERE key=%s""", factoid) cursor.execute("""SELECT * FROM areFacts WHERE key LIKE %s""", factoid)
return cursor.rowcount == 1 return cursor.rowcount == 1
def getDunno(self): def getDunno(self):
@ -787,10 +788,11 @@ class Infobot(callbacks.PrivmsgCommandAndRegexp):
self.confirm() self.confirm()
def stats(self, irc, msg, args, channel): def stats(self, irc, msg, args, channel):
"""takes no arguments """[<channel>]
Returns the number of changes and requests made to the Infobot database Returns the number of changes and requests made to the Infobot database
since the plugin was loaded. since the plugin was loaded. <channel> is only necessary if the
message isn't in the channel itself.
""" """
changes = self.db.getChangeCount(channel) changes = self.db.getChangeCount(channel)
responses = self.db.getResponseCount(channel) responses = self.db.getResponseCount(channel)
@ -812,9 +814,10 @@ class Infobot(callbacks.PrivmsgCommandAndRegexp):
status=stats status=stats
def tell(self, irc, msg, args, channel, nick, _, factoid): def tell(self, irc, msg, args, channel, nick, _, factoid):
"""<nick> [about] <factoid> """[<channel>] <nick> [about] <factoid>
Tells <nick> about <factoid>. Tells <nick> about <factoid>. <channel> is only necessary if the
message isn't sent in the channel itself.
""" """
try: try:
hostmask = irc.state.nickToHostmask(nick) hostmask = irc.state.nickToHostmask(nick)
@ -830,6 +833,44 @@ class Infobot(callbacks.PrivmsgCommandAndRegexp):
tell = wrap(tell, ['channeldb', 'something', tell = wrap(tell, ['channeldb', 'something',
optional(('literal', 'about')), 'text']) optional(('literal', 'about')), 'text'])
def update(self, irc, msg, args, channel, isAre, url):
"""[<channel>] {is,are} <url|file>
Updates the Infobot database using the dumped database at remote <url>
or local <file>. The first argument should be "is" or "are", and
determines whether the is or are database is updated.
"""
isAre = isAre.lower()
if isAre == 'is':
add = self.db.setIs
elif isAre == 'are':
add = self.db.setAre
count = 0
try:
fd = webutils.getUrlFd(url)
except webutils.WebError:
try:
fd = file(url)
except EnvironmentError:
irc.errorInvalid('url or file')
for line in fd:
line = line.rstrip('\r\n')
try:
(key, value) = line.split(' => ', 1)
except ValueError: #unpack list of wrong size
self.log.debug('Invalid line: %r', line)
continue
else:
key = key.rstrip()
value = value.lstrip()
self.log.debug('Adding factoid %r with value %r.', key, value)
add(channel, key, value)
count += 1
fd.close()
irc.replySuccess('%s added.' % utils.nItems('factoid', count))
update = wrap(update,
['owner', 'channeldb', ('literal', ('is', 'are')),
first('url', 'text')])
Class = Infobot Class = Infobot

View File

@ -105,6 +105,9 @@ def getUrlFd(url, headers=None):
raise WebError, strError(e) raise WebError, strError(e)
except urllib2.URLError, e: except urllib2.URLError, e:
raise WebError, strError(e.reason) raise WebError, strError(e.reason)
# Raised when urllib doesn't recognize the url type
except ValueError, e:
raise WebError, strError(e)
def getUrl(url, size=None, headers=None): def getUrl(url, size=None, headers=None):
"""Gets a page. Returns a string that is the page gotten.""" """Gets a page. Returns a string that is the page gotten."""