Code

3415d8cedd2a0a33a4f270570bf91b9096bb9569
[roundup.git] / roundup / cgi / wsgi_handler.py
1 # WSGI interface for Roundup Issue Tracker
2 #
3 # This module is free software, you may redistribute it
4 # and/or modify under the same terms as Python.
5 #
7 import os
8 import cgi
9 import weakref
11 import roundup.instance
12 from roundup.cgi import TranslationService
13 from BaseHTTPServer import BaseHTTPRequestHandler
16 class Writer(object):
17     '''Perform a start_response if need be when we start writing.'''
18     def __init__(self, request):
19         self.request = request #weakref.ref(request)
20     def write(self, data):
21         f = self.request.get_wfile()
22         self.write = f
23         return f(data)
25 class RequestDispatcher(object):
26     def __init__(self, home, debug=False, timing=False, lang=None):
27         assert os.path.isdir(home), '%r is not a directory'%(home,)
28         self.home = home
29         self.debug = debug
30         self.timing = timing
31         if lang:
32             self.translator = TranslationService.get_translation(lang,
33                 tracker_home=home)
34         else:
35             self.translator = None
37     def __call__(self, environ, start_response):
38         """Initialize with `apache.Request` object"""
39         self.environ = environ
40         request = RequestDispatcher(self.home, self.debug, self.timing)
41         request.__start_response = start_response
43         request.wfile = Writer(request)
44         request.__wfile = None
46         tracker = roundup.instance.open(self.home, not self.debug)
48         # need to strip the leading '/'
49         environ["PATH_INFO"] = environ["PATH_INFO"][1:]
50         if request.timing:
51             environ["CGI_SHOW_TIMING"] = request.timing
53         form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
55         client = tracker.Client(tracker, request, environ, form,
56             request.translator)
57         try:
58             client.main()
59         except roundup.cgi.client.NotFound:
60             request.start_response([('Content-Type', 'text/html')], 404)
61             request.wfile.write('Not found: %s'%client.path)
63         # all body data has been written using wfile
64         return []
66     def start_response(self, headers, response_code):
67         """Set HTTP response code"""
68         description = BaseHTTPRequestHandler.responses[response_code]
69         self.__wfile = self.__start_response('%d %s'%(response_code,
70             description), headers)
72     def get_wfile(self):
73         if self.__wfile is None:
74             raise ValueError, 'start_response() not called'
75         return self.__wfile