#!/usr/bin/python2.3 ### # Copyright (c) 2003 Colin Walters # 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. ### """ ArchNotify: Notifies an irc channel on changes to an arch repository """ from baseplugin import * import re import time import conf import ircdb import ircmsgs import privmsgs import ircutils import schedule import callbacks def get_changes(archive, snappath=None): if snappath is None: snappath = os.path.join(os.path.expanduser('~'), archive + '.snap') if not os.access(snappath, os.R_OK): debug.msg('doing initial snap', 'high') os.system('tla abrowse -A %s --snap %s 1>/dev/null' % (archive, snappath)) else: debug.msg('parsing existing snap', 'high') pipe = os.popen('tla abrowse --since %s %s' % (snappath, archive)) revision_re = re.compile('^\s+(\w+(?:-?\w+)*)--(\w+(?:-?\w+)*)--((\d+)(\.\d+)*)\s+$') patches_re = re.compile('^\s+patch-(\d+) \.\. patch-(\d+)\s+$') changes=[] category='' branch='' version='' patches=[] l = pipe.readline() while l != '': l = pipe.readline() match = revision_re.match(l) if match: category = match.group(1) branch = match.group(2) version = match.group(3) continue match = patches_re.match(l) if match: patches = range(int(match.group(1)),int(match.group(2))+1) for patch in patches: revision="%s--%s--%s--patch-%s" % (category, branch, version, patch) changes.append((revision, get_summary(archive,revision))) continue pipe.close() debug.msg('doing new snap', 'high') os.system('tla abrowse -A %s --force --snap %s 1>/dev/null' % (archive, snappath)) return changes def get_summary(archive, revision): summary_re = re.compile('^Summary: (.+)$') pipe = os.popen('tla cat-archive-log -A %s %s' % (archive, revision)) l = pipe.readline() while l != '': l = pipe.readline() match = summary_re.match(l) if match: pipe.close() return match.group(1) return "(Error: couldn't get summary)" class ArchNotify(privmsgs.CapabilityCheckingPrivmsg): capability = 'admin' def __init__(self): callbacks.Privmsg.__init__(self) self.last_check = time.time() self.archive = 'address@hidden' self.channel = '#rhythmbox' self.snappath = os.path.join(os.path.expanduser('~'), self.archive + '.snap') def __call__(self, irc, msg): callbacks.Privmsg.__call__(self, irc, msg) if (time.time() - self.last_check) > 60: self.last_check = time.time() changes = get_changes(self.archive, self.snappath) debug.msg('changes: %s' % (changes,), 'high') for change in changes: irc.queueMsg(ircmsgs.privmsg(self.channel, 'Revision: %s/%s' % (self.archive, change[0],))) irc.queueMsg(ircmsgs.privmsg(self.channel, "Summary: " + change[1])) def abrowse(self, irc, msg, args): irc.reply(msg, open(self.snappath).read()) Class = ArchNotify