| 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, ExtensionPoint, implements |
|---|
| 13 | from trac.util.compat import sorted |
|---|
| 14 | from trac.web.chrome import Chrome |
|---|
| 15 | from tractags.api import TagSystem, ITagProvider, _ |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | class TagChangeAdminPanel(Component): |
|---|
| 19 | |
|---|
| 20 | implements(IAdminPanelProvider) |
|---|
| 21 | |
|---|
| 22 | tag_providers = ExtensionPoint(ITagProvider) |
|---|
| 23 | |
|---|
| 24 | # AdminPanelProvider methods |
|---|
| 25 | def get_admin_panels(self, req): |
|---|
| 26 | if 'TAGS_ADMIN' in req.perm: |
|---|
| 27 | yield ('tags', _('Tag System'), 'replace', _('Replace')) |
|---|
| 28 | |
|---|
| 29 | def render_admin_panel(self, req, cat, page, version): |
|---|
| 30 | req.perm.require('TAGS_ADMIN') |
|---|
| 31 | |
|---|
| 32 | realms = [p.get_taggable_realm() for p in self.tag_providers |
|---|
| 33 | if (not hasattr(p, 'check_permission') or \ |
|---|
| 34 | p.check_permission(req.perm, 'view'))] |
|---|
| 35 | # Check request for enabled filters, or use default. |
|---|
| 36 | if [r for r in realms if r in req.args] == []: |
|---|
| 37 | for realm in realms: |
|---|
| 38 | req.args[realm] = 'on' |
|---|
| 39 | checked_realms = [r for r in realms if r in req.args] |
|---|
| 40 | data = dict(checked_realms=checked_realms, |
|---|
| 41 | tag_realms=list(dict(name=realm, |
|---|
| 42 | checked=realm in checked_realms) |
|---|
| 43 | for realm in realms)) |
|---|
| 44 | |
|---|
| 45 | tag_system = TagSystem(self.env) |
|---|
| 46 | if req.method == 'POST': |
|---|
| 47 | # Replace Tag |
|---|
| 48 | allow_delete = req.args.get('allow_delete') |
|---|
| 49 | new_tag = req.args.get('tag_new_name').strip() |
|---|
| 50 | new_tag = not new_tag == u'' and new_tag or None |
|---|
| 51 | if not (allow_delete or new_tag): |
|---|
| 52 | data['error'] = _("Selected current tag(s) and either " |
|---|
| 53 | "new tag or delete approval are required") |
|---|
| 54 | else: |
|---|
| 55 | comment = req.args.get('comment', u'') |
|---|
| 56 | old_tags = req.args.get('tag_name') |
|---|
| 57 | if old_tags: |
|---|
| 58 | # Provide list regardless of single or multiple selection. |
|---|
| 59 | old_tags = isinstance(old_tags, list) and old_tags or \ |
|---|
| 60 | [old_tags] |
|---|
| 61 | tag_system.replace_tag(req, old_tags, new_tag, comment, |
|---|
| 62 | allow_delete, filter=checked_realms) |
|---|
| 63 | data['selected'] = new_tag |
|---|
| 64 | |
|---|
| 65 | query = ' or '.join(['realm:%s' % r for r in checked_realms]) |
|---|
| 66 | all_tags = sorted(tag_system.get_all_tags(req, query)) |
|---|
| 67 | data['tags'] = all_tags |
|---|
| 68 | try: |
|---|
| 69 | Chrome(self.env).add_textarea_grips(req) |
|---|
| 70 | except AttributeError: |
|---|
| 71 | # Element modifiers unavailable before Trac 0.12, skip gracefully. |
|---|
| 72 | pass |
|---|
| 73 | return 'admin_tag_change.html', data |
|---|
| 74 | |
|---|