Source

tracvatar / tracvatar / web_ui.py

from trac.core import Component, implements
from trac.web.api import ITemplateStreamFilter
from genshi.filters.transform import Transformer
from genshi.builder import tag
import itertools
import textwrap
import re

class GravatarModule(Component):
    implements(ITemplateStreamFilter)

    def filter_stream(self, req, method, filename, stream, data):
        filter_ = []
        if req.path_info.startswith("/ticket"):
            filter_ = self._ticket_filter(data)
        elif req.path_info.startswith("/timeline"):
            filter_ = self._timeline_filter(data)

        for f in filter_:
            stream |= f
        return stream

    def _crap(self):
        if tracvatar_data:
            hashes = self._get_hashes([t[2] for t in tracvatar_data])
            for t in tracvatar_data:
                if t[2] in hashes:
                    t[3] = hashes[t[2]]

        def f(stream):
            stream = iter(stream)
            elem = next(stream)
            yield elem

            for elem in tag.script(
                "\njQuery(document).ready(function($) {\n    " + 
                "\n    ".join(self._js_calls(page, tracvatar_data)) + 
                "\n}"
                ,type="text/javascript"
            ).generate():
                yield elem

            for elem in stream:
                yield elem

    def _node_attrs(self, node):
        """given a genshi node in a stream, return a dictionary of the 
        'attrs' portion."""

        return dict([(str(qname), value) for qname, value in node[1][1]])

    def _ticket_filter(self, data):
        tracvatar_data = {}
        if 'ticket' in data:
            tracvatar_data['reporter'] = [data['ticket'].values['reporter'], None]
        if 'changes' in data:
            for change in data['changes']:
                tracvatar_data[('change', change['cnum'])] = [change['author'], None]
        self._get_hashes(tracvatar_data)

        def find_change(stream):
            stream = iter(stream)
            start_tag = next(stream)
            attrs = self._node_attrs(start_tag)
            change = re.match(r'trac\-change\-(\d+)', attrs["id"])
            if not change:
                return itertools.chain([start_tag], stream)
            else:
                change = change.group(1)

            elm = tag.img(src="foo_%s.png" % change)
            stream = Transformer('//h3[@class="change"]').prepend(elm.generate())(stream)
            return itertools.chain([start_tag], stream)

        return \
            Transformer('//div[@id="ticket"]').prepend(tag.img(src="foo.png").generate()),\
            Transformer('//div[@id="changelog"]/div[@class="change"]').filter(find_change)

    def _get_hashes(self, tracvatar_data):
        authors = sorted(set([t[0] for t in tracvatar_data.values()]))
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute(
            "select sid, value from session_attribute where name=%%s and sid in (%s)" % (
                ",".join(["%s" for author in authors])
            ), ("email",) + tuple(authors)
        )
        hashes = {}
        for sid, value in cursor.fetchall():
            hashes[sid] = value
        for values in tracvatar_data.values():
            if values[0] in hashes:
                values[1] = hashes[values[0]]