aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'bot/MeetBot/supybotconfig.py')
-rw-r--r--bot/MeetBot/supybotconfig.py174
1 files changed, 174 insertions, 0 deletions
diff --git a/bot/MeetBot/supybotconfig.py b/bot/MeetBot/supybotconfig.py
new file mode 100644
index 0000000..d4921a9
--- /dev/null
+++ b/bot/MeetBot/supybotconfig.py
@@ -0,0 +1,174 @@
+# Richard Darst, June 2009
+
+###
+# Copyright (c) 2009, Richard Darst
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions, and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions, and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the author of this software nor the name of
+# contributors to this software may be used to endorse or promote products
+# derived from this software without specific prior written consent.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+###
+
+
+import types
+
+import supybot.conf as conf
+import supybot.registry as registry
+
+import ircmeeting.meeting as meeting
+import ircmeeting.writers as writers
+
+# The plugin group for configuration
+MeetBotConfigGroup = conf.registerPlugin('MeetBot')
+
+class WriterMap(registry.String):
+ """List of output formats to write. This is a space-separated
+ list of 'WriterName:.ext' pairs. WriterName must be from the
+ writers.py module, '.ext' must be a extension ending in a .
+ """
+ def set(self, s):
+ s = s.split()
+ writer_map = { }
+ for writer in s:
+ #from fitz import interact ; interact.interact()
+ writer, ext = writer.split(':', 1)
+ if not hasattr(writers, writer):
+ raise ValueError("Writer name not found: %s"%writer)
+ #if len(ext) < 2 or ext[0] != '.':
+ # raise ValueError("Extension must start with '.' and have "
+ # "at least one more character.")
+ writer_map[ext] = getattr(writers, writer)
+ self.setValue(writer_map)
+ def setValue(self, writer_map):
+ for e, w in writer_map.iteritems():
+ if not hasattr(w, "format"):
+ raise ValueError("Writer %s must have method .format()"%
+ w.__name__)
+ self.value = writer_map
+ def __str__(self):
+ writers_string = [ ]
+ for ext, w in self.value.iteritems():
+ name = w.__name__
+ writers_string.append("%s:%s"%(name, ext))
+ return " ".join(writers_string)
+
+
+class SupybotConfigProxy(object):
+ def __init__(self, *args, **kwargs):
+ """Do the regular default configuration, and sta"""
+ OriginalConfig = self.__OriginalConfig
+ self.__C = OriginalConfig.__new__(OriginalConfig, *args, **kwargs)
+ # We need to call the __init__ *after* we have rebound the
+ # method to get variables from the config proxy.
+ old_init = self.__C.__init__
+ new_init = types.MethodType(old_init.im_func, self, old_init.im_class)
+ new_init(*args, **kwargs)
+
+ def __getattr__(self, attrname):
+ """Try to get the value from the supybot registry. If it's in
+ the registry, return it. If it's not, then proxy it to th.
+ """
+ if attrname in settable_attributes:
+ M = self.M
+ value = M._registryValue(attrname, channel=M.channel)
+ if not isinstance(value, (str, unicode)):
+ return value
+ # '.' is used to mean "this is not set, use the default
+ # value from the python config class.
+ if value != '.':
+ value = value.replace('\\n', '\n')
+ return value
+ # If the attribute is a _property_, we need to rebind the
+ # "fget" method to the proxy class.
+ # See http://docs.python.org/library/functions.html#property
+ # http://docs.python.org/reference/datamodel.html#descriptors
+ C = self.__C
+ # is this a class attribute AND does it have a fget ?
+ if hasattr(C.__class__, attrname) and \
+ hasattr(getattr(C.__class__, attrname), 'fget'):
+ # Get the 'fget' descriptor, rebind it to self, return its
+ # value.
+ fget = getattr(C.__class__, attrname).fget
+ fget = types.MethodType(fget, self, C.__class__)
+ return fget()
+ # We don't have this value in the registry. So, proxy it to
+ # the normal config object. This is also the path that all
+ # functions take.
+ value = getattr(self.__C, attrname)
+ # If the value is an instance method, we need to re-bind it to
+ # the new config class so that we will get the data values
+ # defined in supydot (otherwise attribute lookups in the
+ # method will bypass the supybot proxy and just use default
+ # values). This will slow things down a little bit, but
+ # that's just the cost of duing business.
+ if hasattr(value, 'im_func'):
+ return types.MethodType(value.im_func, self, value.im_class)
+ return value
+
+
+
+#conf.registerGlobalValue(MeetBot
+use_supybot_config = conf.registerGlobalValue(MeetBotConfigGroup,
+ 'enableSupybotBasedConfig',
+ registry.Boolean(False, ''))
+def is_supybotconfig_enabled(OriginalConfig):
+ return (use_supybot_config.value and
+ not getattr(OriginalConfig, 'dontBotConfig', False))
+
+settable_attributes = [ ]
+def setup_config(OriginalConfig):
+ # Set all string variables in the default Config class as supybot
+ # registry variables.
+ for attrname in dir(OriginalConfig):
+ # Don't configure attributs starting with '_'
+ if attrname[0] == '_':
+ continue
+ attr = getattr(OriginalConfig, attrname)
+ # Don't configure attributes that aren't strings.
+ if isinstance(attr, (str, unicode)):
+ attr = attr.replace('\n', '\\n')
+ # For a global value: conf.registerGlobalValue and remove the
+ # channel= option from registryValue call above.
+ conf.registerChannelValue(MeetBotConfigGroup, attrname,
+ registry.String(attr,""))
+ settable_attributes.append(attrname)
+ if isinstance(attr, bool):
+ conf.registerChannelValue(MeetBotConfigGroup, attrname,
+ registry.Boolean(attr,""))
+ settable_attributes.append(attrname)
+
+ # writer_map
+ # (doing the commented out commands below will erase the previously
+ # stored value of a config variable)
+ #if 'writer_map' in MeetBotConfigGroup._children:
+ # MeetBotConfigGroup.unregister('writer_map')
+ conf.registerChannelValue(MeetBotConfigGroup, 'writer_map',
+ WriterMap(OriginalConfig.writer_map, ""))
+ settable_attributes.append('writer_map')
+
+def get_config_proxy(OriginalConfig):
+ # Here is where the real proxying occurs.
+ SupybotConfigProxy._SupybotConfigProxy__OriginalConfig = OriginalConfig
+ return SupybotConfigProxy
+
+