mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 20:59:27 +01:00
Added userdata registry.
This commit is contained in:
parent
ab1b7d3434
commit
e3b690f933
@ -391,22 +391,30 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
||||
|
||||
_sqlTrans = string.maketrans('*?', '%_')
|
||||
def search(self, irc, msg, args):
|
||||
"""[<channel>] [--{regexp}=<value>] [<glob>]
|
||||
"""[<channel>] [--values] [--{regexp}=<value>] [<glob>]
|
||||
|
||||
Searches the keyspace for keys matching <glob>. If --regexp is given,
|
||||
it associated value is taken as a regexp and matched against the keys.
|
||||
If --values is given, search the value space instead of the keyspace.
|
||||
"""
|
||||
channel = privmsgs.getChannel(msg, args)
|
||||
(optlist, rest) = getopt.getopt(args, '', ['regexp='])
|
||||
(optlist, rest) = getopt.getopt(args, '', ['values', 'regexp='])
|
||||
if not optlist and not rest:
|
||||
raise callbacks.ArgumentError
|
||||
criteria = []
|
||||
tables = ['keys']
|
||||
formats = []
|
||||
criteria = []
|
||||
target = 'keys.key'
|
||||
predicateName = 'p'
|
||||
db = self.getDb(channel)
|
||||
for (option, arg) in optlist:
|
||||
if option == '--regexp':
|
||||
criteria.append('%s(key)' % predicateName)
|
||||
if option == '--values':
|
||||
target = 'factoids.fact'
|
||||
if 'factoids' not in tables:
|
||||
tables.append('factoids')
|
||||
criteria.append('factoids.key_id=keys.id')
|
||||
elif option == '--regexp':
|
||||
criteria.append('%s(TARGET)' % predicateName)
|
||||
try:
|
||||
r = utils.perlReToPythonRe(arg)
|
||||
except ValueError, e:
|
||||
@ -419,10 +427,12 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
||||
for glob in rest:
|
||||
if '*' not in glob and '?' not in glob:
|
||||
glob = '*%s*' % glob
|
||||
criteria.append('key LIKE %s')
|
||||
criteria.append('TARGET LIKE %s')
|
||||
formats.append(glob.translate(self._sqlTrans))
|
||||
cursor = db.cursor()
|
||||
sql = """SELECT key FROM keys WHERE %s""" % ' AND '.join(criteria)
|
||||
sql = """SELECT keys.key FROM %s WHERE %s""" % \
|
||||
(tables, ' AND '.join(criteria))
|
||||
sql = sql.replace('TARGET', target)
|
||||
cursor.execute(sql, formats)
|
||||
if cursor.rowcount == 0:
|
||||
irc.reply('No keys matched that query.')
|
||||
|
@ -130,15 +130,6 @@ class Infobot(callbacks.PrivmsgRegexp):
|
||||
cursor.execute('DELETE FROM are_factoids WHERE key=%s', key)
|
||||
irc.reply(self.getRandomSaying('confirms'))
|
||||
|
||||
def tell(self, irc, msg, match):
|
||||
r"^tell\s+(.+?)\s+about\s+(.+?)(?!\?+)[.! ]*$"
|
||||
(nick, key) = match.groups()
|
||||
try:
|
||||
s = '%s wants you to know that %s' %(msg.nick,self.getFactoid(key))
|
||||
irc.reply(nick, s)
|
||||
except KeyError:
|
||||
irc.reply('I don\'t know anything about %s' % key)
|
||||
|
||||
def factoid(self, irc, msg, match):
|
||||
r"^(no[ :,-]+)?(.+?)\s+(was|is|am|were|are)\s+(also\s+)?(.+?)(?!\?+)$"
|
||||
(correction, key, isAre, addition, value) = match.groups()
|
||||
|
@ -58,17 +58,17 @@ conf.registerGlobalValue(conf.supybot.plugins.Infobot, 'infobotStyleStatus',
|
||||
original Infobot style message or with a short message."""))
|
||||
# FIXME: rename; description
|
||||
conf.registerChannelValue(conf.supybot.plugins.Infobot,
|
||||
'catchWhenNotAddressed', registry.Boolean(True,
|
||||
"""Whether to catch non-addressed stuff at all."""))
|
||||
'catchWhenNotAddressed', registry.Boolean(True, """Whether to catch
|
||||
non-addressed stuff at all."""))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Infobot,
|
||||
'replyQuestionWhenNotAddressed', registry.Boolean(True,
|
||||
"""Whether to answer to non-addressed stuff we know about."""))
|
||||
'replyQuestionWhenNotAddressed', registry.Boolean(True, """Whether to
|
||||
answer to non-addressed stuff we know about."""))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Infobot,
|
||||
'replyDontKnowWhenNotAddressed', registry.Boolean(False,
|
||||
"""Whether to answer to non-addressed stuff we don't know about."""))
|
||||
'replyDontKnowWhenNotAddressed', registry.Boolean(False, """Whether to
|
||||
answer to non-addressed stuff we don't know about."""))
|
||||
conf.registerChannelValue(conf.supybot.plugins.Infobot,
|
||||
'replyWhenNotAddressed', registry.Boolean(False,
|
||||
"""Whether to answer to non-addressed, non-question stuff."""))
|
||||
'replyWhenNotAddressed', registry.Boolean(False, """Whether to answer to
|
||||
non-addressed, non-question stuff."""))
|
||||
|
||||
# Replies
|
||||
# XXX: Move this to a plaintext db of some sort?
|
||||
|
@ -353,9 +353,7 @@ class Misc(callbacks.Privmsg):
|
||||
return
|
||||
module = sys.modules[cb.__class__.__module__]
|
||||
if hasattr(module, '__author__') and module.__author__:
|
||||
s = module.__author__.replace('@', ' AT ')
|
||||
s = s.replace('.', ' DOT ')
|
||||
irc.reply(s)
|
||||
irc.reply(utils.mungeEmailForWeb(module.__author__))
|
||||
else:
|
||||
irc.reply('That plugin doesn\'t have an author that claims it.')
|
||||
|
||||
@ -448,7 +446,7 @@ class Misc(callbacks.Privmsg):
|
||||
irc.reply(ircmsgs.prettyPrint(m))
|
||||
return
|
||||
irc.error('I couldn\'t find a message matching that criteria in '
|
||||
'my history of %s messages.' % len(irc.state.history))
|
||||
'my history of %s messages.' % len(irc.state.history))
|
||||
|
||||
def seconds(self, irc, msg, args):
|
||||
"""[<years>y] [<weeks>w] [<days>d] [<hours>h] [<minutes>m] [<seconds>s]
|
||||
|
@ -103,7 +103,6 @@ def loadPluginClass(irc, module, register=None):
|
||||
"""Loads the plugin Class from the given module into the given irc."""
|
||||
cb = module.Class()
|
||||
name = cb.name()
|
||||
conf.registerPlugin(name)
|
||||
public = True
|
||||
if hasattr(cb, 'public'):
|
||||
public = cb.public
|
||||
@ -194,6 +193,8 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
(_, _, name) = name.split('.')
|
||||
except ValueError: # unpack list of wrong size.
|
||||
continue
|
||||
if name == name.lower(): # This can't be right.
|
||||
name = name.capitalize() # Let's at least capitalize it.
|
||||
conf.registerPlugin(name)
|
||||
if name.startswith('supybot.commands.defaultPlugins'):
|
||||
try:
|
||||
@ -478,7 +479,8 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||
else:
|
||||
irc.error(str(e))
|
||||
return
|
||||
loadPluginClass(irc, module)
|
||||
cb = loadPluginClass(irc, module)
|
||||
name = cb.name() # Let's normalize this.
|
||||
conf.registerPlugin(name, True)
|
||||
irc.replySuccess()
|
||||
|
||||
|
@ -811,6 +811,28 @@ class Privmsg(irclib.IrcCallback):
|
||||
else:
|
||||
return group.get(channel)()
|
||||
|
||||
def userValue(self, name, prefixOrName, default=None):
|
||||
try:
|
||||
id = str(ircdb.users.getUserId(prefixOrName))
|
||||
except KeyError:
|
||||
return None
|
||||
plugin = self.name()
|
||||
group = conf.users.plugins.get(plugin)
|
||||
names = name.split('.')
|
||||
for name in names:
|
||||
group = group.get(name)
|
||||
return group.get(id)()
|
||||
|
||||
def setUserValue(self, prefixOrName, name, value):
|
||||
id = str(ircdb.users.getUserId(prefixOrName))
|
||||
plugin = self.name()
|
||||
group = conf.users.plugins.get(plugin)
|
||||
names = name.split('.')
|
||||
for name in names:
|
||||
group = group.get(name)
|
||||
group = group.get(id)
|
||||
group.set(value)
|
||||
|
||||
|
||||
class IrcObjectProxyRegexp(RichReplyMethods):
|
||||
def __init__(self, irc, msg):
|
||||
|
157
src/conf.py
157
src/conf.py
@ -65,24 +65,42 @@ daemonized = False
|
||||
###
|
||||
allowEval = False
|
||||
|
||||
###
|
||||
# The standard registry.
|
||||
###
|
||||
supybot = registry.Group()
|
||||
supybot.setName('supybot')
|
||||
|
||||
def registerPlugin(name, currentValue=None):
|
||||
supybot.plugins.register(name, registry.Boolean(False, """Determines
|
||||
whether this plugin is loaded by default.""", showDefault=False))
|
||||
if currentValue is not None:
|
||||
supybot.plugins.get(name).setValue(currentValue)
|
||||
def registerGroup(Group, name, group=None):
|
||||
Group.register(name, group)
|
||||
|
||||
def registerGlobalValue(group, name, value):
|
||||
group.register(name, value)
|
||||
|
||||
def registerChannelValue(group, name, value):
|
||||
value.supplyDefault = True
|
||||
group.register(name, value)
|
||||
|
||||
def registerGlobalValue(group, name, value):
|
||||
def registerPlugin(name, currentValue=None):
|
||||
registerGlobalValue(supybot.plugins, name,
|
||||
registry.Boolean(False, """Determines whether this plugin is loaded by
|
||||
default.""", showDefault=False))
|
||||
if currentValue is not None:
|
||||
supybot.plugins.get(name).setValue(currentValue)
|
||||
registerGroup(users.plugins, name)
|
||||
|
||||
###
|
||||
# The user info registry.
|
||||
###
|
||||
users = registry.Group()
|
||||
users.setName('users')
|
||||
registerGroup(users, 'plugins')
|
||||
|
||||
def registerUserValue(group, name, value):
|
||||
assert group.name.startswith('users.')
|
||||
value.supplyDefault = True
|
||||
group.register(name, value)
|
||||
|
||||
def registerGroup(Group, name, group=None):
|
||||
Group.register(name, group)
|
||||
|
||||
class ValidNick(registry.String):
|
||||
"""Value must be a valid IRC nick."""
|
||||
@ -410,37 +428,37 @@ required for changes to this variable to take effect."""))
|
||||
###
|
||||
registerGroup(supybot, 'drivers')
|
||||
registerGlobalValue(supybot.drivers, 'poll',
|
||||
registry.Float(1.0, """Determines the default length of time a driver should
|
||||
block waiting for input."""))
|
||||
registry.Float(1.0, """Determines the default length of time a driver
|
||||
should block waiting for input."""))
|
||||
|
||||
class ValidDriverModule(registry.OnlySomeStrings):
|
||||
validStrings = ('default', 'socketDrivers',
|
||||
'twistedDrivers', 'asyncoreDrivers')
|
||||
|
||||
registerGlobalValue(supybot.drivers, 'module',
|
||||
ValidDriverModule('default', """Determines what driver module the bot will
|
||||
use. socketDrivers, a simple driver based on timeout sockets, is used by
|
||||
default because it's simple and stable. asyncoreDrivers is a bit older (and
|
||||
less well-maintained) but allows you to integrate with asyncore-based
|
||||
applications. twistedDrivers is very stable and simple, and if you've got
|
||||
Twisted installed, is probably your best bet."""))
|
||||
ValidDriverModule('default', """Determines what driver module the bot will
|
||||
use. socketDrivers, a simple driver based on timeout sockets, is used by
|
||||
default because it's simple and stable. asyncoreDrivers is a bit older
|
||||
(and less well-maintained) but allows you to integrate with asyncore-based
|
||||
applications. twistedDrivers is very stable and simple, and if you've got
|
||||
Twisted installed, is probably your best bet."""))
|
||||
|
||||
###
|
||||
# supybot.directories, for stuff relating to directories.
|
||||
###
|
||||
registerGroup(supybot, 'directories')
|
||||
registerGlobalValue(supybot.directories, 'conf',
|
||||
registry.String('conf', """Determines what directory configuration data is
|
||||
put into."""))
|
||||
registry.String('conf', """Determines what directory configuration data is
|
||||
put into."""))
|
||||
registerGlobalValue(supybot.directories, 'data',
|
||||
registry.String('data', """Determines what directory data is put into."""))
|
||||
registry.String('data', """Determines what directory data is put into."""))
|
||||
registerGlobalValue(supybot.directories, 'plugins',
|
||||
registry.CommaSeparatedListOfStrings([_srcDir,_pluginsDir], """Determines
|
||||
what directories the bot will look for plugins in. Accepts a
|
||||
comma-separated list of strings. This means that to add another directory,
|
||||
you can nest the former value and add a new one. E.g. you can say: bot:
|
||||
'config supybot.directories.plugins [config supybot.directories.plugins],
|
||||
newPluginDirectory'."""))
|
||||
registry.CommaSeparatedListOfStrings([_srcDir,_pluginsDir], """Determines
|
||||
what directories the bot will look for plugins in. Accepts a
|
||||
comma-separated list of strings. This means that to add another directory,
|
||||
you can nest the former value and add a new one. E.g. you can say: bot:
|
||||
'config supybot.directories.plugins [config supybot.directories.plugins],
|
||||
newPluginDirectory'."""))
|
||||
|
||||
supybot.register('plugins') # This will be used by plugins, but not here.
|
||||
|
||||
@ -450,28 +468,28 @@ supybot.register('plugins') # This will be used by plugins, but not here.
|
||||
registerGroup(supybot, 'databases')
|
||||
registerGroup(supybot.databases, 'users')
|
||||
registerGlobalValue(supybot.databases.users, 'filename',
|
||||
registry.String('users.conf', """Determines what filename will be used for
|
||||
the users database. This file will go into the directory specified by the
|
||||
supybot.directories.conf variable."""))
|
||||
registry.String('users.conf', """Determines what filename will be used for
|
||||
the users database. This file will go into the directory specified by the
|
||||
supybot.directories.conf variable."""))
|
||||
registerGlobalValue(supybot.databases.users, 'timeoutIdentification',
|
||||
registry.Integer(0, """Determines how long it takes identification to time
|
||||
out. If the value is less than or equal to zero, identification never times
|
||||
out."""))
|
||||
registry.Integer(0, """Determines how long it takes identification to time
|
||||
out. If the value is less than or equal to zero, identification never
|
||||
times out."""))
|
||||
registerGlobalValue(supybot.databases.users, 'hash',
|
||||
registry.Boolean(True, """Determines whether the passwords in the user
|
||||
database will be hashed by default."""))
|
||||
registry.Boolean(True, """Determines whether the passwords in the user
|
||||
database will be hashed by default."""))
|
||||
|
||||
registerGroup(supybot.databases, 'ignores')
|
||||
registerGlobalValue(supybot.databases.ignores, 'filename',
|
||||
registry.String('ignores.conf', """Determines what filename will be used for
|
||||
the ignores database. This file will go into the directory specified by the
|
||||
supybot.directories.conf variable."""))
|
||||
registry.String('ignores.conf', """Determines what filename will be used
|
||||
for the ignores database. This file will go into the directory specified
|
||||
by the supybot.directories.conf variable."""))
|
||||
|
||||
registerGroup(supybot.databases, 'channels')
|
||||
registerGlobalValue(supybot.databases.channels, 'filename',
|
||||
registry.String('channels.conf', """Determines what filename will be used
|
||||
for the channels database. This file will go into the directory specified
|
||||
by the supybot.directories.conf variable."""))
|
||||
registry.String('channels.conf', """Determines what filename will be used
|
||||
for the channels database. This file will go into the directory specified
|
||||
by the supybot.directories.conf variable."""))
|
||||
|
||||
###
|
||||
# Protocol information.
|
||||
@ -494,37 +512,38 @@ class StrictRfc(registry.Boolean):
|
||||
registerGroup(supybot, 'protocols')
|
||||
registerGroup(supybot.protocols, 'irc')
|
||||
registerGlobalValue(supybot.protocols.irc, 'strictRfc',
|
||||
StrictRfc(False, """Determines whether the bot will strictly follow the RFC;
|
||||
currently this only affects what strings are considered to be nicks. If
|
||||
you're using a server or a network that requires you to message a nick such
|
||||
as services@this.network.server then you you should set this to False."""))
|
||||
StrictRfc(False, """Determines whether the bot will strictly follow the
|
||||
RFC; currently this only affects what strings are considered to be nicks.
|
||||
If you're using a server or a network that requires you to message a nick
|
||||
such as services@this.network.server then you you should set this to
|
||||
False."""))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'maxHistoryLength',
|
||||
registry.Integer(1000, """Determines how many old messages the bot will keep
|
||||
around in its history. Changing this variable will not take effect until
|
||||
the bot is restarted."""))
|
||||
registry.Integer(1000, """Determines how many old messages the bot will
|
||||
keep around in its history. Changing this variable will not take effect
|
||||
until the bot is restarted."""))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'throttleTime',
|
||||
registry.Float(1.0, """A floating point number of seconds to throttle queued
|
||||
messages -- that is, messages will not be sent faster than once per
|
||||
throttleTime seconds."""))
|
||||
registry.Float(1.0, """A floating point number of seconds to throttle
|
||||
queued messages -- that is, messages will not be sent faster than once per
|
||||
throttleTime seconds."""))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'ping',
|
||||
registry.Boolean(True, """Determines whether the bot will send PINGs to the
|
||||
server it's connected to in order to keep the connection alive and discover
|
||||
earlier when it breaks. Really, this option only exists for debugging
|
||||
purposes: you always should make it True unless you're testing some strange
|
||||
server issues."""))
|
||||
registry.Boolean(True, """Determines whether the bot will send PINGs to the
|
||||
server it's connected to in order to keep the connection alive and discover
|
||||
earlier when it breaks. Really, this option only exists for debugging
|
||||
purposes: you always should make it True unless you're testing some strange
|
||||
server issues."""))
|
||||
registerGlobalValue(supybot.protocols.irc.ping, 'interval',
|
||||
registry.Integer(120, """Determines the number of seconds between sending
|
||||
pings to the server, if pings are being sent to the server."""))
|
||||
registry.Integer(120, """Determines the number of seconds between sending
|
||||
pings to the server, if pings are being sent to the server."""))
|
||||
|
||||
registerGroup(supybot.protocols, 'http')
|
||||
registerGlobalValue(supybot.protocols.http, 'peekSize',
|
||||
registry.PositiveInteger(4096, """Determines how many bytes the bot will
|
||||
'peek' at when looking through a URL for a doctype or title or something
|
||||
similar. It'll give up after it reads this many bytes, even if it hasn't
|
||||
found what it was looking for."""))
|
||||
registry.PositiveInteger(4096, """Determines how many bytes the bot will
|
||||
'peek' at when looking through a URL for a doctype or title or something
|
||||
similar. It'll give up after it reads this many bytes, even if it hasn't
|
||||
found what it was looking for."""))
|
||||
|
||||
|
||||
###
|
||||
@ -532,12 +551,20 @@ registerGlobalValue(supybot.protocols.http, 'peekSize',
|
||||
###
|
||||
registerGroup(supybot, 'debug')
|
||||
registerGlobalValue(supybot.debug, 'threadAllCommands',
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
thread all commands."""))
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
thread all commands."""))
|
||||
registerGlobalValue(supybot.debug, 'flushVeryOften',
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
flush all flushers *very* often. Useful for debugging when you don't know
|
||||
what's breaking or when, but think that it might be logged."""))
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
flush all flushers *very* often. Useful for debugging when you don't know
|
||||
what's breaking or when, but think that it might be logged."""))
|
||||
|
||||
# Let's open this now since we've got our directories setup.
|
||||
userdataFilename = os.path.join(supybot.directories.conf(), 'userdata.conf')
|
||||
if not os.path.exists(userdataFilename):
|
||||
fd = file(userdataFilename, 'w')
|
||||
fd.write('\n')
|
||||
fd.close()
|
||||
registry.open(userdataFilename)
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||
|
@ -58,11 +58,13 @@ class NonExistentRegistryEntry(RegistryException):
|
||||
|
||||
_cache = utils.InsensitivePreservingDict()
|
||||
_lastModified = 0
|
||||
def open(filename):
|
||||
def open(filename, clear=False):
|
||||
"""Initializes the module by loading the registry file into memory."""
|
||||
global _lastModified
|
||||
_cache.clear()
|
||||
fd = utils.nonCommentNonEmptyLines(file(filename))
|
||||
if clear:
|
||||
_cache.clear()
|
||||
_fd = file(filename)
|
||||
fd = utils.nonCommentNonEmptyLines(_fd)
|
||||
for (i, line) in enumerate(fd):
|
||||
line = line.rstrip('\r\n')
|
||||
try:
|
||||
@ -71,6 +73,7 @@ def open(filename):
|
||||
raise InvalidRegistryFile, 'Error unpacking line #%s' % (i+1)
|
||||
_cache[key] = value
|
||||
_lastModified = time.time()
|
||||
_fd.close()
|
||||
|
||||
def close(registry, filename, annotated=True, helpOnceOnly=False):
|
||||
first = True
|
||||
@ -206,7 +209,7 @@ class Group(object):
|
||||
|
||||
class Value(Group):
|
||||
"""Invalid registry value. If you're getting this message, report it,
|
||||
because someone forgot to put a proper help string here."""
|
||||
because we forgot to put a proper help string here."""
|
||||
def __init__(self, default, help,
|
||||
private=False, showDefault=True, **kwargs):
|
||||
Group.__init__(self, **kwargs)
|
||||
@ -217,7 +220,12 @@ class Value(Group):
|
||||
self.setValue(default)
|
||||
|
||||
def error(self):
|
||||
raise InvalidRegistryValue, utils.normalizeWhitespace(self.__doc__)
|
||||
if self.__doc__:
|
||||
s = self.__doc__
|
||||
else:
|
||||
s = """Invalid registry value. If you're getting this message,
|
||||
report it, because we forgot to put a proper help string here."""
|
||||
raise InvalidRegistryValue, utils.normalizeWhitespace(s)
|
||||
|
||||
def setName(self, *args):
|
||||
if self.name == 'unset':
|
||||
@ -396,7 +404,7 @@ class Regexp(Value):
|
||||
Value.setValue(self, None)
|
||||
else:
|
||||
raise InvalidRegistryValue, \
|
||||
'Can\'t set to a regexp, there would be an inconsistency ' \
|
||||
'Can\'t setValue a regexp, there would be an inconsistency '\
|
||||
'between the regexp and the recorded string value.'
|
||||
|
||||
def __str__(self):
|
||||
|
@ -628,6 +628,12 @@ class InsensitivePreservingDict(UserDict.DictMixin, object):
|
||||
def __reduce__(self):
|
||||
return (self.__class__, (dict(self.data.values()),))
|
||||
|
||||
def mungeEmailForWeb(s):
|
||||
s = s.replace('@', ' AT ')
|
||||
s = s.replace('.', ' DOT ')
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys, doctest
|
||||
doctest.testmod(sys.modules['__main__'])
|
||||
|
@ -65,7 +65,10 @@ commandsProcessed = 0
|
||||
|
||||
ircs = [] # A list of all the IRCs.
|
||||
|
||||
flushers = [] # A periodic function will flush all these.
|
||||
def _flushUserData():
|
||||
registry.close(conf.users, conf.userdataFilename, annotated=False)
|
||||
|
||||
flushers = [_flushUserData] # A periodic function will flush all these.
|
||||
|
||||
registryFilename = None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user