From d88bf5bb11c438724df28cfa577a646ef0f7d9c3 Mon Sep 17 00:00:00 2001 From: Daniel DiPaolo Date: Wed, 2 Feb 2005 04:42:37 +0000 Subject: [PATCH] Conversion of Anonymous --- plugins/Anonymous/README.txt | 1 + plugins/Anonymous/__init__.py | 61 ++++++++++++++++++++++ plugins/Anonymous/config.py | 63 +++++++++++++++++++++++ plugins/Anonymous/plugin.py | 96 +++++++++++++++++++++++++++++++++++ plugins/Anonymous/test.py | 56 ++++++++++++++++++++ 5 files changed, 277 insertions(+) create mode 100644 plugins/Anonymous/README.txt create mode 100644 plugins/Anonymous/__init__.py create mode 100644 plugins/Anonymous/config.py create mode 100644 plugins/Anonymous/plugin.py create mode 100644 plugins/Anonymous/test.py diff --git a/plugins/Anonymous/README.txt b/plugins/Anonymous/README.txt new file mode 100644 index 000000000..d60b47a97 --- /dev/null +++ b/plugins/Anonymous/README.txt @@ -0,0 +1 @@ +Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/Anonymous/__init__.py b/plugins/Anonymous/__init__.py new file mode 100644 index 000000000..f8171034e --- /dev/null +++ b/plugins/Anonymous/__init__.py @@ -0,0 +1,61 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# 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. +### + +""" +Allows folks to talk through the bot anonymously. +""" + +import supybot +import supybot.world as world + +# Use this for the version of this plugin. You may wish to put a CVS keyword +# in here if you're keeping the plugin in CVS or some similar system. +__version__ = "%%VERSION%%" + +# XXX Replace this with an appropriate author or supybot.Author instance. +__author__ = supybot.authors.strike + +# This is a dictionary mapping supybot.Author instances to lists of +# contributions. +__contributors__ = {} + +import config +import plugin +reload(plugin) # In case we're being reloaded. +# Add more reloads here if you add third-party modules and want them to be +# reloaded when this plugin is reloaded. Don't forget to import them as well! + +if world.testing: + import test + +Class = plugin.Class +configure = config.configure + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/Anonymous/config.py b/plugins/Anonymous/config.py new file mode 100644 index 000000000..b9e903ec9 --- /dev/null +++ b/plugins/Anonymous/config.py @@ -0,0 +1,63 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# 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 supybot.conf as conf +import supybot.registry as registry + +def configure(advanced): + # This will be called by supybot to configure this module. advanced is + # a bool that specifies whether the user identified himself as an advanced + # user or not. You should effect your configuration by manipulating the + # registry as appropriate. + from supybot.questions import expect, anything, something, yn + conf.registerPlugin('Anonymous', True) + + +Anonymous = conf.registerPlugin('Anonymous') +# This is where your configuration variables (if any) should go. For example: +# conf.registerGlobalValue(Anonymous, 'someConfigVariableName', +# registry.Boolean(False, """Help for someConfigVariableName.""")) +conf.registerChannelValue(conf.supybot.plugins.Anonymous, + 'requirePresenceInChannel', registry.Boolean(True, """Determines whether + the bot should require people trying to use this plugin to be in the + channel they wish to anonymously send to.""")) +conf.registerGlobalValue(conf.supybot.plugins.Anonymous, 'requireRegistration', + registry.Boolean(True, """Determines whether the bot should require people + trying to use this plugin to be registered.""")) +conf.registerGlobalValue(conf.supybot.plugins.Anonymous, 'requireCapability', + registry.String('', """Determines what capability (if any) the bot should + require people trying to use this plugin to have.""")) +conf.registerGlobalValue(conf.supybot.plugins.Anonymous, 'allowPrivateTarget', + registry.Boolean(False, """Determines whether the bot will require targets + of the "say" command to be public (i.e., channels). If this is True, the + bot will allow people to use the "say" command to send private messages to + other users.""")) + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78 diff --git a/plugins/Anonymous/plugin.py b/plugins/Anonymous/plugin.py new file mode 100644 index 000000000..c678ec4ab --- /dev/null +++ b/plugins/Anonymous/plugin.py @@ -0,0 +1,96 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# 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 supybot.ircdb as ircdb +import supybot.utils as utils +from supybot.commands import * +import supybot.ircmsgs as ircmsgs +import supybot.callbacks as callbacks + +class Anonymous(callbacks.Privmsg): + """This plugin allows users to act through the bot anonymously. The 'do' + command has the bot perform an anonymous action in a given channel, and + the 'say' command allows other people to speak through the bot. Since + this can be fairly well abused, you might want to set + supybot.plugins.Anonymous.requireCapability so only users with that + capability can use this plugin. For extra security, you can require that + the user be *in* the channel they are trying to address anonymously with + supybot.plugins.Anonymous.requirePresenceInChannel, or you can require + that the user be registered by setting + supybot.plugins.Anonymous.requireRegistration. + """ + def _preCheck(self, irc, msg, channel): + if self.registryValue('requireRegistration'): + try: + _ = ircdb.users.getUser(msg.prefix) + except KeyError: + irc.errorNotRegistered(Raise=True) + capability = self.registryValue('requireCapability') + if capability: + if not ircdb.checkCapability(msg.prefix, capability): + irc.errorNoCapability(capability, Raise=True) + if self.registryValue('requirePresenceInChannel', channel) and \ + msg.nick not in irc.state.channels[channel].users: + irc.error(format('You must be in %s to %q in there.', + channel, 'say'), Raise=True) + c = ircdb.channels.getChannel(channel) + if c.lobotomized: + irc.error(format('I\'m lobotomized in %s.', channel), Raise=True) + if not c._checkCapability(self.name()): + irc.error('That channel has set its capabilities so as to ' + 'disallow the use of this plugin.', Raise=True) + + def say(self, irc, msg, args, channel, text): + """ + + Sends to . + """ + self._preCheck(irc, msg, channel) + self.log.info('Saying %s in %s due to %s.' % \ + utils.str.quoted(text), channel, msg.prefix) + irc.queueMsg(ircmsgs.privmsg(channel, text)) + irc.noReply() + say = wrap(say, ['inChannel', 'text']) + + def do(self, irc, msg, args, channel, text): + """ + + Performs in . + """ + self._preCheck(irc, msg, channel) + self.log.info('Performing %s in %s due to %s.'% \ + utils.str.quoted(text), channel, msg.prefix) + irc.queueMsg(ircmsgs.action(channel, text)) + irc.noReply() + do = wrap(do, ['inChannel', 'text']) + +Class = Anonymous + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/Anonymous/test.py b/plugins/Anonymous/test.py new file mode 100644 index 000000000..7791b38e5 --- /dev/null +++ b/plugins/Anonymous/test.py @@ -0,0 +1,56 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# 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. +### + +from supybot.test import * + +class AnonymousTestCase(ChannelPluginTestCase): + plugins = ('Anonymous',) + def testSay(self): + m = self.assertError('anonymous say %s I love you!' % self.channel) + try: + orig = conf.supybot.plugins.Anonymous.requireRegistration() + conf.supybot.plugins.Anonymous.requireRegistration.setValue(False) + m = self.assertNotError('anonymous say %s foo!'%self.channel) + self.failUnless(m.args[1] == 'foo!') + finally: + conf.supybot.plugins.Anonymous.requireRegistration.setValue(orig) + + def testAction(self): + m = self.assertError('anonymous do %s loves you!' % self.channel) + try: + orig = conf.supybot.plugins.Anonymous.requireRegistration() + conf.supybot.plugins.Anonymous.requireRegistration.setValue(False) + m = self.assertNotError('anonymous do %s loves you!'%self.channel) + self.assertEqual(m.args, ircmsgs.action(self.channel, + 'loves you!').args) + finally: + conf.supybot.plugins.Anonymous.requireRegistration.setValue(orig) + + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: