| Name | Title |
|---|---|
| Space | Pylons CookBook |
| Section | Recipes |
| Page | A Pylons Controller with Trac as WSGI Callable |
| Version | 1.0 |
| Status | Draft |
| Curator | Walter Rodrigo de Sá Cruz |
| Reviewed | False |
| Author(s) | Walter Rodrigo de Sá Cruz |
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!