Commits

Mike Bayer  committed 8c49f7a

progress

  • Participants
  • Parent commits ebaa786

Comments (0)

Files changed (2)

File tracvatar/htdocs/tracvatar.css

+img.tracvatar.ticket-reporter {
+  float:left;
+  padding:0 10px 10px 0px;
+}

File tracvatar/web_ui.py

 from trac.core import Component, implements
+from trac.config import Option
+from trac.web.chrome import ITemplateProvider, add_stylesheet
 from trac.web.api import ITemplateStreamFilter
 from genshi.filters.transform import Transformer
 from genshi.builder import tag
+from pkg_resources import resource_filename
 import itertools
 import textwrap
 import re
+import hashlib
 
 class GravatarModule(Component):
-    implements(ITemplateStreamFilter)
+    implements(ITemplateStreamFilter, ITemplateProvider)
+
+    ticket_reporter_size = Option("tracvatar", "ticket_reporter_size", default="60")
+    ticket_comment_size = Option("tracvatar", "ticket_comment_size", default="40")
+
+    default = Option('tracvatar', 'gravatar_default', default='default',
+                            doc="The default value to pass along to gravatar to "
+                            "use if the email address does not match.")
 
     def filter_stream(self, req, method, filename, stream, data):
         filter_ = []
+        author_data = {}
         if req.path_info.startswith("/ticket"):
-            filter_ = self._ticket_filter(data)
+            filter_.append(self._ticket_reporter_filter(data, author_data))
+            filter_.append(self._ticket_comment_filter(data, author_data))
         elif req.path_info.startswith("/timeline"):
-            filter_ = self._timeline_filter(data)
+            filter_.append(self._timeline_filter(data, author_data))
+        elif req.path_info.startswith("/attachment"):
+            filter_.append(self._attachment_filter(data, author_data))
 
+        self._lookup_email(author_data)
         for f in filter_:
-            stream |= f
+            if f is not None:
+                stream |= f
+        add_stylesheet(req, 'tracvatar/tracvatar.css')
         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]]
+    # ITemplateProvider methods
+    def get_htdocs_dirs(self):
+        yield 'tracvatar', resource_filename(__name__, 'htdocs')
 
-        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 get_templates_dirs(self):
+        return []
 
     def _node_attrs(self, node):
         """given a genshi node in a stream, return a dictionary of the 
 
         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 _generate_avatar(self, author, author_data, class_, size):
+        email_hash = author_data[author]
+        href = "http://www.gravatar.com/avatar/" + email_hash
+        href += "?size=%s" % size
+        # for some reason sizing doesn't work if you pass "default=default"
+        if self.default != 'default':
+            href += "&default=%s" % (self.default,)
+        return tag.img(src=href, class_='tracvatar %s' % class_).generate()
+
+    def _attachment_filter(self, data, author_data):
+        if 'attachments' not in data:
+            return
+
+    def _ticket_reporter_filter(self, data, author_data):
+        if 'ticket' not in data:
+            return
+        author = data['ticket'].values['reporter']
+        author_data[author] = None
+
+        return lambda stream: Transformer('//div[@id="ticket"]').\
+                    prepend(
+                        self._generate_avatar(
+                            author, 
+                            author_data, 
+                            'ticket-reporter', 
+                            self.ticket_reporter_size)
+                        )(stream)
+
+    def _ticket_comment_filter(self, data, author_data):
+        if 'changes' not in data:
+            return
+
+        change_data = {}
+        for change in data['changes']:
+            author = change['author']
+            author_data[author] = None
+            change_data[str(change['cnum'])] = author
 
         def find_change(stream):
             stream = iter(stream)
             else:
                 change = change.group(1)
 
-            elm = tag.img(src="foo_%s.png" % change)
-            stream = Transformer('//h3[@class="change"]').prepend(elm.generate())(stream)
+            author = change_data[change]
+            tag = self._generate_avatar(
+                        author, 
+                        author_data, 
+                        'ticket-comment', 
+                        self.ticket_comment_size)
+            stream = Transformer('//h3[@class="change"]').prepend(tag)(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)
+        return 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()]))
+    def _lookup_email(self, author_data):
+        authors = sorted(author_data)
         db = self.env.get_db_cnx()
         cursor = db.cursor()
         cursor.execute(
                 ",".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]]
+        for sid, email in cursor.fetchall():
+            author_data[sid] = hashlib.md5(email.lower()).hexdigest()