From 5d98b1a5bc66e0b4562ca1ef19fa97c94b00acfa Mon Sep 17 00:00:00 2001 From: Jeremy Fincher Date: Wed, 4 Feb 2004 00:39:52 +0000 Subject: [PATCH] Converted ignores to a separate file, rather than a registry value. --- src/Admin.py | 14 ++++----- src/conf.py | 9 +++--- src/ircdb.py | 86 ++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/Admin.py b/src/Admin.py index d73262e88..31102764a 100755 --- a/src/Admin.py +++ b/src/Admin.py @@ -317,7 +317,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): except KeyError: irc.error('I can\'t find a hostmask for %s' % arg) return - conf.supybot.ignores().append(hostmask) + ircdb.ignores.addHostmask(hostmask) irc.replySuccess() def unignore(self, irc, msg, args): @@ -336,20 +336,18 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): irc.error('I can\'t find a hostmask for %s' % arg) return try: - conf.supybot.ignores().remove(hostmask) - while hostmask in conf.supybot.ignores(): - conf.supybot.ignores().remove(hostmask) + ircdb.ignores.removeHostmask(hostmask) irc.replySuccess() - except ValueError: - irc.error('%s wasn\'t in conf.supybot.ignores.' % hostmask) + except KeyError: + irc.error('%s wasn\'t in the ignores database.' % hostmask) def ignores(self, irc, msg, args): """takes no arguments Returns the hostmasks currently being globally ignored. """ - if conf.supybot.ignores(): - irc.reply(utils.commaAndify(imap(repr, conf.supybot.ignores()))) + if ircdb.ignores.hostmasks: + irc.reply(utils.commaAndify(imap(repr, ircdb.ignores.hostmasks))) else: irc.reply('I\'m not currently globally ignoring anyone.') diff --git a/src/conf.py b/src/conf.py index 7128b325c..42c8cf3d7 100644 --- a/src/conf.py +++ b/src/conf.py @@ -134,10 +134,6 @@ anti-capabilities, then the user will have to have the actual capability to override these capabilities. See docs/CAPABILITIES if you don't understand why these default to what they do.""")) -supybot.register('ignores', registry.CommaSeparatedListOfStrings('', """ -A list of hostmasks ignored by the bot. Add people you don't like to here. -""")) - supybot.register('defaultAllow', registry.Boolean(True, """Determines whether the bot by default will allow users to run commands. If this is disabled, a user will have to have the capability for whatever command he wishes to run. @@ -392,11 +388,16 @@ registry.CommaSeparatedListOfStrings([_srcDir,_pluginsDir], supybot.register('databases') supybot.databases.register('users') +supybot.databases.register('ignores') supybot.databases.register('channels') supybot.databases.users.register('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.""")) +supybot.databases.ignores.register('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.""")) supybot.databases.channels.register('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 diff --git a/src/ircdb.py b/src/ircdb.py index 481914bef..785a811d1 100644 --- a/src/ircdb.py +++ b/src/ircdb.py @@ -506,6 +506,7 @@ class UsersDictionary(utils.IterableMap): self._nameCache = {} self._hostmaskCache = {} + # This is separate because the Creator has to access our instance. def open(self, filename): self.filename = filename reader = unpreserve.Reader(IrcUserCreator) @@ -521,7 +522,7 @@ class UsersDictionary(utils.IterableMap): except EnvironmentError, e: log.warning('UsersDictionary.reload failed: %s', e) else: - log.warning('UsersDictionary.reload called without self.filename.') + log.warning('UsersDictionary.reload called with no filename.') def flush(self): """Flushes the database to its file.""" @@ -535,7 +536,7 @@ class UsersDictionary(utils.IterableMap): u.preserve(fd, indent=' ') fd.close() else: - log.warning('UsersDictionary.flush called without self.filename.') + log.warning('UsersDictionary.flush called with no filename.') def iteritems(self): return self.users.iteritems() @@ -655,7 +656,7 @@ class ChannelsDictionary(utils.IterableMap): def flush(self): """Flushes the channel database to its file.""" - if self.filename: + if self.filename is not None: fd = file(self.filename, 'w') for (channel, c) in self.channels.iteritems(): fd.write('channel %s' % channel) @@ -667,7 +668,7 @@ class ChannelsDictionary(utils.IterableMap): def reload(self): """Reloads the channel database from its file.""" - if self.filename: + if self.filename is not None: self.channels.clear() try: self.open(self.filename) @@ -696,24 +697,78 @@ class ChannelsDictionary(utils.IterableMap): return self.channels.iteritems() -### -# Later, I might add some special handling for botnet. -### +class IgnoresDB(object): + def __init__(self): + self.filename = None + self.hostmasks = sets.Set() + + def open(self, filename): + self.filename = filename + fd = file(self.filename) + for line in nonEmptyNonCommentLines(fd): + self.hostmasks.add(line.rstrip('\r\n')) + fd.close() + + def flush(self): + if self.filename is not None: + fd = file(self.filename, 'w') + for hostmask in self.hostmasks: + fd.write(hostmask) + fd.write(os.linesep) + fd.close() + else: + log.warning('IgnoresDB.flush called without self.filename.') + + def reload(self): + if self.filename is not None: + self.hostmasks.clear() + try: + self.open(self.filename) + except EnvironmentError, e: + log.warning('IgnoresDB.reload failed: %s', e) + else: + log.warning('IgnoresDB.reload called without self.filename.') + + def checkIgnored(self, prefix): + for hostmask in self.hostmasks: + if ircutils.hostmaskPatternEqual(hostmask, prefix): + return True + return False + + def addHostmask(self, hostmask): + self.hostmasks.add(hostmask) + + def removeHostmask(self, hostmask): + self.hostmasks.remove(hostmask) + + confDir = conf.supybot.directories.conf() -users = UsersDictionary() try: - users.open(os.path.join(confDir, conf.supybot.databases.users.filename())) + userFile = os.path.join(confDir, conf.supybot.databases.users.filename()) + users = UsersDictionary() + users.open(userFile) except EnvironmentError, e: log.warning('Couldn\'t open user database: %s', e) -channels = ChannelsDictionary() try: - channelFile = conf.supybot.databases.channels.filename() - channels.open(os.path.join(confDir,channelFile)) + channelFile = os.path.join(confDir, + conf.supybot.databases.channels.filename()) + channels = ChannelsDictionary() + channels.open(channelFile) except EnvironmentError, e: log.warning('Couldn\'t open channel database: %s', e) +try: + ignoreFile = os.path.join(confDir, + conf.supybot.databases.ignores.filename()) + ignores = IgnoresDB() + ignores.open(ignoreFile) +except EnvironmentError, e: + log.warning('Couldn\'t open ignore database: %s', e) + + world.flushers.append(users.flush) +world.flushers.append(ignores.flush) world.flushers.append(channels.flush) @@ -725,10 +780,9 @@ def checkIgnored(hostmask, recipient='', users=users, channels=channels): Checks if the user is ignored by the recipient of the message. """ - for ignore in conf.supybot.ignores(): - if ircutils.hostmaskPatternEqual(ignore, hostmask): - log.debug('Ignoring %s due to conf.supybot.ignores.', hostmask) - return True + if ignores.checkIgnored(hostmask): + log.debug('Ignoring %s due to ignore database.', hostmask) + return True try: id = users.getUserId(hostmask) user = users.getUser(id)