[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