| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2011 Itamar Ostricher <itamarost@gmail.com> |
|---|
| 4 | # Copyright (C) 2011-2013 Steffen Hoffmann <hoff.st@web.de> |
|---|
| 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 | |
|---|
| 10 | |
|---|
| 11 | from trac.admin import IAdminPanelProvider |
|---|
| 12 | from trac.core import Component, implements |
|---|
| 13 | from trac.util.compat import sorted |
|---|
| 14 | from trac.web.chrome import Chrome |
|---|
| 15 | from tractags.api import TagSystem, _ |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | class TagChangeAdminPanel(Component): |
|---|
| 19 | """[opt] Admin web-UI providing administrative tag system actions.""" |
|---|
| 20 | |
|---|
| 21 | implements(IAdminPanelProvider) |
|---|
| 22 | |
|---|
| 23 | # AdminPanelProvider methods |
|---|
| 24 | def get_admin_panels(self, req): |
|---|
| 25 | if 'TAGS_ADMIN' in req.perm: |
|---|
| 26 | yield ('tags', _('Tag System'), 'replace', _('Replace')) |
|---|
| 27 | |
|---|
| 28 | def render_admin_panel(self, req, cat, page, version): |
|---|
| 29 | req.perm.require('TAGS_ADMIN') |
|---|
| 30 | |
|---|
| 31 | tag_system = TagSystem(self.env) |
|---|
| 32 | all_realms = tag_system.get_taggable_realms(req.perm) |
|---|
| 33 | # Check request for enabled filters, or use default. |
|---|
| 34 | if [r for r in all_realms if r in req.args] == []: |
|---|
| 35 | for realm in all_realms: |
|---|
| 36 | req.args[realm] = 'on' |
|---|
| 37 | checked_realms = [r for r in all_realms if r in req.args] |
|---|
| 38 | data = dict(checked_realms=checked_realms, |
|---|
| 39 | tag_realms=list(dict(name=realm, |
|---|
| 40 | checked=realm in checked_realms) |
|---|
| 41 | for realm in all_realms)) |
|---|
| 42 | |
|---|
| 43 | if req.method == 'POST': |
|---|
| 44 | # Replace Tag |
|---|
| 45 | allow_delete = req.args.get('allow_delete') |
|---|
| 46 | new_tag = req.args.get('tag_new_name').strip() |
|---|
| 47 | new_tag = not new_tag == u'' and new_tag or None |
|---|
| 48 | if not (allow_delete or new_tag): |
|---|
| 49 | data['error'] = _("Selected current tag(s) and either " |
|---|
| 50 | "new tag or delete approval are required") |
|---|
| 51 | else: |
|---|
| 52 | comment = req.args.get('comment', u'') |
|---|
| 53 | old_tags = req.args.get('tag_name') |
|---|
| 54 | if old_tags: |
|---|
| 55 | # Provide list regardless of single or multiple selection. |
|---|
| 56 | old_tags = isinstance(old_tags, list) and old_tags or \ |
|---|
| 57 | [old_tags] |
|---|
| 58 | tag_system.replace_tag(req, old_tags, new_tag, comment, |
|---|
| 59 | allow_delete, filter=checked_realms) |
|---|
| 60 | data['selected'] = new_tag |
|---|
| 61 | |
|---|
| 62 | query = ' or '.join(['realm:%s' % r for r in checked_realms]) |
|---|
| 63 | all_tags = sorted(tag_system.get_all_tags(req, query)) |
|---|
| 64 | data['tags'] = all_tags |
|---|
| 65 | try: |
|---|
| 66 | Chrome(self.env).add_textarea_grips(req) |
|---|
| 67 | except AttributeError: |
|---|
| 68 | # Element modifiers unavailable before Trac 0.12, skip gracefully. |
|---|
| 69 | pass |
|---|
| 70 | return 'admin_tag_change.html', data |
|---|