diff --git a/plugins/Topic/__init__.py b/plugins/Topic/__init__.py index b0137a617..38f4e7655 100644 --- a/plugins/Topic/__init__.py +++ b/plugins/Topic/__init__.py @@ -42,7 +42,7 @@ __author__ = supybot.authors.jemfinch # This is a dictionary mapping supybot.Author instances to lists of # contributions. -__contributors__ = {} +__contributors__ = { supybot.authors.stepnem: ['persistence support'] } import config import plugin diff --git a/plugins/Topic/plugin.py b/plugins/Topic/plugin.py index 098b55f55..3d9309ff0 100644 --- a/plugins/Topic/plugin.py +++ b/plugins/Topic/plugin.py @@ -27,17 +27,22 @@ # POSSIBILITY OF SUCH DAMAGE. ### -import re +import os import random +import shutil +import tempfile +import cPickle as pickle import supybot.conf as conf +import supybot.ircdb as ircdb import supybot.utils as utils +import supybot.world as world from supybot.commands import * import supybot.ircmsgs as ircmsgs import supybot.plugins as plugins import supybot.ircutils as ircutils import supybot.callbacks as callbacks -import supybot.ircdb as ircdb + def canChangeTopic(irc, msg, args, state): assert not state.channel @@ -96,6 +101,9 @@ addConverter('canChangeTopic', canChangeTopic) def splitTopic(topic, separator): return filter(None, topic.split(separator)) +datadir = conf.supybot.directories.data() +filename = conf.supybot.directories.data.dirize('Topic.pickle') + class Topic(callbacks.Plugin): def __init__(self, irc): self.__parent = super(Topic, self) @@ -104,6 +112,39 @@ class Topic(callbacks.Plugin): self.redos = ircutils.IrcDict() self.lastTopics = ircutils.IrcDict() self.watchingFor332 = ircutils.IrcSet() + try: + pkl = open(filename, 'rb') + try: + self.undos = pickle.load(pkl) + self.redos = pickle.load(pkl) + self.lastTopics = pickle.load(pkl) + self.watchingFor332 = pickle.load(pkl) + except Exception, e: + self.log.debug('Unable to load pickled data: %s', e) + pkl.close() + except IOError, e: + self.log.debug('Unable to open pickle file: %s', e) + world.flushers.append(self._flush) + + def die(self): + world.flushers.remove(self._flush) + self.__parent.die() + + def _flush(self): + try: + pklfd, tempfn = tempfile.mkstemp(suffix='topic', dir=datadir) + pkl = os.fdopen(pklfd, 'wb') + try: + pickle.dump(self.undos, pkl) + pickle.dump(self.redos, pkl) + pickle.dump(self.lastTopics, pkl) + pickle.dump(self.watchingFor332, pkl) + except Exception, e: + self.log.warning('Unable to store pickled data: %s', e) + pkl.close() + shutil.move(tempfn, filename) + except (IOError, shutil.Error), e: + self.log.warning('File error: %s', e) def _splitTopic(self, topic, channel): separator = self.registryValue('separator', channel) @@ -165,10 +206,10 @@ class Topic(callbacks.Plugin): def _checkManageCapabilities(self, irc, msg, channel): """Check if the user has any of the required capabilities to manage the channel topic. - + The list of required capabilities is in requireManageCapability channel config. - + Also allow if the user is a chanop. Since he can change the topic manually anyway. """ diff --git a/src/__init__.py b/src/__init__.py index 68ca7025d..22923e31a 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,3 +1,4 @@ +# coding: utf-8 ### # Copyright (c) 2002-2005, Jeremiah Fincher # All rights reserved. @@ -56,6 +57,7 @@ class authors(object): # This is basically a bag. bwp = Author('Brett Phipps', 'bwp', 'phippsb@gmail.com') bear = Author('Mike Taylor', 'bear', 'bear@code-bear.com') grantbow = Author('Grant Bowman', 'Grantbow', 'grantbow@grantbow.com') + stepnem = Author('Štěpán Němec', 'stepnem', 'stepnem@gmail.com') unknown = Author('Unknown author', 'unknown', 'unknown@supybot.org') # Let's be somewhat safe about this.