source: ticketcreatebuttonsplugin/0.11/ticketCreateButtons/ticketCreateButtons.py @ 9441

Last change on this file since 9441 was 9441, checked in by Chris Nelson, 13 years ago

Initial commit to Trac-Hacks

File size: 4.9 KB
Line 
1from trac.core import *
2from trac.web.api import ITemplateStreamFilter
3
4from genshi.builder import tag
5from genshi.filters import Transformer
6
7revision = "$Rev$"
8url = "$URL$"
9
10class TicketCreateButtons(Component):
11    """Add a buttons to the ticket box to create related tickets which
12    inherit some values from the current ticket.
13   
14    The [tickets-create-buttons] section of trac.ini can be used to
15    add buttons which create a new ticket based on the current
16    ticket.  The plugin handles all *.tag values in that section.  The
17    values are as follows:
18
19    tag : An argument to genshi.filters.Transfomer used to find the
20      ticket form element to which the button will be prepended.
21      Typically this is a custom field name.  For example,
22      .//td[@headers="h_blockedby"] for the MasterTickets blockedBy
23      field.
24    label : The label for the button (e.g., "Create")
25    title : The HTML title element used as a tool tip for the button
26
27    inherit : A comma-separated list of fields whose values should be
28      inherited from the current ticket.  If not present, all fields
29      are inherited.  if present but blank, no fields are inherited.
30      Otherwise, the listed fields are inherited.
31   
32    link : A comma-separated list of pairs of fields used to link the
33      two tickets.  Each element is in the form newfield:currentfield.
34      For example, blockedby:id sets the new ticket's blockedby field
35      to the current tickets id.  link fields override inherited
36      fields.
37
38    set : A comma-separated list of field:value pairs for setting
39      values in the new ticket.  For example, keywords:Foo sets the
40      new ticket's keywords field to Foo. set fields override
41      inherited and link field.
42
43    Example:
44
45    [ticket-create-buttons]
46    blocking.tag = .//td[@headers="h_blocking"]
47    blocking.label = Create
48    blocking.title = Create a new successor
49    blocking.inherit = type, owner, reporter, milestone, component
50    blocking.link = blockedby:id
51    blocking.set = keywords:Foo
52    """
53       
54    implements(ITemplateStreamFilter)
55
56    # ITemplateStreamFilter methods
57
58    def filter_stream(self, req, method, filename, stream, data):
59        if filename == 'ticket.html':
60            ticket = data.get('ticket')
61            if ticket and ticket.exists and \
62                    'TICKET_CREATE' in req.perm(ticket.resource):
63                # Find the configured buttons (anything in
64                # [ticket-create-buttons] that has a name like "*.tag")
65                options=self.config.options('ticket-create-buttons')
66                buttons=[]
67                for n, v in options:
68                    p=n.split('.')
69                    if len(p)==2 and p[1] == 'tag':
70                        buttons.append(p[0])
71
72                # Create the configured buttons
73                for b in buttons:
74                    tag=self.config.get('ticket-create-buttons','%s.tag' % b)
75                    filter = Transformer(tag)
76                    stream = stream | filter.prepend(self._create_button(b, req, ticket, data))
77        return stream
78
79    def _create_button(self, b, req, ticket, data):
80        # Text for button
81        label=self.config.get('ticket-create-buttons','%s.label' % b)
82        title=self.config.get('ticket-create-buttons','%s.title' % b)
83
84        # Field values for new ticket
85        fields = {}
86
87        # Values inherited from the current ticket
88        # No setting: all, blank setting: none, Otherwise: the fields listed
89        inherit=self.config.getlist('ticket-create-buttons',
90                                    '%s.inherit' % b, 
91                                    default=data.keys())
92        for f in inherit:
93            fields[f]=ticket[f]
94
95        # Fields that link the new ticket to the current ticket
96        # Missing or empty, no links.
97        link=self.config.getlist('ticket-create-buttons','%s.link' % b, default=[])
98        for l in link:
99            to, fr = l.split(':')
100            if fr == 'id':
101                fields[to] = ticket.id
102            else:
103                fields[to]=ticket[fr]
104
105        # Specific value assignments.  E.g., a button could always create a test
106        set=self.config.getlist('ticket-create-buttons','%s.set' % b, default=[])
107        for s in set:
108            n, v = s.split(':')
109            fields[n]=v
110
111        # Build the form with the values set up above.
112        return tag.form(
113            tag.div(
114                tag.input(type="submit", name="create_"+b, value=label,
115                          title=title),
116                # With name='field_'+n here the field prefilled for post but not for get
117                [tag.input(type="hidden", name=n, value=v) for n, v in
118                 fields.items()],
119                class_="inlinebuttons"),
120            # With "post" here instead of "get" the ticket is previewed and
121            # we get a warning about the missing summary.
122            method="get", action=req.href.newticket())
Note: See TracBrowser for help on using the repository browser.