Encyclopedia: Port to SQLite 3 (with Matt Wheeler)

This commit is contained in:
Krytarik Raido 2018-03-09 19:56:04 +01:00
parent af7578e888
commit b18cc37a15
8 changed files with 116 additions and 113 deletions

View File

@ -17,6 +17,7 @@ import sys
import time import time
import urllib import urllib
import ConfigParser import ConfigParser
import sqlite
CONFIG_FILENAME = "bantracker.conf" CONFIG_FILENAME = "bantracker.conf"
config = ConfigParser.RawConfigParser() config = ConfigParser.RawConfigParser()

View File

@ -7,29 +7,29 @@ best, this example wil use myfactoids as name. Then create a directory to store
your databases in (somewere in $botdir/data would be best). your databases in (somewere in $botdir/data would be best).
If you choose to enable this plugin during supybot-wizard the database will be If you choose to enable this plugin during supybot-wizard the database will be
created for you. If noy, you can create the database manually. created for you. If noy, you can create the database manually.
In the new directory create an SQLite2 database with the following command: In the new directory create an SQLite 3 database with the following command:
sqlite3 myfactoids.db
sqlite myfactoids.db
Then copy/paste in the below 2 tables: Then copy/paste in the below 2 tables:
CREATE TABLE facts ( CREATE TABLE facts (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
author VARCHAR(100) NOT NULL, author TEXT NOT NULL,
name VARCHAR(20) NOT NULL, name TEXT NOT NULL,
added DATETIME, added TEXT NOT NULL,
value VARCHAR(200) NOT NULL, value TEXT NOT NULL,
popularity INTEGER NOT NULL DEFAULT 0 popularity INTEGER NOT NULL DEFAULT 0
); );
CREATE TABLE log ( CREATE TABLE log (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
author VARCHAR(100) NOT NULL, author TEXT NOT NULL,
name VARCHAR(20) NOT NULL, name TEXT NOT NULL,
added DATETIME, added TEXT NOT NULL,
oldvalue VARCHAR(200) NOT NULL oldvalue TEXT NOT NULL
); );
If you want to create more databases, repeat these last two steps. If you want to create more databases, repeat these last two steps.
When the databases exist, you need to configure the bots to actually use them. When the databases exist, you need to configure the bots to actually use them.

View File

@ -2,6 +2,7 @@
### ###
# Copyright (c) 2006-2007 Dennis Kaarsemaker # Copyright (c) 2006-2007 Dennis Kaarsemaker
# Copyright (c) 2008-2010 Terence Simpson # Copyright (c) 2008-2010 Terence Simpson
# Copyright (c) 2018- Krytarik Raido
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as # it under the terms of version 2 of the GNU General Public License as
@ -22,12 +23,13 @@ funtionality has been moved to PackageInfo
import supybot import supybot
import supybot.world as world import supybot.world as world
__version__ = "2.3" __version__ = "2.4"
__author__ = supybot.Author("Terence Simpson", "tsimpson", "tsimpson@ubuntu.com") __author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@tuxgarage.com")
__contributors__ = { __contributors__ = {
supybot.Author("Dennis Kaarsemaker","Seveas","dennis@kaarsemaker.net"): ['Original Author'] supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],
supybot.Author("Terence Simpson", "tsimpson", "tsimpson@ubuntu.com"): ['Original Author']
} }
__url__ = 'https://launchpad.net/ubuntu-bots/' __url__ = 'https://launchpad.net/ubuntu-bots'
import config import config
reload(config) reload(config)

View File

