Initial Release
This commit is contained in:
commit
d66203e1ea
|
@ -0,0 +1 @@
|
||||||
|
Insert a description of your plugin here, with any notes, etc. about using it.
|
|
@ -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 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -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 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -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.Plugin):
|
||||||
|
"""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):
|
||||||
|
"""<channel> <text>
|
||||||
|
|
||||||
|
Sends <text> to <channel>.
|
||||||
|
"""
|
||||||
|
self._preCheck(irc, msg, channel)
|
||||||
|
self.log.info('Saying %q in %s due to %s.',
|
||||||
|
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):
|
||||||
|
"""<channel> <action>
|
||||||
|
|
||||||
|
Performs <action> in <channel>.
|
||||||
|
"""
|
||||||
|
self._preCheck(irc, msg, channel)
|
||||||
|
self.log.info('Performing %q in %s due to %s.',
|
||||||
|
text, channel, msg.prefix)
|
||||||
|
irc.queueMsg(ircmsgs.action(channel, text))
|
||||||
|
irc.noReply()
|
||||||
|
do = wrap(do, ['inChannel', 'text'])
|
||||||
|
|
||||||
|
Class = Anonymous
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -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 softtabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1 @@
|
||||||
|
Insert a description of your plugin here, with any notes, etc. about using it.
|
|
@ -0,0 +1,43 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||||
|
here. This should describe *what* the plugin does.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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.authors.unknown
|
||||||
|
|
||||||
|
# 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/Raumstatus/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.Flipdot
|
||||||
|
configure = config.configure
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
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('Flipdot', True)
|
||||||
|
|
||||||
|
|
||||||
|
Flipdot = conf.registerPlugin('Flipdot')
|
||||||
|
# This is where your configuration variables (if any) should go. For example:
|
||||||
|
conf.registerGlobalValue(Flipdot, 'host',
|
||||||
|
registry.String("2001:67c:275c:a9::c", """Host of Flipdot"""))
|
||||||
|
conf.registerGlobalValue(Flipdot, 'port',
|
||||||
|
registry.Integer(2323, """Port number of Flipdot"""))
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,75 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, henne
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
from threading import Event, Thread
|
||||||
|
import subprocess
|
||||||
|
import supybot.utils as utils
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
import supybot.ircmsgs as ircmsgs
|
||||||
|
import socket, time
|
||||||
|
import Image, ImageFont, ImageDraw, sys
|
||||||
|
import fileinput
|
||||||
|
|
||||||
|
class Flipdot(callbacks.Plugin):
|
||||||
|
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
def list2byte(l):
|
||||||
|
byte = 0
|
||||||
|
i = 0
|
||||||
|
for i in range(8):
|
||||||
|
byte += 2**(7-i) if l[i] else 0
|
||||||
|
return byte
|
||||||
|
|
||||||
|
def array2packet(a):
|
||||||
|
return str(bytearray([list2byte(a[i*8:i*8+8]) for i in range(len(a)/8)]))
|
||||||
|
|
||||||
|
def str2array(s):
|
||||||
|
IMG_SIZE = (80,16)
|
||||||
|
FONT_SIZE = 11
|
||||||
|
FONT_OFFSET= (1, 3)
|
||||||
|
|
||||||
|
C_BLACK = (0, 0, 0)
|
||||||
|
C_WHITE = (255, 255, 255)
|
||||||
|
|
||||||
|
image = Image.new("RGBA", IMG_SIZE, C_BLACK)
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.fontmode = "1" # No AA
|
||||||
|
#font = ImageFont.load_default()
|
||||||
|
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSans.ttf", FONT_SIZE)
|
||||||
|
|
||||||
|
draw.text(FONT_OFFSET, s, font=font, fill=C_WHITE)
|
||||||
|
|
||||||
|
imgmap = []
|
||||||
|
for pixel in image.getdata():
|
||||||
|
r, g, b, a = pixel
|
||||||
|
if r == 255:
|
||||||
|
imgmap.append(1)
|
||||||
|
else:
|
||||||
|
imgmap.append(0)
|
||||||
|
return imgmap
|
||||||
|
|
||||||
|
def __init__(self, irc):
|
||||||
|
self.__parent = super(Flipdot, self)
|
||||||
|
self.__parent.__init__(irc)
|
||||||
|
# def __del__(self, irc):
|
||||||
|
# ampel.connection.close()
|
||||||
|
def start(self, irc, msg, args):
|
||||||
|
irc.reply("Lampel kann nun gesteuert werden (noch nicht.....)")
|
||||||
|
# ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
# ampel.connection.write("io get port 2\n")
|
||||||
|
# buf = ampel.connection.read_until("\n", 1)
|
||||||
|
# self.state = buf[-2]
|
||||||
|
# irc.reply(self.state)
|
||||||
|
start = wrap(start)
|
||||||
|
def hilfe(self, irc, msg, args):
|
||||||
|
irc.reply("hilfe: Hilft dir...")
|
||||||
|
hilfe = wrap(hilfe)
|
||||||
|
def send(self, irc, msg, args):
|
||||||
|
sock.sendto(array2packet(str2array(msg.strip())), (self.registryValue('host'), self.registryValue('port')))
|
||||||
|
send = wrap(send)
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,41 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||||
|
here. This should describe *what* the plugin does.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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.authors.unknown
|
||||||
|
|
||||||
|
# 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/Raumstatus/download'
|
||||||
|
|
||||||
|
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.Gem
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, henne
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
from threading import Event, Thread
|
||||||
|
import subprocess
|
||||||
|
import supybot.utils as utils
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
import supybot.ircmsgs as ircmsgs
|
||||||
|
import random
|
||||||
|
class Gem(callbacks.Plugin):
|
||||||
|
gemActive = False
|
||||||
|
def __init__(self, irc):
|
||||||
|
self.__parent = super(Gem, self)
|
||||||
|
self.__parent.__init__(irc)
|
||||||
|
def gem(self, irc, msg, args):
|
||||||
|
if self.gemActive:
|
||||||
|
irc.reply("Gem Deactivated")
|
||||||
|
else:
|
||||||
|
c = random.randint(1,100)
|
||||||
|
if c>99:
|
||||||
|
irc.reply("Perfect Gem Activated")
|
||||||
|
elif c>90:
|
||||||
|
irc.reply("Mooooooooooooo!")
|
||||||
|
else:
|
||||||
|
irc.reply("Gem Activated")
|
||||||
|
self.gemActive = not self.gemActive
|
||||||
|
gem = wrap(gem)
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Insert a description of your plugin here, with any notes, etc. about using it.
|
|
@ -0,0 +1,43 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||||
|
here. This should describe *what* the plugin does.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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.authors.unknown
|
||||||
|
|
||||||
|
# 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/Raumstatus/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.Lampel
|
||||||
|
configure = config.configure
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
import telnetlib
|
||||||
|
connection = telnetlib.Telnet()
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
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('Lampel', True)
|
||||||
|
|
||||||
|
|
||||||
|
Lampel = conf.registerPlugin('Lampel')
|
||||||
|
# This is where your configuration variables (if any) should go. For example:
|
||||||
|
conf.registerGlobalValue(Lampel, 'host',
|
||||||
|
registry.String("lampel.raum.ctdo.de", """Host of Lampel"""))
|
||||||
|
conf.registerGlobalValue(Lampel, 'port',
|
||||||
|
registry.Integer(2701, """Port number of Lampel"""))
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,171 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, henne
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
from threading import Event, Thread
|
||||||
|
import subprocess
|
||||||
|
import supybot.utils as utils
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
import supybot.ircmsgs as ircmsgs
|
||||||
|
import ampel
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
class Lampel(callbacks.Plugin):
|
||||||
|
# state = 00
|
||||||
|
threaded = True
|
||||||
|
discoan = False
|
||||||
|
def __init__(self, irc):
|
||||||
|
self.__parent = super(Lampel, self)
|
||||||
|
self.__parent.__init__(irc)
|
||||||
|
# def __del__(self, irc):
|
||||||
|
# ampel.connection.close()
|
||||||
|
def start(self, irc, msg, args):
|
||||||
|
irc.reply("Lampel kann nun gesteuert werden (noch nicht.....)")
|
||||||
|
# ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
# ampel.connection.write("io get port 2\n")
|
||||||
|
# buf = ampel.connection.read_until("\n", 1)
|
||||||
|
# self.state = buf[-2]
|
||||||
|
# irc.reply(self.state)
|
||||||
|
start = wrap(start)
|
||||||
|
def rot(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 04\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
rot = wrap(rot)
|
||||||
|
red = wrap(rot)
|
||||||
|
def gelb(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 02\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
gelb = wrap(gelb)
|
||||||
|
yellow = wrap(gelb)
|
||||||
|
def gruen(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 01\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
gruen = wrap(gruen)
|
||||||
|
green = wrap(gruen)
|
||||||
|
def rotgelbgruen(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 07\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
rotgelbgruen = wrap(rotgelbgruen)
|
||||||
|
allcolors = wrap(rotgelbgruen)
|
||||||
|
allefarben = wrap(rotgelbgruen)
|
||||||
|
alle = wrap(rotgelbgruen)
|
||||||
|
def rotgelb(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 06\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
rotgelb = wrap(rotgelb)
|
||||||
|
gelbrot = wrap(rotgelb)
|
||||||
|
redyellow = wrap(rotgelb)
|
||||||
|
yellowred = wrap(rotgelb)
|
||||||
|
def rotgruen(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 05\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
rotgruen = wrap(rotgruen)
|
||||||
|
redgreen = wrap(rotgruen)
|
||||||
|
gruenrot = wrap(rotgruen)
|
||||||
|
greenred = wrap(rotgruen)
|
||||||
|
def gelbgruen(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 03\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
gelbgruen = wrap(gelbgruen)
|
||||||
|
yellowgreen = wrap(gelbgruen)
|
||||||
|
gruengelb = wrap(gelbgruen)
|
||||||
|
greenyellow = wrap(gelbgruen)
|
||||||
|
def aus(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 00\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
aus = wrap(aus)
|
||||||
|
off = wrap(aus)
|
||||||
|
def hilfe(self, irc, msg, args):
|
||||||
|
irc.reply("Help for the Lampelcontrol")
|
||||||
|
irc.reply("rot: Nur rot an (oder red)")
|
||||||
|
irc.reply("gelb: Nur gelb an (oder yellow)")
|
||||||
|
irc.reply("gruen: Nur gruen an (oder gruen)")
|
||||||
|
irc.reply("rotgelb: Rot und Gelb an (oder gelbrot, redyellow, yellowred)")
|
||||||
|
irc.reply("rotgruen: Rot und Gruen an (oder gruenrot, greenred, redgreen)")
|
||||||
|
irc.reply("gelbgruen: Gelb und Gruen an (oder gruengelb, greenyellow, yellowgreen)")
|
||||||
|
irc.reply("rotgelbgruen: alle an (oder alle, allefarben, allcolors)")
|
||||||
|
irc.reply("aus: alle aus (oder off)")
|
||||||
|
irc.reply("hilfe: Hilft dir...")
|
||||||
|
|
||||||
|
hilfe = wrap(hilfe)
|
||||||
|
def ampelaus(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
for i in range(1, 5):
|
||||||
|
ampel.connection.write("io set port 2 00\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.write("io set port 2 02\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.close()
|
||||||
|
def moo(self, irc, msg, args):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 00\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.write("io set port 2 01\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.write("io set port 2 02\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.write("io set port 2 04\n")
|
||||||
|
time.sleep(1)
|
||||||
|
ampel.connection.write("io set port 2 00\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
moo = wrap(moo)
|
||||||
|
def disco(self, irc, msg, args):
|
||||||
|
if not self.discoan:
|
||||||
|
irc.reply("And the Party begins")
|
||||||
|
self.discoTimer = meinTimer(2, self.discof, 0, [irc])
|
||||||
|
self.discoTimer.daemon = True
|
||||||
|
self.discoan = True
|
||||||
|
self.discoTimer.start()
|
||||||
|
else:
|
||||||
|
irc.reply("The Party is over")
|
||||||
|
self.discoTimer.cancel()
|
||||||
|
self.discoan = False
|
||||||
|
disco = wrap(disco)
|
||||||
|
def discof(self, irc):
|
||||||
|
ampel.connection.open(self.registryValue('host'), self.registryValue('port'))
|
||||||
|
ampel.connection.write("io set port 2 0" + str(random.randint(0, 7)) + "\n")
|
||||||
|
# ampel.connection.write("io set port 2 01\n")
|
||||||
|
ampel.connection.close()
|
||||||
|
# def getState(self, irc, msg, args):
|
||||||
|
# ampel.connection.write("io get port 2\n")
|
||||||
|
# buf = ampel.connection.read_until("\n", 1)
|
||||||
|
# self.state = buf[-2]
|
||||||
|
# irc.reply(buf)
|
||||||
|
# getstate = wrap(getState)
|
||||||
|
|
||||||
|
|
||||||
|
class meinTimer(Thread):
|
||||||
|
def __init__(self, interval, function, iterations=0, args=[], kwargs={}):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.interval = interval
|
||||||
|
self.function = function
|
||||||
|
self.iterations = iterations
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.finished = Event()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
count = 0
|
||||||
|
while not self.finished.isSet() and (self.iterations <= 0 or count < self.iterations):
|
||||||
|
self.finished.wait(self.interval)
|
||||||
|
if not self.finished.isSet():
|
||||||
|
self.function(*self.args, **self.kwargs)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.finished.set()
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Insert a description of your plugin here, with any notes, etc. about using it.
|
|
@ -0,0 +1,43 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||||
|
here. This should describe *what* the plugin does.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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.authors.unknown
|
||||||
|
|
||||||
|
# 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/Raumstatus/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:
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
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('Raumstatus', True)
|
||||||
|
|
||||||
|
|
||||||
|
Raumstatus = conf.registerPlugin('Raumstatus')
|
||||||
|
# This is where your configuration variables (if any) should go. For example:
|
||||||
|
conf.registerGlobalValue(Raumstatus, 'target',
|
||||||
|
registry.String("switch2.raum.chaostreff-dortmund.de", """IP Address to ping."""))
|
||||||
|
conf.registerGlobalValue(Raumstatus, 'interval',
|
||||||
|
registry.Integer(30, """Checking interval."""))
|
||||||
|
conf.registerGlobalValue(Raumstatus, 'channel',
|
||||||
|
registry.String("#ccc.do", """Channel to set topic."""))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
# Stub so local is a module, used for third-party modules
|
|
@ -0,0 +1,100 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, xleave
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
from threading import Event, Thread
|
||||||
|
import subprocess
|
||||||
|
import supybot.utils as utils
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
import supybot.ircmsgs as ircmsgs
|
||||||
|
import re
|
||||||
|
|
||||||
|
raum_in_str = re.compile(".*(raum:|r:).*", re.I).match
|
||||||
|
raumstatus_is_open = re.compile("(raum: |r: )(auf|offen|open)", re.I).match
|
||||||
|
raumstatus_is_closed = re.compile("(raum: |r: )(zu|geschlossen|closed)", re.I).match
|
||||||
|
raumstatus_replace = re.compile("((raum: |r: ))[^ ]*", re.I).sub
|
||||||
|
|
||||||
|
class Raumstatus(callbacks.Plugin):
|
||||||
|
threaded = True
|
||||||
|
foo = "2"
|
||||||
|
def __init__(self, irc):
|
||||||
|
self.__parent = super(Raumstatus, self)
|
||||||
|
self.__parent.__init__(irc)
|
||||||
|
self.meinTimer = RepeatTimer(2, self.Bla, 0, [irc])
|
||||||
|
self.meinTimer.daemon = True
|
||||||
|
def start(self, irc, msg, args):
|
||||||
|
irc.reply("starting timer")
|
||||||
|
self.meinTimer.start()
|
||||||
|
irc.reply("MUST DESTROY UNIVERSE!!!")
|
||||||
|
start = wrap(start)
|
||||||
|
|
||||||
|
def stop(self, irc, msg, args):
|
||||||
|
irc.reply("stopping timer")
|
||||||
|
self.meinTimer.cancel()
|
||||||
|
irc.reply("FUCKED")
|
||||||
|
stop = wrap(stop)
|
||||||
|
|
||||||
|
def Bla(self, irc):
|
||||||
|
c = currentTopic = irc.state.getTopic(self.registryValue('channel'))
|
||||||
|
# import pdb;pdb.set_trace()
|
||||||
|
# c = currentTopic = irc.state.channels["#ccc.do"].topic
|
||||||
|
|
||||||
|
# raise Exception("%s %s %s %s"%("fuck you", type(c), dir(c), c))
|
||||||
|
# print "blabla %s " % self.registryValue('target')
|
||||||
|
ret = subprocess.call("ping -c6 -i .2 %s" % self.registryValue('target'),
|
||||||
|
shell=True,
|
||||||
|
stdout=open('/dev/null','w'),
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
x = raum_in_str(c)
|
||||||
|
if ret == 0:
|
||||||
|
if not x:
|
||||||
|
currentTopic = "Raum: auf | %s"%currentTopic
|
||||||
|
else:
|
||||||
|
if not raumstatus_is_open(currentTopic):
|
||||||
|
currentTopic = raumstatus_replace('\\1auf', currentTopic)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if not x:
|
||||||
|
currentTopic = "Raum: zu | %s"%currentTopic
|
||||||
|
else:
|
||||||
|
if not raumstatus_is_closed(currentTopic):
|
||||||
|
currentTopic = raumstatus_replace('\\1zu', currentTopic)
|
||||||
|
|
||||||
|
if c != currentTopic:
|
||||||
|
irc.queueMsg(ircmsgs.topic(self.registryValue('channel'), currentTopic[:159]))
|
||||||
|
# irc.sendMsg(ircmsgs.privmsg("#ccc.do", "reset topic"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RepeatTimer(Thread):
|
||||||
|
def __init__(self, interval, function, iterations=0, args=[], kwargs={}):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.interval = interval
|
||||||
|
self.function = function
|
||||||
|
self.iterations = iterations
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.finished = Event()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
count = 0
|
||||||
|
while not self.finished.isSet() and (self.iterations <= 0 or count < self.iterations):
|
||||||
|
self.finished.wait(self.interval)
|
||||||
|
if not self.finished.isSet():
|
||||||
|
self.function(*self.args, **self.kwargs)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.finished.set()
|
||||||
|
|
||||||
|
Class = Raumstatus
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2011, Fuck You
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
from supybot.test import *
|
||||||
|
|
||||||
|
class RaumstatusTestCase(PluginTestCase):
|
||||||
|
plugins = ('Raumstatus',)
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,58 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2005, Jeremiah Fincher
|
||||||
|
# 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.
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Includes various web-related commands.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import supybot
|
||||||
|
import supybot.world as world
|
||||||
|
|
||||||
|
__version__ = "%%VERSION%%"
|
||||||
|
|
||||||
|
__author__ = supybot.authors.jemfinch
|
||||||
|
|
||||||
|
# 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 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,61 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2005, Jeremiah Fincher
|
||||||
|
# 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
|
||||||
|
Web = conf.registerPlugin('Web', True)
|
||||||
|
if yn("""This plugin also offers a snarfer that will try to fetch the
|
||||||
|
title of URLs that it sees in the channel. Would like you this
|
||||||
|
snarfer to be enabled?""", default=False):
|
||||||
|
Web.titleSnarfer.setValue(True)
|
||||||
|
|
||||||
|
|
||||||
|
Web = conf.registerPlugin('Web')
|
||||||
|
conf.registerChannelValue(Web, 'titleSnarfer',
|
||||||
|
registry.Boolean(False, """Determines whether the bot will output the HTML
|
||||||
|
title of URLs it sees in the channel."""))
|
||||||
|
conf.registerChannelValue(Web, 'nonSnarfingRegexp',
|
||||||
|
registry.Regexp(None, """Determines what URLs are to be snarfed and stored
|
||||||
|
in the database in the channel; URLs matching the regexp given will not be
|
||||||
|
snarfed. Give the empty string if you have no URLs that you'd like to
|
||||||
|
exclude from being snarfed."""))
|
||||||
|
|
||||||
|
conf.registerGroup(Web, 'fetch')
|
||||||
|
conf.registerGlobalValue(Web.fetch, 'maximum',
|
||||||
|
registry.NonNegativeInteger(0, """Determines the maximum number of
|
||||||
|
bytes the bot will download via the 'fetch' command in this plugin."""))
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,244 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2005, Jeremiah Fincher
|
||||||
|
# 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 HTMLParser
|
||||||
|
import htmlentitydefs
|
||||||
|
|
||||||
|
import supybot.conf as conf
|
||||||
|
import supybot.utils as utils
|
||||||
|
from supybot.commands import *
|
||||||
|
import supybot.plugins as plugins
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.callbacks as callbacks
|
||||||
|
|
||||||
|
class Title(HTMLParser.HTMLParser):
|
||||||
|
entitydefs = htmlentitydefs.entitydefs.copy()
|
||||||
|
entitydefs['nbsp'] = ' '
|
||||||
|
entitydefs['apos'] = '\''
|
||||||
|
def __init__(self):
|
||||||
|
self.inTitle = False
|
||||||
|
self.title = ''
|
||||||
|
HTMLParser.HTMLParser.__init__(self)
|
||||||
|
|
||||||
|
def handle_starttag(self, tag, attrs):
|
||||||
|
if tag == 'title':
|
||||||
|
self.inTitle = True
|
||||||
|
|
||||||
|
def handle_endtag(self, tag):
|
||||||
|
if tag == 'title':
|
||||||
|
self.inTitle = False
|
||||||
|
|
||||||
|
def handle_data(self, data):
|
||||||
|
if self.inTitle:
|
||||||
|
self.title += data
|
||||||
|
|
||||||
|
def handle_entityref(self, name):
|
||||||
|
if self.inTitle:
|
||||||
|
if name in self.entitydefs:
|
||||||
|
self.title += self.entitydefs[name]
|
||||||
|
|
||||||
|
class Web(callbacks.PluginRegexp):
|
||||||
|
"""Add the help for "@help Web" here."""
|
||||||
|
threaded = True
|
||||||
|
regexps = ['titleSnarfer']
|
||||||
|
def callCommand(self, command, irc, msg, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
super(Web, self).callCommand(command, irc, msg, *args, **kwargs)
|
||||||
|
except utils.web.Error, e:
|
||||||
|
irc.reply(str(e))
|
||||||
|
|
||||||
|
def titleSnarfer(self, irc, msg, match):
|
||||||
|
r"https?://[^\])>\s]+"
|
||||||
|
channel = msg.args[0]
|
||||||
|
if not irc.isChannel(channel):
|
||||||
|
return
|
||||||
|
if callbacks.addressed(irc.nick, msg):
|
||||||
|
return
|
||||||
|
if self.registryValue('titleSnarfer', channel):
|
||||||
|
url = match.group(0)
|
||||||
|
r = self.registryValue('nonSnarfingRegexp', channel)
|
||||||
|
if r and r.search(url):
|
||||||
|
self.log.debug('Not titleSnarfing %q.', url)
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
size = conf.supybot.protocols.http.peekSize()
|
||||||
|
text = utils.web.getUrl(url, size=size)
|
||||||
|
except utils.web.Error, e:
|
||||||
|
self.log.info('Couldn\'t snarf title of %u: %s.', url, e)
|
||||||
|
return
|
||||||
|
parser = Title()
|
||||||
|
try:
|
||||||
|
parser.feed(text)
|
||||||
|
except HTMLParser.HTMLParseError:
|
||||||
|
self.log.debug('Encountered a problem parsing %u. Title may '
|
||||||
|
'already be set, though', url)
|
||||||
|
if parser.title:
|
||||||
|
domain = utils.web.getDomain(url)
|
||||||
|
title = utils.web.htmlToText(parser.title.strip())
|
||||||
|
s = format('Title: %s (at %s)', title, domain)
|
||||||
|
irc.reply(s, prefixNick=False)
|
||||||
|
titleSnarfer = urlSnarfer(titleSnarfer)
|
||||||
|
|
||||||
|
def headers(self, irc, msg, args, url):
|
||||||
|
"""<url>
|
||||||
|
|
||||||
|
Returns the HTTP headers of <url>. Only HTTP urls are valid, of
|
||||||
|
course.
|
||||||
|
"""
|
||||||
|
fd = utils.web.getUrlFd(url)
|
||||||
|
try:
|
||||||
|
s = ', '.join([format('%s: %s', k, v)
|
||||||
|
for (k, v) in fd.headers.items()])
|
||||||
|
irc.reply(s)
|
||||||
|
finally:
|
||||||
|
fd.close()
|
||||||
|
headers = wrap(headers, ['httpUrl'])
|
||||||
|
|
||||||
|
_doctypeRe = re.compile(r'(<!DOCTYPE[^>]+>)', re.M)
|
||||||
|
def doctype(self, irc, msg, args, url):
|
||||||
|
"""<url>
|
||||||
|
|
||||||
|
Returns the DOCTYPE string of <url>. Only HTTP urls are valid, of
|
||||||
|
course.
|
||||||
|
"""
|
||||||
|
size = conf.supybot.protocols.http.peekSize()
|
||||||
|
s = utils.web.getUrl(url, size=size)
|
||||||
|
m = self._doctypeRe.search(s)
|
||||||
|
if m:
|
||||||
|
s = utils.str.normalizeWhitespace(m.group(0))
|
||||||
|
irc.reply(s)
|
||||||
|
else:
|
||||||
|
irc.reply('That URL has no specified doctype.')
|
||||||
|
doctype = wrap(doctype, ['httpUrl'])
|
||||||
|
|
||||||
|
def size(self, irc, msg, args, url):
|
||||||
|
"""<url>
|
||||||
|
|
||||||
|
Returns the Content-Length header of <url>. Only HTTP urls are valid,
|
||||||
|
of course.
|
||||||
|
"""
|
||||||
|
fd = utils.web.getUrlFd(url)
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
size = fd.headers['Content-Length']
|
||||||
|
irc.reply(format('%u is %i bytes long.', url, size))
|
||||||
|
except KeyError:
|
||||||
|
size = conf.supybot.protocols.http.peekSize()
|
||||||
|
s = fd.read(size)
|
||||||
|
if len(s) != size:
|
||||||
|
irc.reply(format('%u is %i bytes long.', url, len(s)))
|
||||||
|
else:
|
||||||
|
irc.reply(format('The server didn\'t tell me how long %u '
|
||||||
|
'is but it\'s longer than %i bytes.',
|
||||||
|
url, size))
|
||||||
|
finally:
|
||||||
|
fd.close()
|
||||||
|
size = wrap(size, ['httpUrl'])
|
||||||
|
|
||||||
|
def title(self, irc, msg, args, url):
|
||||||
|
"""<url>
|
||||||
|
|
||||||
|
Returns the HTML <title>...</title> of a URL.
|
||||||
|
"""
|
||||||
|
size = conf.supybot.protocols.http.peekSize()
|
||||||
|
text = utils.web.getUrl(url, size=size)
|
||||||
|
parser = Title()
|
||||||
|
try:
|
||||||
|
parser.feed(text)
|
||||||
|
except HTMLParser.HTMLParseError:
|
||||||
|
self.log.debug('Encountered a problem parsing %u. Title may '
|
||||||
|
'already be set, though', url)
|
||||||
|
if parser.title:
|
||||||
|
irc.reply(utils.web.htmlToText(parser.title.strip()))
|
||||||
|
elif len(text) < size:
|
||||||
|
irc.reply('That URL appears to have no HTML title.')
|
||||||
|
else:
|
||||||
|
irc.reply(format('That URL appears to have no HTML title '
|
||||||
|
'within the first %i bytes.', size))
|
||||||
|
title = wrap(title, ['httpUrl'])
|
||||||
|
|
||||||
|
_netcraftre = re.compile(r'td align="left">\s+<a[^>]+>(.*?)<a href',
|
||||||
|
re.S | re.I)
|
||||||
|
def netcraft(self, irc, msg, args, hostname):
|
||||||
|
"""<hostname|ip>
|
||||||
|
|
||||||
|
Returns Netcraft.com's determination of what operating system and
|
||||||
|
webserver is running on the host given.
|
||||||
|
"""
|
||||||
|
url = 'http://uptime.netcraft.com/up/graph/?host=' + hostname
|
||||||
|
html = utils.web.getUrl(url)
|
||||||
|
m = self._netcraftre.search(html)
|
||||||
|
if m:
|
||||||
|
html = m.group(1)
|
||||||
|
s = utils.web.htmlToText(html, tagReplace='').strip()
|
||||||
|
s = s.rstrip('-').strip()
|
||||||
|
irc.reply(s) # Snip off "the site"
|
||||||
|
elif 'We could not get any results' in html:
|
||||||
|
irc.reply('No results found for %s.' % hostname)
|
||||||
|
else:
|
||||||
|
irc.error('The format of page the was odd.')
|
||||||
|
netcraft = wrap(netcraft, ['text'])
|
||||||
|
|
||||||
|
def urlquote(self, irc, msg, args, text):
|
||||||
|
"""<text>
|
||||||
|
|
||||||
|
Returns the URL quoted form of the text.
|
||||||
|
"""
|
||||||
|
irc.reply(utils.web.urlquote(text))
|
||||||
|
urlquote = wrap(urlquote, ['text'])
|
||||||
|
|
||||||
|
def urlunquote(self, irc, msg, args, text):
|
||||||
|
"""<text>
|
||||||
|
|
||||||
|
Returns the text un-URL quoted.
|
||||||
|
"""
|
||||||
|
s = utils.web.urlunquote(text)
|
||||||
|
irc.reply(s)
|
||||||
|
urlunquote = wrap(urlunquote, ['text'])
|
||||||
|
|
||||||
|
def fetch(self, irc, msg, args, url):
|
||||||
|
"""<url>
|
||||||
|
|
||||||
|
Returns the contents of <url>, or as much as is configured in
|
||||||
|
supybot.plugins.Web.fetch.maximum. If that configuration variable is
|
||||||
|
set to 0, this command will be effectively disabled.
|
||||||
|
"""
|
||||||
|
max = self.registryValue('fetch.maximum')
|
||||||
|
if not max:
|
||||||
|
irc.error('This command is disabled '
|
||||||
|
'(supybot.plugins.Web.fetch.maximum is set to 0).',
|
||||||
|
Raise=True)
|
||||||
|
fd = utils.web.getUrlFd(url)
|
||||||
|
irc.reply(fd.read(max))
|
||||||
|
fetch = wrap(fetch, ['url'])
|
||||||
|
|
||||||
|
Class = Web
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
Binary file not shown.
|
@ -0,0 +1,130 @@
|
||||||
|
###
|
||||||
|
# Copyright (c) 2005, Jeremiah Fincher
|
||||||
|
# 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 WebTestCase(ChannelPluginTestCase):
|
||||||
|
plugins = ('Web',)
|
||||||
|
timeout = 10
|
||||||
|
if network:
|
||||||
|
def testHeaders(self):
|
||||||
|
self.assertError('headers ftp://ftp.cdrom.com/pub/linux')
|
||||||
|
self.assertNotError('headers http://www.slashdot.org/')
|
||||||
|
|
||||||
|
def testDoctype(self):
|
||||||
|
self.assertError('doctype ftp://ftp.cdrom.com/pub/linux')
|
||||||
|
self.assertNotError('doctype http://www.slashdot.org/')
|
||||||
|
m = self.getMsg('doctype http://moobot.sf.net/')
|
||||||
|
self.failUnless(m.args[1].endswith('>'))
|
||||||
|
|
||||||
|
def testSize(self):
|
||||||
|
self.assertError('size ftp://ftp.cdrom.com/pub/linux')
|
||||||
|
self.assertNotError('size http://supybot.sf.net/')
|
||||||
|
self.assertNotError('size http://www.slashdot.org/')
|
||||||
|
|
||||||
|
def testTitle(self):
|
||||||
|
self.assertResponse('title http://www.slashdot.org/',
|
||||||
|
'Slashdot - News for nerds, stuff that matters')
|
||||||
|
# Amazon add a bunch of scripting stuff to the top of their page,
|
||||||
|
# so we need to allow for a larger peekSize
|
||||||
|
# Actually, screw Amazon. Even bumping this up to 10k doesn't give us enough
|
||||||
|
# info.
|
||||||
|
# try:
|
||||||
|
# orig = conf.supybot.protocols.http.peekSize()
|
||||||
|
# conf.supybot.protocols.http.peekSize.setValue(8192)
|
||||||
|
# self.assertNotRegexp('title '
|
||||||
|
# 'http://www.amazon.com/exec/obidos/tg/detail/-/'
|
||||||
|
# '1884822312/qid=1063140754/sr=8-1/ref=sr_8_1/'
|
||||||
|
# '002-9802970-2308826?v=glance&s=books&n=507846',
|
||||||
|
# 'no HTML title')
|
||||||
|
# finally:
|
||||||
|
# conf.supybot.protocols.http.peekSize.setValue(orig)
|
||||||
|
# Checks the non-greediness of the regexp
|
||||||
|
self.assertResponse('title '
|
||||||
|
'http://www.space.com/scienceastronomy/'
|
||||||
|
'jupiter_dark_spot_031023.html',
|
||||||
|
'SPACE.com -- Mystery Spot on Jupiter Baffles '
|
||||||
|
'Astronomers')
|
||||||
|
# Checks for @title not-working correctly
|
||||||
|
self.assertResponse('title '
|
||||||
|
'http://www.catb.org/~esr/jargon/html/F/foo.html',
|
||||||
|
'foo')
|
||||||
|
# Checks for only grabbing the real title tags instead of title
|
||||||
|
# tags inside, for example, script tags. Bug #1190350
|
||||||
|
self.assertNotRegexp('title '
|
||||||
|
'http://www.irinnews.org/report.asp?ReportID=45910&'
|
||||||
|
'SelectRegion=West_Africa&SelectCountry=CHAD',
|
||||||
|
r'document\.write\(')
|
||||||
|
# Checks that title parser grabs the full title instead of just
|
||||||
|
# part of it.
|
||||||
|
self.assertRegexp('title http://www.n-e-r-d.com/', 'N.*E.*R.*D')
|
||||||
|
# Checks that the parser doesn't hang on invalid tags
|
||||||
|
print
|
||||||
|
print "If we have not fixed a bug with the parser, the following",
|
||||||
|
print "test will hang the test-suite."
|
||||||
|
self.assertNotError(
|
||||||
|
'title http://www.youtube.com/watch?v=x4BtiqPN4u8')
|
||||||
|
|
||||||
|
def testNetcraft(self):
|
||||||
|
self.assertNotError('netcraft slashdot.org')
|
||||||
|
|
||||||
|
def testTitleSnarfer(self):
|
||||||
|
try:
|
||||||
|
conf.supybot.plugins.Web.titleSnarfer.setValue(True)
|
||||||
|
self.assertSnarfResponse('http://microsoft.com/',
|
||||||
|
'Title: Microsoft Corporation'
|
||||||
|
' (at microsoft.com)')
|
||||||
|
finally:
|
||||||
|
conf.supybot.plugins.Web.titleSnarfer.setValue(False)
|
||||||
|
|
||||||
|
def testNonSnarfing(self):
|
||||||
|
snarf = conf.supybot.plugins.Web.nonSnarfingRegexp()
|
||||||
|
title = conf.supybot.plugins.Web.titleSnarfer()
|
||||||
|
try:
|
||||||
|
conf.supybot.plugins.Web.nonSnarfingRegexp.set('m/sf/')
|
||||||
|
try:
|
||||||
|
conf.supybot.plugins.Web.titleSnarfer.setValue(True)
|
||||||
|
self.assertSnarfNoResponse('http://sf.net/', 2)
|
||||||
|
self.assertSnarfRegexp('http://www.sourceforge.net/',
|
||||||
|
r'Sourceforge\.net')
|
||||||
|
finally:
|
||||||
|
conf.supybot.plugins.Web.titleSnarfer.setValue(title)
|
||||||
|
finally:
|
||||||
|
conf.supybot.plugins.Web.nonSnarfingRegexp.setValue(snarf)
|
||||||
|
|
||||||
|
def testNonSnarfingRegexpConfigurable(self):
|
||||||
|
self.assertSnarfNoResponse('http://foo.bar.baz/', 2)
|
||||||
|
try:
|
||||||
|
conf.supybot.plugins.Web.nonSnarfingRegexp.set('m/biff/')
|
||||||
|
self.assertSnarfNoResponse('http://biff.bar.baz/', 2)
|
||||||
|
finally:
|
||||||
|
conf.supybot.plugins.Web.nonSnarfingRegexp.set('')
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue