[mentors-ops] r301 - in trunk: . irc irc/ExternalNotice
mentors at mentors.debian.net
mentors at mentors.debian.net
Tue Jul 3 11:32:25 CEST 2007
Author: mentors
Date: 2007-07-03 11:32:24 +0200 (Tue, 03 Jul 2007)
New Revision: 301
Added:
trunk/irc/
trunk/irc/ExternalNotice/
trunk/irc/ExternalNotice/README.txt
trunk/irc/ExternalNotice/__init__.py
trunk/irc/ExternalNotice/config.py
trunk/irc/ExternalNotice/plugin.py
trunk/irc/ExternalNotice/supybot-external-notice.py
trunk/irc/ExternalNotice/test.py
trunk/irc/README.txt
Log:
IRC plugin added.
Added: trunk/irc/ExternalNotice/README.txt
===================================================================
--- trunk/irc/ExternalNotice/README.txt (rev 0)
+++ trunk/irc/ExternalNotice/README.txt 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,48 @@
+ExternalNotice Plugin README
+--
+
+Requirements
+--
+1. Twisted (core only required)
+
+Installation
+--
+Place plugin directory in a configured plugin directory (as usual).
+
+Usage
+--
+Once installed, load the plugin as usual. Now, the supybot user can issue
+notices for supybot to emit on a channel and network it is on, by using the
+provided supybot-external-notice.py script.
+
+The script has the following usage parameters:
+
+usage: supybot-external-notice.py [options] <network> <channel>
+
+options:
+ -h, --help show this help message and exit
+ -s, --stdin Read notice data from stdin.
+ -f FORMATTER, --formatter=FORMATTER
+ formatter to apply to notice body
+
+The plugin has no commands, and no configuration variables.
+
+Under the hood
+--
+ExternalNotice uses the UDP protocol over a Unix Domain Socket which is
+started in ~/.supybot-external-notice for the supybot user.
+
+Security
+--
+The socket is set to be user-only writeable, and unreadable. This is to ensure
+that only the supybot user can connect to the plugin and issue commands. This
+behaviour can be changes by modifying the permissions set on the socket.
+
+As always
+--
+Bugs, suggestions, criticism, advice, improvements and frankenstein-ideas to
+aafshar at gmail.com, or #supybot on freenode.
+
+All the best,
+
+Ali
Added: trunk/irc/ExternalNotice/__init__.py
===================================================================
--- trunk/irc/ExternalNotice/__init__.py (rev 0)
+++ trunk/irc/ExternalNotice/__init__.py 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,65 @@
+###
+# Copyright (c) 2005, Ali Afshar
+# 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.
+###
+
+"""
+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/ExternalNotice/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 softtabstop=4 expandtab textwidth=79:
Added: trunk/irc/ExternalNotice/config.py
===================================================================
--- trunk/irc/ExternalNotice/config.py (rev 0)
+++ trunk/irc/ExternalNotice/config.py 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,48 @@
+###
+# Copyright (c) 2005, Ali Afshar
+# 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('ExternalNotice', True)
+
+
+ExternalNotice = conf.registerPlugin('ExternalNotice')
+# This is where your configuration variables (if any) should go. For example:
+# conf.registerGlobalValue(ExternalNotice, 'someConfigVariableName',
+# registry.Boolean(False, """Help for someConfigVariableName."""))
+
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
Added: trunk/irc/ExternalNotice/plugin.py
===================================================================
--- trunk/irc/ExternalNotice/plugin.py (rev 0)
+++ trunk/irc/ExternalNotice/plugin.py 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,109 @@
+###
+# Copyright (c) 2005, Ali Afshar
+# 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.utils as utils
+import supybot.world as world
+from supybot.commands import *
+import supybot.ircmsgs as ircmsgs
+import supybot.plugins as plugins
+import supybot.ircutils as ircutils
+import supybot.callbacks as callbacks
+
+import twisted.internet.reactor as reactor
+import twisted.internet.protocol as protocol
+
+import os
+
+class ExternalNotice(callbacks.Plugin):
+ """Allow the supybot user to send a notice to a channel."""
+
+ def __init__(self, irc):
+ callbacks.Plugin.__init__(self, irc)
+ self.server = SupyUDP(self)
+ self.path = os.path.expanduser('~/.supybot-external-notice.%s' %
+ irc.nick)
+ if os.path.exists(self.path):
+ os.remove(self.path)
+ self.listener = reactor.listenUNIXDatagram(self.path, self.server)
+ # chaas
+ import grp
+ groupid = grp.getgrnam('mentors')[2]
+ os.chown(self.path, -1, groupid)
+ # /chaas
+ os.chmod(self.path, 720)
+
+ def receivedCommand(self, data):
+ """Received a command over the UDP wire."""
+ error = None
+ commanditems = data.split()
+ if len(commanditems) > 2:
+ network = commanditems.pop(0)
+ channel = commanditems.pop(0)
+ text = ' '.join(commanditems)
+ netfound = False
+ for irc in world.ircs:
+ if irc.network == network:
+ netfound = True
+ chanfound = False
+ for onchannel in irc.state.channels:
+ if channel == onchannel[1:]:
+ chanfound = True
+ # chaas:
+ #m = ircmsgs.notice(onchannel, text)
+ m = ircmsgs.privmsg(onchannel, text)
+ irc.sendMsg(m)
+ if not chanfound:
+ error = 'Bad Channel "%s"' % channel
+ if not netfound:
+ error = 'Bad Network "%s"' % network
+ if error:
+ self.log.info('Attempted external notice: %s', error)
+ else:
+ self.log.info('Successful external notice')
+
+ def die(self):
+ """ Called on unload. Stop listening and remove the socket. """
+ self.listener.stopListening()
+ os.remove(self.path)
+
+class SupyUDP(protocol.DatagramProtocol):
+ """ A very simple datagram protocol """
+
+ def __init__(self, cb):
+ self.cb = cb
+
+ def datagramReceived(self, data, address):
+ """ Just pass the data on to the plugin. """
+ self.cb.receivedCommand(data)
+
+Class = ExternalNotice
+
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
Added: trunk/irc/ExternalNotice/supybot-external-notice.py
===================================================================
--- trunk/irc/ExternalNotice/supybot-external-notice.py (rev 0)
+++ trunk/irc/ExternalNotice/supybot-external-notice.py 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,114 @@
+#! /usr/bin/env python
+
+###
+# Copyright (c) 2005, Ali Afshar
+# 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 os
+import sys
+
+from optparse import OptionParser
+import twisted.internet.reactor as reactor
+import twisted.internet.protocol as protocol
+
+SOCKPATH = os.path.expanduser('~/.supybot-external-notice.%s')
+
+class SupyClient(protocol.DatagramProtocol):
+ """ Simple datagram sending-only protocol. """
+
+ def sendNotice(self, botnick, network, channel, data):
+ command = ' '.join([network, channel, data])
+ self.transport.write(command, SOCKPATH % botnick)
+
+def main():
+ """ Parse the options, generate the data and send. """
+ usage = 'usage: %prog [options] <network> <channel>'
+ parser = OptionParser(usage)
+ parser.add_option('-s', '--stdin', dest='stdin', action='store_true',
+ default=False, help='Read notice data from stdin.')
+ parser.add_option('-f', '--formatter', dest='formatter',
+ help='formatter to apply to notice body')
+ options, args = parser.parse_args()
+ if len(args) < 3:
+ parser.print_help()
+ sys.exit(1)
+ botnick = args.pop(0)
+ network = args.pop(0)
+ channel = args.pop(0)
+ if options.stdin:
+ data = sys.stdin.read()
+ else:
+ data = args.pop(0)
+ if options.formatter:
+ if options.formatter in FORMATTERS:
+ data = FORMATTERS[options.formatter](data)
+ client = SupyClient()
+ reactor.listenUNIXDatagram(0, client)
+ client.sendNotice(botnick, network, channel, data)
+
+# An example formatter
+def format_svn_commit_mail(data):
+ """ Formatter for svn commits. """
+ import email
+ message = email.message_from_string(data)
+ lines = message.get_payload().splitlines()
+ author = lines.pop(0)
+ date = lines.pop(0)
+ revision = 'Rev: %s' % lines.pop(0).split(': ', 1)[-1]
+ lines.pop(0)
+ lines.pop(0)
+ filename = 'File: %s' % lines.pop(0).strip()
+ lines.pop(0)
+ log = lines.pop(0).strip()
+ return 'Svn Commit: %s, %s, %s, %s, %s' % (revision, author, date,
+ filename, log)
+
+def format_darcs_commit_mail(data):
+ """Formatter for darcs commits"""
+ import email
+ message = email.message_from_string(data)
+ lines = message.get_payload().splitlines()
+ author = lines[0]
+ log = lines[4].strip('[')
+ patchnum = lines[5].split('**')[-1].strip('] {')
+ headers = dict(message._headers)
+ date = headers['Date']
+ mlist = headers['To'].split('@')[0]
+ return 'Darcs Commit: %s #%s, %s, Date: %s, Msg: %s' % (mlist,
+ patchnum, author, date, log)
+
+def format_mdn_announce(data):
+ """Formatter for mentors.debian.net announcements"""
+ return data
+
+FORMATTERS = {'svn-commit-mail':format_svn_commit_mail,
+ 'darcs-commit-mail':format_darcs_commit_mail,
+ 'mdn-announce':format_mdn_announce,
+ }
+
+if __name__ == '__main__':
+ main()
Property changes on: trunk/irc/ExternalNotice/supybot-external-notice.py
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/irc/ExternalNotice/test.py
===================================================================
--- trunk/irc/ExternalNotice/test.py (rev 0)
+++ trunk/irc/ExternalNotice/test.py 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,30 @@
+###
+# Copyright (c) 2005, Ali Afshar
+# 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.
+###
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
Added: trunk/irc/README.txt
===================================================================
--- trunk/irc/README.txt (rev 0)
+++ trunk/irc/README.txt 2007-07-03 09:32:24 UTC (rev 301)
@@ -0,0 +1,10 @@
+This plugin is used to announce sponsorship requests to the
+#debian-mentors IRC channel on irc.oftc.net. It is mainly the
+"ExternalNotice" plugin extended by a trivial formatter. Also the
+message is no longer a "notice" but a common "privmsg" to the channel
+because other IRC users complained about that.
+
+The "ExternalNotice" directory needs to be copied into ~/.supybot/plugins/.
+The cgi-bin/Util.py contains an AnnounceOnIrc function to send
+announcements to this plugin through a pipe in
+~/.supybot-external-notice.MentorSeeker
More information about the mentors-ops
mailing list