@ -2,6 +2,7 @@
### ###
# Copyright (c) 2006-2007 Dennis Kaarsemaker # Copyright (c) 2006-2007 Dennis Kaarsemaker
# Copyright (c) 2008-2010 Terence Simpson # Copyright (c) 2008-2010 Terence Simpson
# Copyright (c) 2018- Krytarik Raido
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as # it under the terms of version 2 of the GNU General Public License as
@ -21,7 +22,7 @@ def configure(advanced):
from supybot.questions import yn, something, output from supybot.questions import yn, something, output
from supybot.utils.str import format from supybot.utils.str import format
import os import os
import sqlite import sqlite3
import re import re
def anything(prompt, default=None): def anything(prompt, default=None):
@ -114,29 +115,29 @@ def configure(advanced):
output("supybot.plugins.Encyclopedia.database will be set to %r" % db_file) output("supybot.plugins.Encyclopedia.database will be set to %r" % db_file)
Encyclopedia.database.setValue(db_dir) Encyclopedia.database.setValue(db_dir)
if os.path.exists(os.path.join(db_dir, db_file + '.db')): if os.path.exists(os.path.join(db_dir, '%s.db' % db_file)):
return return
con = sqlite.connect(os.path.join(db_dir, db_file + '.db')) con = sqlite3.connect(os.path.join(db_dir, '%s.db' % db_file))
cur = con.cursor() cur = con.cursor()
try: try:
cur.execute("""CREATE TABLE facts ( cur.execute("""CREATE TABLE facts (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
author VARCHAR(100) NOT NULL, author TEXT NOT NULL,
name VARCHAR(20) NOT NULL, name TEXT NOT NULL,
added DATETIME, added TEXT NOT NULL,
value VARCHAR(200) NOT NULL, value TEXT NOT NULL,
popularity INTEGER NOT NULL DEFAULT 0 popularity INTEGER NOT NULL DEFAULT 0
)""") )""")
#"""
cur.execute("""CREATE TABLE log ( cur.execute("""CREATE TABLE log (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
author VARCHAR(100) NOT NULL, author TEXT NOT NULL,
name VARCHAR(20) NOT NULL, name TEXT NOT NULL,
added DATETIME, added TEXT NOT NULL,
oldvalue VARCHAR(200) NOT NULL oldvalue TEXT NOT NULL
)""") )""")
except: except:
con.rollback() con.rollback()
@ -144,7 +145,6 @@ def configure(advanced):
else: else:
con.commit() con.commit()
finally: finally:
cur.close()
con.close() con.close()
Encyclopedia = conf.registerPlugin('Encyclopedia') Encyclopedia = conf.registerPlugin('Encyclopedia')

View File

