All pastes #1018102 Raw Edit

Something

public text v1 · immutable
#1018102 ·published 2008-05-14 15:59 UTC
rendered paste body
"""
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