source: accountmanagerplugin/0.11/acct_mgr/macros.py @ 12400

Last change on this file since 12400 was 12400, checked in by Steffen Hoffmann, 11 years ago

AccountManagerPlugin: Sync 0.11 with acct_mgr-0.4, the new stable release.

File size: 6.3 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2012 Steffen Hoffmann <hoff.st@web.de>
4# All rights reserved.
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution.
8#
9# Author: Steffen Hoffmann <hoff.st@web.de>
10
11from genshi.builder import Markup, tag
12
13from trac.core import Component, implements
14from trac.perm import PermissionSystem
15from trac.util.compat import sorted
16from trac.web.chrome import Chrome
17from trac.wiki.api import IWikiMacroProvider, WikiSystem, parse_args
18from trac.wiki.formatter import format_to_oneliner
19
20from acct_mgr.admin import fetch_user_data
21from acct_mgr.api import AccountManager, CommonTemplateProvider, _
22from acct_mgr.guard import AccountGuard
23from acct_mgr.util import get_pretty_dateinfo
24
25
26class AccountManagerWikiMacros(CommonTemplateProvider):
27    """Provides wiki macros related to Trac accounts/authenticated users."""
28
29    implements(IWikiMacroProvider)
30   
31    # IWikiMacroProvider
32
33    def get_macros(self):
34        yield 'ProjectStats'
35        yield 'UserQuery'
36
37    def get_macro_description(self, name):
38        if name == 'ProjectStats':
39            return """Wiki macro listing some generic Trac statistics.
40
41This macro accepts a comma-separated list of keyed parameters, in the form
42"key=value". Valid keys:
43 * '''wiki''' -- statistics for TracWiki, values:
44  * ''count'' -- show wiki page count
45 * '''prefix''' -- use with ''wiki'' key: only names that start with that
46 prefix are included
47
48'count' is also recognized without prepended key name.
49"""
50
51        elif name == 'UserQuery':
52            return """Wiki macro listing users that match certain criteria.
53
54This macro accepts a comma-separated list of keyed parameters, in the form
55"key=value". Valid keys:
56 * '''perm''' -- show only that users, a permission action given by ''value''
57 has been granted to
58 * '''locked''' -- retrieve users, who's account has/has not been locked
59 depending on boolean value
60 * '''format''' -- output style: 'count', 'list' or comma-separated values
61 (default)
62 * '''nomatch''' -- replacement wiki markup that is displayed, if there's
63 no match and output style isn't 'count' either
64
65'count' is also recognized without prepended key name. Other non-keyed
66parameters are:
67 * '''locked''' -- alias for 'locked=True'
68 * '''visit''' -- show a list of accounts with last-login information, only
69 available in table format
70 * '''name''' -- forces replacement of maching username with their
71 corresponding full names, if available; adds a full names column if combined
72 with 'visit'
73 * '''email''' -- append email address to usernames, if available
74
75Requires `USER_VIEW` permission for output in any format other then 'count'.
76A misc placeholder with this statement is presented to unprivileged users.
77"""
78
79    def expand_macro(self, formatter, name, content):
80        env = formatter.env
81        req = formatter.req
82        if not content:
83            args = []
84            kw = {}
85        else:
86            args, kw = parse_args(content)
87        if name == 'ProjectStats':
88            if 'wiki' in kw.keys():
89                prefix = 'prefix' in kw.keys() and kw['prefix'] or None
90                wiki = WikiSystem(env)
91                if kw['wiki'] == 'count' or 'count' in args:
92                    return tag(sum(1 for page in wiki.get_pages(prefix)))
93        elif name == 'UserQuery':
94            msg_no_perm = tag.p(Markup(_("(required %(perm)s missing)",
95                                         perm=tag.strong('USER_VIEW'))),
96                                class_='hint')
97            users = []
98            if 'perm' in kw.keys():
99                perm_sys = PermissionSystem(self.env)
100                users = perm_sys.get_users_with_permission(kw['perm'].upper())
101            else:
102                acct_mgr = AccountManager(env)
103                users = list(set(acct_mgr.get_users()))
104            if 'locked' in kw.keys() or 'locked' in args:
105                guard = AccountGuard(env)
106                locked = []
107                for user in users:
108                    if guard.user_locked(user):
109                        locked.append(user)
110                if kw.get('locked', 'True').lower() in ('true', 'yes', '1'):
111                    users = locked
112                else:
113                    users = list(set(users) - set(locked))
114            elif 'visit' in kw.keys() or 'visit' in args:
115                if not 'USER_VIEW' in req.perm:
116                    return msg_no_perm
117                cols = []
118                data = {}
119                data['accounts'] = fetch_user_data(env, req)
120                data['cls'] = 'wiki'
121                for col in ('email', 'name'):
122                    if col in args:
123                        cols.append(col)
124                data['cols'] = cols
125                data['pretty_date'] = get_pretty_dateinfo(env, req)
126                return Chrome(env).render_template(
127                       req, 'user_table.html', data, 'text/html', True)
128            if kw.get('format') == 'count' or 'count' in args:
129                return tag(len(users))
130            if not 'USER_VIEW' in req.perm:
131                return msg_no_perm
132            if 'email' in args or 'name' in args:
133                # Replace username with full name, add email if available.
134                for username, name, email in self.env.get_known_users():
135                    if username in users:
136                        if not 'name' in args or name is None:
137                            name = username
138                        if 'email' in args and email is not None:
139                            email = ''.join(['<', email, '>'])
140                            name = ' '.join([name, email])
141                        if not username == name:
142                            users.pop(users.index(username))
143                            users.append(name)
144            if not users and 'nomatch' in kw.keys():
145                return format_to_oneliner(env, formatter.context,
146                                          kw['nomatch'])
147            users = sorted(users)
148            if kw.get('format') == 'list':
149                return tag.ul([tag.li(Chrome(env).format_author(req, user))
150                               for user in users])
151            else:
152                # Default output format: comma-separated list.
153                return tag(', '.join([Chrome(env).format_author(req, user)
154                                      for user in users]))
Note: See TracBrowser for help on using the repository browser.