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.

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts

Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.




Reader Comments

Be the first to leave a comment!