@ -1,7 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
### ###
# Copyright (c) 2006,2007 Dennis Kaarsemaker # Copyright (c) 2006-2007 Dennis Kaarsemaker
# Copyright (c) 2008, 2009 Terence Simpson # Copyright (c) 2008-2009 Terence Simpson
# Copyright (c) 2018- Krytarik Raido
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as # it under the terms of version 2 of the GNU General Public License as
@ -18,6 +19,7 @@ import sys
# This needs to be set to the location of the commoncgi.py file # This needs to be set to the location of the commoncgi.py file
sys.path.append('/var/www/bot') sys.path.append('/var/www/bot')
from commoncgi import * from commoncgi import *
import sqlite3
### Variables ### Variables
NUM_PER_PAGE=50.0 NUM_PER_PAGE=50.0
@ -77,18 +79,12 @@ class Log:
return self._added[:self._added.find('.')] return self._added[:self._added.find('.')]
return self._added return self._added
## SQLite function to check if a string contains a substring
## Because we can't pass % along to WHERE X LIKE %s
def contains(needle, haystack):
return needle.lower() in haystack.lower() and 1 or 0
# Read POST # Read POST
if 'db' in form: if 'db' in form:
database = form['db'].value database = form['db'].value
if database not in databases: if database not in databases:
database = default_database database = default_database
con = sqlite.connect(os.path.join(datadir, database + '.db')) con = sqlite3.connect(os.path.join(datadir, '%s.db' % database))
con.create_function('contains', 2, contains)
cur = con.cursor() cur = con.cursor()
try: page = int(form['page'].value) try: page = int(form['page'].value)
@ -107,26 +103,26 @@ if search:
if not keys: if not keys:
keys = [''] keys = ['']
query1 = "SELECT name, value, author, added, popularity FROM facts WHERE name NOT LIKE '%%-also' AND (" query1 = "SELECT name, value, author, added, popularity FROM facts WHERE name NOT LIKE '%%-also' AND ("
query2 = "SELECT COUNT(name) FROM facts WHERE " query2 = "SELECT COUNT(*) FROM facts WHERE "
bogus = False bogus = False
for k in keys: for k in keys:
values.extend((k, k)) values.extend(('%%%s%%' % k, '%%%s%%' % k))
if bogus: if bogus:
query1 += ' OR ' query1 += ' OR '
query2 += ' OR ' query2 += ' OR '
query1 += "contains(%s, name) OR contains(%s, value)" query1 += 'name LIKE ? OR value LIKE ?'
query2 += "contains(%s, name) OR contains(%s, value)" query2 += 'name LIKE ? OR value LIKE ?'
bogus=True bogus=True
query1 += ') ORDER BY %s LIMIT %d, %d' % (order_by, NUM_PER_PAGE*page, NUM_PER_PAGE) cur.execute(query1 + ') ORDER BY %s LIMIT %d, %d' % (order_by, NUM_PER_PAGE * page, NUM_PER_PAGE), values)
cur.execute(query1, values)
factoids = [Factoid(*x) for x in cur.fetchall()] factoids = [Factoid(*x) for x in cur.fetchall()]
cur.execute(query2, values) cur.execute(query2, values)
total = cur.fetchall()[0][0] total = cur.fetchall()[0][0]
else: 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)) 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, NUM_PER_PAGE * page, NUM_PER_PAGE))
factoids = [Factoid(*x) for x in cur.fetchall()] factoids = [Factoid(*x) for x in cur.fetchall()]
cur.execute("""SELECT COUNT(*) FROM facts WHERE value NOT LIKE '<alias>%%'""") cur.execute("SELECT COUNT(*) FROM facts WHERE value NOT LIKE '<alias>%%'")
total = cur.fetchall()[0][0] total = cur.fetchall()[0][0]
# Pagination links # Pagination links
@ -168,14 +164,14 @@ def link(match):
i = 0 i = 0
for fact in factoids: for fact in factoids:
name = fact.name name = fact.name
cur.execute("SELECT value FROM facts WHERE name = %s", fact.name + '-also') cur.execute("SELECT value FROM facts WHERE name = ?", ('%s-also' % fact.name,))
more = cur.fetchall() more = cur.fetchall()
if len(more): if len(more):
name += ' $hr$' + ' $hr$'.join([x[0] for x in more]) name += ' $hr$' + ' $hr$'.join([x[0] for x in more])
cur.execute("SELECT name FROM facts WHERE value LIKE %s", '<alias> ' + fact.name) cur.execute("SELECT name FROM facts WHERE value = ?", ('<alias> %s' % fact.name,))
name += ' \n' + ' \n'.join([x[0] for x in cur.fetchall()]) name += ' \n' + ' \n'.join([x[0] for x in cur.fetchall()])
data = [ q(x) for x in fact ] data = [ q(x) for x in fact ]
cur.execute("SELECT author, added FROM log WHERE name = %s ORDER BY id DESC LIMIT 1", fact.name) cur.execute("SELECT author, added FROM log WHERE name = ? ORDER BY id DESC LIMIT 1", (fact.name,))
edit = [Log(*x) for x in cur.fetchall()] edit = [Log(*x) for x in cur.fetchall()]
# edit = [Log(author, added) for (author, added) in cur.fetchall()] # edit = [Log(author, added) for (author, added) in cur.fetchall()]
if edit: if edit:

View File

