[Buildbot-commits] buildbot/buildbot/status/web site.py, NONE, 1.1 waterfall.py, 1.5, 1.6

Brian Warner warner at users.sourceforge.net
Wed Aug 1 22:08:23 UTC 2007


Update of /cvsroot/buildbot/buildbot/buildbot/status/web
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv29177/buildbot/status/web

Modified Files:
	waterfall.py 
Added Files:
	site.py 
Log Message:
[project @ web: split code up more]

Original author: warner at lothar.com
Date: 2007-07-30 03:08:56+00:00

--- NEW FILE: site.py ---

class StatusResource(Resource):
    status = None
    control = None
    favicon = None
    robots_txt = None

    def __init__(self, status, control, changemaster, categories, css):
        """
        @type  status:       L{buildbot.status.builder.Status}
        @type  control:      L{buildbot.master.Control}
        @type  changemaster: L{buildbot.changes.changes.ChangeMaster}
        """
        Resource.__init__(self)
        self.status = status
        self.control = control
        self.changemaster = changemaster
        self.css = css
        waterfall = WaterfallStatusResource(categories, css)
        waterfall.status = self.status
        waterfall.control = control
        waterfall.changemaster = changemaster
        self.putChild("", waterfall)

    def render(self, request):
        request.redirect(request.prePathURL() + '/')
        request.finish()

    def getChild(self, path, request):
        if path == "robots.txt" and self.robots_txt:
            return static.File(self.robots_txt)
        if path == "buildbot.css" and self.css:
            return static.File(self.css)
        if path == "changes":
            return StatusResourceChanges(self.status, self.changemaster)
        if path == "favicon.ico":
            if self.favicon:
                return static.File(self.favicon)
            return NoResource("No favicon.ico registered")

        if path in self.status.getBuilderNames():
            builder = self.status.getBuilder(path)
            control = None
            if self.control:
                control = self.control.getBuilder(path)
            return StatusResourceBuilder(self.status, builder, control)

        return NoResource("No such Builder '%s'" % path)

if hasattr(sys, "frozen"):
    # all 'data' files are in the directory of our executable
    here = os.path.dirname(sys.executable)
    buildbot_icon = os.path.abspath(os.path.join(here, "buildbot.png"))
    buildbot_css = os.path.abspath(os.path.join(here, "classic.css"))
else:
    # running from source
    # the icon is sibpath(__file__, "../buildbot.png") . This is for
    # portability.
    up = os.path.dirname
    buildbot_icon = os.path.abspath(os.path.join(up(up(up(__file__))),
                                                 "buildbot.png"))
    buildbot_css = os.path.abspath(os.path.join(up(__file__), "classic.css"))

