/usr/share/pyshared/boboserver.py is in python-bobo 0.2.2-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | ##############################################################################
#
# Copyright Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Create WSGI-based web applications.
"""
__all__ = (
'Debug',
'Reload',
'server',
'static',
)
__metaclass__ = type
import bobo
import optparse
import os
import mimetypes
import pdb
import re
import sys
import traceback
import types
import webob
def run_server(app, port):
wsgiref.simple_server.make_server('', port, app).serve_forever()
if sys.version_info >= (2, 5):
import wsgiref.simple_server
else:
# can't use wsgiref, use paste
import paste.httpserver
def run_server(app, port):
paste.httpserver.server_runner(app, {}, port=port)
class Directory:
def __init__(self, root, path=None):
self.root = os.path.abspath(root)+os.path.sep
self.path = path or root
@bobo.query('')
def base(self, bobo_request):
return bobo.redirect(bobo_request.url+'/')
@bobo.query('/')
def index(self):
links = []
for name in os.listdir(self.path):
if os.path.isdir(os.path.join(self.path, name)):
name += '/'
links.append('<a href="%s">%s</a>' % (name, name))
return """<html>
<head><title>%s</title></head>
<body>
%s
</body>
</html>
""" % (self.path[len(self.root):], '<br>\n '.join(links))
@bobo.subroute('/:name')
def traverse(self, request, name):
path = os.path.abspath(os.path.join(self.path, name))
if not path.startswith(self.root):
raise bobo.NotFound
if os.path.isdir(path):
return Directory(self.root, path)
else:
return File(path)
bobo.scan_class(Directory)
class File:
def __init__(self, path):
self.path = path
@bobo.query('')
def base(self, bobo_request):
response = webob.Response()
content_type = mimetypes.guess_type(self.path)[0]
if content_type is not None:
response.content_type = content_type
try:
response.body = open(self.path, 'rb').read()
except IOError:
raise bobo.NotFound
return response
bobo.scan_class(File)
def static(route, directory):
"""Create a resource that serves static files from a directory
"""
return bobo.preroute(route, Directory(directory))
class Reload:
"""Module-reload middleware
This middleware can *only* be used with bobo applications. It
monitors a list of modules given by a ``modules`` keyword
parameter and configuration option. When a module changes, it
reloads the module and reinitializes the bobo application.
The Reload class implements the `Paste Deployment
filter_app_factory protocol
<http://pythonpaste.org/deploy/#paste-filter-app-factory>`_ and is
exported as a ``paste.filter_app_factory`` entry point named ``reload``.
"""
def __init__(self, app, default, modules):
if not isinstance(app, bobo.Application):
raise TypeError("Reload can only be used with bobo applications")
self.app = app
self.mtimes = mtimes = {}
for name in modules.split():
module = sys.modules[name]
mtimes[name] = (module.__file__, os.stat(module.__file__).st_mtime)
def __call__(self, environ, start_response):
for name, (path, mtime) in self.mtimes.iteritems():
if os.stat(path).st_mtime != mtime:
print 'Reloading', name
execfile(path, sys.modules[name].__dict__)
self.app.__init__(self.app.config)
self.mtimes[name] = path, os.stat(path).st_mtime
return self.app(environ, start_response)
class Debug:
"""Post-mortem debugging middleware
This middleware catches uncaught exceptions and runs the
``pdb.post_mortem`` debugging function, helping you to debug
exceptions raised by your application.
The Debug class implements the `Paste Deployment
filter_app_factory protocol
<http://pythonpaste.org/deploy/#paste-filter-app-factory>`_ and is
exported as a ``paste.filter_app_factory`` entry point named ``debug``.
"""
def __init__(self, app, default=None):
self.app = app
def __call__(self, environ, start_response):
try:
return self.app(environ, start_response)
except:
traceback.print_exception(*sys.exc_info())
pdb.post_mortem(sys.exc_info()[2])
raise
_mod_re = re.compile(
"(^|>) *(\w[a-zA-Z_.]*)(:|$)"
).search
def server(args=None, Application=bobo.Application):
"""Bobo development server
The server function implements the bobo development server.
It is exported as a ``console_script`` entry point named ``bobo``.
An alternate application can be passed in to run the server with a
different application implementation as long as application passed
in subclasses bobo.Application.
"""
if args is None:
import logging; logging.basicConfig()
args = sys.argv[1:]
usage = "%prog [options] name=value ..."
if sys.version_info >= (2, 5):
usage = 'Usage: ' + usage
parser = optparse.OptionParser(usage)
parser.add_option(
'--port', '-p', type='int', dest='port', default=8080,
help="Specify the port to listen on.")
parser.add_option(
'--file', '-f', dest='file', action='append',
help="Specify a source file to publish.")
parser.add_option(
'--resource', '-r', dest='resource', action='append',
help=("Specify a resource, such as a module or module global,"
" to publish."))
parser.add_option(
'--debug', '-D', action='store_true', dest='debug',
help="Run the post mortem debugger for uncaught exceptions.")
parser.add_option(
'-c', '--configure', dest='configure',
help="Specify the bobo_configure option.")
parser.add_option(
'-s', '--static', dest='static', action='append',
help=("Specify a route and directory (route=directory)"
" to serve statically"))
def error(message):
sys.stderr.write("Error:\n%s\n\n" % message)
parser.parse_args(['-h'])
options, pos = parser.parse_args(args)
resources = options.resource or []
mname = 'bobo__main__'
for path in options.file or ():
module = types.ModuleType(mname)
module.__file__ = path
execfile(module.__file__, module.__dict__)
sys.modules[module.__name__] = module
resources.append(module.__name__)
mname += '_'
for s in options.static or ():
route, path = s.split('=', 1)
resources.append("boboserver:static(%r,%r)" % (route, path))
if not resources:
error("No resources were specified.")
if [a for a in pos if '=' not in a]:
error("Positional arguments must be of the form name=value.")
app_options = dict(a.split('=', 1) for a in pos)
module_names = [m.group(2)
for m in map(_mod_re, resources)
if m is not None]
if options.configure:
if (':' not in options.configure) and module_names:
options.configure = module_names[0]+':'+options.configure
app_options['bobo_configure'] = options.configure
app = Application(app_options, bobo_resources='\n'.join(resources))
app = Reload(app, None, ' '.join(module_names))
if options.debug:
app = Debug(app)
print "Serving %s on port %s..." % (resources, options.port)
run_server(app, options.port)
|