[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