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

Last change on this file was 1826, checked in by muness, 17 years ago

Not just the keywords field.

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