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

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

TagsPlugin:

More fixes for Trac 0.11, thanks again to Gary Oberbrunner.

File size: 4.1 KB
Line 
1from trac.core import *
2from tractags.api import ITaggingSystemProvider, TaggingSystem, sorted, set
3from trac.ticket.query import Query
4from trac.ticket import model
5import re
6from trac.util.text import to_unicode
7
8class TicketTaggingSystem(TaggingSystem):
9    _keyword_split = re.compile(r'''\w[\w.@-]+''', re.UNICODE)
10
11    # These builtin fields can be used as tag sources
12    _builtin_fields = ('component', 'severity', 'priority', 'owner',
13                       'reporter', 'cc', 'version', 'milestone', 'status',
14                       'resolution', 'summary', 'description', 'keywords')
15
16    def __init__(self, env):
17        self.env = env
18        self.fields = [x.strip() for x in self.env.config.get('tags.ticket',
19                       'fields', 'keywords').split(',') if x.strip()
20                       and x.strip() in self._builtin_fields]
21        self.custom_fields = [x.strip() for x in self.env.config.get('tags.ticket',
22                              'custom_fields', '').split(',') if x.strip()]
23
24    def _ticket_tags(self, ticket):
25        return set(self._keyword_split.findall(' '.join([ticket[f] for f in self.fields])))
26
27    def walk_tagged_names(self, names, tags, predicate):
28        db = self.env.get_db_cnx()
29        cursor = db.cursor()
30        tags = set(tags)
31        names = set(names)
32        args = []
33        sql = "SELECT * FROM (SELECT id, %s, %s AS allfields FROM ticket) s" % (','.join(self.fields),
34            '||'.join(["COALESCE(%s, '')" % f for f in self.fields]))
35        constraints = []
36        if names:
37            constraints.append("id IN (" + ', '.join(['%s' for n in names]) + ")")
38            args += [unicode(n) for n in names]
39        if tags:
40            constraints.append("(" + ' OR '.join(["allfields LIKE %s" for t in tags]) + ")")
41            args += ['%' + t + '%' for t in tags]
42        if constraints:
43            sql += " WHERE " + " AND ".join(constraints)
44        sql += " ORDER BY id"
45        cursor.execute(sql, args)
46        for row in cursor:
47            id, ttags = row[0], ' '.join([f for f in row[1:-1] if f])
48            ticket_tags = set(self._keyword_split.findall(ttags))
49            tags = set([to_unicode(x) for x in tags])
50            if not tags or ticket_tags.intersection(tags):               
51                if predicate(id, ticket_tags):
52                    yield (id, ticket_tags)
53               
54    def get_name_tags(self, name):
55        db = self.env.get_db_cnx()
56        cursor = db.cursor()
57        cursor.execute("SELECT keywords FROM ticket WHERE id=%s AND keywords IS NOT NULL AND keywords != ''", (name,))
58        for row in cursor:
59            return set(self._keyword_split.findall(row[0]))
60
61    def add_tags(self, req, name, tags):
62        ticket = model.Ticket(self.env, name)
63        ticket_tags = self._ticket_tags(ticket)
64        ticket_tags.update(tags)
65        ticket['keywords'] = ' '.join(sorted(ticket_tags))
66        ticket.save_changes(req.authname, None)
67
68    def replace_tags(self, req, name, tags):
69        ticket = model.Ticket(self.env, name)
70        ticket['keywords'] = ' '.join(sorted(tags))
71        ticket.save_changes(req.authname, None)
72
73    def remove_tags(self, req, name, tags):
74        ticket = model.Ticket(self.env, name)
75        ticket_tags = self._ticket_tags(ticket)
76        ticket_tags.symmetric_difference_update(tags)
77        ticket['keywords'] = ' '.join(sorted(ticket_tags))
78        ticket.save_changes(req.authname, None)
79
80    def remove_all_tags(self, req, name):
81        ticket = model.Ticket(self.env, name)
82        ticket['keywords'] = ''
83        ticket.save_changes(req.authname, None)
84
85    def name_details(self, name):
86        ticket = model.Ticket(self.env, name)
87        href = self.env.href.ticket(name)
88        summary = ticket['summary'] or u''
89        return (href, '<a href="%s">#%s</a>' % (href, name),
90                ticket.exists and summary)
91
92class TicketTags(Component):
93    """ Export a ticket tag interface. """
94    implements(ITaggingSystemProvider)
95
96    def get_tagspaces_provided(self):
97        yield 'ticket'
98
99    def get_tagging_system(self, tagspace):
100        return TicketTaggingSystem(self.env)
101
Note: See TracBrowser for help on using the repository browser.