From 424f5acebe07d9473c46d48c029b112f49f6e23b Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 29 Oct 2010 09:44:16 +0200 Subject: [PATCH] Move MegaHAL and SupySandbox to the Supybot-plugins repository --- plugins/MegaHAL/README.txt | 1 - plugins/MegaHAL/__init__.py | 67 ------- plugins/MegaHAL/config.py | 72 ------- plugins/MegaHAL/plugin.py | 155 -------------- plugins/MegaHAL/test.py | 43 ---- plugins/SupySandbox/README.txt | 1 - plugins/SupySandbox/__init__.py | 68 ------- plugins/SupySandbox/config.py | 50 ----- plugins/SupySandbox/local/__init__.py | 1 - plugins/SupySandbox/local/fschfsch.py | 279 -------------------------- plugins/SupySandbox/plugin.py | 199 ------------------ plugins/SupySandbox/test.py | 56 ------ 12 files changed, 992 deletions(-) delete mode 100644 plugins/MegaHAL/README.txt delete mode 100644 plugins/MegaHAL/__init__.py delete mode 100644 plugins/MegaHAL/config.py delete mode 100644 plugins/MegaHAL/plugin.py delete mode 100644 plugins/MegaHAL/test.py delete mode 100644 plugins/SupySandbox/README.txt delete mode 100644 plugins/SupySandbox/__init__.py delete mode 100644 plugins/SupySandbox/config.py delete mode 100644 plugins/SupySandbox/local/__init__.py delete mode 100644 plugins/SupySandbox/local/fschfsch.py delete mode 100644 plugins/SupySandbox/plugin.py delete mode 100644 plugins/SupySandbox/test.py diff --git a/plugins/MegaHAL/README.txt b/plugins/MegaHAL/README.txt deleted file mode 100644 index d60b47a97..000000000 --- a/plugins/MegaHAL/README.txt +++ /dev/null @@ -1 +0,0 @@ -Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/MegaHAL/__init__.py b/plugins/MegaHAL/__init__.py deleted file mode 100644 index 6802d6d2c..000000000 --- a/plugins/MegaHAL/__init__.py +++ /dev/null @@ -1,67 +0,0 @@ -### -# Copyright (c) 2010, Valentin Lorentz -# 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. - -### - -""" -This plugins provides a MegaHAL integration for Supybot. -MegaHAL must be installed ('apt-get install megahal' on Debian) -""" - -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__ = "" - -# XXX Replace this with an appropriate author or supybot.Author instance. -__author__ = supybot.Author('Valentin Lorentz', 'ProgVal', - 'progval@gmail.com') - -# This is a dictionary mapping supybot.Author instances to lists of -# contributions. -__contributors__ = {} - -# This is a url where the most recent plugin package can be downloaded. -__url__ = '' # 'http://supybot.com/Members/yourname/MegaHAL/download' - -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=4 expandtab textwidth=79: diff --git a/plugins/MegaHAL/config.py b/plugins/MegaHAL/config.py deleted file mode 100644 index 19f4e84c9..000000000 --- a/plugins/MegaHAL/config.py +++ /dev/null @@ -1,72 +0,0 @@ -### -# Copyright (c) 2010, Valentin Lorentz -# 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 -try: - from supybot.i18n import PluginInternationalization - from supybot.i18n import internationalizeDocstring - _ = PluginInternationalization('MegaHAL') -except: - _ = lambda x:x - internationalizeDocstring = lambda x:x - -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('MegaHAL', True) - - -MegaHAL = conf.registerPlugin('MegaHAL') -# This is where your configuration variables (if any) should go. For example: -# conf.registerGlobalValue(MegaHAL, 'someConfigVariableName', -# registry.Boolean(False, """Help for someConfigVariableName.""")) - -conf.registerGroup(MegaHAL, 'learn') -conf.registerGlobalValue(MegaHAL.learn, 'commands', - registry.Boolean(False, _("""Determines whether the bot answers to messages - beginning by a non-alphanumeric char."""))) -conf.registerGroup(MegaHAL, 'answer') -conf.registerChannelValue(MegaHAL.answer, 'commands', - registry.Boolean(False, _("""Determines whether messages beginning by a - non-alphanumeric char are learned."""))) -conf.registerChannelValue(MegaHAL.answer, 'probability', - registry.Integer(10, _("""Determines the percent of messages the bot will - answer (zero is recommended if you have a tiny database)."""))) -conf.registerChannelValue(MegaHAL.answer, 'probabilityWhenAddressed', - registry.Integer(100, _("""Determines the percent of messages adressed to - the bot the bot will answer."""))) - - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/plugins/MegaHAL/plugin.py b/plugins/MegaHAL/plugin.py deleted file mode 100644 index 1889947fe..000000000 --- a/plugins/MegaHAL/plugin.py +++ /dev/null @@ -1,155 +0,0 @@ -### -# Copyright (c) 2010, Valentin Lorentz -# 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 re -import os -import sys -import random -import supybot.conf as conf -import supybot.utils as utils -from cStringIO import StringIO -from supybot.commands import * -import supybot.plugins as plugins -import supybot.ircutils as ircutils -import supybot.callbacks as callbacks - -try: - import mh_python as megahal -except ImportError: - raise callbacks.Error, 'You need to have MegaHAL installed to use this ' \ - 'plugin. Download it at ' \ - '' \ - 'or with ' - -try: - from supybot.i18n import PluginInternationalization - from supybot.i18n import internationalizeDocstring - _ = PluginInternationalization('MegaHAL') -except: - # This are useless function that's allow to run the plugin on a bot - # without the i18n plugin - _ = lambda x:x - internationalizeDocstring = lambda x:x - -class MegaHAL(callbacks.Plugin): - """This plugins provides a MegaHAL integration for Supybot. - MegaHAL must be installed ('apt-get install megahal' on Debian)""" - callAfter = ['MoobotFactoids', 'Factoids', 'Infobot'] - callBefore = ['Dunno'] - - def __init__(self, irc): - # Call Supybot's scripts - self.__parent = super(MegaHAL, self) - self.__parent.__init__(irc) - - # Save state - saved = (sys.stdout, os.getcwd()) - - # Create proxy for MegaHAL - os.chdir(conf.supybot.directories.data()) - sys.stdout = StringIO() - - # Initialize MegaHAL - megahal.initbrain() - - # Restore state - sys.stdout, cwd = saved - os.chdir(cwd) - - random.seed() - - _dontKnow = [ - 'I don\'t know enough to answer you yet!', - 'I am utterly speechless!', - 'I forgot what I was going to say!' - ] - _translations = { - 'I don\'t know enough to answer you yet!': - _('I don\'t know enough to answer you yet!'), - 'I am utterly speechless!': - _('I am utterly speechless!'), - 'I forgot what I was going to say!': - _('I forgot what I was going to say!'), - } - - def _response(self, msg, prb, reply): - if random.randint(0, 100) < prb: - response = megahal.doreply(msg) - if self._translations.has_key(response): - response = self._translations[response] - reply(response, prefixNick=False) - else: - megahal.learn(msg) - - def doPrivmsg(self, irc, msg): - if not msg.args[0].startswith('#'): # It is a private message - return - message = msg.args[1] - - if message.startswith(irc.nick) or re.match('\W.*', message): - # Managed by invalidCommand - return - - probability = self.registryValue('answer.probability', msg.args[0]) - self._response(message, probability, irc.reply) - - def invalidCommand(self, irc, msg, tokens): - if not msg.args[0].startswith('#'): # It is a private message - # Actually, we would like to answer, but : - # 1) It may be a mistyped identify command (or whatever) - # 2) MegaHAL can't reply without learning - return - message = msg.args[1] - usedToStartWithNick = False - if message.startswith(message): - parsed = re.match('(.+ |\W)?(?P\w.*)', message) - message = parsed.group('message') - usedToStartWithNick = True - if self.registryValue('answer.commands') or usedToStartWithNick: - print msg.args[0] - self._response(message, - self.registryValue('answer.probabilityWhenAddressed', - msg.args[0]), - irc.reply) - elif self.registryValue('learn.commands'): - megahal.learn(message) - - @internationalizeDocstring - def cleanup(self, irc, msg, args): - """takes no argument - - Saves MegaHAL brain to disk.""" - megahal.cleanup() - irc.replySuccess() - -Class = MegaHAL - - -# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/MegaHAL/test.py b/plugins/MegaHAL/test.py deleted file mode 100644 index 6d4b075fd..000000000 --- a/plugins/MegaHAL/test.py +++ /dev/null @@ -1,43 +0,0 @@ -### -# Copyright (c) 2010, Valentin Lorentz -# 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 MegaHALTestCase(PluginTestCase): - plugins = ('MegaHAL',) - - def testCleanup(self): - self.assertNotError('cleanup') - - def testAnswer(self): - self.assertNotRegexp('foo', '.*not a valid.*') - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/plugins/SupySandbox/README.txt b/plugins/SupySandbox/README.txt deleted file mode 100644 index d60b47a97..000000000 --- a/plugins/SupySandbox/README.txt +++ /dev/null @@ -1 +0,0 @@ -Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/SupySandbox/__init__.py b/plugins/SupySandbox/__init__.py deleted file mode 100644 index 5e5a07162..000000000 --- a/plugins/SupySandbox/__init__.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf8 -*- -### -# Copyright (c) 2010, Valentin Lorentz -# 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. - -### - -""" -Ce plugin est un portage du robot IRC Fschfsch, servant à fournir un accès -à la pysandbox sur IRC. -""" - -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__ = "0.1" - -# XXX Replace this with an appropriate author or supybot.Author instance. -__author__ = supybot.Author('Valentin Lorentz', 'ProgVal', - 'progval@gmail.com') - -# This is a dictionary mapping supybot.Author instances to lists of -# contributions. -__contributors__ = {} - -# This is a url where the most recent plugin package can be downloaded. -__url__ = 'http://supybot-fr.tk/SupySandbox' - -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=4 expandtab textwidth=79: diff --git a/plugins/SupySandbox/config.py b/plugins/SupySandbox/config.py deleted file mode 100644 index 748065cad..000000000 --- a/plugins/SupySandbox/config.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf8 -*- -### -# Copyright (c) 2010, Valentin Lorentz -# 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('SupySandbox', True) - - -PySandbox = conf.registerPlugin('SupySandbox') -# This is where your configuration variables (if any) should go. For example: -# conf.registerGlobalValue(PySandbox, 'someConfigVariableName', -# registry.Boolean(False, """Help for someConfigVariableName.""")) - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/plugins/SupySandbox/local/__init__.py b/plugins/SupySandbox/local/__init__.py deleted file mode 100644 index e86e97b86..000000000 --- a/plugins/SupySandbox/local/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Stub so local is a module, used for third-party modules diff --git a/plugins/SupySandbox/local/fschfsch.py b/plugins/SupySandbox/local/fschfsch.py deleted file mode 100644 index 20872fae6..000000000 --- a/plugins/SupySandbox/local/fschfsch.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python -# this file is under the WTFPLv2 [http://sam.zoy.org/wtfpl] -# v1: 2010/05/23 -# Author: Tila - -# You need a configuration file: ~/.fschfsch.py. Config example: -# --- -# host = 'irc.freenode.net' -# port = 7000 -# ssl = True -# nickname = 'botnickname' -# password = 'secret' -# channels = ['##fschfsch', '#channel2', '#channel3'] -# texts = {'help': 'I am fschfsch, a robot snake that evals python code', -# 'sandbox': "I am powered by setrlimit and pysandbox [http://github.com/haypo/pysandbox], I don't fear you"} -# --- - -''' -fschfsch is a Python-evaluating bot. fschfsch is pronounced "fssshh! fssshh!". -''' - -IN_MAXLEN = 300 # bytes -OUT_MAXLEN = 300 # bytes -TIMEOUT = 3 # seconds - -EVAL_MAXTIMESECONDS = TIMEOUT -EVAL_MAXMEMORYBYTES = 10 * 1024 * 1024 # 10 MiB - - -try: - import sandbox as S -except ImportError: - print 'You need pysandbox in order to run fschfsch [http://github.com/haypo/pysandbox].' - raise -try: - import twisted -except ImportError: - print 'You need twisted in order to run fschfsch.' - raise -from twisted.internet.protocol import ReconnectingClientFactory -from twisted.internet import ssl, reactor -from twisted.words.im.ircsupport import IRCProto -from twisted.words.protocols.irc import IRCClient -# other imports -import re -import sys -import os -import resource as R -import select -import signal -import time -import threading -import random - -def createSandboxConfig(): - cfg = S.SandboxConfig( - 'stdout', - 'stderr', - 'regex', - 'unicodedata', # flow wants u'\{ATOM SYMBOL}' :-) - 'future', - 'code', - 'time', - 'datetime', - 'math', - 'itertools', - 'random', - 'encodings', - ) - cfg.allowModule('sys', - 'version', 'hexversion', 'version_info') - return cfg - -def _evalPython(line, locals): - locals = dict(locals) - try: - if "\n" in line: - raise SyntaxError() - code = compile(line, "", "single") - except SyntaxError: - code = compile(line, "", "exec") - exec code in locals - -def evalPython(line, locals=None): - sandbox = S.Sandbox(config=createSandboxConfig()) - - if locals is not None: - locals = dict(locals) - else: - locals = dict() - try: - sandbox.call(_evalPython, line, locals) - except BaseException, e: - print 'Error: [%s] %s' % (e.__class__.__name__, str(e)) - except: - print 'Error: ' - sys.stdout.flush() - -def childProcess(line, w, locals): - # reseed after a fork to avoid generating the same sequence for each child - random.seed() - - sys.stdout = sys.stderr = os.fdopen(w, 'w') - - R.setrlimit(R.RLIMIT_CPU, (EVAL_MAXTIMESECONDS, EVAL_MAXTIMESECONDS)) - R.setrlimit(R.RLIMIT_AS, (EVAL_MAXMEMORYBYTES, EVAL_MAXMEMORYBYTES)) - R.setrlimit(R.RLIMIT_NPROC, (0, 0)) # 0 forks - - evalPython(line, locals) - -def handleChild(childpid, r): - txt = '' - if any(select.select([r], [], [], TIMEOUT)): - txt = os.read(r, OUT_MAXLEN + 1) - os.close(r) - if OUT_MAXLEN < len(txt): - txt = txt[:OUT_MAXLEN] + '...' - - n = 0 - while n < 6: - pid, status = os.waitpid(childpid, os.WNOHANG) - if pid: - break - time.sleep(.5) - n += 1 - if not pid: - os.kill(childpid, signal.SIGKILL) - return 'Timeout' - elif os.WIFEXITED(status): - txts = txt.rstrip().split('\n') - if len(txts) > 1: - txt = txts[0].rstrip() + ' [+ %d line(s)]' % (len(txts) - 1) - else: - txt = txts[0].rstrip() - return 'Output: ' + txt - elif os.WIFSIGNALED(status): - return 'Killed' - - - -class EvalJob(threading.Thread): - def __init__(self, line, irc, channel): - super(EvalJob, self).__init__() - self.line = line - self.irc = irc - self.channel = channel - - def run(self): - output = self.handle_line(self.line) - reactor.callFromThread(self.irc.say, self.channel, output) - self.irc.executionLock.release() - - def handle_line(self, line): - if IN_MAXLEN < len(line): - return '(command is too long: %s bytes, the maximum is %s)' % (len(line), IN_MAXLEN) - - print("Process %s" % repr(line)) - r, w = os.pipe() - childpid = os.fork() - if not childpid: - os.close(r) - childProcess(line, w, self.irc.factory.morevars) - os._exit(0) - else: - os.close(w) - result = handleChild(childpid, r) - print("=> %s" % repr(result)) - return result - - - -class EvalBot(IRCClient): - versionName = 'fschfsch' - versionNum = '0.1' - - #~ def __init__(self, *a, **k): - def connectionMade(self): - self.nickname = self.factory.nick - self.password = self.factory.password - self.talkre = re.compile('^%s[>:,] (.*)$' % self.nickname) - - self.executionLock = threading.Semaphore() - self.pingSelfId = None - - IRCClient.connectionMade(self) - - def signedOn(self): - self.pingSelfId = reactor.callLater(180, self.pingSelf) - for chan in self.factory.channels: - self.join(chan) - - def pingSelf(self): - # used to avoid some timeouts where fschfsch does not reconnect - self.ping(self.nickname) - self.pingSelfId = reactor.callLater(180, self.pingSelf) - - def privmsg(self, user, channel, message): - if self.pingSelfId is not None: - self.pingSelfId.reset(180) - if user.startswith('haypo') and message.startswith('exit'): - os._exit(0) - if not channel: - return - if not message.startswith(self.nickname): - return - if not self.talkre.match(message): - return - if not self.executionLock.acquire(blocking=False): - return - - pyline = self.talkre.match(message).group(1) - pyline = pyline.replace(' $$ ', '\n') - - self.handleThread = EvalJob(pyline, self, channel) - self.handleThread.start() - - -class MyFactory(ReconnectingClientFactory): - def __init__(self, **kw): - for k in kw: - if k in ('nick', 'password', 'channels', 'morevars'): - setattr(self, k, kw[k]) - protocol = EvalBot - -def check_output(expr, expected, locals=None): - from cStringIO import StringIO - original_stdout = sys.stdout - try: - output = StringIO() - sys.stdout = output - evalPython(expr, locals) - stdout = output.getvalue() - assert stdout == expected, "%r != %r" % (stdout, expected) - finally: - sys.stdout = original_stdout - -def runTests(): - # single - check_output('1+1', '2\n') - check_output('1; 2', '1\n2\n') - check_output( - # written in a single line - "prime=lambda n,i=2:" - "False if n%i==0 else prime(n,i+1) if i*i", "single") - except SyntaxError: - code = compile(line, "", "exec") - exec code in locals - -def evalPython(line, locals=None): - sandbox = S.Sandbox(config=createSandboxConfig()) - - if locals is not None: - locals = dict(locals) - else: - locals = dict() - try: - sandbox.call(_evalPython, line, locals) - except BaseException, e: - print 'Error: [%s] %s' % (e.__class__.__name__, str(e)) - except: - print 'Error: ' - sys.stdout.flush() - -def check_output(expr, expected, locals=None): - from cStringIO import StringIO - original_stdout = sys.stdout - try: - output = StringIO() - sys.stdout = output - evalPython(expr, locals) - stdout = output.getvalue() - assert stdout == expected, "%r != %r" % (stdout, expected) - finally: - sys.stdout = original_stdout - -def runTests(): - # single - check_output('1+1', '2\n') - check_output('1; 2', '1\n2\n') - check_output( - # written in a single line - "prime=lambda n,i=2:" - "False if n%i==0 else prime(n,i+1) if i*i.*)') - def sandbox(self, irc, msg, args): - """ - - Runs Python code safely thanks to pysandbox""" - code = self._parser.match(msg.args[1]).group('code') - irc.reply(handle_line(code.replace(' $$ ', '\n'))) - - def runtests(self, irc, msg, args): - irc.reply(runTests()) - - -Class = SupySandbox - - -# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/SupySandbox/test.py b/plugins/SupySandbox/test.py deleted file mode 100644 index abf415165..000000000 --- a/plugins/SupySandbox/test.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf8 -*- -### -# Copyright (c) 2010, Valentin Lorentz -# 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 SupySandboxTestCase(PluginTestCase): - plugins = ('SupySandbox',) - - def testFschfschTestcase(self): - self.assertResponse('runtests', 'True') - - def testCodeIsSuccessfullyRunned(self): - self.assertResponse('sandbox 1+1', "2") - self.assertResponse('sandbox print 1+1', "2") - self.assertResponse('sandbox print \'toto\'', "toto") - - def testMultine(self): - self.assertResponse('sandbox print 1; print 2', "'1\\n2'") - self.assertResponse('sandbox print 1 $$ print 2', "'1\\n2'") - self.assertResponse('sandbox toto=True $$ while toto: $$ print "foo"' - ' $$ toto=False', "foo") - - def testProtections(self): - #self.assertResponse('sandbox while True: print 1', "Timeout") - pass - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: