source: repositoryhooksystemplugin/0.11/repository_hook_system/admin.py

Last change on this file was 7102, checked in by Jeff Hammel, 14 years ago

fix comments

File size: 5.8 KB
Line 
1"""
2RepositoryHookAdmin:
3admin panel interface for controlling hook setup and listeners
4"""
5
6from pkg_resources import resource_filename
7from repository_hook_system.interface import IRepositoryHookSystem
8from repository_hook_system.interface import IRepositoryHookSubscriber
9from trac.admin.api import IAdminPanelProvider
10from trac.config import Option
11from trac.core import *
12from trac.web.chrome import ITemplateProvider
13
14class RepositoryHookAdmin(Component):
15    """webadmin panel for hook configuration"""
16   
17    implements(ITemplateProvider, IAdminPanelProvider)
18    listeners = ExtensionPoint(IRepositoryHookSubscriber)
19
20    systems = ExtensionPoint(IRepositoryHookSystem) 
21    # XXX maybe should be IRepositoryHookSetup?
22    # or perhaps thes IRepositoryHookSetup and IRepositoryChangeListener
23    # interfaces should be combined
24
25    def system(self):
26        """returns the IRepositoryHookSystem appropriate to the repository"""
27        # XXX could abstract this, as this is not specific to TTW functionality
28        for system in self.systems:
29            if self.env.config.get('trac', 'repository_type') in system.type():
30                return system           
31
32
33    ### methods for ITemplateProvider
34
35    """Extension point interface for components that provide their own
36    ClearSilver templates and accompanying static resources.
37    """
38
39    def get_htdocs_dirs(self):
40        """Return a list of directories with static resources (such as style
41        sheets, images, etc.)
42
43        Each item in the list must be a `(prefix, abspath)` tuple. The
44        `prefix` part defines the path in the URL that requests to these
45        resources are prefixed with.
46       
47        The `abspath` is the absolute path to the directory containing the
48        resources on the local file system.
49        """
50        return []
51
52    def get_templates_dirs(self):
53        """Return a list of directories containing the provided template
54        files.
55        """
56        return [resource_filename(__name__, 'templates')]
57
58    ### methods for IAdminPanelProvider
59
60    """Extension point interface for adding panels to the web-based
61    administration interface.
62    """
63
64    def get_admin_panels(self, req):
65        """Return a list of available admin panels.
66       
67        The items returned by this function must be tuples of the form
68        `(category, category_label, page, page_label)`.
69        """
70        if req.perm.has_permission('TRAC_ADMIN'):
71            system = self.system()
72            if system is not None and self.env.config.get('trac', 'repository_dir'):
73                for hook in system.available_hooks():
74                    yield ('repository_hooks', 'Repository Hooks', hook, hook)
75
76    def render_admin_panel(self, req, category, page, path_info):
77        """Process a request for an admin panel.
78       
79        This function should return a tuple of the form `(template, data)`,
80        where `template` is the name of the template to use and `data` is the
81        data to be passed to the template.
82        """
83        hookname = page
84        system = self.system()
85        data = {}
86        data['hook'] = hookname
87
88        if req.method == 'POST':
89
90            # implementation-specific post-processing
91            # XXX should probably handle errors, etc
92            system.process_post(hookname, req)
93
94            # toggle invocation of the hook
95            if req.args.get('enable'):
96                system.enable(hookname)
97            else:
98                system.disable(hookname)
99
100            # set available listeners on a hook
101            listeners = req.args.get('listeners', [])
102            if isinstance(listeners, basestring):
103                listeners = [ listeners ] # XXX ', '.join ?
104            self.env.config.set('repository-hooks', hookname, 
105                                ', '.join(listeners))
106
107            # process posted options to configuration
108            for listener in self.listeners:
109                name = listener.__class__.__name__
110                options = self.options(listener)
111                args = dict([(key.split('%s-' % name, 1)[1], value) 
112                             for key, value in req.args.items()
113                             if key.startswith('%s-' % name)])
114                for option in options:
115                    option_type = options[option]['type']
116                    section = options[option]['section']
117                    value = args.get(option, '')
118                    if option_type == 'bool':
119                        value = value == "on" and "true" or "false"
120                    self.env.config.set(section, option, value)
121
122            self.env.config.save()
123           
124
125        data['enabled'] = system.is_enabled(hookname)
126        data['can_enable'] = system.can_enable(hookname)
127        activated = [ i.__class__.__name__ for i in system.subscribers(hookname) ]
128        data['snippet'] = system.render(hookname, req)
129
130        data['listeners'] = []
131        for listener in self.listeners:
132            _cls = listener.__class__
133            data['listeners'].append(dict(name=_cls.__name__, 
134                                          activated=(_cls.__name__ in activated),
135                                          description=listener.__doc__,
136                                          options=self.options(listener)))
137
138        return ('repositoryhooks.html', data)
139
140    def options(self, listener):
141        _cls = listener.__class__
142        options = [ (i, getattr(_cls, i)) for i in dir(_cls) 
143                    if isinstance(getattr(_cls, i), Option) ]
144        options = dict([(option.name, dict(section=option.section,
145                                         type=option.__class__.__name__.lower()[:-6] or 'text',
146                                         value=getattr(listener, attr),
147                                         description=option.__doc__))
148                        for attr, option in options ])
149        return options
Note: See TracBrowser for help on using the repository browser.