~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to serve-branches

  • Committer: Michael Hudson
  • Date: 2009-02-11 03:04:17 UTC
  • mto: This revision was merged to the branch mainline in revision 269.
  • Revision ID: michael.hudson@canonical.com-20090211030417-skieut3dp2hs666v
raise a 404 when passed an invalid revid

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# This program is free software; you can redistribute it and/or modify
 
3
# it under the terms of the GNU General Public License as published by
 
4
# the Free Software Foundation; either version 2 of the License, or
 
5
# (at your option) any later version.
 
6
#
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software
 
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
"""Search for branches underneath a directory and serve them all."""
 
17
 
 
18
import logging
 
19
import os
 
20
import sys
 
21
 
 
22
from optparse import OptionParser
 
23
 
 
24
from paste import httpserver
 
25
from paste.httpexceptions import HTTPExceptionHandler, HTTPInternalServerError
 
26
from paste.translogger import TransLogger
 
27
 
 
28
from loggerhead import __version__
 
29
from loggerhead.apps.filesystem import (
 
30
    BranchesFromFileSystemRoot, UserBranchesFromFileSystemRoot)
 
31
from loggerhead.util import Reloader
 
32
from loggerhead.apps.error import ErrorHandlerApp
 
33
 
 
34
 
 
35
def command_line_parser():
 
36
    parser = OptionParser("%prog [options] <path>")
 
37
    parser.set_defaults(
 
38
        user_dirs=False,
 
39
        show_version=False,
 
40
        log_folder=None,
 
41
        )
 
42
    parser.add_option("--user-dirs", action="store_true", dest="user_dirs",
 
43
                      help="Serve user directories as ~user.")
 
44
    parser.add_option("--trunk-dir", metavar="DIR",
 
45
                      help="The directory that contains the trunk branches.")
 
46
    parser.add_option("--port", dest="user_port",
 
47
                      help=("Port Loggerhead should listen on "
 
48
                            "(defaults to 8080)."))
 
49
    parser.add_option("--host", dest="user_host",
 
50
                      help="Host Loggerhead should listen on.")
 
51
    parser.add_option("--prefix", dest="user_prefix",
 
52
                      help="Specify host prefix.")
 
53
    parser.add_option("--profile", action="store_true", dest="profile",
 
54
                      help="Generate callgrind profile data to "
 
55
                        "%d-stats.callgrind on each request.")
 
56
    parser.add_option("--reload", action="store_true", dest="reload",
 
57
                      help="Restarts the application when changing python"
 
58
                           " files. Only used for development purposes.")
 
59
    parser.add_option('--log-folder', dest="log_folder",
 
60
                      type=str, help="The directory to place log files in.")
 
61
    parser.add_option("--version", action="store_true", dest="show_version",
 
62
                      help="Print the software version and exit")
 
63
    return parser
 
64
 
 
65
 
 
66
def main(args):
 
67
    parser = command_line_parser()
 
68
    (options, args) = parser.parse_args(sys.argv[1:])
 
69
 
 
70
    if options.show_version:
 
71
        print "loggerhead %s" % __version__
 
72
        sys.exit(0)
 
73
 
 
74
    if len(args) > 1:
 
75
        parser.print_help()
 
76
        sys.exit(1)
 
77
    elif len(args) == 1:
 
78
        [path] = args
 
79
    else:
 
80
        path = '.'
 
81
 
 
82
    if not os.path.isdir(path):
 
83
        print "%s is not a directory" % path
 
84
        sys.exit(1)
 
85
 
 
86
    if options.trunk_dir and not options.user_dirs:
 
87
        print "--trunk-dir is only valid with --user-dirs"
 
88
        sys.exit(1)
 
89
 
 
90
    if options.reload:
 
91
        if Reloader.is_installed():
 
92
            Reloader.install()
 
93
        else:
 
94
            return Reloader.restart_with_reloader()
 
95
 
 
96
    if options.user_dirs:
 
97
        if not options.trunk_dir:
 
98
            print "You didn't specify a directory for the trunk directories."
 
99
            sys.exit(1)
 
100
        app = UserBranchesFromFileSystemRoot(path, options.trunk_dir)
 
101
    else:
 
102
        app = BranchesFromFileSystemRoot(path)
 
103
 
 
104
    # setup_logging()
 
105
    logging.basicConfig()
 
106
    logging.getLogger('').setLevel(logging.DEBUG)
 
107
    logger = getattr(app, 'log', logging.getLogger('loggerhead'))
 
108
    if options.log_folder:
 
109
        logfile_path = os.path.join(options.log_folder, 'serve-branches.log')
 
110
    else:
 
111
        logfile_path = 'serve-branches.log'
 
112
    logfile = logging.FileHandler(logfile_path, 'a')
 
113
    formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(name)s:'
 
114
                                  ' %(message)s')
 
115
    logfile.setFormatter(formatter)
 
116
    logfile.setLevel(logging.DEBUG)
 
117
    logger.addHandler(logfile)
 
118
    # setup_logging() #end
 
119
    app = TransLogger(app, logger=logger)
 
120
    if options.profile:
 
121
        from loggerhead.middleware.profile import LSProfMiddleware
 
122
        app = LSProfMiddleware(app)
 
123
 
 
124
    if not options.user_prefix:
 
125
        prefix = '/'
 
126
    else:
 
127
        prefix = options.user_prefix
 
128
 
 
129
    try:
 
130
        from paste.deploy.config import PrefixMiddleware
 
131
    except ImportError:
 
132
        cant_proxy_correctly_message = (
 
133
            'Unsupported configuration: PasteDeploy not available, but '
 
134
            'loggerhead appears to be behind a proxy.')
 
135
        def check_not_proxied(app):
 
136
            def wrapped(environ, start_response):
 
137
                if 'HTTP_X_FORWARDED_SERVER' in environ:
 
138
                    exc = HTTPInternalServerError()
 
139
                    exc.explanation = cant_proxy_correctly_message
 
140
                    raise exc
 
141
                return app(environ, start_response)
 
142
            return wrapped
 
143
        app = check_not_proxied(app)
 
144
    else:
 
145
        app = PrefixMiddleware(app, prefix=prefix)
 
146
 
 
147
    app = HTTPExceptionHandler(app)
 
148
    app = ErrorHandlerApp(app)
 
149
 
 
150
    if not options.user_port:
 
151
        port = '8080'
 
152
    else:
 
153
        port = options.user_port
 
154
 
 
155
    if not options.user_host:
 
156
        host = '0.0.0.0'
 
157
    else:
 
158
        host = options.user_host
 
159
 
 
160
    httpserver.serve(app, host=host, port=port)
 
161
 
 
162
 
 
163
if __name__ == "__main__":
 
164
    main(sys.argv)