A Pylons controller with Trac as a WSGI callable
This tutorial shows a similar example from "A Pylons Controller with MoinMoin as WSGI Callable"
Introduction
This is a simple walk through of how to plug Trac
into a Pylons controller.
Requirements are Pylons 0.9.4.1 (or later)
The Process
The four-step sequence is:
- install Trac
- create a new trac instance
- add a Pylons trac controller and a route that maps to the trac instance.
install Trac
You can install by easy_install trac or using your Linux distribution package manager.
Create a new trac instance
trac-admin /var/trac/tracinstance initenv
I will ask you a lot of questions that you must answer.
- Add a Pylons trac controller and a route that maps to the trac instance.
Create a new file: myproject/controllers/trac.py and add the following as its content (changing the two instances of myproject to your app's name):
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 | from __future__ import absolute_import
from myproject.lib.base import *
from trac.web.main import dispatch_request
from authkit.permissions import NotAuthenticatedError
import os, StringIO, urllib
template = """\
<html>
<head><title>Please Login!</title></head>
<body>
<h1>Please Login</h1>
<form action="" method="post">
<dl>
<dt>Username:</dt>
<dd><input type="text" name="username"></dd>
<dt>Password:</dt>
<dd><input type="password" name="password"></dd>
</dl>
<input type="hidden" name="r" value="%s" />
<input type="submit" name="authform" />
<hr />
</form>
</body>
</html>
"""
class TracController(BaseController):
def tracpage(self, *args, **kwargs):
# Thanks to ianbicking for a workaround of an empty wsgi.input value
if request.environ.get('paste.parsed_formvars', False):
wsgi_input = urllib.urlencode(
request.environ['paste.parsed_formvars'][0], True)
request.environ['wsgi.input'] = StringIO.StringIO(wsgi_input)
request.environ['CONTENT_LENGTH'] = len(wsgi_input)
os.environ['TRAC_ENV'] = "/var/trac/tracinstance"
if request.environ['PATH_INFO'] == '/logout':
del(session['user'])
session.save()
h.redirect_to('/')
if request.environ['PATH_INFO'] == '/login' and not session.get('user'):
#raise NotAuthenticatedError('Not Authenticated')
return self._redirect_to_sign_in()
if session.get('user'):
request.environ['REMOTE_USER'] = session.get('user')
a = dispatch_request(request.environ, self.start_response)
if len(a) == 0:
return ['']
return a
def _redirect_to_sign_in(self):
if len(request.params) > 1 and request.params['password'] == request.params['username']:
session['user'] = request.params['username']
session.save()
h.redirect_to('/')
else:
return Response(template)
|
Next, edit myproject/config/routing.py, adding the following route:
1 | map.connect('trac/*path_info', controller='trac', action='tracpage', path_info='/')
|
Create the tree /trac/chrome/common inside the /public folder of your pylons application. Copy all the static content from trac to this folder (In my system, it's located at /usr/share/trac/htdocs).
The authentication that i'm using is a pretty simple: username == password.
And look that there's some problem using the authkit middleware.
The section:
1
2
3
4 | a = dispatch_request(request.environ, self.start_response)
if len(a) == 0:
return ['']
return a
|
looks weird. It's a workaround to 'No content returned from controller' that happens without it.
Check the results
Browse to [http://localhost:5000/trac/] and start using your trac inside pylons!