class Waterfall(base.StatusReceiverMultiService):
    """I implement the primary web-page status interface, called a 'Waterfall
    Display' because builds and steps are presented in a grid of boxes which
    move downwards over time. The top edge is always the present. Each column
    represents a single builder. Each box describes a single Step, which may
    have logfiles or other status information.

    All these pages are served via a web server of some sort. The simplest
    approach is to let the buildmaster run its own webserver, on a given TCP
    port, but it can also publish its pages to a L{twisted.web.distrib}
    distributed web server (which lets the buildbot pages be a subset of some
    other web server).

    Since 0.6.3, BuildBot defines class attributes on elements so they can be
    styled with CSS stylesheets. Buildbot uses some generic classes to
    identify the type of object, and some more specific classes for the
    various kinds of those types. It does this by specifying both in the
    class attributes where applicable, separated by a space. It is important
    that in your CSS you declare the more generic class styles above the more
    specific ones. For example, first define a style for .Event, and below
    that for .SUCCESS

    The following CSS class names are used:
        - Activity, Event, BuildStep, LastBuild: general classes
        - waiting, interlocked, building, offline, idle: Activity states
        - start, running, success, failure, warnings, skipped, exception:
          LastBuild and BuildStep states
        - Change: box with change
        - Builder: box for builder name (at top)
        - Project
        - Time

    @type parent: L{buildbot.master.BuildMaster}
    @ivar parent: like all status plugins, this object is a child of the
                  BuildMaster, so C{.parent} points to a
                  L{buildbot.master.BuildMaster} instance, through which
                  the status-reporting object is acquired.
    """

    compare_attrs = ["http_port", "distrib_port", "allowForce",
                     "categories", "css", "favicon", "robots_txt"]

    def __init__(self, http_port=None, distrib_port=None, allowForce=True,
                 categories=None, css=buildbot_css, favicon=buildbot_icon,
                 robots_txt=None):
        """To have the buildbot run its own web server, pass a port number to
        C{http_port}. To have it run a web.distrib server

        @type  http_port: int or L{twisted.application.strports} string
        @param http_port: a strports specification describing which port the
                          buildbot should use for its web server, with the
                          Waterfall display as the root page. For backwards
                          compatibility this can also be an int. Use
                          'tcp:8000' to listen on that port, or
                          'tcp:12345:interface=127.0.0.1' if you only want
                          local processes to connect to it (perhaps because
                          you are using an HTTP reverse proxy to make the
                          buildbot available to the outside world, and do not
                          want to make the raw port visible).

        @type  distrib_port: int or L{twisted.application.strports} string
        @param distrib_port: Use this if you want to publish the Waterfall
                             page using web.distrib instead. The most common
                             case is to provide a string that is an absolute
                             pathname to the unix socket on which the
                             publisher should listen
                             (C{os.path.expanduser(~/.twistd-web-pb)} will
                             match the default settings of a standard
                             twisted.web 'personal web server'). Another
                             possibility is to pass an integer, which means
                             the publisher should listen on a TCP socket,
                             allowing the web server to be on a different
                             machine entirely. Both forms are provided for
                             backwards compatibility; the preferred form is a
                             strports specification like
                             'unix:/home/buildbot/.twistd-web-pb'. Providing
                             a non-absolute pathname will probably confuse
                             the strports parser.

        @type  allowForce: bool
        @param allowForce: if True, present a 'Force Build' button on the
                           per-Builder page that allows visitors to the web
                           site to initiate a build. If False, don't provide
                           this button.

        @type  favicon: string
        @param favicon: if set, provide the pathname of an image file that
                        will be used for the 'favicon.ico' resource. Many
                        browsers automatically request this file and use it
                        as an icon in any bookmark generated from this site.
                        Defaults to the buildbot/buildbot.png image provided
                        in the distribution. Can be set to None to avoid
                        using a favicon at all.

        @type  robots_txt: string
        @param robots_txt: if set, provide the pathname of a robots.txt file.
                           Many search engines request this file and obey the
                           rules in it. E.g. to disallow them to crawl the
                           status page, put the following two lines in
                           robots.txt::
                              User-agent: *
                              Disallow: /
        """

        base.StatusReceiverMultiService.__init__(self)
        assert allowForce in (True, False) # TODO: implement others
        if type(http_port) is int:
            http_port = "tcp:%d" % http_port
        self.http_port = http_port
        if distrib_port is not None:
            if type(distrib_port) is int:
                distrib_port = "tcp:%d" % distrib_port
            if distrib_port[0] in "/~.": # pathnames
                distrib_port = "unix:%s" % distrib_port
        self.distrib_port = distrib_port
        self.allowForce = allowForce
        self.categories = categories
        self.css = css
        self.favicon = favicon
        self.robots_txt = robots_txt

    def __repr__(self):
        if self.http_port is None:
            return "<Waterfall on path %s>" % self.distrib_port
        if self.distrib_port is None:
            return "<Waterfall on port %s>" % self.http_port
        return "<Waterfall on port %s and path %s>" % (self.http_port,
                                                       self.distrib_port)

    def setServiceParent(self, parent):
        """
        @type  parent: L{buildbot.master.BuildMaster}
        """
        base.StatusReceiverMultiService.setServiceParent(self, parent)
        self.setup()

    def setup(self):
        status = self.parent.getStatus()
        if self.allowForce:
            control = interfaces.IControl(self.parent)
        else:
            control = None
        change_svc = self.parent.change_svc
        sr = StatusResource(status, control, change_svc, self.categories,
                            self.css)
        sr.favicon = self.favicon
        sr.robots_txt = self.robots_txt
        self.site = server.Site(sr)

        if self.http_port is not None:
            s = strports.service(self.http_port, self.site)
            s.setServiceParent(self)
        if self.distrib_port is not None:
            f = pb.PBServerFactory(distrib.ResourcePublisher(self.site))
            s = strports.service(self.distrib_port, f)
            s.setServiceParent(self)


Index: waterfall.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/status/web/waterfall.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- waterfall.py	1 Aug 2007 22:08:11 -0000	1.5
+++ waterfall.py	1 Aug 2007 22:08:21 -0000	1.6
@@ -582,222 +582,3 @@
             data += " </tr>\n"
         return data
 
