From d66203e1ea40d3d6249920375d1347d7fce8e9eb Mon Sep 17 00:00:00 2001 From: Tim Windelschmidt Date: Fri, 23 Oct 2015 16:46:09 +0200 Subject: [PATCH] Initial Release --- plugins/Anonymous/README.txt | 1 + plugins/Anonymous/__init__.py | 61 ++ plugins/Anonymous/__init__.pyc | Bin 0 -> 581 bytes plugins/Anonymous/config.py | 63 ++ plugins/Anonymous/config.pyc | Bin 0 -> 1625 bytes plugins/Anonymous/plugin.py | 96 ++ plugins/Anonymous/plugin.pyc | Bin 0 -> 3319 bytes plugins/Anonymous/test.py | 56 ++ plugins/Flipdot/README.txt | 1 + plugins/Flipdot/__init__.py | 43 + plugins/Flipdot/__init__.pyc | Bin 0 -> 632 bytes plugins/Flipdot/config.py | 27 + plugins/Flipdot/config.pyc | Bin 0 -> 849 bytes plugins/Flipdot/plugin.py | 75 ++ plugins/Flipdot/plugin.pyc | Bin 0 -> 7884 bytes plugins/Gem/__init__.py | 41 + plugins/Gem/__init__.pyc | Bin 0 -> 576 bytes plugins/Gem/plugin.py | 35 + plugins/Gem/plugin.pyc | Bin 0 -> 1494 bytes plugins/Lampel/README.txt | 1 + plugins/Lampel/__init__.py | 43 + plugins/Lampel/__init__.pyc | Bin 0 -> 632 bytes plugins/Lampel/ampel.py | 2 + plugins/Lampel/ampel.pyc | Bin 0 -> 207 bytes plugins/Lampel/config.py | 27 + plugins/Lampel/config.pyc | Bin 0 -> 849 bytes plugins/Lampel/plugin.py | 171 ++++ plugins/Lampel/plugin.pyc | Bin 0 -> 7884 bytes plugins/Raumstatus/README.txt | 1 + plugins/Raumstatus/__init__.py | 43 + plugins/Raumstatus/__init__.pyc | Bin 0 -> 674 bytes plugins/Raumstatus/config.py | 34 + plugins/Raumstatus/config.pyc | Bin 0 -> 970 bytes plugins/Raumstatus/local/__init__.py | 1 + plugins/Raumstatus/plugin.py | 100 ++ plugins/Raumstatus/plugin.pyc | Bin 0 -> 3966 bytes plugins/Raumstatus/test.py | 14 + plugins/Web/__init__.py | 58 ++ plugins/Web/__init__.pyc | Bin 0 -> 566 bytes plugins/Web/config.py | 61 ++ plugins/Web/config.pyc | Bin 0 -> 1672 bytes plugins/Web/plugin.py | 244 +++++ plugins/Web/plugin.pyc | Bin 0 -> 8837 bytes plugins/Web/test.py | 130 +++ supifoo.conf | 1341 ++++++++++++++++++++++++++ 45 files changed, 2770 insertions(+) create mode 100644 plugins/Anonymous/README.txt create mode 100644 plugins/Anonymous/__init__.py create mode 100644 plugins/Anonymous/__init__.pyc create mode 100644 plugins/Anonymous/config.py create mode 100644 plugins/Anonymous/config.pyc create mode 100644 plugins/Anonymous/plugin.py create mode 100644 plugins/Anonymous/plugin.pyc create mode 100644 plugins/Anonymous/test.py create mode 100644 plugins/Flipdot/README.txt create mode 100644 plugins/Flipdot/__init__.py create mode 100644 plugins/Flipdot/__init__.pyc create mode 100644 plugins/Flipdot/config.py create mode 100644 plugins/Flipdot/config.pyc create mode 100644 plugins/Flipdot/plugin.py create mode 100644 plugins/Flipdot/plugin.pyc create mode 100644 plugins/Gem/__init__.py create mode 100644 plugins/Gem/__init__.pyc create mode 100644 plugins/Gem/plugin.py create mode 100644 plugins/Gem/plugin.pyc create mode 100644 plugins/Lampel/README.txt create mode 100644 plugins/Lampel/__init__.py create mode 100644 plugins/Lampel/__init__.pyc create mode 100644 plugins/Lampel/ampel.py create mode 100644 plugins/Lampel/ampel.pyc create mode 100644 plugins/Lampel/config.py create mode 100644 plugins/Lampel/config.pyc create mode 100644 plugins/Lampel/plugin.py create mode 100644 plugins/Lampel/plugin.pyc create mode 100644 plugins/Raumstatus/README.txt create mode 100644 plugins/Raumstatus/__init__.py create mode 100644 plugins/Raumstatus/__init__.pyc create mode 100644 plugins/Raumstatus/config.py create mode 100644 plugins/Raumstatus/config.pyc create mode 100644 plugins/Raumstatus/local/__init__.py create mode 100644 plugins/Raumstatus/plugin.py create mode 100644 plugins/Raumstatus/plugin.pyc create mode 100644 plugins/Raumstatus/test.py create mode 100644 plugins/Web/__init__.py create mode 100644 plugins/Web/__init__.pyc create mode 100644 plugins/Web/config.py create mode 100644 plugins/Web/config.pyc create mode 100644 plugins/Web/plugin.py create mode 100644 plugins/Web/plugin.pyc create mode 100644 plugins/Web/test.py create mode 100644 supifoo.conf diff --git a/plugins/Anonymous/README.txt b/plugins/Anonymous/README.txt new file mode 100644 index 0000000..d60b47a --- /dev/null +++ b/plugins/Anonymous/README.txt @@ -0,0 +1 @@ +Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/Anonymous/__init__.py b/plugins/Anonymous/__init__.py new file mode 100644 index 0000000..5e491b2 --- /dev/null +++ b/plugins/Anonymous/__init__.py @@ -0,0 +1,61 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +""" +Allows folks to talk through the bot anonymously. +""" + +import supybot +import supybot.world as world + +# Use this for the version of this plugin. You may wish to put a CVS keyword +# in here if you're keeping the plugin in CVS or some similar system. +__version__ = "%%VERSION%%" + +# XXX Replace this with an appropriate author or supybot.Author instance. +__author__ = supybot.authors.strike + +# This is a dictionary mapping supybot.Author instances to lists of +# contributions. +__contributors__ = {} + +import config +import plugin +reload(plugin) # In case we're being reloaded. +# Add more reloads here if you add third-party modules and want them to be +# reloaded when this plugin is reloaded. Don't forget to import them as well! + +if world.testing: + import test + +Class = plugin.Class +configure = config.configure + + +# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/Anonymous/__init__.pyc b/plugins/Anonymous/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2237eeb3e3c2eca0b6778518cfdee8b817b540f GIT binary patch literal 581 zcmYL_J#X7E5QdME;zWuackHOefG2C{(4`0x6dkf8MFVu;LP!>EQKm_QJT}#wDZjTr zpgGEROMow*`*_I%(?7F9H^0BH;j|Ju?`Zosk`{oIGH4Uf3^>7&6X;XmDYT>+NCy1{ z^b_EhpvZD{Zp(q^XD)yjAg@6d@XCP66#6MRe=g5}&%i(|_cy?AK<3cTfzRXH&&w>1 z^ogXn*V?}La%1(*muO3@^{&Lu*|6>Clx1VFtc^9p-UhFSRiXaUdi2-iUMzlo`|cu+U;ss@n6fY9umvmlPbMn;zJL^17q7R+g zNi4>;V}ZKjb3&}Gp=uM5nkgCEDYa4C5f3_Sl^M}VZR>WN38hD6wiy2)@;J&@U3-uD zKYws?Ndf#9|Cz$7vwK-JTCTgU4jXAISBHILhwAv2ukO!ZRSBVtLLpX%0k6pWWpCS{ b*^pr}KbAl5>KoO{ys&Xq1J+ZN;@kVQ}ySr}dLr>+x zDGwW|>zWG^)Kh_6wa&eHr{8^&^H?+(*5-I%xkN~p)j)T_h zz$}F05Yi5O0XXgg1~BVE8p0L9mb|&_xAq4K&+V40z zyudBrgIn>qbx8Y=4(`FNw*EFCU2Aca(&1>G(i1=F*-rved$dAYyR^(p5(J|BDD^ym z%K-8YTy`K2;WC803zuC8Y|p0_g7r)TD%RnsOGo#;U$0tMPP`~Fv37-2Ueq=d#nkr6 zFe=B!>X20ze)DaiiaJ-789BUt=x|k8Pn3;LD>PQ9!o;)*v7;Tkld&UiUF1X+Cw7Ar zjZH}F#Md9Ba=?X_K&4x&N#)|~gyIhS31YVdIq>VG;Ii5&NvW!e3(jLlKun{u_PI1xrSUnrF^(Ygwu0Cx_9+RCr|B`4L3mqzSu^64(q3dAT~m#HT{ZV@_3?{oBpIeqJFl;1FD4%-!79r2zU&@y8GmPve1>;hx^8+o;xWyx`r)bUh+Z=qS z79r1tl#3qO=7=YtPCRDI@Oq0SD$ltuw(C(@O{7SOeuU8uo43hqM~v;cL)23GxoO^U zF1$B45I&S=xEO|Z3XuH~$2YfZQein7!>2T8RyE|vuXYopO*9%(hIWladkx)G$L?O+ z2RC+`p6S}(uGWYLgou}&@I(KYw6?kPS^vakh4ckk`1kt!W_kUcQWAL)`|m+Bi_PW! zDAk0^#)0E=Xtn#axI6xVOM}<<_ + + Sends to . + """ + 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): + """ + + Performs in . + """ + 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: diff --git a/plugins/Anonymous/plugin.pyc b/plugins/Anonymous/plugin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2766507c4e418e8437f85762cbd2610e70e62ab6 GIT binary patch literal 3319 zcmcguZEqVz5T5f}5+@~nQ44_r%S(u$R+vl9`oZY>q zhr*}u3;HYgUHk=p06a5ywnIS(p$f~lw>z`*vNQ9{Uj4T#?PT!mFr?~N$NMupHpUR) z?@>ZD@u=s`mo=KysaKa}jgkf(SNobYX;H5=-?u`ORqCx$R42VklQkMbMT34Ox*&Se zYm;tMZ=Ee1b(*ji|Bl~5$HUa|aL27-{5;LlVw&Z4;bH^SFYwqS44Nv>dNtMrl71lpC8YAC2+WYLGb<%zaIYu2RRK?nK#6Tj3XG(`k@KY8*hi+CI}}n3*ZWmXfSD z&Qiq|)hK?dQx%SbG}XynY>Gq|%kS8r*jZ?;oXfy5YNoSUqS;3~)4|D$Uc$4ZI1P2B z3MUNVz(A{E5Sye>XF5q#Fu*~hyQ;`?HH}AOr_O>D2Zm1VMAGK70%z`);j!ICp1MY# z=CRTH!7LcWN$d(`GnJ)KT?X$gb{w*x)DteZu^-q1-XiR9_N&Y&{mhvFro-GoU+EU_ zu1qbpacI~IpXW}T-T_C?1IY721qKF85vL=`ViXx|?K1ux0QmRsj(7-JjZi*F_vbl+ zvmCQa&Q);^xLlUb89j=v(?&;XfBWioexK6qv5;7!K@NnhsbM-z1fX;zi z0q})K<`ETJ46BKt_Z(w`K>w*h-=99BhHKJEo6JMU7;O*WXm1rJYFgaH)DmE7edAb3Q65F?A%mOGa9?_OI{|57sc9Wb9T%yR3v zY=Qi3=`h=;JV((O-F0>B0_5#2ydUgLRgwXG*);wU1tbz(`v|OKz-m$N+-u;IiXCIT zLSw8!MEepGQEa7k%u7>cLrj+p%)6%1v)n&NSg0bpS|N*+_`+>AaIOs@xLASJtz&s9j_xYf{TI!Ppzd_M8i>SQSSKm_DH zwIexwWn3<=z8G6Xy%1v9few-qD3Fd_LIUuJa=GBPZTFzV73MRF zBpFFIk}SpPF!MRXQWvMW&h zBkR98U-3y^Mm~K`$9+7O%afWnkfy6hp5!^6-z@%z;QjyE`w~_cIZ=D%$H}Gq9hRRk zNMXg|X0#Bvl*G57sM^d|?>{Hfe;2#`_juq8`tS3wjX}U%TJm?W{<~E9oD@lu#O!6H z$l+U%qU>9YFC?k#3S5Exeu^&9FLB@RPqQdbc*$*}-;c7e-H|8@cFZugJm}`wANeR+Re50&DvVK!vtyM^Y1ok-#&Z(CvxuMr0kyMjCytkK>>fH~ literal 0 HcmV?d00001 diff --git a/plugins/Anonymous/test.py b/plugins/Anonymous/test.py new file mode 100644 index 0000000..e2a9ab0 --- /dev/null +++ b/plugins/Anonymous/test.py @@ -0,0 +1,56 @@ +### +# Copyright (c) 2005, Daniel DiPaolo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +from supybot.test import * + +class AnonymousTestCase(ChannelPluginTestCase): + plugins = ('Anonymous',) + def testSay(self): + m = self.assertError('anonymous say %s I love you!' % self.channel) + try: + orig = conf.supybot.plugins.Anonymous.requireRegistration() + conf.supybot.plugins.Anonymous.requireRegistration.setValue(False) + m = self.assertNotError('anonymous say %s foo!'%self.channel) + self.failUnless(m.args[1] == 'foo!') + finally: + conf.supybot.plugins.Anonymous.requireRegistration.setValue(orig) + + def testAction(self): + m = self.assertError('anonymous do %s loves you!' % self.channel) + try: + orig = conf.supybot.plugins.Anonymous.requireRegistration() + conf.supybot.plugins.Anonymous.requireRegistration.setValue(False) + m = self.assertNotError('anonymous do %s loves you!'%self.channel) + self.assertEqual(m.args, ircmsgs.action(self.channel, + 'loves you!').args) + finally: + conf.supybot.plugins.Anonymous.requireRegistration.setValue(orig) + + +# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/Flipdot/README.txt b/plugins/Flipdot/README.txt new file mode 100644 index 0000000..d60b47a --- /dev/null +++ b/plugins/Flipdot/README.txt @@ -0,0 +1 @@ +Insert a description of your plugin here, with any notes, etc. about using it. diff --git a/plugins/Flipdot/__init__.py b/plugins/Flipdot/__init__.py new file mode 100644 index 0000000..240b28a --- /dev/null +++ b/plugins/Flipdot/__init__.py @@ -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: diff --git a/plugins/Flipdot/__init__.pyc b/plugins/Flipdot/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d3f440956b593579ebe46efc94573f375c4b363 GIT binary patch literal 632 zcmYjNJ(JTg5M3v^wl-(^6v?9xJYndVYxuj@T?1>` z2WUob-+sK^mFAB-_Up&fry8a+Bm0i7?+GM8L70J@fzF^HGV&R;b13E@2^WAFv{%qB zp;&<;$#sgapNkn3?3r(%*Z^(;H}Erqj7+X<947dMxmlpkzso!)y2U-UXFA2hmKnQ7TArkkoyHqxW9mOYp?5)!>Tv23X zo22=M&eJ0%T^U1ToliZYxi_{qfu*`JLuJD}A!=)aQ&kL9J!yrAP7_~J0i{psF46H@ z5_PC;DHHuzo;%cOn-9A5KCJ($qQe6@@DKcJa`VQXF|Rb%O;g4bn%tG~T-i%LPVo8I qGZ#V`6@)l;mvBwOH)kuO#<#z_%G&t+PL_TA-Q$ literal 0 HcmV?d00001 diff --git a/plugins/Flipdot/config.py b/plugins/Flipdot/config.py new file mode 100644 index 0000000..a047c5c --- /dev/null +++ b/plugins/Flipdot/config.py @@ -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: diff --git a/plugins/Flipdot/config.pyc b/plugins/Flipdot/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c327502efa5688f96014f13174d64c55944ec4d GIT binary patch literal 849 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: + 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: diff --git a/plugins/Gem/plugin.pyc b/plugins/Gem/plugin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5eb886d8f8967c7279684803ba4f899e0a7c93b3 GIT binary patch literal 1494 zcmb_b+iuf95S_K1Yn>*o1QKuM1sQ~zA3zoNK2cRpC4^rr$KE7%eUo=x6sbI*@*(^n zPkaE(jO{eM0#0{2vzOU(=FFNuC*$PDnHxg;nfU)D4)q;Pgnt53fJ}fVATz)-K+voK zsR^FRJJ7cv>4Ded(1f%PSM8<&Bt!6q-M$edWAMgZcmRnFp528LNDjd}?7}H{Q-~~( zHY77x35a^|4d4#olXpZA7ET{Q#=r1$4D@sl&AS_!YfTGRn@R@Jg(GN*%ri~w&Skb^ zOQ&ArP|wjwAd(VEGB3Q!vxq-AJ&=8nJ-EX{^uS&4eIXsEL22LMP*2ckzU>x)8i3Yk zn;4Loa4RSQ6>!0*E*y&v5NuVKvT`Yrw$b>A()Y`tA~Hjo@Z&tzzTXg~V@jqgCKOkp zgE6pCbM)q$B9rrFD#Ohts8=$dS3#XEi|xEj>vf!~Ii_#@({k%lwT^Kp$_wIHgyayc z9kZ_(Ae#iBdPF=Dl%rvje+13!P?5+a)?X~R#mZT5Z9#S3?dIZ%{3);Xc`fYL23(hX z(#1oLoBM1kBKP9L86k=bHARaAPTtBO)bUNAWfYUXaYQCWqaL8Sl+{Xx`h>Q=+HLe` znKFDR_P@t!f^&atZN#A~*D~V-lBKF-nQpnmsvwVwOb>7ixpA%?Dw<0ZE~&=)WNNLc zoE|ja?_28c`--}Uk}9f2U-ZSu9N7**)^w}p2O8&V7Xxtlof1q{FUzV3 zrBa$i!KblZ7W%Z-ajF=2<8kJ8EiAGO6;PU#?GCif&iZuz{vmugO(uf33y$_Ogh84v zgYa50-ur0(7CeXwE54=m-2=?Q9dgOwl-(^6v?9xJYndVYxuj@T?1>` z2WUob-+sK^mFAB-_Up&fry8a+Bm0i7?+GM8L70J@fzF^HGV&R;b13E@2^WAFv{%qB zp;&<;$#sgapNkn3?3r(%*Z^(;H}Erqj7+X<947dMxmlpkzso!)y2U-UXFA2hmKnQ7TArkkoyHqxW9mOYp?5)!>Tv23X zo22=M&eJ0%T^U1ToliZYxi_{qfu*`JLuJD}A!=)aQ&kL9J!yrAP7_~J0i{psF46H@ z5_PC;DHHuzo;%cOn-9A5KCJ($qQe6@@DKcJa`VQXF|Rb%O;g4bn%tG~T-i%LPVo8I qGZ#V`6@)l;mvBwOH)kuO#<#z_%G&t+PL_TA-Q$ literal 0 HcmV?d00001 diff --git a/plugins/Lampel/ampel.py b/plugins/Lampel/ampel.py new file mode 100644 index 0000000..25acd60 --- /dev/null +++ b/plugins/Lampel/ampel.py @@ -0,0 +1,2 @@ +import telnetlib +connection = telnetlib.Telnet() diff --git a/plugins/Lampel/ampel.pyc b/plugins/Lampel/ampel.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a1e3f8bcbc84809201e8a58c04cc004ae672ca0 GIT binary patch literal 207 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 PyXVU!o6eJUI#2!pfrqH? literal 0 HcmV?d00001 diff --git a/plugins/Raumstatus/config.py b/plugins/Raumstatus/config.py new file mode 100644 index 0000000..4d006fb --- /dev/null +++ b/plugins/Raumstatus/config.py @@ -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: diff --git a/plugins/Raumstatus/config.pyc b/plugins/Raumstatus/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f950d6c33a855a6d4380b6120d8bcd8fde3e5298 GIT binary patch literal 970 zcmbtS&2G~`5T3P@G)Y?mR9sO+FTP+S4iypzfqFo_l*&OIa&vY!wuArJ9T$AaDZB#@ z$^*d68mmZfW96Bh*>86Cn;H8*PUkOQJbN$U_nOfDhQxj+rRWn-0PF;;#o&6d^I`3S z^57f5dIVa)ZVbwY1BFeTdjxs{iXb0$Q&5CX;NZc*2f@)jOq$>sD2kZ<4bO+$$DmFI znE0%MQ{tBYq;)L?nPU>4+G4R+oY0O z{VP>KLEw~YMU)ZIXj5pJWl6i$Rb+_drtYG~Ww+5C>4+KRY1nkG#NKO-KBkP88N&F9 zh}m$h!NjB*?Kz`ga+KNgkaLGJOKOWoZ?{iXZLn-B6)J7dDDLWJ`Bo{TtzBZhY^a%` zD~PJp<~Awv$DHgTsmn~uPlPWAD5ObIkFunybYa;(mr{nRwvSx6JLjxcBW+DC!+>Xk zC!~fUa7i(b74QFX+V|UZj>_P~ZlL^5Uoq1k2J^0{H%aj^DO&A1u|mWD1qWYIC8;)d gQ~2*uOeyQDvQ}-OU$gDnvk(h!Hd}Zn;!O1N3m{$JJOBUy literal 0 HcmV?d00001 diff --git a/plugins/Raumstatus/local/__init__.py b/plugins/Raumstatus/local/__init__.py new file mode 100644 index 0000000..e86e97b --- /dev/null +++ b/plugins/Raumstatus/local/__init__.py @@ -0,0 +1 @@ +# Stub so local is a module, used for third-party modules diff --git a/plugins/Raumstatus/plugin.py b/plugins/Raumstatus/plugin.py new file mode 100644 index 0000000..eccc096 --- /dev/null +++ b/plugins/Raumstatus/plugin.py @@ -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: diff --git a/plugins/Raumstatus/plugin.pyc b/plugins/Raumstatus/plugin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c912defb1e3753951113860da24f25c4a5370b55 GIT binary patch literal 3966 zcmb_f>uwvz6+TN+lqgY_Bgd+h8V;RHL8*xZC#?;*MG@Fmfn2NvE80QWG{kCmL@u@5 zrFUlS$e@rP_V2zze&rqVBzciOK>K}XMUi%XS|VpS=gjR~zcZ@-cXj#OpY6j?&i<6|TEl;M(em!|6) zGF+DK@|0YWVN<%zDY+`cOVYhGCD)|8CT2~BmnEv{;4OJkk>R>@uT1$1ukzoX^6Rhi zuTJ@kbNmhI{z0N8F-;j>lOs=}hP)JcA@W^!Q=(-t73Hp+bKeoODcwI({eyNBR*L_J zzjg&9w}5W%sY#uyW7HYsCW!XiFrqki+x8Oro$YoW6r;P7{O;Dyw!IEk$!LMo+G+>I z(Ih)MGU+56n{>;*|N4UG#iVa+I7l*Uu`0x`iMH$&uA4t;>t8>#{=My%!S`{Yb%87F zxsxgIJv93bIwSNgbS>T4tGTAat_b>`_Cq+fDie?Ac}``(9HI&`fZNAJO;^{&EpjldOHbqK zpk2ku`!Vl{(WKo#r~a_T*yKK^9WB(GnWEPl2RWU!M1C($W7q4s6%f7|o4|GAk;xr* z-b(_<14kxKOKuHRCohaTItt7vOUn@8gf+>L?u+xV4O+Cbw=vosWFxbCn3!-dfTK;i z%UC$fPIkvh(T`KRJCpB>wKG2P7qN8{%~DkH*1gN#4KL(fY}8sU`)3SbsG+7TjYu1T zt}vjzvl$SWi3H(G-S#yo5gfUT(|*fQX?qP54<8+LS`YRPI{w$+wI1z%{&>$n*t>c2 zrtVVH=4PCn_>8a8(mbP0f&5i=40bic$oAn)ks$Bei?PRLoOT1vGS9?Y#phzJk&Vaa z)=(e+^U?h;_a3P3{u=Hq)#mkKkcK9CO>h4#u31NSAquPctjoq9;KX^Q>3RymxX=(- z1JIO?hU4k}3R4*#$G3J`k<%)DGDLDsQx3U|xea75ycjJA)Q#|6WNHE#xf)}ydWr>0 zGSTokU62WmXvlFz@?T`KAoeBEa#EEI-0%!4_kH{fd%$KW5Wgy60Dkn$tb$ z4MFa`vS)R+CxuoJxGKk0$yYR#o8q)s%qxin(Isg?a@_1;lZH9{wGYIAuLePyn#9sO z>fn#V+pUk|*3Kub53TwcG2AzB=1c#H z-SHZmSssMOz5Tn@W#v&ZpA@Dr50U4zGGGrWZ&ee-Y#g>3qH~}?(}j-3Gc0mKaH%5U zD2MSm{o{q?jZc?tquKY+iT7@O)2n-HUQ<7HZ?)3&u2#$6b&T5zW=y7DFAYWp^?;mS zZLDSJk0S-D@l~ zYRw9pPsu_w{bO+5L$e>DD@#1`p|2&9^&PJ_qP-GL zNR&7#($K|Os@{k(5sF zCT?NeKSWaiU`1-2e?lro`<=glUV?xFPCfbY8I3Vid%`fy{3oRqw2uLvcL?TOQITUL zM>z{pEesS_2h1G+jN)oFH(o~^FUo();tx;X!Ie)M{CkPP1E^z&}r_* z_P{u`RvFSk?EIM(X9lEhn%%l9%!<@qh*34Q@*;hV^DWUr5bU?SD@foCPpwL!+3uq$ zsLva-eB*F>U*Be>VpT3RPG99J^o5A(6CHox(KLp5`T+KKF!XoXF+BXgvE#zol{$Kp zxLd+;U!m!vpzf_V8cXf#p!L04ViX=Sniyq*y~{}!6FiJh4l}n?xHu`Xx*QQ#rgLF7 z8U<-&9V^q6dG=COsGpAKHv#_3lPKFc!IC>Yfo1A22#>8wIiu!pIV&PQE#zoaR0diR zB8}t3Xp#6_18x+!aNxg>IsXH8e?q6BgW~9aNP+?A(*|O}(Me h^Y^k={DZ<;K2kSOY}UMGwDQxeT=Vo(*}T1R_5Zg;C;I>Z literal 0 HcmV?d00001 diff --git a/plugins/Raumstatus/test.py b/plugins/Raumstatus/test.py new file mode 100644 index 0000000..2845cb1 --- /dev/null +++ b/plugins/Raumstatus/test.py @@ -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: diff --git a/plugins/Web/__init__.py b/plugins/Web/__init__.py new file mode 100644 index 0000000..68e4db1 --- /dev/null +++ b/plugins/Web/__init__.py @@ -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: diff --git a/plugins/Web/__init__.pyc b/plugins/Web/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f873ac0e67e2c6bef788bec52cf8d1efd4be0c0f GIT binary patch literal 566 zcmYL_y-ve05XUcRDI~O%k+DmqE;M3C2!R;7fCLgqUaTa(HjWaz@&~933ls0f8}R^e zPFt{)zkm1TyG!qTl)m45J(jRLG2Pen*-sJyz(^wyF*Fe{f-T2T_ki_4koEy1s1KkX z06PRpB}eL1tFz7PF$kvZ`{wM3tG`w}swh+g>(%!6M^aD(N_%uQ%Nem#r4Q!K(?qV9!Vf S@h}?4r2Rm{DD5X?C($oPFN9wJ literal 0 HcmV?d00001 diff --git a/plugins/Web/config.py b/plugins/Web/config.py new file mode 100644 index 0000000..2ce3e3b --- /dev/null +++ b/plugins/Web/config.py @@ -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: diff --git a/plugins/Web/config.pyc b/plugins/Web/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..512756aca292415f0adaee803bfb948f68185393 GIT binary patch literal 1672 zcmbVM-EQMV6h31o-A%ULEDKj$pn;p_s(Anqpk2g*v{c9~thN#tllUZduxEm2+}6^D zoANYByajK=B@Y1K95*Fh!3|bCo-^nFeBUJf^Jx6@v){7?-988Seva4wiY3QSQAM;? zbfI=)LhF<+Qpywhh3H~HtY|%?Jf$0$9fNNG;nTy&1$7PEQH|!=k`3kM;f&%1|-f^>^7z-+ProduFc@8|HdZ z7;CvY(fXBZt6W#*kE}b_LRtFz!S0efJ!j3<%qz}6!w}FvFHKv8=_BmJJ6L?X>EpAM{QaQwOJf(D|69r|rkvvK7eB*pRsf6{npqTuX_stgjcMz->t;O$eg zvCeXJvgriBUTPcu5CQx+1{{8*o~ksND9MqDge5`#~Rb=5p-?X zv_Zi5>inCRGV}Ym{Rd<+XzQ#@1H{UB1-kh^-p&cC2>hnuNEKk$BbjSsbM1p`IG3!q zl*mmmbL06fihSHhsSTKhY*H{VLrT3WFWL6pShO|oS$LZT)OrEE*mJ!J9a1(iK)Dp6 z6$VP{_9zPa9p5rBIH`=U7gd|HUN){q_~^ZhF8mPs3lnQ|UDj<~VhH4m`=f|_ztw9C zgn@)xO8j{j08iB4!IHZxTRD^K%hHJESdtv;g{$j0IGNVnMLn55K{BD}j{A`#S-c$~ zs&=P6&6`fBx)ZW^0kZfnA>;|~Vb|-pdEVbpA-S~p%(;q<%_8gMPbL!-\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): + """ + + Returns the HTTP headers of . 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'(]+>)', re.M) + def doctype(self, irc, msg, args, url): + """ + + Returns the DOCTYPE string of . 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): + """ + + Returns the Content-Length header of . 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): + """ + + Returns the HTML ... 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+]+>(.*?) + + 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): + """ + + 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): + """ + + 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): + """ + + Returns the contents of , 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: diff --git a/plugins/Web/plugin.pyc b/plugins/Web/plugin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38d94ba1bcb9f2284f34e393f9ac0c8c5ef1f1da GIT binary patch literal 8837 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 w$')) + + 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: diff --git a/supifoo.conf b/supifoo.conf new file mode 100644 index 0000000..08a0672 --- /dev/null +++ b/supifoo.conf @@ -0,0 +1,1341 @@ +### +# Determines the bot's default nick. +# +# Default value: supybot +### +supybot.nick: raumgirl + +### +# Determines what alternative nicks will be used if the primary nick +# (supybot.nick) isn't available. A %s in this nick is replaced by the +# value of supybot.nick when used. If no alternates are given, or if all +# are used, the supybot.nick will be perturbed appropriately until an +# unused nick is found. +# +# Default value: %s` %s_ +### +supybot.nick.alternates: %s` %s_ + +### +# Determines the bot's ident string, if the server doesn't provide one +# by default. +# +# Default value: supybot +### +supybot.ident: raumgirl + +### +# Determines the user the bot sends to the server. A standard user using +# the current version of the bot will be generated if this is left +# empty. +# +# Default value: +### +supybot.user: + +### +# Determines what networks the bot will connect to. +# +# Default value: +### +supybot.networks: hackint + +### +# Determines what password will be used on hackint. Yes, we know that +# technically passwords are server-specific and not network-specific, +# but this is the best we can do right now. +# +# Default value: +### +supybot.networks.hackint.password: + +### +# Determines what servers the bot will connect to for hackint. Each will +# be tried in order, wrapping back to the first when the cycle is +# completed. +# +# Default value: +### +supybot.networks.hackint.servers: 195.160.168.7:9999 + +### +# Determines what channels the bot will join only on hackint. +# +# Default value: +### +supybot.networks.hackint.channels: #ctdo + +### +# Determines what key (if any) will be used to join the channel. +# +# Default value: +### +supybot.networks.hackint.channels.key: + +### +# Determines whether the bot will attempt to connect with SSL sockets to +# hackint. +# +# Default value: False +### +supybot.networks.hackint.ssl: True + +### +# Determines how timestamps printed for human reading should be +# formatted. Refer to the Python documentation for the time module to +# see valid formatting characters for time formats. +# +# Default value: %I:%M %p, %B %d, %Y +### +supybot.reply.format.time: %I:%M %p, %B %d, %Y + +### +# Determines whether elapsed times will be given as "1 day, 2 hours, 3 +# minutes, and 15 seconds" or as "1d 2h 3m 15s". +# +# Default value: False +### +supybot.reply.format.time.elapsed.short: False + +### +# Determines the absolute maximum length of the bot's reply -- no reply +# will be passed through the bot with a length greater than this. +# +# Default value: 131072 +### +supybot.reply.maximumLength: 131072 + +### +# Determines whether the bot will break up long messages into chunks and +# allow users to use the 'more' command to get the remaining chunks. +# +# Default value: True +### +supybot.reply.mores: True + +### +# Determines what the maximum number of chunks (for use with the 'more' +# command) will be. +# +# Default value: 50 +### +supybot.reply.mores.maximum: 50 + +### +# Determines how long individual chunks will be. If set to 0, uses our +# super-tweaked, get-the-most-out-of-an-individual-message default. +# +# Default value: 0 +### +supybot.reply.mores.length: 0 + +### +# Determines how many mores will be sent instantly (i.e., without the +# use of the more command, immediately when they are formed). Defaults +# to 1, which means that a more command will be required for all but the +# first chunk. +# +# Default value: 1 +### +supybot.reply.mores.instant: 1 + +### +# Determines whether the bot will send multi-message replies in a single +# message or in multiple messages. For safety purposes (so the bot is +# less likely to flood) it will normally send everything in a single +# message, using mores if necessary. +# +# Default value: True +### +supybot.reply.oneToOne: True + +### +# Determines whether the bot will reply with an error message when it is +# addressed but not given a valid command. If this value is False, the +# bot will remain silent, as long as no other plugins override the +# normal behavior. +# +# Default value: True +### +supybot.reply.whenNotCommand: False + +### +# Determines whether error messages that result from bugs in the bot +# will show a detailed error message (the uncaught exception) or a +# generic error message. +# +# Default value: False +### +supybot.reply.error.detailed: False + +### +# Determines whether the bot will send error messages to users in +# private. You might want to do this in order to keep channel traffic to +# minimum. This can be used in combination with +# supybot.reply.error.withNotice. +# +# Default value: False +### +supybot.reply.error.inPrivate: False + +### +# Determines whether the bot will send error messages to users via +# NOTICE instead of PRIVMSG. You might want to do this so users can +# ignore NOTICEs from the bot and not have to see error messages; or you +# might want to use it in combination with supybot.reply.errorInPrivate +# so private errors don't open a query window in most IRC clients. +# +# Default value: False +### +supybot.reply.error.withNotice: False + +### +# Determines whether the bot will send an error message to users who +# attempt to call a command for which they do not have the necessary +# capability. You may wish to make this True if you don't want users to +# understand the underlying security system preventing them from running +# certain commands. +# +# Default value: False +### +supybot.reply.error.noCapability: False + +### +# Determines whether the bot will reply privately when replying in a +# channel, rather than replying to the whole channel. +# +# Default value: False +### +supybot.reply.inPrivate: False + +### +# Determines whether the bot will reply with a notice when replying in a +# channel, rather than replying with a privmsg as normal. +# +# Default value: False +### +supybot.reply.withNotice: False + +### +# Determines whether the bot will reply with a notice when it is sending +# a private message, in order not to open a /query window in clients. +# This can be overridden by individual users via the user configuration +# variable reply.withNoticeWhenPrivate. +# +# Default value: False +### +supybot.reply.withNoticeWhenPrivate: False + +### +# Determines whether the bot will always prefix the user's nick to its +# reply to that user's command. +# +# Default value: True +### +supybot.reply.withNickPrefix: True + +### +# Determines whether the bot should attempt to reply to all messages +# even if they don't address it (either via its nick or a prefix +# character). If you set this to True, you almost certainly want to set +# supybot.reply.whenNotCommand to False. +# +# Default value: False +### +supybot.reply.whenNotAddressed: False + +### +# Determines whether the bot will allow you to send channel-related +# commands outside of that channel. Sometimes people find it confusing +# if a channel-related command (like Filter.outfilter) changes the +# behavior of the channel but was sent outside the channel itself. +# +# Default value: False +### +supybot.reply.requireChannelCommandsToBeSentInChannel: False + +### +# Supybot normally replies with the full help whenever a user misuses a +# command. If this value is set to True, the bot will only reply with +# the syntax of the command (the first line of the help) rather than the +# full help. +# +# Default value: False +### +supybot.reply.showSimpleSyntax: False + +### +# Determines what prefix characters the bot will reply to. A prefix +# character is a single character that the bot will use to determine +# what messages are addressed to it; when there are no prefix characters +# set, it just uses its nick. Each character in this string is +# interpreted individually; you can have multiple prefix chars +# simultaneously, and if any one of them is used as a prefix the bot +# will assume it is being addressed. +# +# Default value: +### +supybot.reply.whenAddressedBy.chars: + +### +# Determines what strings the bot will reply to when they are at the +# beginning of the message. Whereas prefix.chars can only be one +# character (although there can be many of them), this variable is a +# space-separated list of strings, so you can set something like '@@ ??' +# and the bot will reply when a message is prefixed by either @@ or ??. +# +# Default value: +### +supybot.reply.whenAddressedBy.strings: + +### +# Determines whether the bot will reply when people address it by its +# nick, rather than with a prefix character. +# +# Default value: True +### +supybot.reply.whenAddressedBy.nick: True + +### +# Determines whether the bot will reply when people address it by its +# nick at the end of the message, rather than at the beginning. +# +# Default value: False +### +supybot.reply.whenAddressedBy.nick.atEnd: False + +### +# Determines what extra nicks the bot will always respond to when +# addressed by, even if its current nick is something else. +# +# Default value: +### +supybot.reply.whenAddressedBy.nicks: + +### +# Determines whether the bot will unidentify someone when that person +# changes his or her nick. Setting this to True will cause the bot to +# track such changes. It defaults to False for a little greater +# security. +# +# Default value: False +### +supybot.followIdentificationThroughNickChanges: False + +### +# Determines whether the bot will always join a channel when it's +# invited. If this value is False, the bot will only join a channel if +# the user inviting it has the 'admin' capability (or if it's explicitly +# told to join the channel using the Admin.join command) +# +# Default value: False +### +supybot.alwaysJoinOnInvite: False + +### +# Determines what message the bot replies with when a command succeeded. +# If this configuration variable is empty, no success message will be +# sent. +### +supybot.replies.success: The operation succeeded. + +### +# Determines what error message the bot gives when it wants to be +# ambiguous. +### +supybot.replies.error: An error has occurred and has been logged. Please\ + contact this bot's administrator for more\ + information. + +### +# Determines what message the bot replies with when someone tries to use +# a command that requires being identified or having a password and +# neither credential is correct. +### +supybot.replies.incorrectAuthentication: Your hostmask doesn't match or your\ + password is wrong. + +### +# Determines what error message the bot replies with when someone tries +# to accessing some information on a user the bot doesn't know about. +### +supybot.replies.noUser: I can't find %s in my user database. If you didn't\ + give a user name, then I might not know what your\ + user is, and you'll need to identify before this\ + command might work. + +### +# Determines what error message the bot replies with when someone tries +# to do something that requires them to be registered but they're not +# currently recognized. +### +supybot.replies.notRegistered: You must be registered to use this command.\ + If you are already registered, you must\ + either identify (using the identify command)\ + or add a hostmask matching your current\ + hostmask (using the "hostmask add" command). + +### +# Determines what error message is given when the bot is telling someone +# they aren't cool enough to use the command they tried to use. +### +supybot.replies.noCapability: You don't have the %s capability. If you think\ + that you should have this capability, be sure\ + that you are identified before trying again.\ + The 'whoami' command can tell you if you're\ + identified. + +### +# Determines what generic error message is given when the bot is telling +# someone that they aren't cool enough to use the command they tried to +# use, and the author of the code calling errorNoCapability didn't +# provide an explicit capability for whatever reason. +### +supybot.replies.genericNoCapability: You're missing some capability you\ + need. This could be because you\ + actually possess the anti-capability\ + for the capability that's required of\ + you, or because the channel provides\ + that anti-capability by default, or\ + because the global capabilities include\ + that anti-capability. Or, it could be\ + because the channel or\ + supybot.capabilities.default is set to\ + False, meaning that no commands are\ + allowed unless explicitly in your\ + capabilities. Either way, you can't do\ + what you want to do. + +### +# Determines what error messages the bot sends to people who try to do +# things in a channel that really should be done in private. +### +supybot.replies.requiresPrivacy: That operation cannot be done in a channel. + +### +# Determines what message the bot sends when it thinks you've +# encountered a bug that the developers don't know about. +### +supybot.replies.possibleBug: This may be a bug. If you think it is, please\ + file a bug report at . + +### +# A floating point number of seconds to throttle snarfed URLs, in order +# to prevent loops between two bots snarfing the same URLs and having +# the snarfed URL in the output of the snarf message. +# +# Default value: 10.0 +### +supybot.snarfThrottle: 10.0 + +### +# Determines the number of seconds between running the upkeep function +# that flushes (commits) open databases, collects garbage, and records +# some useful statistics at the debugging level. +# +# Default value: 3600 +### +supybot.upkeepInterval: 3600 + +### +# Determines whether the bot will periodically flush data and +# configuration files to disk. Generally, the only time you'll want to +# set this to False is when you want to modify those configuration files +# by hand and don't want the bot to flush its current version over your +# modifications. Do note that if you change this to False inside the +# bot, your changes won't be flushed. To make this change permanent, you +# must edit the registry yourself. +# +# Default value: True +### +supybot.flush: True + +### +# Determines what characters are valid for quoting arguments to commands +# in order to prevent them from being tokenized. +# +# Default value: " +### +supybot.commands.quotes: " + +### +# Determines whether the bot will allow nested commands, which rule. You +# definitely should keep this on. +# +# Default value: True +### +supybot.commands.nested: True + +### +# Determines what the maximum number of nested commands will be; users +# will receive an error if they attempt commands more nested than this. +# +# Default value: 10 +### +supybot.commands.nested.maximum: 10 + +### +# Supybot allows you to specify what brackets are used for your nested +# commands. Valid sets of brackets include [], <>, and {} (). [] has +# strong historical motivation, as well as being the brackets that don't +# require shift. <> or () might be slightly superior because they cannot +# occur in a nick. If this string is empty, nested commands will not be +# allowed in this channel. +# +# Default value: [] +### +supybot.commands.nested.brackets: [] + +### +# Supybot allows nested commands. Enabling this option will allow nested +# commands with a syntax similar to UNIX pipes, for example: 'bot: foo | +# bar'. +# +# Default value: False +### +supybot.commands.nested.pipeSyntax: False + +### +# Determines what commands have default plugins set, and which plugins +# are set to be the default for each of those commands. +### +supybot.commands.defaultPlugins.addcapability: Admin +supybot.commands.defaultPlugins.capabilities: User +supybot.commands.defaultPlugins.disable: Owner +supybot.commands.defaultPlugins.enable: Owner +supybot.commands.defaultPlugins.help: Misc +supybot.commands.defaultPlugins.ignore: Admin + +### +# Determines what plugins automatically get precedence over all other +# plugins when selecting a default plugin for a command. By default, +# this includes the standard loaded plugins. You probably shouldn't +# change this if you don't know what you're doing; if you do know what +# you're doing, then also know that this set is case-sensitive. +# +# Default value: Plugin Admin Misc User Owner Config Channel +### +supybot.commands.defaultPlugins.importantPlugins: Plugin Admin Misc User Owner Config Channel +supybot.commands.defaultPlugins.list: Misc +supybot.commands.defaultPlugins.reload: Owner +supybot.commands.defaultPlugins.removecapability: Admin +supybot.commands.defaultPlugins.unignore: Admin + +### +# Determines what commands are currently disabled. Such commands will +# not appear in command lists, etc. They will appear not even to exist. +# +# Default value: +### +supybot.commands.disabled: + +### +# Determines whether the bot will defend itself against command- +# flooding. +# +# Default value: True +### +supybot.abuse.flood.command: True + +### +# Determines how many commands users are allowed per minute. If a user +# sends more than this many commands in any 60 second period, he or she +# will be ignored for supybot.abuse.flood.command.punishment seconds. +# +# Default value: 12 +### +supybot.abuse.flood.command.maximum: 500 + +### +# Determines how many seconds the bot will ignore users who flood it +# with commands. +# +# Default value: 300 +### +supybot.abuse.flood.command.punishment: 300 + +### +# Determines whether the bot will defend itself against invalid command- +# flooding. +# +# Default value: True +### +supybot.abuse.flood.command.invalid: True + +### +# Determines how many invalid commands users are allowed per minute. If +# a user sends more than this many invalid commands in any 60 second +# period, he or she will be ignored for +# supybot.abuse.flood.command.invalid.punishment seconds. Typically, +# this value is lower than supybot.abuse.flood.command.maximum, since +# it's far less likely (and far more annoying) for users to flood with +# invalid commands than for them to flood with valid commands. +# +# Default value: 5 +### +supybot.abuse.flood.command.invalid.maximum: 5 + +### +# Determines how many seconds the bot will ignore users who flood it +# with invalid commands. Typically, this value is higher than +# supybot.abuse.flood.command.punishment, since it's far less likely +# (and far more annoying) for users to flood witih invalid commands than +# for them to flood with valid commands. +# +# Default value: 600 +### +supybot.abuse.flood.command.invalid.punishment: 30 + +### +# Determines the default length of time a driver should block waiting +# for input. +# +# Default value: 1.0 +### +supybot.drivers.poll: 1.0 + +### +# Determines what driver module the bot will use. Socket, a simple +# driver based on timeout sockets, is used by default because it's +# simple and stable. Twisted is very stable and simple, and if you've +# got Twisted installed, is probably your best bet. +# +# Default value: default +### +supybot.drivers.module: Twisted + +### +# Determines the maximum time the bot will wait before attempting to +# reconnect to an IRC server. The bot may, of course, reconnect earlier +# if possible. +# +# Default value: 300.0 +### +supybot.drivers.maxReconnectWait: 300.0 + +### +# Determines what directory configuration data is put into. +# +# Default value: conf +### +supybot.directories.conf: /home/blechhaufen/raumgirl/conf + +### +# Determines what directory data is put into. +# +# Default value: data +### +supybot.directories.data: /home/blechhaufen/raumgirl/data + +### +# Determines what directory temporary files are put into. +# +# Default value: tmp +### +supybot.directories.data.tmp: /home/blechhaufen/raumgirl/data/tmp + +### +# Determines what directory backup data is put into. +# +# Default value: backup +### +supybot.directories.backup: /home/blechhaufen/raumgirl/backup + +### +# Determines what directories the bot will look for plugins in. Accepts +# a comma-separated list of strings. This means that to add another +# directory, you can nest the former value and add a new one. E.g. you +# can say: bot: 'config supybot.directories.plugins [config +# supybot.directories.plugins], newPluginDirectory'. +# +# Default value: +### +supybot.directories.plugins: /home/blechhaufen/raumgirl/plugins + +### +# Determines what directory the bot will store its logfiles in. +# +# Default value: logs +### +supybot.directories.log: /home/blechhaufen/raumgirl/logs + +### +# Determines what plugins will be loaded. +# +# Default value: +### +supybot.plugins: Web Admin Misc Raumstatus Channel User Anonymous Owner Lampel Config Gem lampel + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Admin: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Admin.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Anonymous: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Anonymous.public: True + +### +# Determines whether the bot should require people trying to use this +# plugin to be in the channel they wish to anonymously send to. +# +# Default value: True +### +supybot.plugins.Anonymous.requirePresenceInChannel: False + +### +# Determines whether the bot should require people trying to use this +# plugin to be registered. +# +# Default value: True +### +supybot.plugins.Anonymous.requireRegistration: True + +### +# Determines what capability (if any) the bot should require people +# trying to use this plugin to have. +# +# Default value: +### +supybot.plugins.Anonymous.requireCapability: + +### +# 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. +# +# Default value: False +### +supybot.plugins.Anonymous.allowPrivateTarget: False + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Channel: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Channel.public: True + +### +# Determines whether the bot will always try to rejoin a channel +# whenever it's kicked from the channel. +# +# Default value: True +### +supybot.plugins.Channel.alwaysRejoin: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Config: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Config.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Gem: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Gem.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Lampel: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Lampel.public: True + +### +# Host of Lampel +# +# Default value: lampel.raum.ctdo.de +### +supybot.plugins.Lampel.host: lampel.raum.ctdo.de + +### +# Port number of Lampel +# +# Default value: 2701 +### +supybot.plugins.Lampel.port: 2701 + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Misc: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Misc.public: True + +### +# Determines whether the bot will list private plugins with the list +# command if given the --private switch. If this is disabled, non-owner +# users should be unable to see what private plugins are loaded. +# +# Default value: True +### +supybot.plugins.Misc.listPrivatePlugins: True + +### +# Determines the format string for timestamps in the Misc.last command. +# Refer to the Python documentation for the time module to see what +# formats are accepted. If you set this variable to the empty string, +# the timestamp will not be shown. +# +# Default value: [%H:%M:%S] +### +supybot.plugins.Misc.timestampFormat: [%H:%M:%S] + +### +# Determines whether or not the timestamp will be included in the output +# of last when it is part of a nested command +# +# Default value: False +### +supybot.plugins.Misc.last.nested.includeTimestamp: False + +### +# Determines whether or not the nick will be included in the output of +# last when it is part of a nested command +# +# Default value: False +### +supybot.plugins.Misc.last.nested.includeNick: False + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Owner: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Owner.public: True + +### +# Determines what quit message will be used by default. If the quit +# command is called without a quit message, this will be used. If this +# value is empty, the nick of the person giving the quit command will be +# used. +# +# Default value: +### +supybot.plugins.Owner.quitMsg: + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Raumstatus: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Raumstatus.public: True + +### +# IP Address to ping. +# +# Default value: switch2.raum.chaostreff-dortmund.de +### +supybot.plugins.Raumstatus.target: switch2.raum.chaostreff-dortmund.de + +### +# Checking interval. +# +# Default value: 30 +### +supybot.plugins.Raumstatus.interval: 5 + +### +# Channel to set topic. +#### +supybot.plugins.Raumstatus.channel: #ctdo + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.User: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.User.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Web: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Web.public: True + +### +# Determines whether the bot will output the HTML title of URLs it sees +# in the channel. +# +# Default value: False +### +supybot.plugins.Web.titleSnarfer: True + +### +# 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. +# +# Default value: +### +supybot.plugins.Web.nonSnarfingRegexp: + +### +# Determines the maximum number of bytes the bot will download via the +# 'fetch' command in this plugin. +# +# Default value: 0 +### +supybot.plugins.Web.fetch.maximum: 0 + +### +# Determines whether the bot will always load important plugins (Admin, +# Channel, Config, Misc, Owner, and User) regardless of what their +# configured state is. Generally, if these plugins are configured not to +# load, you didn't do it on purpose, and you still want them to load. +# Users who don't want to load these plugins are smart enough to change +# the value of this variable appropriately :) +# +# Default value: True +### +supybot.plugins.alwaysLoadImportant: True + +### +# Determines what databases are available for use. If this value is not +# configured (that is, if its value is empty) then sane defaults will be +# provided. +# +# Default value: anydbm cdb flat pickle +### +supybot.databases: + +### +# Determines what filename will be used for the users database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: users.conf +### +supybot.databases.users.filename: users.conf + +### +# Determines how long it takes identification to time out. If the value +# is less than or equal to zero, identification never times out. +# +# Default value: 0 +### +supybot.databases.users.timeoutIdentification: 0 + +### +# Determines whether the bot will allow users to unregister their users. +# This can wreak havoc with already-existing databases, so by default we +# don't allow it. Enable this at your own risk. (Do also note that this +# does not prevent the owner of the bot from using the unregister +# command.) +# +# Default value: False +### +supybot.databases.users.allowUnregistration: False + +### +# Determines what filename will be used for the ignores database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: ignores.conf +### +supybot.databases.ignores.filename: ignores.conf + +### +# Determines what filename will be used for the channels database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: channels.conf +### +supybot.databases.channels.filename: channels.conf + +### +# Determines whether database-based plugins that can be channel-specific +# will be so. This can be overridden by individual channels. Do note +# that the bot needs to be restarted immediately after changing this +# variable or your db plugins may not work for your channel; also note +# that you may wish to set +# supybot.databases.plugins.channelSpecific.link appropriately if you +# wish to share a certain channel's databases globally. +# +# Default value: True +### +supybot.databases.plugins.channelSpecific: True + +### +# Determines what channel global (non-channel-specific) databases will +# be considered a part of. This is helpful if you've been running +# channel-specific for awhile and want to turn the databases for your +# primary channel into global databases. If +# supybot.databases.plugins.channelSpecific.link.allow prevents linking, +# the current channel will be used. Do note that the bot needs to be +# restarted immediately after changing this variable or your db plugins +# may not work for your channel. +# +# Default value: # +### +supybot.databases.plugins.channelSpecific.link: # + +### +# Determines whether another channel's global (non-channel-specific) +# databases will be allowed to link to this channel's databases. Do note +# that the bot needs to be restarted immediately after changing this +# variable or your db plugins may not work for your channel. +# +# Default value: True +### +supybot.databases.plugins.channelSpecific.link.allow: True + +### +# Determines whether CDB databases will be allowed as a database +# implementation. +# +# Default value: True +### +supybot.databases.types.cdb: True + +### +# Determines how often CDB databases will have their modifications +# flushed to disk. When the number of modified records is greater than +# this part of the number of unmodified records, the database will be +# entirely flushed to disk. +# +# Default value: 0.5 +### +supybot.databases.types.cdb.maximumModifications: 0.5 + +### +# Determines what will be used as the default banmask style. +# +# Default value: host user +### +supybot.protocols.irc.banmask: host user + +### +# Determines whether the bot will strictly follow the RFC; currently +# this only affects what strings are considered to be nicks. If you're +# using a server or a network that requires you to message a nick such +# as services@this.network.server then you you should set this to False. +# +# Default value: False +### +supybot.protocols.irc.strictRfc: False + +### +# Determines what user modes the bot will request from the server when +# it first connects. Many people might choose +i; some networks allow +# +x, which indicates to the auth services on those networks that you +# should be given a fake host. +# +# Default value: +### +supybot.protocols.irc.umodes: + +### +# Determines what vhost the bot will bind to before connecting to the +# IRC server. +# +# Default value: +### +supybot.protocols.irc.vhost: + +### +# Determines how many old messages the bot will keep around in its +# history. Changing this variable will not take effect until the bot is +# restarted. +# +# Default value: 1000 +### +supybot.protocols.irc.maxHistoryLength: 1000 + +### +# A floating point number of seconds to throttle queued messages -- that +# is, messages will not be sent faster than once per throttleTime +# seconds. +# +# Default value: 1.0 +### +supybot.protocols.irc.throttleTime: 1.0 + +### +# Determines whether the bot will send PINGs to the server it's +# connected to in order to keep the connection alive and discover +# earlier when it breaks. Really, this option only exists for debugging +# purposes: you always should make it True unless you're testing some +# strange server issues. +# +# Default value: True +### +supybot.protocols.irc.ping: True + +### +# Determines the number of seconds between sending pings to the server, +# if pings are being sent to the server. +# +# Default value: 120 +### +supybot.protocols.irc.ping.interval: 120 + +### +# Determines whether the bot will refuse duplicate messages to be queued +# for delivery to the server. This is a safety mechanism put in place to +# prevent plugins from sending the same message multiple times; most of +# the time it doesn't matter, unless you're doing certain kinds of +# plugin hacking. +# +# Default value: False +### +supybot.protocols.irc.queuing.duplicates: False + +### +# Determines how many seconds must elapse between JOINs sent to the +# server. +# +# Default value: 0.0 +### +supybot.protocols.irc.queuing.rateLimit.join: 0.0 + +### +# Determines how many bytes the bot will 'peek' at when looking through +# a URL for a doctype or title or something similar. It'll give up after +# it reads this many bytes, even if it hasn't found what it was looking +# for. +# +# Default value: 4096 +### +supybot.protocols.http.peekSize: 4096 + +### +# Determines what proxy all HTTP requests should go through. The value +# should be of the form 'host:port'. +# +# Default value: +### +supybot.protocols.http.proxy: + +### +# Determines whether the bot will ignore unregistered users by default. +# Of course, that'll make it particularly hard for those users to +# register or identify with the bot, but that's your problem to solve. +# +# Default value: False +### +supybot.defaultIgnore: False + +### +# A string that is the external IP of the bot. If this is the empty +# string, the bot will attempt to find out its IP dynamically (though +# sometimes that doesn't work, hence this variable). +# +# Default value: +### +supybot.externalIP: + +### +# Determines what the default timeout for socket objects will be. This +# means that *all* sockets will timeout when this many seconds has gone +# by (unless otherwise modified by the author of the code that uses the +# sockets). +# +# Default value: 10 +### +supybot.defaultSocketTimeout: 10 + +### +# Determines what file the bot should write its PID (Process ID) to, so +# you can kill it more easily. If it's left unset (as is the default) +# then no PID file will be written. A restart is required for changes to +# this variable to take effect. +# +# Default value: +### +supybot.pidFile: + +### +# Determines whether the bot will automatically thread all commands. +# +# Default value: False +### +supybot.debug.threadAllCommands: False + +### +# Determines whether the bot will automatically flush all flushers +# *very* often. Useful for debugging when you don't know what's breaking +# or when, but think that it might be logged. +# +# Default value: False +### +supybot.debug.flushVeryOften: False + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(name)s %(message)s +### +supybot.log.format: %(levelname)s %(asctime)s %(name)s %(message)s + +### +# Determines what the minimum priority level logged to file will be. Do +# note that this value does not affect the level logged to stdout; for +# that, you should set the value of supybot.log.stdout.level. Valid +# values are DEBUG, INFO, WARNING, ERROR, and CRITICAL, in order of +# increasing priority. +# +# Default value: INFO +### +supybot.log.level: INFO + +### +# Determines the format string for timestamps in logfiles. Refer to the +# Python documentation for the time module to see what formats are +# accepted. If you set this variable to the empty string, times will be +# logged in a simple seconds-since-epoch format. +# +# Default value: %Y-%m-%dT%H:%M:%S +### +supybot.log.timestampFormat: %Y-%m-%dT%H:%M:%S + +### +# Determines whether the bot will log to stdout. +# +# Default value: True +### +supybot.log.stdout: True + +### +# Determines whether the bot's logs to stdout (if enabled) will be +# colorized with ANSI color. +# +# Default value: False +### +supybot.log.stdout.colorized: False + +### +# Determines whether the bot will wrap its logs when they're output to +# stdout. +# +# Default value: True +### +supybot.log.stdout.wrap: True + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(message)s +### +supybot.log.stdout.format: %(levelname)s %(asctime)s %(message)s + +### +# Determines what the minimum priority level logged will be. Valid +# values are DEBUG, INFO, WARNING, ERROR, and CRITICAL, in order of +# increasing priority. +# +# Default value: INFO +### +supybot.log.stdout.level: INFO + +### +# Determines whether the bot will separate plugin logs into their own +# individual logfiles. +# +# Default value: False +### +supybot.log.plugins.individualLogfiles: False + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(message)s +### +supybot.log.plugins.format: %(levelname)s %(asctime)s %(message)s + +### +# These are the capabilities that are given to everyone by default. If +# they are normal capabilities, then the user will have to have the +# appropriate anti-capability if you want to override these +# capabilities; if they are anti-capabilities, then the user will have +# to have the actual capability to override these capabilities. See +# docs/CAPABILITIES if you don't understand why these default to what +# they do. +# +# Default value: -owner -admin -trusted +### +supybot.capabilities: -owner -admin -trusted + +### +# Determines whether the bot by default will allow users to have a +# capability. If this is disabled, a user must explicitly have the +# capability for whatever command he wishes to run. +# +# Default value: True +### +supybot.capabilities.default: True