@ -2,6 +2,7 @@
### ###
# Copyright (c) 2006-2007 Dennis Kaarsemaker # Copyright (c) 2006-2007 Dennis Kaarsemaker
# Copyright (c) 2008-2010 Terence Simpson # Copyright (c) 2008-2010 Terence Simpson
# Copyright (c) 2018- Krytarik Raido
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as # it under the terms of version 2 of the GNU General Public License as
@ -17,7 +18,7 @@
from supybot.commands import * from supybot.commands import *
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
import sqlite, datetime, time, pytz import sqlite3, datetime, time, pytz
import supybot.registry as registry import supybot.registry as registry
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
import supybot.conf as conf import supybot.conf as conf
@ -161,6 +162,13 @@ def checkUrl(s):
return bool(urlRe.search(s)) return bool(urlRe.search(s))
class DbWrapper(object):
def __init__(self, db, name):
self.db = db
self.name = name
self.time = time.time()
class Encyclopedia(callbacks.Plugin): class Encyclopedia(callbacks.Plugin):
"""!factoid: show factoid""" """!factoid: show factoid"""
@ -270,13 +278,12 @@ class Encyclopedia(callbacks.Plugin):
db = self.registryValue('database',channel) db = self.registryValue('database',channel)
if channel in self.databases: if channel in self.databases:
if self.databases[channel].time < time.time() - 3600 or self.databases[channel].name != db: if self.databases[channel].time < time.time() - 3600 or self.databases[channel].name != db:
self.databases[channel].close() self.databases[channel].db.close()
self.databases.pop(channel) self.databases.pop(channel)
if channel not in self.databases: if channel not in self.databases:
self.databases[channel] = sqlite.connect(os.path.join(self.registryValue('datadir'), '%s.db' % db)) self.databases[channel] = DbWrapper(
self.databases[channel].name = db sqlite3.connect(os.path.join(self.registryValue('datadir'), '%s.db' % db)), db)
self.databases[channel].time = time.time() return self.databases[channel].db
return self.databases[channel]
def get_log_db(self, channel=None): def get_log_db(self, channel=None):
db = "%s-log" % self.registryValue('database',channel) db = "%s-log" % self.registryValue('database',channel)
@ -287,13 +294,11 @@ class Encyclopedia(callbacks.Plugin):
channel = "%s-log" % channel channel = "%s-log" % channel
if channel in self.databases: if channel in self.databases:
if self.databases[channel].time < time.time() - 3600 or self.databases[channel].name != db: if self.databases[channel].time < time.time() - 3600 or self.databases[channel].name != db:
self.databases[channel].close() self.databases[channel].db.close()
self.databases.pop(channel) self.databases.pop(channel)
if channel not in self.databases: if channel not in self.databases:
self.databases[channel] = sqlite.connect(db_path) self.databases[channel] = DbWrapper(sqlite3.connect(db_path), db)
self.databases[channel].name = db return self.databases[channel].db
self.databases[channel].time = time.time()
return self.databases[channel]
def addressed(self, recipients, text, irc, msg): def addressed(self, recipients, text, irc, msg):
nlen = len(irc.nick) nlen = len(irc.nick)
@ -346,9 +351,9 @@ class Encyclopedia(callbacks.Plugin):
db = self.get_db(channel) db = self.get_db(channel)
cur = db.cursor() cur = db.cursor()
if deleted: if deleted:
cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE name = %s", name) cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE name = ?", (name,))
else: else:
cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE name = %s AND value NOT like '<deleted>%%'", name) cur.execute("SELECT name, value, author, added, popularity FROM facts WHERE name = ? AND value NOT LIKE '<deleted>%%'", (name,))
factoids = cur.fetchall() factoids = cur.fetchall()
if len(factoids): if len(factoids):
f = factoids[0] f = factoids[0]
@ -371,20 +376,18 @@ class Encyclopedia(callbacks.Plugin):
def factoid_info(self, channel, factoid): def factoid_info(self, channel, factoid):
if not factoid: if not factoid:
return return
db = self.get_db(channel)
cur = db.cursor()
if not factoid.value.startswith('<alias>'): if not factoid.value.startswith('<alias>'):
# Try and find aliases # Try and find aliases
db = self.get_db(channel) cur.execute("SELECT name FROM facts WHERE value = ?", ('<alias> %s' % factoid.name,))
cur = db.cursor()
cur.execute("SELECT name FROM facts WHERE value = %s", '<alias> ' + factoid.name)
data = cur.fetchall() data = cur.fetchall()
if data: if data:
factoid.value = "<reply> %s aliases: %s" % (factoid.name, ', '.join([x[0] for x in data])) factoid.value = "<reply> %s aliases: %s" % (factoid.name, ', '.join([x[0] for x in data]))
else: else:
factoid.value = "<reply> %s has no aliases" % (factoid.name) factoid.value = "<reply> %s has no aliases" % factoid.name
# Author info # Author info
db = self.get_db(channel) cur.execute("SELECT author, added FROM log WHERE name = ?", (factoid.name,))
cur = db.cursor()
cur.execute("SELECT author, added FROM log WHERE name = %s", factoid.name)
data = cur.fetchall() data = cur.fetchall()
factoid.value += " - added by %s on %s" % (factoid.author[:factoid.author.find('!')], factoid.added[:factoid.added.find('.')]) factoid.value += " - added by %s on %s" % (factoid.author[:factoid.author.find('!')], factoid.added[:factoid.added.find('.')])
if data: if data:
@ -456,7 +459,7 @@ class Encyclopedia(callbacks.Plugin):
if checkIgnored(msg.prefix,msg.args[0]): if checkIgnored(msg.prefix,msg.args[0]):
return return
# Are we being queried? # Are we being queried?
recipient, text = msg.args recipient, text = msg.args[0], msg.args[1].decode('utf-8')
if not self.registryValue('enabled', ircutils.isChannel(recipient) and recipient or None): if not self.registryValue('enabled', ircutils.isChannel(recipient) and recipient or None):
# Encyclopedia is disabled here, do nothing # Encyclopedia is disabled here, do nothing
return return
@ -551,7 +554,7 @@ class Encyclopedia(callbacks.Plugin):
retmsg = '' retmsg = ''
ret = self.registryValue('notfoundmsg') ret = self.registryValue('notfoundmsg')
if ret.count('%') == ret.count('%s') == 1: if ret.count('%') == ret.count('%s') == 1:
ret = ret % repr(text) ret = ret % repr(text).lstrip('u')
if channel.lower() == irc.nick.lower() or self.registryValue('privateNotFound', channel): if channel.lower() == irc.nick.lower() or self.registryValue('privateNotFound', channel):
myqueue(irc, msg.nick, ret) myqueue(irc, msg.nick, ret)
else: else:
@ -624,7 +627,7 @@ class Encyclopedia(callbacks.Plugin):
factoid = retmsg = None factoid = retmsg = None
def log_change(factoid): def log_change(factoid):
cs.execute('''insert into log (author, name, added, oldvalue) values (%s, %s, %s, %s)''', cs.execute("INSERT INTO log (author, name, added, oldvalue) VALUES (?, ?, ?, ?)",
(editor, factoid.name, str(datetime.datetime.now(pytz.timezone("UTC"))), factoid.value)) (editor, factoid.name, str(datetime.datetime.now(pytz.timezone("UTC"))), factoid.value))
db.commit() db.commit()
@ -701,7 +704,7 @@ class Encyclopedia(callbacks.Plugin):
ret = self.check_aliases(channel, factoid) ret = self.check_aliases(channel, factoid)
if ret: if ret:
return ret return ret
cs.execute("UPDATE facts SET value=%s where name=%s", (factoid.value,factoid.name)) cs.execute("UPDATE facts SET value = ? WHERE name = ?", (factoid.value, factoid.name))
db.commit() db.commit()
return retmsg return retmsg
@ -725,7 +728,7 @@ class Encyclopedia(callbacks.Plugin):
ret = self.check_aliases(channel, factoid) ret = self.check_aliases(channel, factoid)
if ret: if ret:
return ret return ret
cs.execute("INSERT INTO facts (name, value, author, added) VALUES (%s, %s, %s, %s)", cs.execute("INSERT INTO facts (name, value, author, added) VALUES (?, ?, ?, ?)",
(name, value, editor, str(datetime.datetime.now(pytz.timezone("UTC"))))) (name, value, editor, str(datetime.datetime.now(pytz.timezone("UTC")))))
db.commit() db.commit()
return "I'll remember that, %s" % editor[:editor.find('!')] return "I'll remember that, %s" % editor[:editor.find('!')]
@ -767,7 +770,7 @@ class Encyclopedia(callbacks.Plugin):
factoid = getattr(factoids,key) factoid = getattr(factoids,key)
if (not display_info and not display_raw): if (not display_info and not display_raw):
cur = db.cursor() cur = db.cursor()
cur.execute("UPDATE FACTS SET popularity = %d WHERE name = %s", factoid.popularity+1, factoid.name) cur.execute("UPDATE facts SET popularity = ? WHERE name = ?", (factoid.popularity+1, factoid.name))
db.commit() db.commit()
if display_raw: if display_raw:
ret.append(factoid.value) ret.append(factoid.value)
@ -819,13 +822,13 @@ class Encyclopedia(callbacks.Plugin):
return return
cur = db.cursor() cur = db.cursor()
now = str(datetime.datetime.now(pytz.timezone("UTC"))) now = str(datetime.datetime.now(pytz.timezone("UTC")))
cur.execute("SELECT value FROM requests WHERE name = %s", name) cur.execute("SELECT value FROM requests WHERE name = ?", (name,))
items = cur.fetchall() items = cur.fetchall()
if len(items): if len(items):
for item in items: for item in items:
if item[0] == msg: if item[0] == msg:
return return
cur.execute("INSERT INTO requests (type, name, value, oldval, who, date, rank) VALUES (%i, %s, %s, %s, %s, %s, 0)", cur.execute("INSERT INTO requests (type, name, value, oldval, who, date, rank) VALUES (?, ?, ?, ?, ?, ?, 0)",
(int(bool(tp)), name, msg, oldval, nick, now)) (int(bool(tp)), name, msg, oldval, nick, now))
db.commit() db.commit()
@ -835,8 +838,7 @@ class Encyclopedia(callbacks.Plugin):
cur = db.cursor() cur = db.cursor()
ret = {} ret = {}
for k in keys: for k in keys:
k = k.replace("'","\'") cur.execute("SELECT name, value FROM facts WHERE name LIKE ? OR value LIKE ?", ('%%%s%%' % k, '%%%s%%' % k))
cur.execute("SELECT name,value FROM facts WHERE name LIKE '%%%s%%' OR VAlUE LIKE '%%%s%%'" % (k, k))
res = cur.fetchall() res = cur.fetchall()
for r in res: for r in res:
val = r[1] val = r[1]
@ -883,11 +885,11 @@ class Encyclopedia(callbacks.Plugin):
fd2.close() fd2.close()
# Do some checking to make sure we have an SQLite database # Do some checking to make sure we have an SQLite database
fd2 = open(tmp_db, 'rb') fd2 = open(tmp_db, 'rb')
data = fd2.read(47) check = fd2.read(15)
if data == '** This file contains an SQLite 2.1 database **': # OK, rename to dpath if check == 'SQLite format 3': # OK, rename to dpath
os.rename(tmp_db, dpath) os.rename(tmp_db, dpath)
try: try:
self.databases[channel].close() self.databases[channel].db.close()
except: except:
pass pass
try: try:
@ -896,7 +898,7 @@ class Encyclopedia(callbacks.Plugin):
pass pass
else: # Remove the tmpparary file and raise an error else: # Remove the tmpparary file and raise an error
os.remove(tmp_db) os.remove(tmp_db)
raise RuntimeError, "Downloaded file was not a SQLite 2.1 database" raise RuntimeError, "Downloaded file was not an SQLite 3 database"
db = self.registryValue('database', channel) db = self.registryValue('database', channel)
if not db: if not db:
@ -954,16 +956,16 @@ class Encyclopedia(callbacks.Plugin):
if not author: if not author:
author = msg.prefix author = msg.prefix
def isLastEdit(name, id): def isLastEdit(name, id):
cur.execute("SELECT MAX(id) FROM log WHERE name=%s", (name,)) cur.execute("SELECT max(id) FROM log WHERE name = ?", (name,))
return int(cur.fetchall()[0][0]) == id return int(cur.fetchall()[0][0]) == id
author = author.split('!', 1)[0] author = author.split('!', 1)[0]
db = self.get_db(channel) db = self.get_db(channel)
cur = db.cursor() cur = db.cursor()
ret = {} ret = {}
log_ret = {} log_ret = {}
cur.execute("SELECT name,value FROM facts WHERE author LIKE '%s%%'" % (author,)) cur.execute("SELECT name, value FROM facts WHERE author LIKE ?", ('%s%%' % author,))
res = cur.fetchall() res = cur.fetchall()
cur.execute("SELECT id, name, oldvalue FROM log WHERE author LIKE '%s%%'" % (author,)) cur.execute("SELECT id, name, oldvalue FROM log WHERE author LIKE ?", ('%s%%' % author,))
log_res = cur.fetchall() log_res = cur.fetchall()
for r in res: for r in res:
val = r[1] val = r[1]
@ -1035,8 +1037,8 @@ class Encyclopedia(callbacks.Plugin):
cur = db.cursor() cur = db.cursor()
sessid = hashlib.md5('%s%s%d' % (msg.prefix, time.time(), random.randint(1,100000))).hexdigest() sessid = hashlib.md5('%s%s%d' % (msg.prefix, time.time(), random.randint(1,100000))).hexdigest()
cur.execute("INSERT INTO sessions (session_id, user, time) VALUES (%s, %s, %d)", cur.execute("INSERT INTO sessions (session_id, user, time) VALUES (?, ?, ?)",
(sessid, msg.nick, int(time.mktime(time.gmtime())) )) (sessid, msg.nick, int(time.mktime(time.gmtime()))))
db.commit() db.commit()
irc.reply("Login at http://jussi01.com/stdin/test/facts.cgi?sessid=%s" % sessid, private=True) irc.reply("Login at http://jussi01.com/stdin/test/facts.cgi?sessid=%s" % sessid, private=True)