-
-class StatusResource(Resource):
-    status = None
-    control = None
-    favicon = None
-    robots_txt = None
-
-    def __init__(self, status, control, changemaster, categories, css):
-        """
-        @type  status:       L{buildbot.status.builder.Status}
-        @type  control:      L{buildbot.master.Control}
-        @type  changemaster: L{buildbot.changes.changes.ChangeMaster}
-        """
-        Resource.__init__(self)
-        self.status = status
-        self.control = control
-        self.changemaster = changemaster
-        self.css = css
-        waterfall = WaterfallStatusResource(categories, css)
-        waterfall.status = self.status
-        waterfall.control = control
-        waterfall.changemaster = changemaster
-        self.putChild("", waterfall)
-
-    def render(self, request):
-        request.redirect(request.prePathURL() + '/')
-        request.finish()
-
-    def getChild(self, path, request):
-        if path == "robots.txt" and self.robots_txt:
-            return static.File(self.robots_txt)
-        if path == "buildbot.css" and self.css:
-            return static.File(self.css)
-        if path == "changes":
-            return StatusResourceChanges(self.status, self.changemaster)
-        if path == "favicon.ico":
-            if self.favicon:
-                return static.File(self.favicon)
-            return NoResource("No favicon.ico registered")
-
-        if path in self.status.getBuilderNames():
-            builder = self.status.getBuilder(path)
-            control = None
-            if self.control:
-                control = self.control.getBuilder(path)
-            return StatusResourceBuilder(self.status, builder, control)
-
-        return NoResource("No such Builder '%s'" % path)
-
-if hasattr(sys, "frozen"):
-    # all 'data' files are in the directory of our executable
-    here = os.path.dirname(sys.executable)
-    buildbot_icon = os.path.abspath(os.path.join(here, "buildbot.png"))
-    buildbot_css = os.path.abspath(os.path.join(here, "classic.css"))
-else:
-    # running from source
-    # the icon is sibpath(__file__, "../buildbot.png") . This is for
-    # portability.
-    up = os.path.dirname
-    buildbot_icon = os.path.abspath(os.path.join(up(up(up(__file__))),
-                                                 "buildbot.png"))
-    buildbot_css = os.path.abspath(os.path.join(up(__file__), "classic.css"))
-
-class Waterfall(base.StatusReceiverMultiService):
-    """I implement the primary web-page status interface, called a 'Waterfall
-    Display' because builds and steps are presented in a grid of boxes which
-    move downwards over time. The top edge is always the present. Each column
-    represents a single builder. Each box describes a single Step, which may
-    have logfiles or other status information.
-
-    All these pages are served via a web server of some sort. The simplest
-    approach is to let the buildmaster run its own webserver, on a given TCP
-    port, but it can also publish its pages to a L{twisted.web.distrib}
-    distributed web server (which lets the buildbot pages be a subset of some
-    other web server).
-
-    Since 0.6.3, BuildBot defines class attributes on elements so they can be
-    styled with CSS stylesheets. Buildbot uses some generic classes to
-    identify the type of object, and some more specific classes for the
-    various kinds of those types. It does this by specifying both in the
-    class attributes where applicable, separated by a space. It is important
-    that in your CSS you declare the more generic class styles above the more
-    specific ones. For example, first define a style for .Event, and below
-    that for .SUCCESS
-
-    The following CSS class names are used:
-        - Activity, Event, BuildStep, LastBuild: general classes
-        - waiting, interlocked, building, offline, idle: Activity states
-        - start, running, success, failure, warnings, skipped, exception:
-          LastBuild and BuildStep states
-        - Change: box with change
-        - Builder: box for builder name (at top)
-        - Project
-        - Time
-
-    @type parent: L{buildbot.master.BuildMaster}
-    @ivar parent: like all status plugins, this object is a child of the
-                  BuildMaster, so C{.parent} points to a
-                  L{buildbot.master.BuildMaster} instance, through which
-                  the status-reporting object is acquired.
-    """
-
-    compare_attrs = ["http_port", "distrib_port", "allowForce",
-                     "categories", "css", "favicon", "robots_txt"]
-
-    def __init__(self, http_port=None, distrib_port=None, allowForce=True,
-                 categories=None, css=buildbot_css, favicon=buildbot_icon,
-                 robots_txt=None):
-        """To have the buildbot run its own web server, pass a port number to
-        C{http_port}. To have it run a web.distrib server
-
-        @type  http_port: int or L{twisted.application.strports} string
-        @param http_port: a strports specification describing which port the
-                          buildbot should use for its web server, with the
-                          Waterfall display as the root page. For backwards
-                          compatibility this can also be an int. Use
-                          'tcp:8000' to listen on that port, or
-                          'tcp:12345:interface=127.0.0.1' if you only want
-                          local processes to connect to it (perhaps because
-                          you are using an HTTP reverse proxy to make the
-                          buildbot available to the outside world, and do not
-                          want to make the raw port visible).
-
-        @type  distrib_port: int or L{twisted.application.strports} string
-        @param distrib_port: Use this if you want to publish the Waterfall
-                             page using web.distrib instead. The most common
-                             case is to provide a string that is an absolute
-                             pathname to the unix socket on which the
-                             publisher should listen
-                             (C{os.path.expanduser(~/.twistd-web-pb)} will
-                             match the default settings of a standard
-                             twisted.web 'personal web server'). Another
-                             possibility is to pass an integer, which means
-                             the publisher should listen on a TCP socket,
-                             allowing the web server to be on a different
-                             machine entirely. Both forms are provided for
-                             backwards compatibility; the preferred form is a
-                             strports specification like
-                             'unix:/home/buildbot/.twistd-web-pb'. Providing
-                             a non-absolute pathname will probably confuse
-                             the strports parser.
-
-        @type  allowForce: bool
-        @param allowForce: if True, present a 'Force Build' button on the
-                           per-Builder page that allows visitors to the web
-                           site to initiate a build. If False, don't provide
-                           this button.
-
-        @type  favicon: string
-        @param favicon: if set, provide the pathname of an image file that
-                        will be used for the 'favicon.ico' resource. Many
-                        browsers automatically request this file and use it
-                        as an icon in any bookmark generated from this site.
-                        Defaults to the buildbot/buildbot.png image provided
-                        in the distribution. Can be set to None to avoid
-                        using a favicon at all.
-
-        @type  robots_txt: string
-        @param robots_txt: if set, provide the pathname of a robots.txt file.
-                           Many search engines request this file and obey the
-                           rules in it. E.g. to disallow them to crawl the
-                           status page, put the following two lines in
-                           robots.txt::
-                              User-agent: *
-                              Disallow: /
-        """
-
-        base.StatusReceiverMultiService.__init__(self)
-        assert allowForce in (True, False) # TODO: implement others
-        if type(http_port) is int:
-            http_port = "tcp:%d" % http_port
-        self.http_port = http_port
-        if distrib_port is not None:
-            if type(distrib_port) is int:
-                distrib_port = "tcp:%d" % distrib_port
-            if distrib_port[0] in "/~.": # pathnames
-                distrib_port = "unix:%s" % distrib_port
-        self.distrib_port = distrib_port
-        self.allowForce = allowForce
-        self.categories = categories
-        self.css = css
-        self.favicon = favicon
-        self.robots_txt = robots_txt
-
-    def __repr__(self):
-        if self.http_port is None:
-            return "<Waterfall on path %s>" % self.distrib_port
-        if self.distrib_port is None:
-            return "<Waterfall on port %s>" % self.http_port
-        return "<Waterfall on port %s and path %s>" % (self.http_port,
-                                                       self.distrib_port)
-
-    def setServiceParent(self, parent):
-        """
-        @type  parent: L{buildbot.master.BuildMaster}
-        """
-        base.StatusReceiverMultiService.setServiceParent(self, parent)
-        self.setup()
-
-    def setup(self):
-        status = self.parent.getStatus()
-        if self.allowForce:
-            control = interfaces.IControl(self.parent)
-        else:
-            control = None
-        change_svc = self.parent.change_svc
-        sr = StatusResource(status, control, change_svc, self.categories,
-                            self.css)
-        sr.favicon = self.favicon
-        sr.robots_txt = self.robots_txt
-        self.site = server.Site(sr)
-
-        if self.http_port is not None:
-            s = strports.service(self.http_port, self.site)
-            s.setServiceParent(self)
-        if self.distrib_port is not None:
-            f = pb.PBServerFactory(distrib.ResourcePublisher(self.site))
-            s = strports.service(self.distrib_port, f)
-            s.setServiceParent(self)





More information about the Commits mailing list