source: hackergotchiplugin/0.11/hackergotchi/web_ui.py

Last change on this file was 16756, checked in by Ryan J Ollos, 7 years ago

TracHackergotchi 1.2: Run autopep8 on codebase

File size: 4.1 KB
Line 
1# Created by Noah Kantrowitz on 2008-05-16.
2# Copyright (c) 2008 Noah Kantrowitz. All rights reserved.
3import itertools
4import re
5
6
7from trac.core import *
8from trac.web.api import ITemplateStreamFilter
9from trac.web.chrome import ITemplateProvider, add_stylesheet
10from trac.config import Option, OrderedExtensionsOption
11from genshi.builder import tag
12from genshi.filters.transform import Transformer
13from pkg_resources import resource_filename
14
15from hackergotchi.api import IHackergotchiProvider
16
17
18class HackergotchiModule(Component):
19    """A stream filter to add hackergotchi emblems to the timeline."""
20
21    providers = OrderedExtensionsOption('hackergotchi', 'providers',
22                                        IHackergotchiProvider,
23                                        default='GravatarHackergotchiProvider, IdenticonHackergotchiProvider')
24
25    implements(ITemplateStreamFilter, ITemplateProvider)
26
27    anon_re = re.compile('([^<]+?)\s+<([^>]+)>', re.U)
28
29    # ITemplateStreamFilter methods
30    def filter_stream(self, req, method, filename, stream, data):
31        if req.path_info.startswith('/timeline'):
32            closure_state = [0]
33            cache = {}
34
35            def f(stream):
36                # Update the closed value
37                n = closure_state[0]
38                closure_state[0] += 1
39
40                # Extract the user information
41                author = data['events'][n]['author'].strip()
42                user_info = cache.get(author)
43                if user_info is not None:
44                    author, name, email = user_info
45                else:
46                    db = self.env.get_db_cnx()
47                    user_info = self._get_info(author, db)
48                    cache[author] = user_info
49                    author, name, email = user_info
50
51                # Try to find a provider
52                for provider in self.providers:
53                    href = provider.get_hackergotchi(
54                        req.href, author, name, email)
55                    if href is not None:
56                        break
57                else:
58                    href = req.href.chrome('hackergotchi', 'default.png')
59
60                # Build our element
61                elm = tag.img(src=href, alt='Hackergotchi for %s' % author,
62                              class_='hackergotchi')
63
64                # Output the combined stream
65                return itertools.chain(elm.generate(), stream)
66
67            stream |= Transformer(
68                '//div[@id="content"]/dl/dt/a/span[@class="time"]').filter(f)
69            add_stylesheet(req, 'hackergotchi/hackergotchi.css')
70        return stream
71
72    # ITemplateProvider methods
73    def get_htdocs_dirs(self):
74        yield 'hackergotchi', resource_filename(__name__, 'htdocs')
75
76    def get_templates_dirs(self):
77        # return [resource_filename(__name__, 'templates')]
78        return []
79
80    # Internal methods
81    def _get_info(self, author, db):
82        if author == 'anonymous':
83            # Don't even bother trying for "anonymous"
84            return author, None, None
85
86        md = self.anon_re.match(author)
87        if md:
88            # name <email>
89            return 'anonymous', md.group(1), md.group(2)
90
91        cursor = db.cursor()
92        cursor.execute('SELECT name, value FROM session_attribute WHERE sid=%s AND authenticated=%s',
93                       (author, 1))
94        rows = cursor.fetchall()
95        if rows:
96            # Authenticated user, with session
97            name = email = None
98            for key, value in rows:
99                if key == 'name':
100                    name = value
101                elif key == 'email':
102                    email = value
103            if name or email:
104                return author, name, email
105            else:
106                return author, None, None
107
108        # Assume anonymous user from this point on
109        if '@' in author:
110            # Likely an email address
111            return 'anonymous', None, author
112
113        # See if there is a default domain
114        domain = self.config.get('notification', 'smtp_default_domain')
115        if domain and ' ' not in author:
116            return author, None, author + '@' + domain
117
118        return 'anonymous', author, None
Note: See TracBrowser for help on using the repository browser.