5
""" information items .. keyword/description pairs """
7
__copyright__ = 'this file is in the public domain'
9
from gozerbot.commands import cmnds
10
from gozerbot.examples import examples
11
from gozerbot.redispatcher import rebefore, reafter
12
from gozerbot.datadir import datadir
13
from gozerbot.persist.persist import Persist
14
from gozerbot.generic import lockdec, cchar
15
from gozerbot.aliases import aliases
16
from gozerbot.plughelp import plughelp
17
from gozerbot.callbacks import callbacks
18
from gozerbot.users import users
19
from gozerbot.config import config
20
if not config['nodb']:
21
from gozerbot.database.db import db
22
import thread, os, time
24
plughelp.add('infoitem', 'also known as factoids .. info can be retrieved \
25
by keyword or searched')
27
infolock = thread.allocate_lock()
29
# create lock descriptor
30
locked = lockdec(infolock)
32
class Infoitems(Persist):
34
""" information items """
37
def add(self, item, issue, userhost=None, ttime=None):
40
if self.data.has_key(item):
41
if not issue in self.data[item]:
42
self.data[item].append(issue)
44
self.data[item] = [issue]
48
def addnosave(self, item, issue, userhost=None, ttime=None):
49
""" add item but don't save """
51
if self.data.has_key(item):
52
self.data[item].append(issue)
54
self.data[item] = [issue]
57
def deltxt(self, item, txt):
58
""" delete todo item with txt in it """
60
if not self.data.has_key(item):
62
for i in range(len(self.data[item])-1, -1, -1):
63
if txt in self.data[item][i]:
64
del self.data[item][i]
72
def delete(self, item, itemnr):
73
""" delete item with nr from list """
75
del self.data[item.lower()][int(itemnr)]
86
""" get description of item """
87
if self.data.has_key(item):
88
return self.data[item]
91
""" return number of items """
94
def searchdescr(self, txt):
96
for i, j in self.data.iteritems():
102
def searchitem(self, txt):
104
for i, j in self.data.iteritems():
106
result.append((i, j))
109
class InfoitemsDb(object):
111
""" information items """
113
def add(self, item, description, userhost, ttime):
116
result = db.execute(""" INSERT INTO infoitems(item, description, \
117
userhost, time) VALUES(%s, %s, %s, %s) """, (item, description, \
122
""" get infoitems """
124
result = db.execute(""" SELECT description FROM \
125
infoitems WHERE item = %s """, item)
132
def delete(self, indexnr):
133
""" delete item with indexnr """
134
result = db.execute(""" DELETE FROM infoitems WHERE indx = %s """, \
138
def deltxt(self, item, txt):
139
""" delete item with matching txt """
140
result = db.execute(""" DELETE FROM infoitems WHERE item = %s AND \
141
description LIKE %s """, (item, '%%%s%%' % txt))
145
""" return number of items """
146
result = db.execute(""" SELECT COUNT(*) FROM infoitems """)
149
def searchitem(self, search):
151
result = db.execute(""" SELECT item, description \
152
FROM infoitems WHERE item LIKE %s """, '%%%s%%' % search)
155
def searchdescr(self, search):
156
""" search descriptions """
157
result = db.execute(""" SELECT item, description \
158
FROM infoitems WHERE description LIKE %s """, '%%%s%%' % search)
161
if not config['nodb']:
164
info = Infoitems(datadir + os.sep + 'infoitems')
170
""" return number of infoitems """
173
def infopre(bot, ievent):
174
""" see if info callback needs to be called """
175
cc = cchar(bot, ievent)
176
if ievent.origtxt and cc == ievent.origtxt[0] and not ievent.usercmnd \
180
def infocb(bot, ievent):
181
""" implement a !infoitem callback """
182
if users.allowed(ievent.userhost, 'USER'):
183
data = info.get(ievent.txt)
185
ievent.reply('%s is: ' % ievent.txt, data , dot=True)
187
callbacks.add('PRIVMSG', infocb, infopre)
189
def handle_infosize(bot, ievent):
190
""" info-size .. show number of information items """
191
ievent.reply("we have %s infoitems" % info.size())
193
cmnds.add('info-size', handle_infosize, ['USER', 'WEB', 'ANON'])
194
examples.add('info-size', 'show number of infoitems', 'info-size')
196
def handle_addinfoitem(bot, ievent):
197
""" <keyword> = <description> .. add information item """
199
(what, description) = ievent.groups
201
ievent.reply('i need <item> <description>')
203
if len(description) < 3:
204
ievent.reply('i need at least 3 chars for the description')
207
info.add(what, description, ievent.userhost, time.time())
208
ievent.reply('item added')
210
rebefore.add(10, '^(.+?)\s+=\s+(.+)$', handle_addinfoitem, ['USER', \
211
'INFOADD'], allowqueue=False)
212
examples.add('=', 'add description to item', 'dunk = top')
214
def handle_question(bot, ievent):
215
""" <keyword>? .. ask for information item description """
217
what = ievent.groups[0]
219
ievent.reply('i need a argument')
221
what = what.strip().lower()
222
infoitems = info.get(what)
224
ievent.reply("%s is: " % what, infoitems, dot=True)
226
ievent.reply('nothing known about %s' % what)
229
reafter.add(10, '^(.+)\?$', handle_question, ['USER', 'WEB', 'JCOLL', \
230
'ANON'], allowqueue=True)
231
reafter.add(10, '^\?(.+)$', handle_question, ['USER', 'WEB', 'JCOLL', \
232
'ANON'], allowqueue=True)
233
examples.add('?', 'show infoitems of <what>', '1) test? 2) ?test')
235
def handle_forget(bot, ievent):
236
""" forget <keyword> <txttomatch> .. remove information item where \
237
description matches txt given """
238
if len(ievent.args) > 1:
239
what = ' '.join(ievent.args[:-1])
240
txt = ievent.args[-1]
242
ievent.missing('<item> <txttomatch> (min 3 chars)')
245
ievent.reply('i need txt with at least 3 characters')
247
what = what.strip().lower()
249
nrtimes = info.deltxt(what, txt)
251
ievent.reply('no records matching %s found' % what)
254
ievent.reply('item deleted')
256
ievent.reply('delete %s of %s failed' % (txt, what))
258
cmnds.add('info-forget', handle_forget, ['FORGET', 'OPER'])
259
examples.add('info-forget', 'forget <item> containing <txt>', 'info-forget \
261
aliases.data['forget'] = 'info-forget'
263
def handle_searchdescr(bot, ievent):
264
""" info-sd <txttosearchfor> .. search information items descriptions """
266
ievent.missing('<txt>')
270
what = what.strip().lower()
271
result = info.searchdescr(what)
275
res.append("[%s] %s" % (i[0], i[1]))
276
ievent.reply("the following matches %s: " % what, res, dot=True)
278
ievent.reply('none found')
280
cmnds.add('info-sd', handle_searchdescr, ['USER', 'WEB', 'ANON'])
281
examples.add('info-sd', 'info-sd <txt> .. search description of \
282
infoitems', 'info-sd http')
283
aliases.data['sd'] = 'info-sd'
284
aliases.data['sl'] = 'info-sd'
286
def handle_searchitem(bot, ievent):
287
""" info-si <txt> .. search information keywords """
289
ievent.missing('<txt>')
293
what = what.strip().lower()
294
result = info.searchitem(what)
298
res.append("[%s] %s" % (i[0], i[1]))
299
ievent.reply("the following matches %s: " % what, res, dot=True)
301
ievent.reply('none found')
303
cmnds.add('info-si', handle_searchitem, ['USER', 'WEB', 'ANON'])
304
examples.add('info-si', 'info-si <txt> .. search the infoitems keys', \
306
aliases.data['si'] = 'info-si'