mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-11-04 01:27:21 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			228 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
###
 | 
						|
# Copyright (c) 2002, Jeremiah Fincher
 | 
						|
# All rights reserved.
 | 
						|
#
 | 
						|
# Redistribution and use in source and binary forms, with or without
 | 
						|
# modification, are permitted provided that the following conditions are met:
 | 
						|
#
 | 
						|
#   * Redistributions of source code must retain the above copyright notice,
 | 
						|
#     this list of conditions, and the following disclaimer.
 | 
						|
#   * Redistributions in binary form must reproduce the above copyright notice,
 | 
						|
#     this list of conditions, and the following disclaimer in the
 | 
						|
#     documentation and/or other materials provided with the distribution.
 | 
						|
#   * Neither the name of the author of this software nor the name of
 | 
						|
#     contributors to this software may be used to endorse or promote products
 | 
						|
#     derived from this software without specific prior written consent.
 | 
						|
#
 | 
						|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
						|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
						|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
						|
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | 
						|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
						|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
						|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
						|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
						|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
						|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
						|
# POSSIBILITY OF SUCH DAMAGE.
 | 
						|
###
 | 
						|
 | 
						|
"""
 | 
						|
Handles "factoids," little tidbits of information held in a database and 
 | 
						|
available on demand via several commands.
 | 
						|
 | 
						|
Commands include:
 | 
						|
  addfactoid
 | 
						|
  removefactoid
 | 
						|
  lookupfactoid
 | 
						|
  lockfactoid
 | 
						|
  unlockfactoid
 | 
						|
  randomfactoid
 | 
						|
  factoidinfo
 | 
						|
"""
 | 
						|
 | 
						|
from baseplugin import *
 | 
						|
 | 
						|
import time
 | 
						|
import os.path
 | 
						|
 | 
						|
import sqlite
 | 
						|
 | 
						|
import conf
 | 
						|
import ircdb
 | 
						|
import privmsgs
 | 
						|
import callbacks
 | 
						|
 | 
						|
