[Divmod-commits] r8997 - further factoring improvements; report request functionality
Jp Calderone
exarkun at divmod.org
Sun Sep 17 22:19:48 EDT 2006
Author: exarkun
Date: Sun Sep 17 22:19:47 2006
New Revision: 8997
Modified:
sandbox/exarkun/commit-bot/commit_bot.py
sandbox/exarkun/commit-bot/ticket.py
Log:
further factoring improvements; report request functionality
Modified: sandbox/exarkun/commit-bot/commit_bot.py
==============================================================================
--- sandbox/exarkun/commit-bot/commit_bot.py (original)
+++ sandbox/exarkun/commit-bot/commit_bot.py Sun Sep 17 22:19:47 2006
@@ -2,9 +2,6 @@
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.spread import pb
-from twisted.web import client
-from twisted.internet import task
-from twisted.python import log
import config
@@ -16,20 +13,25 @@
self.proto = proto
-class CommitBot(irc.IRCClient, commit.RepositoryChange, ticket.TicketChange, alert.MuninAlert):
+class CommitBot(irc.IRCClient, commit.RepositoryChange, ticket.TicketChange, ticket.TicketReview, alert.MuninAlert):
nickname = config.BOT_NICK
password = config.BOT_PASS
lineRate = config.LINE_RATE
notificationPort = None
- _ticketCall = None
def connectionLost(self, reason):
if self.notificationPort is not None:
self.notificationPort.stopListening()
- if self._ticketCall is not None:
- self._ticketCall.stop()
+
+ for cls in self.__class__.__bases__[1:]:
+ try:
+ f = cls.connectionLost
+ except AttributeError:
+ pass
+ else:
+ f(self, reason)
def signedOn(self):
@@ -38,92 +40,27 @@
self.notificationPort = reactor.listenTCP(
config.BOT_PORT, sf)
- self._ticketCall = task.LoopingCall(self.reportAllReviewTickets)
- self._ticketCall.start(60 * 60 * 5)
+ for cls in self.__class__.__bases__[1:]:
+ try:
+ f = cls.signedOn
+ except AttributeError:
+ pass
+ else:
+ f(self)
+
+
+ def noticed(self, user, channel, message):
+ pass
- def reportAllReviewTickets(self):
- """
- Call L{reportReviewTickets} with each element of L{config.TICKET_RULES}.
- """
- for (url, channel) in config.TICKET_RULES:
- d = self.reportReviewTickets(url, channel)
- d.addErrback(
- log.err,
- "Failed to report review tickets from %r to %r" % (
- url, channel))
-
-
- def reportReviewTickets(self, trackerRoot, channel):
- """
- Retrieve the list of tickets currently up for review from the
- tracker at the given location and report them to the given channel.
-
- @param trackerRoot: The base URL of the trac instance from which to
- retrieve ticket information. C{"http://example.com/trac/"}, for
- example.
-
- @param channel: The channel to which to send the results.
-
- @return: A Deferred which fires when the report has been completed.
- """
- d = self._getReviewTickets(trackerRoot)
- d.addCallback(self._reportReviewTickets, channel)
- return d
-
-
- def _getReviewTickets(self, trackerRoot):
- """
- Retrieve the list of tickets currently up for review from the
- tracker at the given location.
-
- @return: A Deferred which fires with a C{list} of C{int}s. Each
- element is the number of a ticket up for review.
- """
- url = trackerRoot + (
- "query?"
- "status=new&"
- "status=assigned&"
- "status=reopened&"
- "format=tab&"
- "keywords=~review"
- "&order=priority")
- d = client.getPage(url)
- d.addCallback(self._parseReviewTicketQuery)
- return d
-
-
- def _parseReviewTicketQuery(self, result):
- """
- Split up a multi-line tab-delimited set of ticket information and
- return two-tuples of ticket numbers as integers and owners as
- strings.
-
- The first line of input is expected to be column definitions and is
- skipped.
- """
- for line in result.splitlines()[1:]:
- parts = line.split('\t')
- yield int(parts[0]), parts[4]
-
-
- def _reportReviewTickets(self, reviewTicketInfo, channel):
- """
- Format the given list of ticket numbers and send it to the given channel.
- """
- tickets = self._formatTicketNumbers(reviewTicketInfo)
- self.join(channel)
- self.msg(channel, "Tickets pending review: " + tickets)
-
-
- def _formatTicketNumbers(self, reviewTicketInfo):
- tickets = []
- for (id, owner) in reviewTicketInfo:
- if owner:
- tickets.append('#%d (%s)' % (id, owner))
+ def privmsg(self, user, channel, message):
+ for cls in self.__class__.__bases__[1:]:
+ try:
+ f = cls.privmsg
+ except AttributeError:
+ pass
else:
- tickets.append('#%d' % (id,))
- return ', '.join(tickets)
+ f(self, user, channel, message)
Modified: sandbox/exarkun/commit-bot/ticket.py
==============================================================================
--- sandbox/exarkun/commit-bot/ticket.py (original)
+++ sandbox/exarkun/commit-bot/ticket.py Sun Sep 17 22:19:47 2006
@@ -1,7 +1,8 @@
-from twisted.internet import reactor
+from twisted.internet import reactor, task
from twisted.spread import pb
from twisted.python import log
+from twisted.web import client
import config
@@ -40,6 +41,120 @@
self.ticketMessageFormat % vars(ticket),
config.LINE_LENGTH)
+
+class TicketReview:
+ """
+ Automated review ticket reporting.
+ """
+
+ _ticketCall = None
+
+ def signedOn(self):
+ self._ticketCall = task.LoopingCall(self.reportAllReviewTickets)
+ self._ticketCall.start(60 * 60 * 5)
+
+
+ def privmsg(self, user, channel, message):
+ if 'review branches' in message:
+ for (url, chan) in config.TICKET_RULES:
+ if chan == channel:
+ d = self.reportReviewTickets(url, chan)
+ d.addErrback(
+ log.err,
+ "Failed to satisfy review ticket request from "
+ "%r to %r" % (url, chan))
+
+
+ def connectionLost(self, reason):
+ if self._ticketCall is not None:
+ self._ticketCall.stop()
+
+
+ def reportAllReviewTickets(self):
+ """
+ Call L{reportReviewTickets} with each element of L{config.TICKET_RULES}.
+ """
+ for (url, channel) in config.TICKET_RULES:
+ d = self.reportReviewTickets(url, channel)
+ d.addErrback(
+ log.err,
+ "Failed to report review tickets from %r to %r" % (
+ url, channel))
+
+
+ def reportReviewTickets(self, trackerRoot, channel):
+ """
+ Retrieve the list of tickets currently up for review from the
+ tracker at the given location and report them to the given channel.
+
+ @param trackerRoot: The base URL of the trac instance from which to
+ retrieve ticket information. C{"http://example.com/trac/"}, for
+ example.
+
+ @param channel: The channel to which to send the results.
+
+ @return: A Deferred which fires when the report has been completed.
+ """
+ d = self._getReviewTickets(trackerRoot)
+ d.addCallback(self._reportReviewTickets, channel)
+ return d
+
+
+ def _getReviewTickets(self, trackerRoot):
+ """
+ Retrieve the list of tickets currently up for review from the
+ tracker at the given location.
+
+ @return: A Deferred which fires with a C{list} of C{int}s. Each
+ element is the number of a ticket up for review.
+ """
+ url = trackerRoot + (
+ "query?"
+ "status=new&"
+ "status=assigned&"
+ "status=reopened&"
+ "format=tab&"
+ "keywords=~review"
+ "&order=priority")
+ d = client.getPage(url)
+ d.addCallback(self._parseReviewTicketQuery)
+ return d
+
+
+ def _parseReviewTicketQuery(self, result):
+ """
+ Split up a multi-line tab-delimited set of ticket information and
+ return two-tuples of ticket numbers as integers and owners as
+ strings.
+
+ The first line of input is expected to be column definitions and is
+ skipped.
+ """
+ for line in result.splitlines()[1:]:
+ parts = line.split('\t')
+ yield int(parts[0]), parts[4]
+
+
+ def _reportReviewTickets(self, reviewTicketInfo, channel):
+ """
+ Format the given list of ticket numbers and send it to the given channel.
+ """
+ tickets = self._formatTicketNumbers(reviewTicketInfo)
+ self.join(channel)
+ self.msg(channel, "Tickets pending review: " + tickets)
+
+
+ def _formatTicketNumbers(self, reviewTicketInfo):
+ tickets = []
+ for (id, owner) in reviewTicketInfo:
+ if owner:
+ tickets.append('#%d (%s)' % (id, owner))
+ else:
+ tickets.append('#%d' % (id,))
+ return ', '.join(tickets)
+
+
+
def _sendTicket(ticket):
cf = pb.PBClientFactory()
reactor.connectTCP(config.BOT_HOST, config.BOT_PORT, cf)
More information about the Divmod-commits
mailing list