Convert tabs to spaces
This commit is contained in:
parent
3acf60d6e9
commit
20c1ffd2fc
52
bin/pyircbot
52
bin/pyircbot
@ -7,29 +7,29 @@ from pyircbot import PyIRCBot
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
" logging level and facility "
|
||||
logging.basicConfig(level=logging.DEBUG, format="%(asctime)-15s %(levelname)-8s %(message)s")
|
||||
log = logging.getLogger('main')
|
||||
|
||||
" parse command line args "
|
||||
parser = OptionParser()
|
||||
parser.add_option("-c", "--config", action="store", type="string", dest="config", help="Path to config file")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
log.debug(options)
|
||||
|
||||
if not options.config:
|
||||
log.critical("No bot config file specified (-c). Exiting.")
|
||||
sys.exit(0)
|
||||
|
||||
botconfig = PyIRCBot.load(options.config)
|
||||
|
||||
log.debug(botconfig)
|
||||
|
||||
bot = PyIRCBot(botconfig)
|
||||
try:
|
||||
bot.loop()
|
||||
except KeyboardInterrupt:
|
||||
bot.kill()
|
||||
|
||||
" logging level and facility "
|
||||
logging.basicConfig(level=logging.DEBUG, format="%(asctime)-15s %(levelname)-8s %(message)s")
|
||||
log = logging.getLogger('main')
|
||||
|
||||
" parse command line args "
|
||||
parser = OptionParser()
|
||||
parser.add_option("-c", "--config", action="store", type="string", dest="config", help="Path to config file")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
log.debug(options)
|
||||
|
||||
if not options.config:
|
||||
log.critical("No bot config file specified (-c). Exiting.")
|
||||
sys.exit(0)
|
||||
|
||||
botconfig = PyIRCBot.load(options.config)
|
||||
|
||||
log.debug(botconfig)
|
||||
|
||||
bot = PyIRCBot(botconfig)
|
||||
try:
|
||||
bot.loop()
|
||||
except KeyboardInterrupt:
|
||||
bot.kill()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""
|
||||
.. module:: Core
|
||||
:synopsis: Core module of the bot
|
||||
:synopsis: Core module of the bot
|
||||
|
||||
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""
|
||||
.. module:: ModuleBase
|
||||
:synopsis: Base class that modules will extend
|
||||
:synopsis: Base class that modules will extend
|
||||
|
||||
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
|
||||
|
||||
@ -11,65 +11,65 @@ import os
|
||||
from .pyircbot import PyIRCBot
|
||||
|
||||
class ModuleBase:
|
||||
"""All modules will extend this class
|
||||
|
||||
:param bot: A reference to the main bot passed when this module is created
|
||||
:type bot: PyIRCBot
|
||||
:param moduleName: The name assigned to this module
|
||||
:type moduleName: str
|
||||
"""
|
||||
|
||||
def __init__(self, bot, moduleName):
|
||||
self.moduleName=moduleName
|
||||
"""Assigned name of this module"""
|
||||
|
||||
self.bot = bot
|
||||
"""Reference to the master PyIRCBot object"""
|
||||
|
||||
self.hooks=[]
|
||||
"""Hooks (aka listeners) this module has"""
|
||||
|
||||
self.services=[]
|
||||
"""If this module provides services usable by another module, they're listed
|
||||
here"""
|
||||
|
||||
self.config={}
|
||||
"""Configuration dictionary. Autoloaded from `%(datadir)s/%(modulename)s.json`"""
|
||||
|
||||
self.log = logging.getLogger("Module.%s" % self.moduleName)
|
||||
"""Logger object for this module"""
|
||||
|
||||
# Autoload config if available
|
||||
self.loadConfig()
|
||||
|
||||
self.log.info("Loaded module %s" % self.moduleName)
|
||||
|
||||
def loadConfig(self):
|
||||
"""Loads this module's config into self.config"""
|
||||
configPath = self.bot.getConfigPath(self.moduleName)
|
||||
if not configPath == None:
|
||||
self.config = PyIRCBot.load(configPath)
|
||||
|
||||
def ondisable(self):
|
||||
"""Called when the module should be disabled. Your module should do any sort
|
||||
of clean-up operations here like ending child threads or saving data files.
|
||||
"""
|
||||
pass
|
||||
|
||||
def getConfigPath(self):
|
||||
"""Returns the absolute path of this module's json config file"""
|
||||
return self.bot.getConfigPath(self.moduleName)
|
||||
|
||||
def getFilePath(self, f=None):
|
||||
"""Returns the absolute path to a file in this Module's data dir
|
||||
|
||||
:param f: The file name included in the path
|
||||
:type channel: str
|
||||
:Warning: .. Warning:: this does no error checking if the file exists or is\
|
||||
writable. The bot's data dir *should* always be writable"""
|
||||
return self.bot.getDataPath(self.moduleName) + (f if f else '')
|
||||
"""All modules will extend this class
|
||||
|
||||
:param bot: A reference to the main bot passed when this module is created
|
||||
:type bot: PyIRCBot
|
||||
:param moduleName: The name assigned to this module
|
||||
:type moduleName: str
|
||||
"""
|
||||
|
||||
def __init__(self, bot, moduleName):
|
||||
self.moduleName=moduleName
|
||||
"""Assigned name of this module"""
|
||||
|
||||
self.bot = bot
|
||||
"""Reference to the master PyIRCBot object"""
|
||||
|
||||
self.hooks=[]
|
||||
"""Hooks (aka listeners) this module has"""
|
||||
|
||||
self.services=[]
|
||||
"""If this module provides services usable by another module, they're listed
|
||||
here"""
|
||||
|
||||
self.config={}
|
||||
"""Configuration dictionary. Autoloaded from `%(datadir)s/%(modulename)s.json`"""
|
||||
|
||||
self.log = logging.getLogger("Module.%s" % self.moduleName)
|
||||
"""Logger object for this module"""
|
||||
|
||||
# Autoload config if available
|
||||
self.loadConfig()
|
||||
|
||||
self.log.info("Loaded module %s" % self.moduleName)
|
||||
|
||||
def loadConfig(self):
|
||||
"""Loads this module's config into self.config"""
|
||||
configPath = self.bot.getConfigPath(self.moduleName)
|
||||
if not configPath == None:
|
||||
self.config = PyIRCBot.load(configPath)
|
||||
|
||||
def ondisable(self):
|
||||
"""Called when the module should be disabled. Your module should do any sort
|
||||
of clean-up operations here like ending child threads or saving data files.
|
||||
"""
|
||||
pass
|
||||
|
||||
def getConfigPath(self):
|
||||
"""Returns the absolute path of this module's json config file"""
|
||||
return self.bot.getConfigPath(self.moduleName)
|
||||
|
||||
def getFilePath(self, f=None):
|
||||
"""Returns the absolute path to a file in this Module's data dir
|
||||
|
||||
:param f: The file name included in the path
|
||||
:type channel: str
|
||||
:Warning: .. Warning:: this does no error checking if the file exists or is\
|
||||
writable. The bot's data dir *should* always be writable"""
|
||||
return self.bot.getDataPath(self.moduleName) + (f if f else '')
|
||||
|
||||
class ModuleHook:
|
||||
def __init__(self, hook, method):
|
||||
self.hook=hook
|
||||
self.method=method
|
||||
def __init__(self, hook, method):
|
||||
self.hook=hook
|
||||
self.method=method
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
.. module:: AttributeStorage
|
||||
:synopsis: An item key->value storage engine based on mysql
|
||||
:synopsis: An item key->value storage engine based on mysql
|
||||
|
||||
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
|
||||
|
||||
@ -10,165 +10,165 @@
|
||||
from pyircbot.modulebase import ModuleBase,ModuleHook
|
||||
|
||||
class AttributeStorage(ModuleBase):
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
self.hooks=[]
|
||||
self.services=["attributes"]
|
||||
self.db = None
|
||||
serviceProviders = self.bot.getmodulesbyservice("mysql")
|
||||
if len(serviceProviders)==0:
|
||||
self.log.error("AttributeStorage: Could not find a valid mysql service provider")
|
||||
else:
|
||||
self.log.info("AttributeStorage: Selecting mysql service provider: %s" % serviceProviders[0])
|
||||
self.db = serviceProviders[0]
|
||||
|
||||
if not self.db.connection.tableExists("attribute"):
|
||||
self.log.info("AttributeStorage: Creating table: attribute")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `attribute` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`attribute` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `attribute` (`attribute`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.connection.tableExists("items"):
|
||||
self.log.info("AttributeStorage: Creating table: items")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `items` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`item` varchar(512) CHARACTER SET utf8 NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.connection.tableExists("values"):
|
||||
self.log.info("AttributeStorage: Creating table: values")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `values` (
|
||||
`itemid` int(11) NOT NULL,
|
||||
`attributeid` int(11) NOT NULL,
|
||||
`value` varchar(512) CHARACTER SET utf8 NOT NULL,
|
||||
PRIMARY KEY (`itemid`,`attributeid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
# self.getItem('xMopxShell', 'name')
|
||||
# self.getKey('xMopxShell', 'name')
|
||||
# self.setKey('xMopxShell', 'name', 'dave')
|
||||
|
||||
# SELECT `i`.`id`, `i`.`item`, `a`.`attribute`, `v`.`value` FROM `items` `i` INNER JOIN `values` `v` on `v`.`itemid`=`i`.`id` INNER JOIN `attribute` `a` on `a`.`id`=`v`.`attributeid` ORDER BY `i`.`id` ASC, `a`.`id` ASC LIMIT 1000 ;
|
||||
|
||||
def getItem(self, name):
|
||||
"""Get all values for a item
|
||||
|
||||
:param name: the item
|
||||
:type name: str
|
||||
:returns: dict -- the item's values expressed as a dict"""
|
||||
c = self.db.connection.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=%s;""",
|
||||
(name,)
|
||||
)
|
||||
item = {}
|
||||
while True:
|
||||
row = c.fetchone()
|
||||
if row == None:
|
||||
break
|
||||
item[row["attribute"]]=row["value"]
|
||||
c.close()
|
||||
|
||||
if len(item)==0:
|
||||
return {}
|
||||
return item
|
||||
|
||||
def get(self, item, key):
|
||||
return self.getKey(item, key)
|
||||
|
||||
def getKey(self, item, key):
|
||||
"""Get the value of an key on an item
|
||||
|
||||
:param item: the item to fetch a key from
|
||||
:type item: str
|
||||
:param key: they key who's value to return
|
||||
:type key: str
|
||||
:returns: str -- the item from the database or **None**"""
|
||||
c = self.db.connection.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=%s
|
||||
AND
|
||||
`a`.`attribute`=%s;""",
|
||||
(item,key)
|
||||
)
|
||||
row = c.fetchone()
|
||||
c.close()
|
||||
if row == None:
|
||||
return None
|
||||
return row["value"]
|
||||
|
||||
def set(self, item, key, value):
|
||||
return self.setKey(item, key, value)
|
||||
|
||||
def setKey(self, item, key, value):
|
||||
"""Set the key on an item
|
||||
|
||||
:param item: the item name to set the key on
|
||||
:type item: str
|
||||
:param key: the key to set
|
||||
:type key: tuple
|
||||
:param value: the value to set
|
||||
:type value: str"""
|
||||
item = item.lower()
|
||||
attribute = key.lower()
|
||||
|
||||
# Check attribute exists
|
||||
c = self.db.connection.query("SELECT `id` FROM `attribute` WHERE `attribute`=%s;", (attribute))
|
||||
row = c.fetchone()
|
||||
attributeId = -1
|
||||
if row == None:
|
||||
c = self.db.connection.query("INSERT INTO `attribute` (`attribute`) VALUES (%s);", (attribute))
|
||||
attributeId = c.lastrowid
|
||||
else:
|
||||
attributeId = row["id"]
|
||||
c.close()
|
||||
|
||||
# check item exists
|
||||
c = self.db.connection.query("SELECT `id` FROM `items` WHERE `item`=%s;", (item))
|
||||
row = c.fetchone()
|
||||
itemId = -1
|
||||
if row == None:
|
||||
c = self.db.connection.query("INSERT INTO `items` (`item`) VALUES (%s);", (item))
|
||||
itemId = c.lastrowid
|
||||
else:
|
||||
itemId = row["id"]
|
||||
c.close()
|
||||
|
||||
if value == None:
|
||||
# delete it
|
||||
c = self.db.connection.query("DELETE FROM `values` WHERE `itemid`=%s AND `attributeid`=%s ;", (itemId, attributeId))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s (Deleted)" % (itemId, attributeId, value))
|
||||
else:
|
||||
# add attribute
|
||||
c = self.db.connection.query("REPLACE INTO `values` (`itemid`, `attributeid`, `value`) VALUES (%s, %s, %s);", (itemId, attributeId, value))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s" % (itemId, attributeId, value))
|
||||
c.close()
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
self.hooks=[]
|
||||
self.services=["attributes"]
|
||||
self.db = None
|
||||
serviceProviders = self.bot.getmodulesbyservice("mysql")
|
||||
if len(serviceProviders)==0:
|
||||
self.log.error("AttributeStorage: Could not find a valid mysql service provider")
|
||||
else:
|
||||
self.log.info("AttributeStorage: Selecting mysql service provider: %s" % serviceProviders[0])
|
||||
self.db = serviceProviders[0]
|
||||
|
||||
if not self.db.connection.tableExists("attribute"):
|
||||
self.log.info("AttributeStorage: Creating table: attribute")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `attribute` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`attribute` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `attribute` (`attribute`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.connection.tableExists("items"):
|
||||
self.log.info("AttributeStorage: Creating table: items")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `items` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`item` varchar(512) CHARACTER SET utf8 NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.connection.tableExists("values"):
|
||||
self.log.info("AttributeStorage: Creating table: values")
|
||||
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `values` (
|
||||
`itemid` int(11) NOT NULL,
|
||||
`attributeid` int(11) NOT NULL,
|
||||
`value` varchar(512) CHARACTER SET utf8 NOT NULL,
|
||||
PRIMARY KEY (`itemid`,`attributeid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
|
||||
c.close()
|
||||
|
||||
# self.getItem('xMopxShell', 'name')
|
||||
# self.getKey('xMopxShell', 'name')
|
||||
# self.setKey('xMopxShell', 'name', 'dave')
|
||||
|
||||
# SELECT `i`.`id`, `i`.`item`, `a`.`attribute`, `v`.`value` FROM `items` `i` INNER JOIN `values` `v` on `v`.`itemid`=`i`.`id` INNER JOIN `attribute` `a` on `a`.`id`=`v`.`attributeid` ORDER BY `i`.`id` ASC, `a`.`id` ASC LIMIT 1000 ;
|
||||
|
||||
def getItem(self, name):
|
||||
"""Get all values for a item
|
||||
|
||||
:param name: the item
|
||||
:type name: str
|
||||
:returns: dict -- the item's values expressed as a dict"""
|
||||
c = self.db.connection.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=%s;""",
|
||||
(name,)
|
||||
)
|
||||
item = {}
|
||||
while True:
|
||||
row = c.fetchone()
|
||||
if row == None:
|
||||
break
|
||||
item[row["attribute"]]=row["value"]
|
||||
c.close()
|
||||
|
||||
if len(item)==0:
|
||||
return {}
|
||||
return item
|
||||
|
||||
def get(self, item, key):
|
||||
return self.getKey(item, key)
|
||||
|
||||
def getKey(self, item, key):
|
||||
"""Get the value of an key on an item
|
||||
|
||||
:param item: the item to fetch a key from
|
||||
:type item: str
|
||||
:param key: they key who's value to return
|
||||
:type key: str
|
||||
:returns: str -- the item from the database or **None**"""
|
||||
c = self.db.connection.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=%s
|
||||
AND
|
||||
`a`.`attribute`=%s;""",
|
||||
(item,key)
|
||||
)
|
||||
row = c.fetchone()
|
||||
c.close()
|
||||
if row == None:
|
||||
return None
|
||||
return row["value"]
|
||||
|
||||
def set(self, item, key, value):
|
||||
return self.setKey(item, key, value)
|
||||
|
||||
def setKey(self, item, key, value):
|
||||
"""Set the key on an item
|
||||
|
||||
:param item: the item name to set the key on
|
||||
:type item: str
|
||||
:param key: the key to set
|
||||
:type key: tuple
|
||||
:param value: the value to set
|
||||
:type value: str"""
|
||||
item = item.lower()
|
||||
attribute = key.lower()
|
||||
|
||||
# Check attribute exists
|
||||
c = self.db.connection.query("SELECT `id` FROM `attribute` WHERE `attribute`=%s;", (attribute))
|
||||
row = c.fetchone()
|
||||
attributeId = -1
|
||||
if row == None:
|
||||
c = self.db.connection.query("INSERT INTO `attribute` (`attribute`) VALUES (%s);", (attribute))
|
||||
attributeId = c.lastrowid
|
||||
else:
|
||||
attributeId = row["id"]
|
||||
c.close()
|
||||
|
||||
# check item exists
|
||||
c = self.db.connection.query("SELECT `id` FROM `items` WHERE `item`=%s;", (item))
|
||||
row = c.fetchone()
|
||||
itemId = -1
|
||||
if row == None:
|
||||
c = self.db.connection.query("INSERT INTO `items` (`item`) VALUES (%s);", (item))
|
||||
itemId = c.lastrowid
|
||||
else:
|
||||
itemId = row["id"]
|
||||
c.close()
|
||||
|
||||
if value == None:
|
||||
# delete it
|
||||
c = self.db.connection.query("DELETE FROM `values` WHERE `itemid`=%s AND `attributeid`=%s ;", (itemId, attributeId))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s (Deleted)" % (itemId, attributeId, value))
|
||||
else:
|
||||
# add attribute
|
||||
c = self.db.connection.query("REPLACE INTO `values` (`itemid`, `attributeid`, `value`) VALUES (%s, %s, %s);", (itemId, attributeId, value))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s" % (itemId, attributeId, value))
|
||||
c.close()
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
.. module:: AttributeStorageLite
|
||||
:synopsis: An item key->value storage engine based on Sqlite
|
||||
:synopsis: An item key->value storage engine based on Sqlite
|
||||
|
||||
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
|
||||
|
||||
@ -10,159 +10,159 @@
|
||||
from pyircbot.modulebase import ModuleBase,ModuleHook
|
||||
|
||||
class AttributeStorageLite(ModuleBase):
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
self.hooks=[]
|
||||
self.services=["attributes"]
|
||||
self.db = None
|
||||
serviceProviders = self.bot.getmodulesbyservice("sqlite")
|
||||
if len(serviceProviders)==0:
|
||||
self.log.error("AttributeStorage: Could not find a valid sqlite service provider")
|
||||
else:
|
||||
self.log.info("AttributeStorage: Selecting sqlite service provider: %s" % serviceProviders[0])
|
||||
self.db = serviceProviders[0].opendb("attributes.db")
|
||||
|
||||
if not self.db.tableExists("attribute"):
|
||||
self.log.info("AttributeStorage: Creating table: attribute")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `attribute` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`attribute` varchar(128) UNIQUE
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.tableExists("items"):
|
||||
self.log.info("AttributeStorage: Creating table: items")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `items` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`item` varchar(512)
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.tableExists("values"):
|
||||
self.log.info("AttributeStorage: Creating table: values")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `values` (
|
||||
`itemid` INTEGER NOT NULL,
|
||||
`attributeid` INTEGER NOT NULL,
|
||||
`value` TEXT,
|
||||
PRIMARY KEY (`itemid`, `attributeid`)
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
#print(self.setKey('xmopxshell', 'name', 'dave'))
|
||||
#print(self.getKey('xmopxshell', 'name'))
|
||||
#print(self.getItem('xMopxShell'))
|
||||
|
||||
def getItem(self, name):
|
||||
"""Get all values for a item
|
||||
|
||||
:param name: the item
|
||||
:type name: str
|
||||
:returns: dict -- the item's values expressed as a dict"""
|
||||
c = self.db.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=?;""",
|
||||
(name.lower(),)
|
||||
)
|
||||
item = {}
|
||||
while True:
|
||||
row = c.fetchone()
|
||||
if row == None:
|
||||
break
|
||||
item[row["attribute"]]=row["value"]
|
||||
c.close()
|
||||
|
||||
if len(item)==0:
|
||||
return {}
|
||||
return item
|
||||
|
||||
def get(self, item, key):
|
||||
return self.getKey(item, key)
|
||||
def getKey(self, item, key):
|
||||
"""Get the value of an key on an item
|
||||
|
||||
:param item: the item to fetch a key from
|
||||
:type item: str
|
||||
:param key: they key who's value to return
|
||||
:type key: str
|
||||
:returns: str -- the item from the database or **None**"""
|
||||
c = self.db.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=?
|
||||
AND
|
||||
`a`.`attribute`=?;""",
|
||||
(item.lower(),key.lower())
|
||||
)
|
||||
row = c.fetchone()
|
||||
|
||||
c.close()
|
||||
if row == None:
|
||||
return None
|
||||
return row["value"]
|
||||
|
||||
def set(self, item, key, value):
|
||||
return self.setKey(item, key, value)
|
||||
def setKey(self, item, key, value):
|
||||
"""Set the key on an item
|
||||
|
||||
:param item: the item name to set the key on
|
||||
:type item: str
|
||||
:param key: the key to set
|
||||
:type key: tuple
|
||||
:param value: the value to set
|
||||
:type value: str"""
|
||||
item = item.lower()
|
||||
attribute = key.lower()
|
||||
|
||||
# Check attribute exists
|
||||
c = self.db.query("SELECT `id` FROM `attribute` WHERE `attribute`=?;", (attribute,))
|
||||
row = c.fetchone()
|
||||
attributeId = -1
|
||||
if row == None:
|
||||
c = self.db.query("INSERT INTO `attribute` (`attribute`) VALUES (?);", (attribute,))
|
||||
attributeId = c.lastrowid
|
||||
else:
|
||||
attributeId = row["id"]
|
||||
c.close()
|
||||
|
||||
# check item exists
|
||||
c = self.db.query("SELECT `id` FROM `items` WHERE `item`=?;", (item,))
|
||||
row = c.fetchone()
|
||||
itemId = -1
|
||||
if row == None:
|
||||
c = self.db.query("INSERT INTO `items` (`item`) VALUES (?);", (item,))
|
||||
itemId = c.lastrowid
|
||||
else:
|
||||
itemId = row["id"]
|
||||
c.close()
|
||||
|
||||
if value == None:
|
||||
# delete it
|
||||
c = self.db.query("DELETE FROM `values` WHERE `itemid`=? AND `attributeid`=? ;", (itemId, attributeId))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s (Deleted)" % (itemId, attributeId, value))
|
||||
else:
|
||||
# add attribute
|
||||
c = self.db.query("REPLACE INTO `values` (`itemid`, `attributeid`, `value`) VALUES (?, ?, ?);", (itemId, attributeId, value))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s" % (itemId, attributeId, value))
|
||||
c.close()
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
self.hooks=[]
|
||||
self.services=["attributes"]
|
||||
self.db = None
|
||||
serviceProviders = self.bot.getmodulesbyservice("sqlite")
|
||||
if len(serviceProviders)==0:
|
||||
self.log.error("AttributeStorage: Could not find a valid sqlite service provider")
|
||||
else:
|
||||
self.log.info("AttributeStorage: Selecting sqlite service provider: %s" % serviceProviders[0])
|
||||
self.db = serviceProviders[0].opendb("attributes.db")
|
||||
|
||||
if not self.db.tableExists("attribute"):
|
||||
self.log.info("AttributeStorage: Creating table: attribute")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `attribute` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`attribute` varchar(128) UNIQUE
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.tableExists("items"):
|
||||
self.log.info("AttributeStorage: Creating table: items")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `items` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`item` varchar(512)
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
if not self.db.tableExists("values"):
|
||||
self.log.info("AttributeStorage: Creating table: values")
|
||||
c = self.db.query("""CREATE TABLE IF NOT EXISTS `values` (
|
||||
`itemid` INTEGER NOT NULL,
|
||||
`attributeid` INTEGER NOT NULL,
|
||||
`value` TEXT,
|
||||
PRIMARY KEY (`itemid`, `attributeid`)
|
||||
) ;""")
|
||||
c.close()
|
||||
|
||||
#print(self.setKey('xmopxshell', 'name', 'dave'))
|
||||
#print(self.getKey('xmopxshell', 'name'))
|
||||
#print(self.getItem('xMopxShell'))
|
||||
|
||||
def getItem(self, name):
|
||||
"""Get all values for a item
|
||||
|
||||
:param name: the item
|
||||
:type name: str
|
||||
:returns: dict -- the item's values expressed as a dict"""
|
||||
c = self.db.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=?;""",
|
||||
(name.lower(),)
|
||||
)
|
||||
item = {}
|
||||
while True:
|
||||
row = c.fetchone()
|
||||
if row == None:
|
||||
break
|
||||
item[row["attribute"]]=row["value"]
|
||||
c.close()
|
||||
|
||||
if len(item)==0:
|
||||
return {}
|
||||
return item
|
||||
|
||||
def get(self, item, key):
|
||||
return self.getKey(item, key)
|
||||
def getKey(self, item, key):
|
||||
"""Get the value of an key on an item
|
||||
|
||||
:param item: the item to fetch a key from
|
||||
:type item: str
|
||||
:param key: they key who's value to return
|
||||
:type key: str
|
||||
:returns: str -- the item from the database or **None**"""
|
||||
c = self.db.query("""SELECT
|
||||
`i`.`id`,
|
||||
`i`.`item`,
|
||||
`a`.`attribute`,
|
||||
`v`.`value`
|
||||
FROM
|
||||
`items` `i`
|
||||
INNER JOIN `values` `v`
|
||||
on `v`.`itemid`=`i`.`id`
|
||||
INNER JOIN `attribute` `a`
|
||||
on `a`.`id`=`v`.`attributeid`
|
||||
|
||||
WHERE
|
||||
`i`.`item`=?
|
||||
AND
|
||||
`a`.`attribute`=?;""",
|
||||
(item.lower(),key.lower())
|
||||
)
|
||||
row = c.fetchone()
|
||||
|
||||
c.close()
|
||||
if row == None:
|
||||
return None
|
||||
return row["value"]
|
||||
|
||||
def set(self, item, key, value):
|
||||
return self.setKey(item, key, value)
|
||||
def setKey(self, item, key, value):
|
||||
"""Set the key on an item
|
||||
|
||||
:param item: the item name to set the key on
|
||||
:type item: str
|
||||
:param key: the key to set
|
||||
:type key: tuple
|
||||
:param value: the value to set
|
||||
:type value: str"""
|
||||
item = item.lower()
|
||||
attribute = key.lower()
|
||||
|
||||
# Check attribute exists
|
||||
c = self.db.query("SELECT `id` FROM `attribute` WHERE `attribute`=?;", (attribute,))
|
||||
row = c.fetchone()
|
||||
attributeId = -1
|
||||
if row == None:
|
||||
c = self.db.query("INSERT INTO `attribute` (`attribute`) VALUES (?);", (attribute,))
|
||||
attributeId = c.lastrowid
|
||||
else:
|
||||
attributeId = row["id"]
|
||||
c.close()
|
||||
|
||||
# check item exists
|
||||
c = self.db.query("SELECT `id` FROM `items` WHERE `item`=?;", (item,))
|
||||
row = c.fetchone()
|
||||
itemId = -1
|
||||
if row == None:
|
||||
c = self.db.query("INSERT INTO `items` (`item`) VALUES (?);", (item,))
|
||||
itemId = c.lastrowid
|
||||
else:
|
||||
itemId = row["id"]
|
||||
c.close()
|
||||
|
||||
if value == None:
|
||||
# delete it
|
||||
c = self.db.query("DELETE FROM `values` WHERE `itemid`=? AND `attributeid`=? ;", (itemId, attributeId))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s (Deleted)" % (itemId, attributeId, value))
|
||||
else:
|
||||
# add attribute
|
||||
c = self.db.query("REPLACE INTO `values` (`itemid`, `attributeid`, `value`) VALUES (?, ?, ?);", (itemId, attributeId, value))
|
||||
self.log.debug("AttributeStorage: Stored item %s attribute %s value: %s" % (itemId, attributeId, value))
|
||||
c.close()
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""
|
||||
.. module:: BitcoinPrice
|
||||
:synopsis: Provides .bitcoin to show price indexes
|
||||
:synopsis: Provides .bitcoin to show price indexes
|
||||
|
||||
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
|
||||
|
||||
@ -11,32 +11,32 @@ from requests import get
|
||||
from time import time
|
||||
|
||||
class BitcoinPrice(ModuleBase):
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
|
||||
self.cache = None
|
||||
self.cacheAge = 0
|
||||
|
||||
self.hooks=[
|
||||
ModuleHook(["PRIVMSG"], self.btc)
|
||||
]
|
||||
|
||||
def btc(self, args, prefix, trailing):
|
||||
prefix = self.bot.decodePrefix(prefix)
|
||||
replyTo = prefix.nick if not "#" in args[0] else args[0]
|
||||
|
||||
cmd = self.bot.messageHasCommand([".btc", ".bitcoin"], trailing)
|
||||
if cmd:
|
||||
data = self.getApi()
|
||||
self.bot.act_PRIVMSG(replyTo, "%s: %s" % (
|
||||
prefix.nick,
|
||||
"\x02\x0307Bitcoin:\x03\x02 \x0307{buy:.0f}\x0f$ - High: \x0307{high:.0f}\x0f$ - Low: \x0307{low:.0f}\x0f$ - Volume: \x0307{vol_cur:.0f}\x03฿".format(**data['ticker'])
|
||||
))
|
||||
|
||||
def getApi(self):
|
||||
if self.cache == None or time()-self.cacheAge>self.config["cache"]:
|
||||
self.cache = get("https://btc-e.com/api/2/btc_usd/ticker").json()
|
||||
self.cacheAge = time()
|
||||
return self.cache
|
||||
|
||||
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
|
||||
self.cache = None
|
||||
self.cacheAge = 0
|
||||
|
||||
self.hooks=[
|
||||
ModuleHook(["PRIVMSG"], self.btc)
|
||||
]
|
||||
|
||||
def btc(self, args, prefix, trailing):
|
||||
prefix = self.bot.decodePrefix(prefix)
|
||||
replyTo = prefix.nick if not "#" in args[0] else args[0]
|
||||
|
||||
cmd = self.bot.messageHasCommand([".btc", ".bitcoin"], trailing)
|
||||
if cmd:
|
||||
data = self.getApi()
|
||||
self.bot.act_PRIVMSG(replyTo, "%s: %s" % (
|
||||
prefix.nick,
|
||||
"\x02\x0307Bitcoin:\x03\x02 \x0307{buy:.0f}\x0f$ - High: \x0307{high:.0f}\x0f$ - Low: \x0307{low:.0f}\x0f$ - Volume: \x0307{vol_cur:.0f}\x03฿".format(**data['ticker'])
|
||||
))
|
||||
|
||||
def getApi(self):
|
||||
if self.cache == None or time()-self.cacheAge>self.config["cache"]:
|
||||
self.cache = get("https://btc-e.com/api/2/btc_usd/ticker").json()
|
||||
self.cacheAge = time()
|
||||
return self.cache
|
||||
|
||||
|
@ -4,258 +4,258 @@ import time
|
||||
import math
|
||||
|
||||
class Calc(ModuleBase):
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
|
||||
self.hooks=[ModuleHook("PRIVMSG", self.calc)]
|
||||
self.timers={}
|
||||
|
||||
self.sqlite = self.bot.getBestModuleForService("sqlite")
|
||||
if self.sqlite==None:
|
||||
self.log.error("Calc: SQLIite service is required.")
|
||||
return
|
||||
|
||||
self.sql = self.sqlite.opendb("calc.db")
|
||||
|
||||
if not self.sql.tableExists("calc_addedby"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_addedby` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`username` varchar(32),
|
||||
`userhost` varchar(128)
|
||||
) ;
|
||||
""")
|
||||
c.close()
|
||||
if not self.sql.tableExists("calc_channels"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_channels` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`channel` varchar(32)
|
||||
) ;
|
||||
""")
|
||||
if not self.sql.tableExists("calc_definitions"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_definitions` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`word` INTEGET,
|
||||
`definition` varchar(512),
|
||||
`addedby` INTEGER,
|
||||
`date` timestamp,
|
||||
`status` varchar(16)
|
||||
) ;
|
||||
""")
|
||||
if not self.sql.tableExists("calc_words"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_words` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`channel` INTEGER,
|
||||
`word` varchar(512),
|
||||
`status` varchar(32),
|
||||
unique(`channel`,`word`)
|
||||
);
|
||||
""")
|
||||
c.close()
|
||||
|
||||
def timeSince(self, channel, timetype):
|
||||
if not channel in self.timers:
|
||||
self.createDefaultTimers(channel)
|
||||
return time.time()-self.timers[channel][timetype]
|
||||
|
||||
def updateTimeSince(self, channel, timetype):
|
||||
if not channel in self.timers:
|
||||
self.createDefaultTimers(channel)
|
||||
self.timers[channel][timetype] = time.time()
|
||||
|
||||
def createDefaultTimers(self, channel):
|
||||
self.timers[channel]={"add":0, "calc":0, "calcspec":0, "match":0}
|
||||
|
||||
def remainingToStr(self, total, elasped):
|
||||
remaining = total-elasped
|
||||
minutes = int(math.floor(remaining/60))
|
||||
seconds = int(remaining - (minutes*60))
|
||||
return "Please wait %s minute(s) and %s second(s)." % (minutes, seconds)
|
||||
|
||||
def calc(self, args, prefix, trailing):
|
||||
# Channel only
|
||||
if not args[0][0]=="#":
|
||||
return
|
||||
sender = self.bot.decodePrefix(prefix)
|
||||
|
||||
foundCalc = False
|
||||
commandFound = ""
|
||||
for cmd in self.config["cmd_calc"]:
|
||||
if trailing[0:len(cmd)] == cmd and ( len(trailing) == len(cmd) or (trailing[len(cmd):len(cmd)+1] in [" ", "="])):
|
||||
commandFound=cmd
|
||||
foundCalc=True
|
||||
|
||||
if foundCalc:
|
||||
calcCmd = trailing[len(cmd)-1:].strip()
|
||||
if "=" in calcCmd[1:]:
|
||||
" Add a new calc "
|
||||
calcWord, calcDefinition = calcCmd.split("=", 1)
|
||||
calcWord = calcWord.strip()
|
||||
calcDefinition = calcDefinition.strip()
|
||||
if self.config["allowDelete"] and calcDefinition == "":
|
||||
result = self.deleteCalc(args[0], calcWord)
|
||||
if result:
|
||||
self.bot.act_PRIVMSG(args[0], "Calc deleted, %s." % sender.nick)
|
||||
else:
|
||||
self.bot.act_PRIVMSG(args[0], "Sorry %s, I don't know what '%s' is." % (sender.nick, calcWord))
|
||||
else:
|
||||
if self.config["delaySubmit"]>0 and self.timeSince(args[0], "add") < self.config["delaySubmit"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delaySubmit"], self.timeSince(args[0], "add")))
|
||||
else:
|
||||
self.addNewCalc(args[0], calcWord, calcDefinition, prefix)
|
||||
self.bot.act_PRIVMSG(args[0], "Thanks for the info, %s." % sender.nick)
|
||||
self.updateTimeSince(args[0], "add")
|
||||
elif len(calcCmd)>0:
|
||||
" Lookup the word in calcCmd "
|
||||
|
||||
if self.config["delayCalcSpecific"]>0 and self.timeSince(args[0], "calcspec") < self.config["delayCalcSpecific"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delayCalcSpecific"], self.timeSince(args[0], "calcspec")))
|
||||
else:
|
||||
randCalc = self.getSpecificCalc(args[0], calcCmd)
|
||||
if randCalc==None:
|
||||
self.bot.act_PRIVMSG(args[0], "Sorry %s, I don't know what '%s' is." % (sender.nick, calcCmd))
|
||||
else:
|
||||
self.bot.act_PRIVMSG(args[0], "%s \x03= %s \x0314[added by: %s]" % (randCalc["word"], randCalc["definition"], randCalc["by"]))
|
||||
self.updateTimeSince(args[0], "calcspec")
|
||||
else:
|
||||
if self.config["delayCalc"]>0 and self.timeSince(args[0], "calc") < self.config["delayCalc"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delayCalc"], self.timeSince(args[0], "calc")))
|
||||
else:
|
||||
randCalc = self.getRandomCalc(args[0])
|
||||
if randCalc == None:
|
||||
self.bot.act_PRIVMSG(args[0], "This channel has no calcs, %s :(" % (sender.nick,))
|
||||
else:
|
||||
self.bot.act_PRIVMSG(args[0], "%s \x03= %s \x0314[added by: %s]" % (randCalc["word"], randCalc["definition"], randCalc["by"]))
|
||||
self.updateTimeSince(args[0], "calc")
|
||||
return
|
||||
|
||||
cmd = self.bot.messageHasCommand(self.config["cmd_match"], trailing, True)
|
||||
if cmd:
|
||||
if self.config["delayMatch"]>0 and self.timeSince(args[0], "match") < self.config["delayMatch"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delayMatch"], self.timeSince(args[0], "match")))
|
||||
else:
|
||||
term = cmd.args_str
|
||||
if term.strip()=='':
|
||||
return
|
||||
c = self.sql.getCursor()
|
||||
channelId = self.getChannelId(args[0])
|
||||
c.execute("SELECT * FROM `calc_words` WHERE `word` LIKE ? AND `channel`=? ORDER BY `word` ASC ;", ("%%"+term+"%%", channelId))
|
||||
rows = c.fetchall()
|
||||
if len(rows)==0:
|
||||
self.bot.act_PRIVMSG(args[0], "%s: Sorry, no matches" % sender.nick)
|
||||
else:
|
||||
matches = []
|
||||
for row in rows[0:10]:
|
||||
if row == None:
|
||||
break
|
||||
matches.append(row["word"])
|
||||
self.bot.act_PRIVMSG(args[0], "%s: %s match%s (%s\x03)" % (sender.nick, len(matches), "es" if len(matches)>1 else "", ", \x03".join(matches) ))
|
||||
self.updateTimeSince(args[0], "match")
|
||||
|
||||
def addNewCalc(self, channel, word, definition, prefix):
|
||||
sender = self.bot.decodePrefix(prefix)
|
||||
|
||||
" Find the channel ID"
|
||||
channelId = self.getChannelId(channel)
|
||||
|
||||
" Check if we need to add a user"
|
||||
c = self.sql.getCursor()
|
||||
name = sender.nick
|
||||
host = sender.hostname
|
||||
c.execute("SELECT * FROM `calc_addedby` WHERE `username`=? AND `userhost`=? ;", (name, host))
|
||||
rows = c.fetchall()
|
||||
if len(rows)==0:
|
||||
c.execute("INSERT INTO `calc_addedby` (`username`, `userhost`) VALUES (?, ?) ;", (name, host,))
|
||||
c.execute("SELECT * FROM `calc_addedby` WHERE `username`=? AND `userhost`=? ;", (name, host))
|
||||
rows = c.fetchall()
|
||||
addedId = rows[0]["id"]
|
||||
|
||||
" Check if the word exists"
|
||||
c.execute("SELECT * FROM `calc_words` WHERE `channel`=? AND `word`=? ;", (channelId, word))
|
||||
rows = c.fetchall()
|
||||
if len(rows)==0:
|
||||
c.execute("INSERT INTO `calc_words` (`channel`, `word`, `status`) VALUES (?, ?, ?) ;", (channelId, word, 'approved'))
|
||||
c.execute("SELECT * FROM `calc_words` WHERE `channel`=? AND `word`=? ;", (channelId, word))
|
||||
rows = c.fetchall()
|
||||
wordId = rows[0]["id"]
|
||||
" Add definition "
|
||||
c.execute("INSERT INTO `calc_definitions` (`word`, `definition`, `addedby`, `date`, `status`) VALUES (?, ?, ?, ?, ?) ;", (wordId, definition, addedId, datetime.datetime.now(), 'approved',))
|
||||
c.close()
|
||||
pass
|
||||
|
||||
def getSpecificCalc(self, channel, word):
|
||||
c = self.sql.getCursor()
|
||||
channelId = self.getChannelId(channel)
|
||||
c.execute("SELECT `cw`.`word`, (SELECT `cdq`.`id` FROM `calc_definitions` `cdq` WHERE `cdq`.`word`=`cw`.`id` AND `cdq`.`status`='approved' ORDER BY `cdq`.`date` DESC LIMIT 1) as `definitionId` FROM `calc_words` `cw` WHERE `cw`.`channel`=? AND `cw`.`status`='approved' AND `cw`.`word`=? COLLATE NOCASE ORDER BY RANDOM() LIMIT 1 ;", (channelId, word.lower()))
|
||||
word = c.fetchone()
|
||||
|
||||
if word == None:
|
||||
return None
|
||||
|
||||
c.execute("SELECT `ca`.`username`, `cd`.`definition` FROM `calc_definitions` `cd` JOIN `calc_addedby` `ca` ON `ca`.`id` = `cd`.`addedby` WHERE `cd`.`id`=? LIMIT 1 ;", (word["definitionId"], ))
|
||||
|
||||
who = c.fetchone()
|
||||
|
||||
if who == None:
|
||||
return None
|
||||
|
||||
c.close()
|
||||
return {"word":word["word"], "definition":who["definition"], "by":who["username"]}
|
||||
|
||||
|
||||
def getRandomCalc(self, channel):
|
||||
c = self.sql.getCursor()
|
||||
channelId = self.getChannelId(channel)
|
||||
|
||||
for i in range(0, 5):
|
||||
c.execute("SELECT `cw`.`word`, (SELECT `cdq`.`id` FROM `calc_definitions` `cdq` WHERE `cdq`.`word`=`cw`.`id` AND `cdq`.`status`='approved' ORDER BY `cdq`.`date` DESC LIMIT 1) as `definitionId` FROM `calc_words` `cw` WHERE `cw`.`channel`=? AND `cw`.`status`='approved' ORDER BY RANDOM() LIMIT 1 ;", (channelId,))
|
||||
word = c.fetchone()
|
||||
if word == None:
|
||||
return None
|
||||
c.execute("SELECT `ca`.`username`, `cd`.`definition` FROM `calc_definitions` `cd` JOIN `calc_addedby` `ca` ON `ca`.`id` = `cd`.`addedby` WHERE `cd`.`id`=? LIMIT 1 ;", (word["definitionId"], ))
|
||||
|
||||
who = c.fetchone()
|
||||
|
||||
if who == None:
|
||||
continue
|
||||
|
||||
c.close()
|
||||
return {"word":word["word"], "definition":who["definition"], "by":who["username"]}
|
||||
|
||||
def deleteCalc(self, channel, word):
|
||||
" Return true if deleted something, false if it doesnt exist"
|
||||
c = self.sql.getCursor()
|
||||
channelId = self.getChannelId(channel)
|
||||
c.execute("SELECT * FROM `calc_words` WHERE `channel`=? and `word`=? ;", (channelId, word))
|
||||
rows = c.fetchall()
|
||||
if len(rows)==0:
|
||||
c.close()
|
||||
return False
|
||||
|
||||
wordId = rows[0]["id"]
|
||||
|
||||
#c.execute("DELETE FROM `calc_words` WHERE `id`=? ;", (wordId,))
|
||||
#c.execute("DELETE FROM `calc_definitions` WHERE `word`=? ;", (wordId,))
|
||||
c.execute("UPDATE `calc_definitions` SET `status`='deleted' WHERE `word`=? ;", (wordId,))
|
||||
|
||||
c.close()
|
||||
return True
|
||||
|
||||
def getChannelId(self, channel):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("SELECT * FROM `calc_channels` WHERE `channel` = ?", (channel,))
|
||||
rows = c.fetchall()
|
||||
if len(rows)==0:
|
||||
c.execute("INSERT INTO `calc_channels` (`channel`) VALUES (?);", (channel,))
|
||||
c.execute("SELECT * FROM `calc_channels` WHERE `channel` = ?", (channel,))
|
||||
rows = c.fetchall()
|
||||
chId = rows[0]["id"]
|
||||
c.close()
|
||||
return chId
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName);
|
||||
|
||||
self.hooks=[ModuleHook("PRIVMSG", self.calc)]
|
||||
self.timers={}
|
||||
|
||||
self.sqlite = self.bot.getBestModuleForService("sqlite")
|
||||
if self.sqlite==None:
|
||||
self.log.error("Calc: SQLIite service is required.")
|
||||
return
|
||||
|
||||
self.sql = self.sqlite.opendb("calc.db")
|
||||
|
||||
if not self.sql.tableExists("calc_addedby"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_addedby` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`username` varchar(32),
|
||||
`userhost` varchar(128)
|
||||
) ;
|
||||
""")
|
||||
c.close()
|
||||
if not self.sql.tableExists("calc_channels"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_channels` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`channel` varchar(32)
|
||||
) ;
|
||||
""")
|
||||
if not self.sql.tableExists("calc_definitions"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_definitions` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`word` INTEGET,
|
||||
`definition` varchar(512),
|
||||
`addedby` INTEGER,
|
||||
`date` timestamp,
|
||||
`status` varchar(16)
|
||||
) ;
|
||||
""")
|
||||
if not self.sql.tableExists("calc_words"):
|
||||
c = self.sql.getCursor()
|
||||
c.execute("""
|
||||
CREATE TABLE `calc_words` (
|
||||
`id` INTEGER PRIMARY KEY,
|
||||
`channel` INTEGER,
|
||||
`word` varchar(512),
|
||||
`status` varchar(32),
|
||||
unique(`channel`,`word`)
|
||||
);
|
||||
""")
|
||||
c.close()
|
||||
|
||||
def timeSince(self, channel, timetype):
|
||||
if not channel in self.timers:
|
||||
self.createDefaultTimers(channel)
|
||||
return time.time()-self.timers[channel][timetype]
|
||||
|
||||
def updateTimeSince(self, channel, timetype):
|
||||
if not channel in self.timers:
|
||||
self.createDefaultTimers(channel)
|
||||
self.timers[channel][timetype] = time.time()
|
||||
|
||||
def createDefaultTimers(self, channel):
|
||||
self.timers[channel]={"add":0, "calc":0, "calcspec":0, "match":0}
|
||||
|
||||
def remainingToStr(self, total, elasped):
|
||||
remaining = total-elasped
|
||||
minutes = int(math.floor(remaining/60))
|
||||
seconds = int(remaining - (minutes*60))
|
||||
return "Please wait %s minute(s) and %s second(s)." % (minutes, seconds)
|
||||
|
||||
def calc(self, args, prefix, trailing):
|
||||
# Channel only
|
||||
if not args[0][0]=="#":
|
||||
return
|
||||
sender = self.bot.decodePrefix(prefix)
|
||||
|
||||
foundCalc = False
|
||||
commandFound = ""
|
||||
for cmd in self.config["cmd_calc"]:
|
||||
if trailing[0:len(cmd)] == cmd and ( len(trailing) == len(cmd) or (trailing[len(cmd):len(cmd)+1] in [" ", "="])):
|
||||
commandFound=cmd
|
||||
foundCalc=True
|
||||
|
||||
if foundCalc:
|
||||
calcCmd = trailing[len(cmd)-1:].strip()
|
||||
if "=" in calcCmd[1:]:
|
||||
" Add a new calc "
|
||||
calcWord, calcDefinition = calcCmd.split("=", 1)
|
||||
calcWord = calcWord.strip()
|
||||
calcDefinition = calcDefinition.strip()
|
||||
if self.config["allowDelete"] and calcDefinition == "":
|
||||
result = self.deleteCalc(args[0], calcWord)
|
||||
if result:
|
||||
self.bot.act_PRIVMSG(args[0], "Calc deleted, %s." % sender.nick)
|
||||
else:
|
||||
self.bot.act_PRIVMSG(args[0], "Sorry %s, I don't know what '%s' is." % (sender.nick, calcWord))
|
||||
else:
|
||||
if self.config["delaySubmit"]>0 and self.timeSince(args[0], "add") < self.config["delaySubmit"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delaySubmit"], self.timeSince(args[0], "add")))
|
||||
else:
|
||||
self.addNewCalc(args[0], calcWord, calcDefinition, prefix)
|
||||
self.bot.act_PRIVMSG(args[0], "Thanks for the info, %s." % sender.nick)
|
||||
self.updateTimeSince(args[0], "add")
|
||||
elif len(calcCmd)>0:
|
||||
" Lookup the word in calcCmd "
|
||||
|
||||
if self.config["delayCalcSpecific"]>0 and self.timeSince(args[0], "calcspec") < self.config["delayCalcSpecific"]:
|
||||
self.bot.act_PRIVMSG(sender.nick, self.remainingToStr(self.config["delayCalcSpecific"], self.timeSince(args[0], "calcspec")))
|
||||
else:
|
||||
randCalc = self.getSpecificCalc(args[0], calcCmd)
|
||||
if randCalc==None:
|
||||
self.bot.act_PRIVMSG(args[0], "Sorry %s, I don't know what '%s' is." % (sender.nick, calcCmd))
|
||||