Modifying Trac Project List with WSGI
Here is my log of how I modified Project List on http://beecoop.com/projecs.
Terminology:
Trac calls this: Environment Index
from here: http://code.google.com/p/modwsgi/wiki/IntegrationWithTrac
I got instructions to make following modification in my /var/lib/trac/apache/apache.wsgi
import trac.web.main
import sys
sys.stdout = sys.stderr
_application = trac.web.main.dispatch_request
def application(environ, start_response):
environ['trac.env_parent_dir'] = '/var/lib/trac/sites'
environ['trac.env_index_template'] = '/var/lib/trac/global/templates/projects.html'
return _application(environ, start_response)
environ['trac.env_index_template'] indicates where the template for this page is located.
the default template is here: http://trac.edgewall.org/browser/trunk/trac/templates/index.html
I just copied it from there.
Now, I don’t want to show private projects on /projects page, so I modified my /var/lib/trac/apache/apache.wsgi in the following way.
import sys
import pkg_resources
from genshi.core import Markup
from genshi.builder import Fragment, tag
from genshi.output import DocType
from genshi.template import TemplateLoader
import trac.web.main
from trac import __version__ as TRAC_VERSION
from trac.util.datefmt import format_datetime, http_date, localtz, timezone
from trac.util.text import to_unicode
from trac.web.api import *
from trac import perm
sys.stdout = sys.stderr
def projects(environ, start_response):
req = Request(environ, start_response)
loadpaths = [pkg_resources.resource_filename('trac', 'templates')]
template = environ['trac.env_index_template']
data = {'trac': {'version': TRAC_VERSION, 'time': format_datetime()}, 'req': req}
if req.environ.get('trac.template_vars'):
for pair in req.environ['trac.template_vars'].split(','):
key, val = pair.split('=')
data[key] = val
if use_clearsilver:
req.hdf[key] = val
try:
href = Href(req.base_path)
projects = []
for env_name, env_path in trac.web.main.get_environments(environ).items():
try:
env = trac.web.main.open_environment(env_path,
use_cache=not environ['wsgi.run_once'])
# check if project has anonymous access
permissions = perm.PermissionSystem(env)
if permissions.get_user_permissions('anonymous'):
proj = {
'name': env.project_name,
'description': env.project_description,
'href': href(env_name)
}
projects.append(proj)
except Exception, e:
proj = {'name': env_name, 'description': to_unicode(e)}
projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
data['projects'] = projects
loader = TemplateLoader(loadpaths, variable_lookup='lenient')
tmpl = loader.load(template)
stream = tmpl.generate(**data)
output = stream.render('xhtml', doctype=DocType.XHTML_STRICT)
req.send(output, 'text/html')
except RequestDone:
pass
_trac = trac.web.main.dispatch_request
def application(environ, start_response):
environ['trac.env_parent_dir'] = '/var/lib/trac/sites'
environ['trac.env_index_template'] = '/var/lib/trac/global/templates/projects.html'
if environ['REQUEST_URI'] != '/projects/':
return _trac(environ, start_response)
else:
return projects(environ, start_response)
Next, is going to be shared sessions across all projects and modifying this view to show public projects and projects that I have access to.
