source: tagsplugin/tags/0.6/tractags/ticket.py

Last change on this file was 3033, checked in by Alec Thomas, 16 years ago

Whoops.

File size: 3.6 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2006 Alec Thomas <alec@swapoff.org>
4#
5# This software is licensed as described in the file COPYING, which
6# you should have received as part of this distribution.
7#
8
9import re
10from trac.core import *
11from tractags.api import TagSystem, ITagProvider
12from trac.ticket.model import Ticket
13from trac.util.text import to_unicode
14from trac.util.compat import set, sorted
15from trac.config import *
16from trac.resource import Resource
17
18
19class TicketTagProvider(Component):
20    """A tag provider using ticket fields as sources of tags.
21
22    Currently does NOT support custom fields.
23    """
24    implements(ITagProvider)
25
26    fields = ListOption('tags', 'ticket_fields', 'keywords',
27        doc='List of ticket fields to expose as tags.')
28
29    ignore_closed_tickets = BoolOption('tags', 'ignore_closed_tickets', True,
30        'Do not collect tags from closed tickets.')
31
32#    custom_fields = ListOption('tags', 'custom_ticket_fields',
33#        doc='List of custom ticket fields to expose as tags.')
34
35    # ITagProvider methods
36    def get_taggable_realm(self):
37        return 'ticket'
38
39    def get_tagged_resources(self, req, tags):
40        if 'TICKET_VIEW' not in req.perm:
41            return
42
43        split_into_tags = TagSystem(self.env).split_into_tags
44        db = self.env.get_db_cnx()
45        cursor = db.cursor()
46        args = []
47        ignore = ''
48        if self.ignore_closed_tickets:
49            ignore = " WHERE status != 'closed'"
50        sql = "SELECT * FROM (SELECT id, %s, %s AS fields FROM ticket%s) s" % (
51            ','.join(self.fields),
52            '||'.join(["COALESCE(%s, '')" % f for f in self.fields]),
53            ignore)
54        constraints = []
55        if tags:
56            constraints.append(
57                "(" + ' OR '.join(["fields LIKE %s" for t in tags]) + ")")
58            args += ['%' + t + '%' for t in tags]
59        else:
60            constraints.append("fields != ''")
61
62        if constraints:
63            sql += " WHERE " + " AND ".join(constraints)
64        sql += " ORDER BY id"
65        self.env.log.debug(sql)
66        cursor.execute(sql, args)
67        for row in cursor:
68            id, ttags = row[0], ' '.join([f for f in row[1:-1] if f])
69            perm = req.perm('ticket', id)
70            if 'TICKET_VIEW' not in perm or 'TAGS_VIEW' not in perm:
71                continue
72            ticket_tags = split_into_tags(ttags)
73            tags = set([to_unicode(x) for x in tags])
74            if (not tags or ticket_tags.intersection(tags)):
75                yield Resource('ticket', id), ticket_tags
76
77
78    def get_resource_tags(self, req, resource):
79        if 'TICKET_VIEW' not in req.perm(resource):
80            return
81        ticket = Ticket(self.env, resource.id)
82        return self._ticket_tags(ticket)
83
84    def set_resource_tags(self, req, resource, tags):
85        req.perm.require('TICKET_MODIFY', resource)
86        split_into_tags = TagSystem(self.env).split_into_tags
87        ticket = Ticket(self.env, resource.id)
88        all = self._ticket_tags(ticket)
89        keywords = split_into_tags(ticket['keywords'])
90        tags.difference_update(all.difference(keywords))
91        ticket['keywords'] = u' '.join(sorted(map(to_unicode, tags)))
92        ticket.save_changes(req.username, u'')
93
94    def remove_resource_tags(self, req, resource):
95        req.perm.require('TICKET_MODIFY', resource)
96        ticket = Ticket(self.env, resource.id)
97        ticket['keywords'] = u''
98        ticket.save_changes(req.username, u'')
99
100    # Private methods
101    def _ticket_tags(self, ticket):
102        split_into_tags = TagSystem(self.env).split_into_tags
103        return split_into_tags(
104            ' '.join(filter(None, [ticket[f] for f in self.fields])))
Note: See TracBrowser for help on using the repository browser.