2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
"""I contain PythonScript, which is a very simple python script resource.
15
import cStringIO as StringIO
19
from twisted.web import http
20
from twisted import copyright
23
from twisted.web import resource
24
from twisted.web import static
26
rpyNoResource = """<p>You forgot to assign to the variable "resource" in your script. For example:</p>
30
import mygreatresource
32
resource = mygreatresource.MyGreatResource()
36
class AlreadyCached(Exception):
37
"""This exception is raised when a path has already been cached.
41
def __init__(self, path, registry):
43
self.registry = registry
47
c = self.registry.getCachedPath(self.path)
49
raise AlreadyCached(c)
55
noRsrc = error.ErrorPage(500, "Whoops! Internal Error", rpyNoResource)
57
def ResourceScript(path, registry):
59
I am a normal py file which must define a 'resource' global, which should
60
be an instance of (a subclass of) web.resource.Resource; it will be
63
cs = CacheScanner(path, registry)
64
glob = {'__file__': path,
68
'recache': cs.recache}
70
execfile(path, glob, glob)
71
except AlreadyCached, ac:
73
rsrc = glob['resource']
74
if cs.doCache and rsrc is not noRsrc:
75
registry.cachePath(path, rsrc)
78
def ResourceTemplate(path, registry):
79
from quixote import ptl_compile
81
glob = {'__file__': path,
82
'resource': error.ErrorPage(500, "Whoops! Internal Error",
86
e = ptl_compile.compile_template(open(path), path)
88
return glob['resource']
91
class ResourceScriptWrapper(resource.Resource):
93
def __init__(self, path, registry=None):
94
resource.Resource.__init__(self)
96
self.registry = registry or static.Registry()
98
def render(self, request):
99
res = ResourceScript(self.path, self.registry)
100
return res.render(request)
102
def getChildWithDefault(self, path, request):
103
res = ResourceScript(self.path, self.registry)
104
return res.getChildWithDefault(path, request)
108
class ResourceScriptDirectory(resource.Resource):
109
def __init__(self, pathname, registry=None):
110
resource.Resource.__init__(self)
112
self.registry = registry or static.Registry()
114
def getChild(self, path, request):
115
fn = os.path.join(self.path, path)
117
if os.path.isdir(fn):
118
return ResourceScriptDirectory(fn, self.registry)
119
if os.path.exists(fn):
120
return ResourceScript(fn, self.registry)
121
return error.NoResource()
123
def render(self, request):
124
return error.NoResource().render(request)
127
class PythonScript(resource.Resource):
128
"""I am an extremely simple dynamic resource; an embedded python script.
130
This will execute a file (usually of the extension '.epy') as Python code,
131
internal to the webserver.
134
def __init__(self, filename, registry):
135
"""Initialize me with a script name.
137
self.filename = filename
138
self.registry = registry
140
def render(self, request):
141
"""Render me to a web client.
143
Load my file, execute it in a special namespace (with 'request' and
144
'__file__' global vars) and finish the request. Output to the web-page
145
will NOT be handled with print - standard output goes to the log - but
148
request.setHeader("x-powered-by","Twisted/%s" % copyright.version)
149
namespace = {'request': request,
150
'__file__': self.filename,
151
'registry': self.registry}
153
execfile(self.filename, namespace, namespace)
155
if e.errno == 2: #file not found
156
request.setResponseCode(http.NOT_FOUND)
157
request.write(error.NoResource("File not found.").render(request))
159
io = StringIO.StringIO()
160
traceback.print_exc(file=io)
161
request.write(html.PRE(io.getvalue()))
163
return server.NOT_DONE_YET