""" display SVN URLs in trac's respository browser """ from genshi.builder import tag from genshi.filters.transform import StreamBuffer from genshi.filters.transform import Transformer from genshi.input import TEXT from trac.core import * from trac.config import Option from trac.web import ITemplateStreamFilter class SVNURLs(Component): implements(ITemplateStreamFilter) ### class data svn_base_url = Option('svnurls', 'svn_base_url', doc="base URL of svn repository") link_text = Option('svnurls', 'link_text', default='[svn]', doc="text display for svn url links") link_title = "URL of SVN location" def url(self, path): return u'/'.join((self.svn_base_url.rstrip(u'/'), path.lstrip(u'/'))) ### methods for handling different views ### these should return the stream def browser(self, stream, data): if not data.has_key('path') # this probably means that there is an upstream error return stream # mark up the title # XXX disabled due to a bug in Transformer.substitute # - see http://genshi.edgewall.org/ticket/226 # stream |= Transformer('//title/text()').substitute('/', data['svn_base_url'] '/') # provide a link to the svn repository stream |= Transformer("//div[@id='content']/h1").after(tag.a(self.link_text, href=self.url(data['path']), title=self.link_title)) # if a directory, provide links to the children files if data['dir']: pos = 1 offset = 2 # table header, index of 0 (python) versus 1 (xpath) if data['path'] != '/': offset = 1 # parent directory row # add the table header stream |= Transformer("//table[@id='dirlist']//th[%s]" % pos).after(tag.th('URL')) # add table cells for idx, entry in enumerate(data['dir']['entries']): contents = "%s of %s" % (idx, len(data['dir']['entries'])) stream |= Transformer("//table[@id='dirlist']//tr[%s]/td[%s]" % (offset idx, pos)).after(tag.td(tag.a(self.link_text, href=self.url(entry.path), title=self.link_title))) return stream def svnlog(self, stream, data): return stream # method for ITemplateStreamFilter def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. `req` is the current request object, `method` is the Genshi render method (xml, xhtml or text), `filename` is the filename of the template to be rendered, `stream` is the event stream and `data` is the data for the current template. See the Genshi documentation for more information. """ svn_base_url = self.svn_base_url.rstrip('/') handlers = { '/browser': self.browser, '/log': self.svnlog, } path = req.environ.get('PATH_INFO') if svn_base_url: for handler in handlers: if path.startswith(handler): import pdb; pdb.set_trace() return handlers[handler](stream, data) return stream