/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk
422.3.2 by John Arbash Meinel
Fix bug #716201 by suppressing body content when getting a HEAD request.
1
# Copyright 2009, 2010, 2011 Canonical Ltd
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
262.2.1 by Martin Pool
Stub code to allow loggerhead to load as a plugin
17
18
# This file allows loggerhead to be treated as a plugin for bzr.
19
#
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
20
# XXX: Because loggerhead already contains a loggerhead directory, much of the
21
# code is going to appear loaded at bzrlib.plugins.loggerhead.loggerhead.
22
# This seems like the easiest thing, because bzrlib wants the top-level plugin
23
# directory to be the module, but when it's used as a library people expect
24
# the source directory to contain a directory called loggerhead.  -- mbp
25
# 20090123
26
27
"""Loggerhead web viewer for Bazaar branches.
28
329.2.1 by Matt Nordhoff
Strip trailing whitespace
29
This provides a new option "--http" to the "bzr serve" command, that
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
30
starts a web server to browse the contents of a branch.
31
"""
262.2.1 by Martin Pool
Stub code to allow loggerhead to load as a plugin
32
420 by Max Kanat-Alexander
Merge info file, mark as compatible with bzr 2.3.
33
from info import (
34
    bzr_plugin_version as version_info,
35
    bzr_compatible_versions,
36
    )
262.2.2 by Martin Pool
Merge in 'serve --http' based on code from mwh
37
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
38
if __name__ == 'bzrlib.plugins.loggerhead':
39
    import bzrlib
262.2.5 by Martin Pool
This loggerhead will work with bzr 1.13
40
    from bzrlib.api import require_any_api
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
41
420 by Max Kanat-Alexander
Merge info file, mark as compatible with bzr 2.3.
42
    require_any_api(bzrlib, bzr_compatible_versions)
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
43
44
    # NB: Normally plugins should lazily load almost everything, but this
45
    # seems reasonable to have in-line here: bzrlib.commands and options are
46
    # normally loaded, and the rest of loggerhead won't be loaded until serve
47
    # --http is run.
360 by Martin Albisetti
Avoid diluting sys.path if loggerhead is installed systemwide, install loggerhead as a plugin (Jelmer Vernooij)
48
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
49
    # transport_server_registry was added in bzr 1.16. When we drop support for
50
    # older releases, we can remove the code to override cmd_serve.
51
52
    try:
53
        from bzrlib.transport import transport_server_registry
54
    except ImportError:
55
        transport_server_registry = None
56
57
    DEFAULT_HOST = '0.0.0.0'
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
58
    DEFAULT_PORT = 8080
360 by Martin Albisetti
Avoid diluting sys.path if loggerhead is installed systemwide, install loggerhead as a plugin (Jelmer Vernooij)
59
    HELP = ('Loggerhead, a web-based code viewer and server. (default port: %d)' %
352.4.3 by Matt Nordhoff
Better line-wrapping
60
            (DEFAULT_PORT,))
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
61
405.1.4 by John Arbash Meinel
The basic support seems to be working, as evidenced by running against bzr.dev.
62
    def setup_logging(config):
63
        import logging
64
        import sys
65
66
        logger = logging.getLogger('loggerhead')
67
        handler = logging.StreamHandler(sys.stderr)
68
        handler.setLevel(logging.DEBUG)
69
        logger.addHandler(handler)
70
        logging.getLogger('simpleTAL').addHandler(handler)
71
        logging.getLogger('simpleTALES').addHandler(handler)
72
389.2.1 by Matt Nordhoff
Some random PEP 8 and otehr stylistic changes.
73
418.1.1 by John Arbash Meinel
Allow running the loggerhead test suite using 'bzr selftest'
74
    def _ensure_loggerhead_path():
75
        """Ensure that you can 'import loggerhead' and get the root."""
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
76
        # loggerhead internal code will try to 'import loggerhead', so
359.1.2 by Jelmer Vernooij
Avoid diluting sys.path if loggerhead is installed systemwide.
77
        # let's put it on the path if we can't find it in the existing path
78
        try:
405.1.3 by John Arbash Meinel
Change the import check so it actually works.
79
            import loggerhead.apps.transport
359.1.2 by Jelmer Vernooij
Avoid diluting sys.path if loggerhead is installed systemwide.
80
        except ImportError:
81
            import os.path, sys