View File

@ -2,6 +2,7 @@
### ###
# Copyright (c) 2006 Dennis Kaarsemaker # Copyright (c) 2006 Dennis Kaarsemaker
# Copyright (c) 2010 Elián Hanisch # Copyright (c) 2010 Elián Hanisch
# Copyright (c) 2018 Krytarik Raido
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -33,29 +34,30 @@ class EncyclopediaTestCase(ChannelPluginTestCase):
self.createDB() self.createDB()
def createDB(self): def createDB(self):
import sqlite, os import sqlite3, os
dbfile = os.path.join(Econf.datadir(), '%s.db' %Econf.database()) dbfile = os.path.join(Econf.datadir(), '%s.db' %Econf.database())
try: try:
os.remove(dbfile) os.remove(dbfile)
except: except:
pass pass
db = sqlite.connect(dbfile) db = sqlite3.connect(dbfile)
cursor = db.cursor() cur = db.cursor()
cursor.execute('CREATE TABLE facts ('\ cur.execute("""CREATE TABLE facts (
'id INTEGER PRIMARY KEY,'\ id INTEGER PRIMARY KEY,
'author VARCHAR(100) NOT NULL,'\ author TEXT NOT NULL,
'name VARCHAR(20) NOT NULL,'\ name TEXT NOT NULL,
'added DATETIME,'\ added TEXT NOT NULL,
'value VARCHAR(200) NOT NULL,'\ value TEXT NOT NULL,
'popularity INTEGER NOT NULL DEFAULT 0);') popularity INTEGER NOT NULL DEFAULT 0
cursor.execute('CREATE TABLE log ('\ )""")
'id INTEGER PRIMARY KEY,'\ cur.execute("""CREATE TABLE log (
'author VARCHAR(100) NOT NULL,'\ id INTEGER PRIMARY KEY,
'name VARCHAR(20) NOT NULL,'\ author TEXT NOT NULL,
'added DATETIME,'\ name TEXT NOT NULL,
'oldvalue VARCHAR(200) NOT NULL);') added TEXT NOT NULL,
oldvalue TEXT NOT NULL
)""")
db.commit() db.commit()
cursor.close()
db.close() db.close()
self.getCallback().databases = {} self.getCallback().databases = {}

View File

@ -14,7 +14,7 @@
# #
### ###
import cgi, cgitb, re, sys, math, os, hashlib, sqlite, random, time, datetime, pytz, Cookie, StringIO, urllib2 import cgi, cgitb, re, sys, math, os, hashlib, random, time, datetime, pytz, Cookie, StringIO, urllib2
import cPickle as pickle import cPickle as pickle
cgitb.enable() cgitb.enable()