class Factoids(ChannelDBHandler, callbacks.Privmsg):
 | 
						|
    def __init__(self):
 | 
						|
        ChannelDBHandler.__init__(self)
 | 
						|
        callbacks.Privmsg.__init__(self)
 | 
						|
        
 | 
						|
    def makeDb(self, filename):
 | 
						|
        if os.path.exists(filename):
 | 
						|
            return sqlite.connect(filename)
 | 
						|
        db = sqlite.connect(filename)
 | 
						|
        cursor = db.cursor()
 | 
						|
        cursor.execute("""CREATE TABLE keys (
 | 
						|
                          id INTEGER PRIMARY KEY,
 | 
						|
                          key TEXT,
 | 
						|
                          locked BOOLEAN
 | 
						|
                          )""")
 | 
						|
        cursor.execute("""CREATE TABLE factoids (
 | 
						|
                          id INTEGER PRIMARY KEY,
 | 
						|
                          key_id INTEGER,
 | 
						|
                          added_by TEXT,
 | 
						|
                          added_at TIMESTAMP,
 | 
						|
                          fact TEXT
 | 
						|
                          )""")
 | 
						|
        cursor.execute("""CREATE TRIGGER remove_factoids
 | 
						|
                          BEFORE DELETE ON keys
 | 
						|
                          BEGIN
 | 
						|
                            DELETE FROM factoids WHERE key_id = old.id;
 | 
						|
                          END
 | 
						|
                       """)
 | 
						|
        db.commit()
 | 
						|
        return db
 | 
						|
 | 
						|
    def addfactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key> <value>"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        (key, factoid) = privmsgs.getArgs(args, needed=2)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        cursor = db.cursor()
 | 
						|
        cursor.execute("""SELECT id, locked FROM keys WHERE key=%s""", key)
 | 
						|
        if cursor.rowcount == 0:
 | 
						|
            cursor.execute("""INSERT INTO keys VALUES (NULL, %s, 0)""", key)
 | 
						|
            db.commit()
 | 
						|
            cursor.execute("""SELECT id, locked FROM keys WHERE key=%s""", key)
 | 
						|
        (id, locked) = map(int, cursor.fetchone())
 | 
						|
        capability = ircdb.makeChannelCapability(channel, 'factoids')
 | 
						|
        if not locked:
 | 
						|
            if not ircdb.checkCapability(msg.prefix, capability):
 | 
						|
                irc.error(msg, conf.replyNoCapability % capability)
 | 
						|
                return
 | 
						|
            if ircdb.users.hasUser(msg.prefix):
 | 
						|
                name = ircdb.users.getUserName(msg.prefix)
 | 
						|
            else:
 | 
						|
                name = msg.nick
 | 
						|
            cursor.execute("""INSERT INTO factoids VALUES
 | 
						|
                              (NULL, %s, %s, %s, %s)""",
 | 
						|
                           id, name, int(time.time()), factoid)
 | 
						|
            db.commit()
 | 
						|
            irc.reply(msg, conf.replySuccess)
 | 
						|
        else:
 | 
						|
            irc.error(msg, 'That factoid is locked.')
 | 
						|
        
 | 
						|
    def lookupfactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key> [<number>]"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        (key, number) = privmsgs.getArgs(args, optional=1)
 | 
						|
        try:
 | 
						|
            number = int(number)
 | 
						|
        except ValueError:
 | 
						|
            key += number
 | 
						|
            number = 0
 | 
						|
        db = self.getDb(channel)
 | 
						|
        cursor = db.cursor()
 | 
						|
        cursor.execute("""SELECT factoids.fact FROM factoids, keys WHERE
 | 
						|
                          keys.key=%s AND factoids.key_id=keys.id
 | 
						|
                          ORDER BY factoids.id""", key)
 | 
						|
        results = cursor.fetchall()
 | 
						|
        if len(results) == 0:
 | 
						|
            irc.error(msg, 'No factoid matches that key.')
 | 
						|
        else:
 | 
						|
            factoid = results[number][0]
 | 
						|
            irc.reply(msg, '%s/%s: %s' % (key, number, factoid))
 | 
						|
            
 | 
						|
    def lockfactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key>"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        key = privmsgs.getArgs(args)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        capability = ircdb.makeChannelCapability(channel, 'factoids')
 | 
						|
        if ircdb.checkCapability(msg.prefix, capability):
 | 
						|
            cursor = db.cursor()
 | 
						|
            cursor.execute("""UPDATE keys SET locked = 1 WHERE key=%s""", key)
 | 
						|
            db.commit()
 | 
						|
            irc.reply(msg, conf.replySuccess)
 | 
						|
        else:
 | 
						|
            irc.error(msg, conf.replyNoCapability % capability)
 | 
						|
        
 | 
						|
    def unlockfactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key>"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        key = privmsgs.getArgs(args)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        capability = ircdb.makeChannelCapability(channel, 'factoids')
 | 
						|
        if ircdb.checkCapability(msg.prefix, capability):
 | 
						|
            cursor = db.cursor()
 | 
						|
            cursor.execute("""UPDATE keys SET locked = 0 WHERE key=%s""", key)
 | 
						|
            db.commit()
 | 
						|
            irc.reply(msg, conf.replySuccess)
 | 
						|
        else:
 | 
						|
            irc.error(msg, conf.replyNoCapability % capability)
 | 
						|
 | 
						|
    def removefactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key>"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        key = privmsgs.getArgs(args)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        capability = ircdb.makeChannelCapability(channel, 'factoids')
 | 
						|
        if ircdb.checkCapability(msg.prefix, capability):
 | 
						|
            cursor = db.cursor()
 | 
						|
            cursor.execute("""DELETE FROM keys WHERE key=%s""", key)
 | 
						|
            db.commit()
 | 
						|
            irc.reply(msg, conf.replySuccess)
 | 
						|
        else:
 | 
						|
            irc.error(msg, conf.replyNoCapability % capability)
 | 
						|
            
 | 
						|
    def randomfactoid(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself)"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        cursor = db.cursor()
 | 
						|
        cursor.execute("""SELECT fact, key_id FROM factoids
 | 
						|
                          ORDER BY random()
 | 
						|
                          LIMIT 1""")
 | 
						|
        if cursor.rowcount != 0:
 | 
						|
            (factoid, keyId) = cursor.fetchone()
 | 
						|
            cursor.execute("""SELECT key FROM keys WHERE id=%s""", keyId)
 | 
						|
            key = cursor.fetchone()[0]
 | 
						|
            irc.reply(msg, '%s: %s' % (key, factoid))
 | 
						|
        else:
 | 
						|
            irc.error(msg, 'I couldn\'t find a factoid.')
 | 
						|
 | 
						|
    def factoidinfo(self, irc, msg, args):
 | 
						|
        "[<channel>] (If not sent in the channel itself) <key>"
 | 
						|
        channel = privmsgs.getChannel(msg, args)
 | 
						|
        key = privmsgs.getArgs(args)
 | 
						|
        db = self.getDb(channel)
 | 
						|
        cursor = db.cursor()
 | 
						|
        cursor.execute("""SELECT id, locked FROM keys WHERE key=%s""", key)
 | 
						|
        if cursor.rowcount == 0:
 | 
						|
            irc.error(msg, 'No factoid matches that key.')
 | 
						|
            return
 | 
						|
        (id, locked) = map(int, cursor.fetchone())
 | 
						|
        cursor.execute("""SELECT  added_by, added_at FROM factoids
 | 
						|
                          WHERE key_id=%s
 | 
						|
                          ORDER BY id""", id)
 | 
						|
        factoids = cursor.fetchall()
 | 
						|
        L = []
 | 
						|
        counter = 0
 | 
						|
        for (added_by, added_at) in factoids:
 | 
						|
            added_at = time.strftime(conf.timestampFormat,
 | 
						|
                                     time.localtime(int(added_at)))
 | 
						|
            L.append('#%s was added by %s at %s' % (counter,added_by,added_at))
 | 
						|
            counter += 1
 | 
						|
        factoids = '; '.join(L)
 | 
						|
        s = 'Key %r is %s and has %s factoids associated with it: %s' % \
 | 
						|
            (key, locked and 'locked' or 'not locked', counter, '; '.join(L))
 | 
						|
        irc.reply(msg, s)
 | 
						|
                       
 | 
						|
 | 
						|
 | 
						|
Class = Factoids
 | 
						|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
 |