7
__copyright__ = 'this file is in the public domain'
9
from gozerbot.persist.persist import Persist
10
from gozerbot.utils.nextid import nextid
11
from gozerbot.commands import cmnds
12
from gozerbot.examples import examples
13
from gozerbot.datadir import datadir
14
from gozerbot.generic import lockdec, rlog
15
from gozerbot.plughelp import plughelp
16
from gozerbot.aliases import aliases
17
from gozerbot.config import config
18
if not config['nodb']:
19
from gozerbot.database.db import db
20
from gplugs.olddb.karma import karma
21
import random, re, time, thread, os
23
plughelp.add('quote', 'manage quotes')
25
class Quoteitem(object):
27
""" object representing a quote """
29
def __init__(self, idnr, txt, nick=None, userhost=None, ttime=None):
33
self.userhost = userhost
36
quoteslock = thread.allocate_lock()
37
locked = lockdec(quoteslock)
39
class Quotes(Persist):
41
""" list of quotes """
44
def __init__(self, fname):
45
Persist.__init__(self, fname)
50
""" return nr of quotes """
54
def add(self, nick, userhost, quote):
56
id = nextid.next('quotes')
57
item = Quoteitem(id, quote, nick, userhost, \
59
self.data.append(item)
64
def addnosave(self, nick, userhost, quote, ttime):
65
""" add quote but don't call save """
66
id = nextid.next('quotes')
67
item = Quoteitem(nextid.next('quotes'), quote, nick, userhost, ttime)
68
self.data.append(item)
72
def delete(self, quotenr):
73
""" delete quote with id == nr """
74
for i in range(len(self.data)):
75
if self.data[i].id == quotenr:
81
""" get random quote """
84
quotenr = random.randint(0, len(self.data)-1)
85
return self.data[quotenr]
87
def idquote(self, quotenr):
88
""" get quote by id """
93
def whoquote(self, quotenr):
94
""" get who quoted the quote """
97
return (i.nick, i.time)
100
""" get last quote """
101
return self.data[len(self.data)-nr:]
103
def search(self, what):
104
""" search quotes """
108
andre = re.compile('and', re.I)
109
ands = re.split(andre, what)
113
if i.txt.find(item.strip()) == -1:
121
def searchlast(self, what, nr=1):
122
""" search quotes backwards limit to 1"""
126
andre = re.compile('and', re.I)
127
ands = re.split(andre, what)
129
for i in self.data[::-1]:
131
if i.txt.find(item.strip()) == -1:
140
class QuotesDb(object):
142
""" quotes db interface """
145
""" return nr of quotes """
146
result = db.execute(""" SELECT COUNT(*) FROM quotes """)
149
def add(self, nick, userhost, quote):
151
result = db.execute(""" INSERT INTO quotes(quote, userhost, \
152
createtime, nick) VALUES (%s, %s, %s, %s) """, (quote, userhost, \
156
def delete(self, quotenr):
157
""" delete quote with id == nr """
158
result = db.execute(""" DELETE FROM quotes WHERE indx = %s """, \
163
""" get random quote """
164
result = db.execute(""" SELECT indx FROM quotes """)
171
idnr = random.choice(indices)
172
return self.idquote(idnr)
174
def idquote(self, quotenr):
175
""" get quote by id """
178
result = db.execute(""" SELECT indx, quote FROM quotes WHERE \
179
indx = %s """, quotenr)
181
return Quoteitem(*result[0])
183
def whoquote(self, quotenr):
184
""" get who quoted the quote """
185
result = db.execute(""" SELECT nick, createtime FROM quotes WHERE \
186
indx = %s """, (quotenr, ))
190
def last(self, nr=1):
191
""" get last quote """
192
result = db.execute(""" SELECT indx, quote FROM quotes ORDER BY \
193
indx DESC LIMIT %s """, (nr, ))
197
res.append(Quoteitem(*i))
200
def search(self, what):
201
""" search quotes """
202
result = db.execute(""" SELECT indx, quote FROM quotes WHERE \
203
quote LIKE %s """, '%%%s%%' % what)
207
res.append(Quoteitem(*i))
210
def searchlast(self, what, nr):
211
""" search quotes """
212
result = db.execute(""" SELECT indx, quote FROM quotes WHERE \
213
quote LIKE %s ORDER BY indx DESC LIMIT %s """, ('%%%s%%' % what, nr))
217
res.append(Quoteitem(*i))
220
if not config['nodb']:
223
quotes = Quotes(datadir + os.sep + 'quotes')
227
""" return number of quotes """
230
def search(what, queue):
231
""" search the quotes """
232
rlog(10, 'quote', 'searched for %s' % what)
233
result = quotes.search(what)
235
queue.put_nowait("#%s %s" % (i.id, i.txt))
237
def handle_quoteadd(bot, ievent):
238
""" quote-add <txt> .. add a quote """
240
ievent.missing("<quote>")
242
idnr = quotes.add(ievent.nick, ievent.userhost, ievent.rest)
243
ievent.reply('quote %s added' % idnr)
245
cmnds.add('quote-add', handle_quoteadd, ['USER', 'QUOTEADD'], allowqueue=False)
246
examples.add('quote-add', 'quote-add <txt> .. add quote', 'quote-add mekker')
247
aliases.data['aq'] = 'quote-add'
249
def handle_quotewho(bot, ievent):
250
""" quote-who <nr> .. show who added a quote """
252
quotenr = int(ievent.args[0])
254
ievent.missing("<nr>")
257
ievent.reply("argument must be an integer")
259
result = quotes.whoquote(quotenr)
260
if not result or not result[0] or not result[1]:
261
ievent.reply('no who quote data available')
264
ievent.reply('quote #%s was made by %s on %s' % (quotenr, result[0], result[1]))
266
cmnds.add('quote-who', handle_quotewho, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
267
examples.add('quote-who', 'quote-who <nr> .. show who quote <nr>', \
269
aliases.data['wq'] = 'quote-who'
271
def handle_quotedel(bot, ievent):
272
""" quote-del <nr> .. delete quote by id """
274
quotenr = int(ievent.args[0])
276
ievent.missing('<nr>')
279
ievent.reply('argument needs to be an integer')
281
if quotes.delete(quotenr):
282
ievent.reply('quote deleted')
284
ievent.reply("can't delete quote with nr %s" % quotenr)
286
cmnds.add('quote-del', handle_quotedel, ['QUOTEDEL', 'OPER', 'QUOTE'])
287
examples.add('quote-del', 'quote-del <nr> .. delete quote', 'quote-del 2')
288
aliases.data['dq'] = 'quote-del'
290
def handle_quotelast(bot, ievent):
291
""" quote-last .. show last quote """
294
(nr, search) = ievent.args
300
except (IndexError, ValueError):
303
search = ievent.args[0]
307
ievent.reply('nr needs to be between 1 and 4')
309
search = re.sub('^d', '', search)
311
quotelist = quotes.searchlast(search, nr)
313
quotelist = quotes.last(nr)
314
if quotelist != None:
315
for quote in quotelist:
316
qkarma = karma.get('quote %s' % quote.id)
318
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
320
ievent.reply('#%s %s' % (quote.id, quote.txt))
322
ievent.reply("can't fetch quote")
324
cmnds.add('quote-last', handle_quotelast, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
325
examples.add('quote-last', 'show last quote', 'quote-last')
326
aliases.data['lq'] = 'quote-last'
328
def handle_quote2(bot, ievent):
329
""" quote-2 .. show 2 random quotes """
330
quote = quotes.random()
332
qkarma = karma.get('quote %s' % quote.id)
334
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
336
ievent.reply('#%s %s' % (quote.id, quote.txt))
338
ievent.reply('no quotes yet')
340
quote = quotes.random()
342
qkarma = karma.get('quote %s' % quote.id)
344
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
346
ievent.reply('#%s %s' % (quote.id, quote.txt))
348
cmnds.add('quote-2', handle_quote2, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
349
examples.add('quote-2', 'quote-2 .. show 2 random quotes', 'quote-2')
350
aliases.data['2q'] = 'quote-2'
352
def handle_quoteid(bot, ievent):
353
""" quote-id <nr> .. show quote by id """
355
quotenr = int(ievent.args[0])
357
ievent.missing('<nr>')
360
ievent.reply('argument must be an integer')
362
quote = quotes.idquote(quotenr)
364
qkarma = karma.get('quote %s' % quote.id)
366
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
368
ievent.reply('#%s %s' % (quote.id, quote.txt))
370
ievent.reply("can't fetch quote with id %s" % quotenr)
372
cmnds.add('quote-id', handle_quoteid, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
373
examples.add('quote-id', 'quote-id <nr> .. get quote <nr>', 'quote-id 2')
374
aliases.data['iq'] = 'quote-id'
376
def handle_quote(bot, ievent):
377
""" quote .. show random quote """
378
quote = quotes.random()
380
qkarma = karma.get('quote %s' % quote.id)
382
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
384
ievent.reply('#%s %s' % (quote.id, quote.txt))
386
ievent.reply('no quotes yet')
388
cmnds.add('quote', handle_quote, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
389
examples.add('quote', 'show random quote', 'quote')
390
aliases.data['q'] = 'quote'
392
def handle_quotesearch(bot, ievent):
393
""" quote-search <txt> .. search quotes """
395
ievent.missing('<item>')
400
result = quotes.search(what)
405
res.append('#%s %s' % (quote.id, quote.txt))
408
if nrtimes > len(result):
409
nrtimes = len(result)
410
randquotes = random.sample(result, nrtimes)
411
for quote in randquotes:
412
qkarma = karma.get('quote %s' % quote.id)
414
ievent.reply('#%s (%s) %s' % (quote.id, qkarma, quote.txt))
416
ievent.reply("#%s %s" % (quote.id, quote.txt))
418
ievent.reply('no quotes found with %s' % what)
420
cmnds.add('quote-search', handle_quotesearch, ['USER', 'WEB', 'ANON', \
422
examples.add('quote-search', 'quote-search <txt> .. search quotes for <txt>'\
423
, 'quote-search bla')
424
aliases.data['sq'] = 'quote-search'
426
def handle_quotescount(bot, ievent):
427
""" quote-count .. show number of quotes """
428
ievent.reply('quotes count is %s' % quotes.size())
430
cmnds.add('quote-count', handle_quotescount, ['USER', 'WEB', 'ANON', \
432
examples.add('quote-count', 'count nr of quotes', 'quote-count')
433
aliases.data['cq'] = 'quote-count'
435
def handle_quotegood(bot, ievent):
436
""" show top ten positive karma """
437
result = karma.quotegood(limit=10)
442
resultstr += "%s: %s " % (i[0], i[1])
443
ievent.reply('quote goodness: %s' % resultstr)
445
ievent.reply('quote karma void')
447
cmnds.add('quote-good', handle_quotegood, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
448
examples.add('quote-good', 'show top 10 quote karma', 'quote-good')
450
def handle_quotebad(bot, ievent):
451
""" show top ten negative karma """
452
result = karma.quotebad(limit=10)
457
resultstr += "%s: %s " % (i[0], i[1])
458
ievent.reply('quote badness: %s' % resultstr)
460
ievent.reply('quote karma void')
462
cmnds.add('quote-bad', handle_quotebad, ['USER', 'WEB', 'ANON', 'ANONQUOTE'])
463
examples.add('quote-bad', 'show lowest 10 quote karma', 'quote-bad')