82
            sys.path.append(os.path.dirname(__file__))
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
83
418.1.1 by John Arbash Meinel
Allow running the loggerhead test suite using 'bzr selftest'
84
    def serve_http(transport, host=None, port=None, inet=None):
422.3.2 by John Arbash Meinel
Fix bug #716201 by suppressing body content when getting a HEAD request.
85
        # TODO: if we supported inet to pass requests in and respond to them,
86
        #       then it would be easier to test the full stack, but it probably
87
        #       means routing around paste.httpserver.serve which probably
88
        #       isn't testing the full stack
418.1.1 by John Arbash Meinel
Allow running the loggerhead test suite using 'bzr selftest'
89
        from paste.httpexceptions import HTTPExceptionHandler
90
        from paste.httpserver import serve
91
92
        _ensure_loggerhead_path()
93
422.3.2 by John Arbash Meinel
Fix bug #716201 by suppressing body content when getting a HEAD request.
94
        from loggerhead.apps.http_head import HeadMiddleware
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
95
        from loggerhead.apps.transport import BranchesFromTransportRoot
96
        from loggerhead.config import LoggerheadConfig
389.2.1 by Matt Nordhoff
Some random PEP 8 and otehr stylistic changes.
97
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
98
        if host is None:
99
            host = DEFAULT_HOST
100
        if port is None:
101
            port = DEFAULT_PORT
359.2.2 by Matt Nordhoff
Fix a stupid mistake constructing argv
102
        argv = ['--host', host, '--port', str(port), '--', transport.base]
103
        if not transport.is_readonly():
104
            argv.insert(0, '--allow-writes')
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
105
        config = LoggerheadConfig(argv)
405.1.4 by John Arbash Meinel
The basic support seems to be working, as evidenced by running against bzr.dev.
106
        setup_logging(config)
388 by Matt Nordhoff
serve_http was passing a transport to BranchesFromTransportRoot, not an URL.
107
        app = BranchesFromTransportRoot(transport.base, config)
422.3.2 by John Arbash Meinel
Fix bug #716201 by suppressing body content when getting a HEAD request.
108
        app = HeadMiddleware(app)
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
109
        app = HTTPExceptionHandler(app)
110
        serve(app, host=host, port=port)
111
112
    if transport_server_registry is not None:
113
        transport_server_registry.register('http', serve_http, help=HELP)
114
    else:
115
        import bzrlib.builtins
116
        from bzrlib.commands import get_cmd_object, register_command
117
        from bzrlib.option import Option
118
119
        _original_command = get_cmd_object('serve')
120
121
        class cmd_serve(bzrlib.builtins.cmd_serve):
122
            __doc__ = _original_command.__doc__
123
124
            takes_options = _original_command.takes_options + [
125
                Option('http', help=HELP)]
126
127
            def run(self, *args, **kw):
128
                if 'http' in kw:
129
                    from bzrlib.transport import get_transport
359.2.1 by Matt Nordhoff
Add an --allow-writes option to serve-branches and "bzr serve"
130
                    allow_writes = kw.get('allow_writes', False)
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
131
                    path = kw.get('directory', '.')
132
                    port = kw.get('port', DEFAULT_PORT)
133
                    # port might be an int already...
134
                    if isinstance(port, basestring) and ':' in port:
135
                        host, port = port.split(':')
136
                    else:
137
                        host = DEFAULT_HOST
359.2.1 by Matt Nordhoff
Add an --allow-writes option to serve-branches and "bzr serve"
138
                    if allow_writes:
139
                        transport = get_transport(path)
140
                    else:
141
                        transport = get_transport('readonly+' + path)
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
142
                    serve_http(transport, host, port)
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
143
                else:
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
144
                    super(cmd_serve, self).run(*args, **kw)
262.2.2 by Martin Pool
Merge in 'serve --http' based on code from mwh
145
352.4.1 by Matt Nordhoff
Use the "bzr serve" protocol registry if it's available.
146
        register_command(cmd_serve)
418.1.1 by John Arbash Meinel
Allow running the loggerhead test suite using 'bzr selftest'
147
148
    def load_tests(standard_tests, module, loader):
149
        _ensure_loggerhead_path()
150
        standard_tests.addTests(loader.loadTestsFromModuleNames(
151
            ['bzrlib.plugins.loggerhead.loggerhead.tests']))
152
        return standard_tests