Example #1
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename != 'query.html':
         return stream
     query_string = 'query:' + '&'.join(['%s=%s' % (key, '|'.join([cond for cond in values]))
                                         for constraint in data['query'].constraints
                                         for key, values in constraint.items()])
     page_name = 'report_resource' in data and \
         'report:%s' % data['report_resource'].id or query_string
     if 'page_name' in req.args:
         page_name = req.args['page_name']
         query_string += '&page_name=%s' % page_name
     page = WikiPage(self.env, page_name)
     if 'WIKI_MODIFY' not in req.perm(page.resource):
         return stream
     cols = [header['name'] for header in data['headers']]
     text = '= Snapshot of [%s the query]: =\n' % query_string
     text += '{{{#!QueryResults(group=%s) \n' % data['query'].group
     text += '||= href =||= %s\n' % ' =||= '.join(cols)
     for (group_name, tickets) in data['groups']:
         text += '|| group: %s\n' % group_name
         for ticket in tickets:
             text += '|| %s || %s\n' % (ticket['href'],
                 ' || '.join([self.formatter(ticket[col]) for col in cols]))
     text += '}}}'
     div = tag.div(tag.input(value='Save as wiki:', type='submit'),
                   tag.input(name='action', value='edit', type='hidden'),
                   tag.input(name='text', value=text, type='hidden'),
                   tag.input(name='page', value=page_name))
     return stream | Transformer('//div[@id="content"]/div[@class="buttons"]') \
         .append(tag.form(div, action=get_resource_url(self.env, Resource('wiki'), self.env.href)))
Example #2
0
 def _clone_form(self, req, ticket, data):
     fields = {}
     for f in data.get('fields', []):
         name = f['name']
         if name == 'summary':
             fields['summary'] = _("%(summary)s (cloned)",
                                   summary=ticket['summary'])
         elif name == 'description':
             fields['description'] = \
                 _("Cloned from #%(id)s:\n----\n%(description)s",
                   id=ticket.id, description=ticket['description'])
         else:
             fields[name] = ticket[name]
     return tag.form(tag.div(tag.input(
         type="submit",
         name="clone",
         value=captioned_button(req, '+#', _("Clone")),
         title=_("Create a copy of this ticket")), [
             tag.input(type="hidden", name='field_' + n, value=v)
             for n, v in fields.iteritems()
         ],
                             tag.input(type="hidden",
                                       name='preview',
                                       value=''),
                             class_="inlinebuttons"),
                     method="post",
                     action=req.href.newticket())
    def filter_stream(self, req, method, filename, stream, data):
        """
        Returns changed stream for `prefs_general.html` template with notification
        opt-out preference option.

        `req` is the current request object, `method` is the Genshi render
        method (xml, xhtml or text), `filename` is the filename of the template
        to be rendered, `stream` is the event stream and `data` is the data for
        the current template.
        """

        if filename == 'prefs_general.html' and req.authname != 'anonymous':
            stream |= Transformer('.//table').append(
                tag.tr(
                    tag.th(
                        tag.label('Ticket notifications opt-out:', **{'for': 'ticket-notification-optout'}),
                    ),
                    tag.td(
                        tag.input(type="hidden", name="ticket-notification-optout_cb", value=""),
                        tag.input(type="checkbox", id="ticket-notification-optout", name="ticket-notification-optout", checked=req.session.get('ticket-notification-optout') or None),
                    ),
                    **{'class': 'field'}
                ),
            )
        return stream
Example #4
0
class Aggregator(Component):
    implements(ITemplateStreamFilter, IRequestFilter)

    # IRequestFilter methods
    def pre_process_request(self, req, handler):
        return handler

    def post_process_request(self, req, template, data, content_type):
        if not 'aggregate' in req.args \
                or not data \
                or not 'ticket' in data \
                or not 'changes' in data:
            return template, data, content_type
        ticket = data['ticket']
        if not 'TICKET_MODIFY' in req.perm(ticket.resource):
            return template, data, content_type
        cnum = int(req.args['aggregate'])
        changes = iter(data['changes'])
        for change in changes:
            if 'cnum' in change and change['cnum'] == cnum:
                self._aggregate(ticket.id, change, changes.next())
                req.redirect(req.href.ticket(ticket.id) + '#comment:%d' % cnum)
        return template, data, content_type
 
    # ITemplateStreamFilter methods
    def filter_stream(self, req, method, filename, stream, data):
        if filename != 'ticket.html':
            return stream
        if 'cnum_edit' in req.args: # comment editing
            return stream
        ticket = data.get('ticket')
        if not 'TICKET_MODIFY' in req.perm(ticket.resource):
            return stream
        transformer = Transformer()
        if data.has_key('changes'):
            changes = data['changes']
            # 前のコメントと, field の重複がなく, authorが一致していて, 時間が離れていない場合, Aggregateボタンを出す
            aggregatable = set()
            last = {'date': datetime.now(), 'fields': {}, 'author': None}
            for change in changes:
                try:
                    delta = change['date'].replace(tzinfo=None) - last['date'].replace(tzinfo=None)
                    if last['author'] == change['author'] \
                            and len(set(last['fields'].keys()) & set(change['fields'].keys())) == 0 \
                            and delta.days == 0 and delta.seconds <= 3600:
                        aggregatable.add(last['cnum'])
                except KeyError, e:
                    pass
                except AttributeError, e:
                    pass
                last = change
            self.log.debug('aggregatable: %s' % aggregatable)
            # Build transformer
            for cnum in aggregatable:
                transformer = transformer \
                    .select('//div[@id="changelog"]/div[@id="trac-change-%s"]/h3[@class="change"])' % cnum) \
                    .after(tag.form(tag.input(type='hidden', name='aggregate', value=cnum),
                                    tag.div(tag.input(type='submit', value='Aggregate', title="to next"),
                                            class_='inlinebuttons'))) \
                    .end()
Example #5
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename != 'report_view.html':
         return stream
     page_name = 'report:%s' % data['context'].resource.id
     page_label = data['title']
     page = WikiPage(self.env, page_name)
     if 'WIKI_MODIFY' not in req.perm(page.resource):
         return stream
     text = '= Snapshot of [%s %s]: =\n' % (page_name, page_label)
     text += '{{{#!QueryResults\n'
     cols = [header['col'] for header in data.get('header_groups', [[]])[0] if not header['hidden']]
     cols_work = [t for t in cols]  # copy
     if 'ticket' in cols_work:
         cols_work[cols_work.index('ticket')] = 'id'  # replace 'ticket' to 'id'
     text += '||= href =||= %s\n' % ' =||= '.join(cols_work)
     for  groupindex, row_group in data.get('row_groups', []):
         text += '|| group: %s\n' % groupindex
         for row in row_group:
             row = row['cell_groups'][0]
             ticket = {}
             for value in row:
                 ticket[value['header']['col']] = value['value']
             ticket['href'] = get_resource_url(self.env, Resource('ticket', ticket.get('ticket', 0)), self.env.href)
             text += '|| %s || %s\n' % (ticket['href'],
                 ' || '.join([self.formatter(col, ticket[col]) for col in cols]))
     text += '}}}'
     div = tag.div(tag.input(value='Save as wiki:', type='submit'),
                   tag.input(name='action', value='edit', type='hidden'),
                       tag.input(name='text', value=text, type='hidden'),
                   tag.input(name='page', value=page_name))
     return stream | Transformer('//div[@id="content"]/div[@class="buttons"]') \
         .append(tag.form(div, action=get_resource_url(self.env, Resource('wiki'), self.env.href)))
Example #6
0
    def filter_stream(self, req, method, filename, stream, data):
        # Get path
        if filename == 'browser.html':
            # self.req_han = SupoSERequestHandler()
            path = data.get('created_path')
            repo = self.env.get_repository(authname=req.authname)
            node = get_existing_node(req, repo, path, repo.youngest_rev)
            file = ""
            if node:
                if node.isfile:
                    file = posixpath.basename(path)
                    path = posixpath.dirname(path)

            #raise Exception( path )
            filter = Transformer('//div[@id="jumprev"]')
            search = tag.div( tag.form( 
            # tag.div( "Repository search" ),
                tag.input( type = "text", id = "suquery", 
                    name = "q", size = 13, value = ""),
                tag.input( type = "hidden", id = "suquerypath", 
                    name = "p", size = 13, value = path),
                tag.input( type = "hidden", id = "suqueryfile", 
                    name = "f", size = 13, value = file),
                tag.input( type = "submit", value="Repo Search"),
                action=req.href.reposearch(),
                method="get", id="reposearch" ) )
                
            
            return stream | filter.after(search)
        return stream
Example #7
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename != 'query.html':
         return stream
     query_string = 'query:' + '&'.join([
         '%s=%s' % (key, '|'.join([cond for cond in values]))
         for constraint in data['query'].constraints
         for key, values in constraint.items()
     ])
     page_name = 'report_resource' in data and \
         'report:%s' % data['report_resource'].id or query_string
     if 'page_name' in req.args:
         page_name = req.args['page_name']
         query_string += '&page_name=%s' % page_name
     page = WikiPage(self.env, page_name)
     if 'WIKI_MODIFY' not in req.perm(page.resource):
         return stream
     cols = [header['name'] for header in data['headers']]
     text = '= Snapshot of [%s the query]: =\n' % query_string
     text += '{{{#!QueryResults(group=%s) \n' % data['query'].group
     text += '||= href =||= %s\n' % ' =||= '.join(cols)
     for (group_name, tickets) in data['groups']:
         text += '|| group: %s\n' % group_name
         for ticket in tickets:
             text += '|| %s || %s\n' % (ticket['href'], ' || '.join(
                 [self.formatter(ticket[col]) for col in cols]))
     text += '}}}'
     div = tag.div(tag.input(value='Save as wiki:', type='submit'),
                   tag.input(name='action', value='edit', type='hidden'),
                   tag.input(name='text', value=text, type='hidden'),
                   tag.input(name='page', value=page_name))
     return stream | Transformer('//div[@id="content"]/div[@class="buttons"]') \
         .append(tag.form(div, action=get_resource_url(self.env, Resource('wiki'), self.env.href)))
Example #8
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(
                _("""Please type [%(token)s] as verification token,
                exactly replicating everything within the braces.""",
                  token=tag.b(self.reg_basic_token))),
                         class_='hint')
            insert = tag(
                tag.label(
                    _("Parole:"),
                    tag.input(type='text',
                              name='basic_token',
                              size=20,
                              class_='textwidget',
                              value=old_value)), hint)
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(
            insert,
            tag.input(type='hidden',
                      name='sentinel',
                      title=_("Better do not fill this field.")))
        return insert, data
Example #9
0
 def _clone_form(self, req, ticket, data):
     fields = {}
     for f in data.get("fields", []):
         name = f["name"]
         if name == "summary":
             fields["summary"] = _("%(summary)s (cloned)", summary=ticket["summary"])
         elif name == "description":
             fields["description"] = _(
                 "Cloned from #%(id)s:\n----\n%(description)s", id=ticket.id, description=ticket["description"]
             )
         else:
             fields[name] = ticket[name]
     return tag.form(
         tag.div(
             tag.input(
                 type="submit",
                 name="clone",
                 value=captioned_button(req, "+#", _("Clone")),
                 title=_("Create a copy of this ticket"),
             ),
             [tag.input(type="hidden", name="field_" + n, value=v) for n, v in fields.iteritems()],
             tag.input(type="hidden", name="preview", value=""),
             class_="inlinebuttons",
         ),
         method="post",
         action=req.href.newticket(),
     )
Example #10
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.get_header("X-Moz") == "prefetch":
         return stream
     if filename == "ticket.html":
         if not self.check_permissions(req):
             return stream
         chrome = Chrome(self.env)
         filter = Transformer('//fieldset[@id="properties"]')
         # add a hidden div to hold the ticket_fields input
         snippet = tag.div(style="display:none;")
         snippet = tag.input(type="hidden", id="field-ticket_fields", name="field_ticket_fields", value=','.join(data['ticket_fields']))
         stream = stream | filter.after(snippet)
         if req.path_info != '/newticket':
             # insert the ticket field groups after the standard trac 'Change Properties' field group
             stream = stream | filter.after(chrome.render_template(req, 'ticket_fields_datatable.html', data, fragment=True))
     elif filename == "admin_enums.html":
         if not self.check_permissions(req) or not req.args.get('path_info'):
             return stream
         for k,v in {'cat_id':'ticket', 'panel_id':'type'}.iteritems():
             if k not in req.args or req.args.get(k) != v:
                 return stream
         if 'ticket_fields' in data:
             chrome = Chrome(self.env)
             filter = Transformer('//div[@class="buttons"]')
             # add a hidden div to hold the ticket_fields input
             snippet = tag.div(style="display:none;")
             snippet = tag.input(type="hidden", id="field-ticket_fields", name="field_ticket_fields", value=','.join(data['ticket_fields']))
             stream = stream | filter.before(snippet)
             stream = stream | filter.before(chrome.render_template(req, 'ticket_fields_datatable.html', data, fragment=True))
     return stream
Example #11
0
    def filter_stream(self, req, method, filename, stream, data):
        # Add delete buttons to the ticket form
        ticket = data.get('ticket')
        if filename == 'ticket.html' and 'TICKET_ADMIN' in req.perm(ticket.resource):

            # Add Delete button to ticket description
            if data['ticket'].values['description']:
                # Reply button and associated elements are present
                filter = Transformer("//div[@class='description']//div[@class='inlinebuttons']")
                stream |= filter.append(tag.input(type='submit', name='delete',
                                                  title="Delete this ticket", value='Delete'))
            else:
                # Reply button and associated elements not present
                filter = Transformer("//div[@class='description']/h3")
                stream |= filter.after( \
                    tag.form(tag.div(tag.input(type='submit', name='delete',
                                               title="Delete this ticket", value='Delete'),
                                     class_='inlinebuttons'
                                     ),
                             name='addreply', method='get', action='#comment')
                             )

            # Add Delete buttons to ticket comments
            stream |= Transformer("//div[@id='changelog']//div[@class='inlinebuttons']") \
                          .append(tag.input(type='submit', name='delete',
                                            title="Delete this comment", value='Delete'))

        return stream
Example #12
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(_(
                """Apologies for the inconvenience, but please use the Sugarlabs Wiki,
                find the page referring to find the gold in the pot, and insert here
                the four words on the second line, or send mail to systems mailing list.""",
                token=tag.b(self.reg_basic_token))), class_='hint')
            insert = tag(
                tag.label(_("Parole:"),
                          tag.input(type='text', name='basic_token', size=20,
                                    class_='textwidget', value=old_value)),
                          hint
                )
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(insert,
                     tag.input(type='hidden', name='sentinel',
                               title=_("Better do not fill this field."))
                 )
        return insert, data
Example #13
0
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            # TRANSLATOR: Hint for visible bot trap registration input field.
            hint = tag.p(Markup(_(
                """Please type [%(token)s] as verification token,
                exactly replicating everything within the braces.""",
                token=tag.b(self.reg_basic_token))), class_='hint')
            insert = tag(
                tag.label(_("Parole:"),
                          tag.input(type='text', name='basic_token', size=20,
                                    class_='textwidget', value=old_value)),
                          hint
                )
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(insert,
                     tag.input(type='hidden', name='sentinel',
                               title=_("Better do not fill this field."))
                 )
        return insert, data
Example #14
0
    def filter_stream(self, req, method, filename, stream, data):
        # check preconditions
        if filename != 'ticket.html':
            return stream
        transformer = Transformer()
        # build 'Hide these fields' Area
        hide_names = req.session.get('hidefieldchanges', [])
        hide_fields = []
        for field in data['fields']:
            name = field['name']
            checkbox = name in hide_names \
                and tag.input(type='checkbox', checked=True, name=name) \
                or tag.input(type='checkbox', name=name)
            hide_fields.append(tag.label(checkbox, field['label']))
            hide_fields.append(tag.br)
        hide_fields.append(tag.input(name='submit', type='submit', value='Hide these fields'))
        transformer = transformer \
            .select('//div[@id="changelog"]') \
            .before(tag.form(tag.input(value='hide changes', id='hidechangesbutton', type='button', style_='float: right;'),
                             tag.div(hide_fields, style='display: none', id='hidefields'),
                             action='#', class_='inlinebuttons hidechanges')).end()
        # build 'show all changes' button
#        showallbutton = tag.input(value='show all', name='showall', class_='showallbutton', type='submit', style_='float: right;')
#        showallbutton = tag.form(showallbutton, action='#', method='get', class_='inlinebuttons hidechanges')
#        transformer = transformer.select('//div[@id="changelog"]').before(showallbutton).end()
        # build 'hide customfield' buttons
        hidebutton = tag.input(value='hide', name="hide", class_='hidebutton', style_='display: none', type='submit')
        hidebutton = tag.form(hidebutton, action='#', method='get', class_='inlinebuttons hidefieldchanges')
        transformer = transformer \
            .select('//div[@id="changelog"]/div[@class="change"]/ul[@class="changes"]/li') \
            .prepend(hidebutton).end()
        # return filtered stream
        return stream | transformer
Example #15
0
    def filter_stream(self, req, method, filename, stream, data):
        # Add delete buttons to the ticket form
        ticket = data.get("ticket")
        if filename == "ticket.html" and "TICKET_ADMIN" in req.perm(ticket.resource):

            # Add Delete button to ticket description
            if data["ticket"].values["description"]:
                # Reply button and associated elements are present
                filter = Transformer("//div[@class='description']//div[@class='inlinebuttons']")
                stream |= filter.append(
                    tag.input(type="submit", name="delete", title="Delete this ticket", value="Delete")
                )
            else:
                # Reply button and associated elements not present
                filter = Transformer("//div[@class='description']/h3")
                stream |= filter.after(
                    tag.form(
                        tag.div(
                            tag.input(type="submit", name="delete", title="Delete this ticket", value="Delete"),
                            class_="inlinebuttons",
                        ),
                        name="addreply",
                        method="get",
                        action="#comment",
                    )
                )

            # Add Delete buttons to ticket comments
            stream |= Transformer("//div[@id='changelog']//div[@class='inlinebuttons']").append(
                tag.input(type="submit", name="delete", title="Delete this comment", value="Delete")
            )

        return stream
Example #16
0
 def delete_ticket():
     return tag.form(
         tag.div(
             tag.input(type='hidden', name='action', value='delete'),
             tag.input(type='submit', value=_('Delete'),
                       title=_('Delete ticket')),
             class_='inlinebuttons'),
         action='#', method='get')
Example #17
0
 def _toggleBox(self, req, label, name, default):
     if self._session(req, name, default) == 'true':
         checkbox = tag.input(type='checkbox',
                              name=name,
                              value='true',
                              checked='checked')
     else:
         checkbox = tag.input(type='checkbox', name=name, value='true')
     return checkbox + ' ' + tag.label(label, for_=name)
Example #18
0
 def delete_ticket():
     return tag.form(tag.div(tag.input(type='hidden',
                                       name='action',
                                       value='delete'),
                             tag.input(type='submit',
                                       value=_('Delete'),
                                       title=_('Delete ticket')),
                             class_='inlinebuttons'),
                     action='#',
                     method='get')
Example #19
0
 def _toggleBox(self, req, label, name, default):
     if self._session(req, name, default) == 'true':
         checkbox= tag.input(type= 'checkbox',
                             name= name,
                             value='true',
                             checked='checked')
     else:
         checkbox= tag.input(type= 'checkbox',
                             name= name,
                             value= 'true')
     return checkbox + ' ' + tag.label(label, for_= name)
Example #20
0
 def delete_ticket():
     return tag.form(
         tag.div(
             tag.input(type='hidden', name='action', value='delete'),
             tag.input(type='submit',
                       value=captioned_button(req, u'–', # 'EN DASH'
                                              _("Delete")),
                       title=_('Delete ticket'),
                       class_="trac-delete"),
             class_="inlinebuttons"),
         action='#', method='get')
    def _clone_form(self, req, ticket, data):
        fields = self.ticket_cloner.build_clone_form(req, ticket, data)

        return tag.form(
            tag.div(
                tag.input(type="submit", name="clone", value=_("Clone"),
                          title=_("Create a copy of this ticket")),
                [tag.input(type="hidden", name='field_' + n, value=v)
                 for n, v in fields.iteritems()],
                tag.input(type="hidden", name='preview', value=''),
                class_="inlinebuttons"),
            method="post", action=req.href.newticket())
Example #22
0
 def _ccme_form(self, req, ticket, data):  # pylint: disable=no-self-use
     return tag.form(tag.div(tag.input(
         type="submit",
         name="ccme",
         value=captioned_button(req, u'\u2709', _("Cc Me!")),
         title=_("Add/remove yourself to/from the Cc list")),
                             tag.input(type="hidden",
                                       name='ticket',
                                       value=ticket.id),
                             class_="inlinebuttons"),
                     method="post",
                     action=req.href('/ccme'))
Example #23
0
 def delete_comment():
     for event in buffer:
         cnum = event[1][1].get('id')[12:]
         return tag.form(
             tag.div(
                 tag.input(type='hidden', name='action',
                           value='delete-comment'),
                 tag.input(type='hidden', name='cnum', value=cnum),
                 tag.input(type='submit', value=_('Delete'),
                           title=_('Delete comment %(num)s',
                                   num=cnum)),
                 class_='inlinebuttons'),
             action='#', method='get')
Example #24
0
    def _reminder_add_form(self, req):
        if 'TICKET_REMINDER_MODIFY' not in req.perm and 'TICKET_ADMIN' not in req.perm:
            return None

        return \
            tag.form(
                tag.div(
                    tag.input(type="hidden", name="action", value="addreminder"),
                    tag.input(type="submit", value="Add reminder"),
                ),
                method="get",
                action="",
                id="addreminder",
            )
Example #25
0
    def _reminder_add_form(self, req):
        if 'TICKET_REMINDER_MODIFY' not in req.perm and 'TICKET_ADMIN' not in req.perm:
            return None

        return \
            tag.form(
                tag.div(
                    tag.input(type="hidden", name="action", value="addreminder"),
                    tag.input(type="submit", value="Add reminder"),
                ),
                method="get",
                action="",
                id="addreminder",
            )
Example #26
0
    def _reminder_delete_form(self, req, reminder_id):
        if 'TICKET_REMINDER_MODIFY' not in req.perm and 'TICKET_ADMIN' not in req.perm:
            return None

        return \
            tag.form(
                tag.div(
                    tag.input(type="hidden", name="action", value="deletereminder"),
                    tag.input(type="hidden", name="reminder", value=reminder_id),
                    tag.input(type="submit", value="Delete"),
                    class_="inlinebuttons",
                ),
                method="get",
                action="",
            )
Example #27
0
    def _reminder_delete_form(self, req, reminder_id):
        if 'TICKET_REMINDER_MODIFY' not in req.perm and 'TICKET_ADMIN' not in req.perm:
            return None

        return \
            tag.form(
                tag.div(
                    tag.input(type="hidden", name="action", value="deletereminder"),
                    tag.input(type="hidden", name="reminder", value=reminder_id),
                    tag.input(type="submit", value="Delete"),
                    class_="inlinebuttons",
                ),
                method="get",
                action="",
            )
Example #28
0
 def _process_edit(self, req, stream, method, tags):
     stage = 1
     elm = tag.div([
         tag.label('Tag under: (',
                   tag.a('view all tags', href=req.href.tags()),
                   ')',
                   for_='tags'),
         tag.br(),
         tag.input(title='Comma separated list of tags',
                   type='text',
                   id='tags',
                   size='30',
                   name='tags',
                   value=', '.join(tags)),
     ],
                   class_='field')
     for kind, data, pos in stream:
         yield kind, data, pos
         if stage == 1 and \
            kind is START and \
            data[0].localname == 'input' and \
            data[1].get('id') == 'comment':
             stage = 2
         elif stage == 2 and \
              kind is END and \
              data.localname == 'div':
             for e in elm.generate():
                 yield e
             stage = None
Example #29
0
 def delete_comment():
     for event in buffer:
         cnum, cdate = event[1][1].get('id')[12:].split('-', 1)
         return tag.form(
             tag.div(
                 tag.input(type='hidden', name='action',
                           value='delete-comment'),
                 tag.input(type='hidden', name='cnum', value=cnum),
                 tag.input(type='hidden', name='cdate', value=cdate),
                 tag.input(type='submit',
                           value=captioned_button(req, u'–', # 'EN DASH'
                                                  _("Delete")),
                           title=_('Delete comment %(num)s', num=cnum),
                           class_="trac-delete"),
                 class_="inlinebuttons"),
             action='#', method='get')
Example #30
0
 def _process_edit(self, req, stream, method, tags):
     stage = 1                     
     elm = tag.div([tag.label('Tag under: (', 
                              tag.a('view all tags', href=req.href.tags()),
                              ')', 
                              for_='tags'), 
                    tag.br(), 
                    tag.input(title='Comma separated list of tags',
                              type='text',
                              id='tags',
                              size='30',
                              name='tags',
                              value=', '.join(tags)
                             ),
                   ], class_='field')
     for kind, data, pos in stream:            
         yield kind, data, pos
         if stage == 1 and \
            kind is START and \
            data[0].localname == 'input' and \
            data[1].get('id') == 'comment':
             stage = 2
         elif stage == 2 and \
              kind is END and \
              data.localname == 'div':
             for e in elm.generate():
                 yield e
             stage = None
Example #31
0
 def render_registration_fields(self, req, data):
     """Add an email address text input field to the registration form."""
     # Preserve last input for editing on failure instead of typing
     # everything again.
     old_value = req.args.get('email', '').strip()
     insert = tag.label(_("Email:"),
                        tag.input(type='text', name='email', size=20,
                                  class_='textwidget', value=old_value)
              )
     # Deferred import required to aviod circular import dependencies.
     from acct_mgr.web_ui import AccountModule
     reset_password = AccountModule(self.env).reset_password_enabled
     verify_account = is_enabled(self.env, EmailVerificationModule) and \
                      EmailVerificationModule(self.env).verify_email
     if verify_account:
         # TRANSLATOR: Registration form hints for a mandatory input field.
         hint = tag.p(_("""The email address is required for Trac to send
                        you a verification token."""), class_='hint')
         if reset_password:
             hint = tag(hint, tag.p(_(
                        """Entering your email address will also enable you
                        to reset your password if you ever forget it."""),
                        class_='hint')
                    )
         return tag(insert, hint), data
     elif reset_password:
         # TRANSLATOR: Registration form hint, if email input is optional.
         hint = tag.p(_("""Entering your email address will enable you to
                        reset your password if you ever forget it."""),
                      class_='hint')
         return dict(optional=tag(insert, hint)), data
     else:
         # Always return the email text input itself as optional field.
         return dict(optional=insert), data
Example #32
0
 def render_registration_fields(self, req, data):
     """Add an email address text input field to the registration form."""
     # Preserve last input for editing on failure instead of typing
     # everything again.
     old_value = req.args.get('email', '').strip()
     insert = tag.label(_("Email:"),
                        tag.input(type='text', name='email', size=20,
                                  class_='textwidget', value=old_value)
              )
     # Deferred import required to aviod circular import dependencies.
     from acct_mgr.web_ui import AccountModule
     reset_password = AccountModule(self.env).reset_password_enabled
     verify_account = is_enabled(self.env, EmailVerificationModule) and \
                      EmailVerificationModule(self.env).verify_email
     if verify_account:
         # TRANSLATOR: Registration form hints for a mandatory input field.
         hint = tag.p(_("""The email address is required for Trac to send
                        you a verification token."""), class_='hint')
         if reset_password:
             hint = tag(hint, tag.p(_(
                        """Entering your email address will also enable you
                        to reset your password if you ever forget it."""),
                        class_='hint')
                    )
         return tag(insert, hint), data
     elif reset_password:
         # TRANSLATOR: Registration form hint, if email input is optional.
         hint = tag.p(_("""Entering your email address will enable you to
                        reset your password if you ever forget it."""),
                      class_='hint')
         return dict(optional=tag(insert, hint)), data
     else:
         # Always return the email text input itself as optional field.
         return dict(optional=insert), data
Example #33
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info.startswith('/ticket'):
         button = tag.div(
             tag.input(type="submit",
                       title=_("Translate to %s") %
                       req.locale.get_display_name(),
                       value=_("Translate"),
                       forward=_("Translate"),
                       backward=_("Untranslate"),
                       working=_("Working"),
                       name="translate",
                       class_="translate"))
         button(class_="inlinebuttons")
         script = tag.script('')
         script(src='https://www.google.com/jsapi?key=' + self.googleApiKey)
         script(type='text/javascript')
         stream |= Transformer('//head').prepend(script)
         stream |= Transformer(
             '//div[@id="content"]/div[@id="ticket"]/div[@class="description"]/h3'
         ).after(button)
         stream |= Transformer(
             '//div[@id="content"]/div/div[@id="changelog"]/div[@class="change"]/h3'
         ).after(button)
         add_stylesheet(req, 'translate/translate.css')
         add_script_data(req, {'googleApiKey': self.googleApiKey})
         add_script_data(req, {'sessionLanguage': req.locale.language})
         add_script(req, 'translate/translate.js')
     return stream
    def render_ticket_action_control(self, req, ticket, action):
        config = self.parse_config()
        assert action in config

        control = []
        hints = []

        data = config[action]
        
        action_name = action # @@TODO: config'able label/name

        chrome = Chrome(self.env)

        from trac.ticket.web_ui import TicketModule
        prepared_fields = TicketModule(self.env)._prepare_fields(req, ticket)

        for field in data.get('fields', []):
            id = "action_%s_%s" % (action, field)

            operation = data.get('operations', {}).get(field, "change")
            assert operation in ["change", "unset"]
            if operation == "unset":
                hints.append("%s will be unset" % field) # @@TODO: i18n
                continue
            assert operation == "change"
            current_value = ticket._old.get(field, ticket[field]) or ""

            rendered_control = ''
            prepared_field = [pfield for pfield in prepared_fields 
                              if pfield['name'] == field]
            if len(prepared_field):
                prepared_field = prepared_field[0]

                # we can't use chrome.render_template here, or it will blow away
                # key scripts like jquery.js and trac.js in the eventual 'primary' template
                # that's rendered by process_request
                template = chrome.load_template("ticket_fields.html", method="xhtml")
                rendered_control = template.generate(ticket=ticket, field=prepared_field)
                if rendered_control:
                    rendered_control = Markup(rendered_control)
            control.append(tag.label(field,
                                     rendered_control or tag.input(
                        name=id, id=id,
                        type='text', value=current_value)))

        current_status = ticket._old.get('status', ticket['status'])
        new_status = data['status'].get(current_status) or \
            data['status']['*']

        if new_status != '*':
            hints.append("Next status will be %s" % new_status) # @@TODO: i18n

        add_script(req, "workflow_ticketfields/workflow_ticketfields.js")
        return (action_name, tag.div(*[tag.div(element, style=("display: inline-block; "
                                                               "margin-right: 1em"))
                                       for element in control],
                                      class_="workflow_ticket_fields",
                                      style="margin-left: 2em; display: none"), 
                '. '.join(hints) + '.' if hints else '')
Example #35
0
 def get_stream(self, req, method, filename, stream, original_data):
     if 'linkinfo' in req.args:
         link_info = tag.input(name="linkinfo",
                               value=req.args['linkinfo'],
                               type="hidden")
     else:
         link_info = tag.comment('no link')
     return Transformer('//form[@id="propertyform"]').prepend(link_info)
Example #36
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info == '/timeline':
         insert = builder(Markup('<br />'), tag_("matching tags "),
                          builder.input(type='text', name=self.key,
                                        value=data.get(self.key)))
         xpath = '//form[@id="prefs"]/div[1]'
         stream = stream | Transformer(xpath).append(insert)
     return stream
Example #37
0
 def delete_comment():
     for event in buffer:
         cnum = event[1][1].get('id')[12:]
         return tag.form(tag.div(tag.input(type='hidden',
                                           name='action',
                                           value='delete-comment'),
                                 tag.input(type='hidden',
                                           name='cnum',
                                           value=cnum),
                                 tag.input(type='submit',
                                           value=_('Delete'),
                                           title=_(
                                               'Delete comment %(num)s',
                                               num=cnum)),
                                 class_='inlinebuttons'),
                         action='#',
                         method='get')
Example #38
0
 def helper(field_stream):
     s = Stream(field_stream)
     value = s.select('@value').textOf()
     name = s.select('@name').textOf()
     for kind,data,pos in tag.span(value, id=("field-%s"%field)).generate():
         yield kind,data,pos
     for kind,data,pos in tag.input(value=value, name=name, type="hidden").generate():
         yield kind,data,pos
Example #39
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.get_header("X-Moz") == "prefetch":
         return stream
     if filename == "ticket.html":
         if not self.check_permissions(req):
             return stream
         chrome = Chrome(self.env)
         filter = Transformer('//fieldset[@id="properties"]')
         # add a hidden div to hold the ticket_fields input
         snippet = tag.div(style="display:none;")
         snippet = tag.input(type="hidden",
                             id="field-ticket_fields",
                             name="field_ticket_fields",
                             value=','.join(data['ticket_fields']))
         stream = stream | filter.after(snippet)
         if req.path_info != '/newticket':
             # insert the ticket field groups after the standard trac 'Change Properties' field group
             stream = stream | filter.after(
                 chrome.render_template(req,
                                        'ticket_fields_datatable.html',
                                        data,
                                        fragment=True))
     elif filename == "admin_enums.html":
         if not self.check_permissions(req) or not req.args.get(
                 'path_info'):
             return stream
         for k, v in {'cat_id': 'ticket', 'panel_id': 'type'}.iteritems():
             if k not in req.args or req.args.get(k) != v:
                 return stream
         if 'ticket_fields' in data:
             chrome = Chrome(self.env)
             filter = Transformer('//div[@class="buttons"]')
             # add a hidden div to hold the ticket_fields input
             snippet = tag.div(style="display:none;")
             snippet = tag.input(type="hidden",
                                 id="field-ticket_fields",
                                 name="field_ticket_fields",
                                 value=','.join(data['ticket_fields']))
             stream = stream | filter.before(snippet)
             stream = stream | filter.before(
                 chrome.render_template(req,
                                        'ticket_fields_datatable.html',
                                        data,
                                        fragment=True))
     return stream
    def filter_stream(self, req, method, filename, stream, data):
        if req.path_info.startswith('/browser') and not data.get('tortoise-svn-message'):
            # add a hidden dialog div for the tortoisve svn message
            message = tag.p("TortoiseSVN is a Windows explorer client you can use to browse your Subversion repository.",
                          tag.p("If you have not installed TortoiseSVN, you can download it now from the ",
                              tag.a("TortoiseSVN website.",
                                  href="http://tortoisesvn.net/downloads.html",
                                  target="_blank"
                              ),
                          ),
                          tag.p("If you have installed TortoiseSVN, please select continue.",
                          ),
                          tag.p("If your local network requires a proxy to access the Internet, note that ",
                                tag.a("TortoiseSVN has proxy settings ",
                                    href="http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-dug-settings.html#tsvn-dug-settings-network"
                                ),
                                "which are configured separately to your normal Windows browser proxy.",
                            class_="info-light"
                          ),
                          tag.p("This message will not appear again if you click continue.",
                            class_="info-light"
                          ),
                      )
            form =  tag.form(
                        tag.div(
                            tag.input(
                                type="hidden",
                                name="__FORM_TOKEN",
                                value=req.form_token
                            ),
                        ),
                        tag.input(
                            name="tortoise-svn-message",
                            value="True",
                        ),
                        id_="tortoise-svn-message-form",
                        class_="hidden"
                    )

            stream = stream | Transformer("//*[@id='dirlist']").after(tag.div(message, form,
                                                                                id_='tortoise-svn-message-dialog',
                                                                                class_='hidden'
                                                                             )
                                                                      )
        return stream
 def _clone_form(self, req, ticket, data):
     fields = self.ticket_cloner.build_clone_form(req, ticket, data)
     action = self.ticket_clone_form_action or req.href.newticket()
     method = self.ticket_clone_form_method
     if method == "GET":
         field_name_fn = lambda name: name
     else:
         field_name_fn = lambda name: "field_%s" % name
     
     return tag.form(
         tag.div(
             tag.input(type="submit", name="clone", value=_("Clone"),
                       title=_("Create a copy of this ticket")),
             [tag.input(type="hidden", name=field_name_fn(n), value=v)
              for n, v in fields.iteritems()],
             tag.input(type="hidden", name='preview', value=''),
             class_="inlinebuttons"),
         method=method, action=action)
Example #42
0
def prepend_ctxtnav(req, elm_or_label, href):
    """Prepend an entry to the current page's ctxtnav bar.
    
    add_ctxtnav(), sadly, always appends to the right side of the (right-aligned by default) context nav, changing the onscreen locations of the links people are already used to.
    """
    elm = tag(tag.label(elm_or_label, for_='rev'), ' ',
              tag.input(type='text', id='rev', readonly='readonly',
                        value=href, size=len(href)))
    req.chrome.setdefault('ctxtnav', []).insert(0, elm)
 def _build_renamechildren_field(self):
     return tag.div(tag.label(
         tag.input(_("Also rename children"), \
                     type='checkbox',
                     id='rename_children', \
                     name='rename_children',
                     checked='checked') \
                     ), \
                    class_='field')
    def _create_button(self, b, req, ticket, data):
        # Text for button
        label=self.config.get('ticket-create-buttons','%s.label' % b)
        title=self.config.get('ticket-create-buttons','%s.title' % b)

        # Field values for new ticket
        fields = {}

        # Values inherited from the current ticket
        # No setting: all, blank setting: none, Otherwise: the fields listed
        inherit=self.config.getlist('ticket-create-buttons',
                                    '%s.inherit' % b, 
                                    default=data.keys())
        for f in inherit:
            fields[f]=ticket[f]

        # Fields that link the new ticket to the current ticket
        # Missing or empty, no links.
        link=self.config.getlist('ticket-create-buttons','%s.link' % b, default=[])
        for l in link:
            to, fr = l.split(':')
            if fr == 'id':
                fields[to] = ticket.id
            else:
                fields[to]=ticket[fr]

        # Specific value assignments.  E.g., a button could always create a test
        set=self.config.getlist('ticket-create-buttons','%s.set' % b, default=[])
        for s in set:
            n, v = s.split(':')
            fields[n]=v

        # Build the form with the values set up above.
        return tag.form(
            tag.div(
                tag.input(type="submit", name="create_"+b, value=label,
                          title=title),
                # With name='field_'+n here the field prefilled for post but not for get
                [tag.input(type="hidden", name=n, value=v) for n, v in
                 fields.items()],
                class_="inlinebuttons"),
            # With "post" here instead of "get" the ticket is previewed and 
            # we get a warning about the missing summary.
            method="get", action=req.href.newticket())
Example #45
0
    def get_content(self, req):
        """Returns the Genshi tags for the new HTML elements representing the
        Captcha.
        """
        values = {}
        values['ip'] = req.remote_addr
        values['submitted'] = int(time.time())
        math_problem_text = self.create_math_problem(values)
        values['author'] = req.args.get('author')
        values['summary'] = req.args.get('field_summary')
        values['text'] = self.get_failed_attempt_text(req)
        values['href'] = req.path_info

        # Save the problem so that the post request of the web server knows
        # which request to process.  This is required on FCGI and mod_python
        # web servers, because there may be many different processes handling
        # the request and there's no guarantee that the same web server will
        # handle both the form display and the form submit.
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        fields = values.keys()
        cursor.execute(
            "INSERT INTO mathcaptcha_history (%s) VALUES (%s)" %
            (','.join(fields), ','.join(['%s'] * len(fields))),
            [values[name] for name in fields])
        id = db.get_last_id(cursor, 'mathcaptcha_history')
        db.commit()
        self.env.log.debug(
            "%s %s %s%s: generating math solution: id=%d, %d %s %d = %d" %
            (req.remote_addr, req.remote_user, req.base_path, req.path_info,
             id, values['left_operand'], values['operator'],
             values['right_operand'], values['solution']))

        # Obfuscating the names of the input variables to trick spam harvesters
        # to put other data in the solutions field.  The math solution is
        # named "email" in the hopes that it will attract email addresses
        # instead of numbers.  The database key is named "url" to try to
        # attract non-numbers
        content = tag.div(
        )(tag.label('Anonymous users are allowed to post by %s ' %
                    math_problem_text) +
          tag.input(type='text', name='email', class_='textwidget', size='5') +
          tag.input(type='hidden', name='url', value=str(id + self.id_offset)))
        return content
Example #46
0
    def filter_stream(self, req, method, filename, stream, data):
        if 'TICKET_ADMIN' in req.perm:
            if req.path_info == '/admin/ticket/components' or req.path_info == '/admin/ticket/components/':
                components = data.get('components')
                # 'components' will be None if component with specified name already exists.
                if not components:
                    return stream
                
                default_ccs = DefaultCC.select(self.env)

                stream = stream | Transformer('//table[@id="complist"]/thead/tr') \
                    .append(tag.th('Default CC'))

                filter = Transformer('//table[@id="complist"]/tbody')
                default_comp = self.config.get('ticket', 'default_component')
                for comp in components:
                    if default_comp == comp.name:
                        default_tag = tag.input(type='radio', name='default', value=comp.name, checked='checked')
                    else:
                        default_tag = tag.input(type='radio', name='default', value=comp.name)

                    if comp.name in default_ccs:
                        default_cc = default_ccs[comp.name]
                    else:
                        default_cc = ''

                    filter = filter.append(tag.tr(tag.td(tag.input(type='checkbox', name='sel', value=comp.name), class_='sel'),
                                                  tag.td(tag.a(comp.name, href=req.href.admin('ticket', 'components') + '/' + comp.name), class_='name'),
                                                  tag.td(comp.owner, class_='owner'),
                                                  tag.td(default_tag, class_='default'),
                                                  tag.td(default_cc, class_='defaultcc')))
                return stream | filter

            elif req.path_info.startswith('/admin/ticket/components/') and data.get('component'):
                cc = DefaultCC(self.env, data.get('component').name)
                filter = Transformer('//form[@id="modcomp"]/fieldset/div[@class="buttons"]')
                filter = filter.before(tag.div("Default CC:",
                                               tag.br(),
                                               tag.input(type="text", name="defaultcc", value=cc.cc),
                                               class_="field")) \
                                               .before(tag.input(type='hidden', name='old_name', value=cc.name))
                return stream | filter

        return stream
Example #47
0
 def render_ticket_action_control(self, req, ticket, action):
     """Returns the action control"""
     id = 'action_%s_xref' % action
     ticketnum = req.args.get(id, '')
     actions = ConfigurableTicketWorkflow(self.env).actions
     label = actions[action]['name']
     hint = actions[action].get('xref_hint',
         'The specified ticket will be cross-referenced with this ticket')
     control = tag.input(type='text', id=id, name=id, value=ticketnum)
     return (label, control, hint)
Example #48
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info == '/timeline':
         insert = builder(
             Markup('<br />'), tag_("matching tags "),
             builder.input(type='text',
                           name=self.key,
                           value=data.get(self.key)))
         xpath = '//form[@id="prefs"]/div[1]'
         stream = stream | Transformer(xpath).append(insert)
     return stream
Example #49
0
 def helper(field_stream):
     s = Stream(field_stream)
     value = s.select('@value').textOf()
     name = s.select('@name').textOf()
     for kind, data, pos in tag.span(value,
                                     id=("field-%s" % field)).generate():
         yield kind, data, pos
     for kind, data, pos in tag.input(value=value, name=name,
                                      type="hidden").generate():
         yield kind, data, pos
Example #50
0
 def render_ticket_action_control(self, req, ticket, action):
     """Returns the action control"""
     id = 'action_%s_xref' % action
     ticketnum = req.args.get(id, '')
     actions = self.get_configurable_workflow().actions
     label = actions[action]['name']
     hint = actions[action].get('xref_hint',
         'The specified ticket will be cross-referenced with this ticket')
     control = tag.input(type='text', id=id, name=id, value=ticketnum)
     return (label, control, hint)
Example #51
0
 def select_helper(stream):
     s = Stream(stream)
     name = s.select('@name').textOf()
     opt = s.select('//option[@selected]')
     if not opt: s.select('//option[position()=1]')
     text = opt.select("text()").textOf()
     value = s.select('@value').textOf()
     if not value: value = text
     for kind, data, pos in tag.input(value=value, name=name,
                                      type="hidden").generate():
         yield kind, data, pos
 def _user_field_input(self, req):
     return tag.div(tag.label("Include users: ",
                              tag.input(type="text",
                                        name="inc_users",
                                        value=req.session.get('timeline.filter.inc_users',''),
                                        style_="width:60%"
                                       )
                             )
                    +
                    tag.br()
                    +
                    tag.label("Exclude users: ",
                              tag.input(type="text",
                                        name="exc_users",
                                        value=req.session.get('timeline.filter.exc_users',''),
                                        style_="width:60%"
                                       )
                             )
                   )                    
                                
Example #53
0
 def _filterBox(self, req, label, name):
     return tag.label(
         label,
         tag.input(
             type="text",
             name=name,
             value=self._session(req, name, ''),
             style_="width:60%",
             title=
             _('available prefixes: contains: ~, starts with: ^, ends with: $'
               )))
Example #54
0
 def filter_stream(self, req, method, filename, stream, data):
     # check preconditions
     if filename != 'ticket.html':
         return stream
     transformer = Transformer()
     # build 'Hide these fields' Area
     hide_names = req.session.get('hidefieldchanges', [])
     hide_fields = []
     for field in data['fields']:
         name = field['name']
         checkbox = name in hide_names \
             and tag.input(type='checkbox', checked=True, name=name) \
             or tag.input(type='checkbox', name=name)
         hide_fields.append(tag.label(checkbox, field['label']))
         hide_fields.append(tag.br)
     hide_fields.append(
         tag.input(name='submit', type='submit', value='Hide these fields'))
     transformer = transformer \
         .select('//div[@id="changelog"]') \
         .before(tag.form(tag.input(value='hide changes', id='hidechangesbutton', type='button', style_='float: right;'),
                          tag.div(hide_fields, style='display: none', id='hidefields'),
                          action='#', class_='inlinebuttons hidechanges')).end()
     # build 'show all changes' button
     #        showallbutton = tag.input(value='show all', name='showall', class_='showallbutton', type='submit', style_='float: right;')
     #        showallbutton = tag.form(showallbutton, action='#', method='get', class_='inlinebuttons hidechanges')
     #        transformer = transformer.select('//div[@id="changelog"]').before(showallbutton).end()
     # build 'hide customfield' buttons
     hidebutton = tag.input(value='hide',
                            name="hide",
                            class_='hidebutton',
                            style_='display: none',
                            type='submit')
     hidebutton = tag.form(hidebutton,
                           action='#',
                           method='get',
                           class_='inlinebuttons hidefieldchanges')
     transformer = transformer \
         .select('//div[@id="changelog"]/div[@class="change"]/ul[@class="changes"]/li') \
         .prepend(hidebutton).end()
     # return filtered stream
     return stream | transformer
Example #55
0
    def filter_stream(self, req, method, filename, stream, data):
        if 'TICKET_ADMIN' in req.perm and \
                req.path_info.startswith('/admin/ticket/components'):
            if data.get('component'):
                cc = DefaultCC(self.env, data.get('component').name)
                filter = Transformer('//form[@class="mod"]/fieldset'
                                     '/div[@class="field"][2]')
                filter = filter.after(tag.div("Default CC:",
                                              tag.br(),
                                              tag.input(type='text',
                                                        name='defaultcc',
                                                        value=cc.cc),
                                              class_='field')) \
                               .before(tag.input(type='hidden',
                                                 name='old_name',
                                                 value=cc.name))
                return stream | filter
            else:
                filter = Transformer('//form[@id="addcomponent"]'
                                     '/fieldset/div[@class="buttons"]')
                stream |= filter.before(
                    tag.div("Default CC:",
                            tag.br(),
                            tag.input(type='text', name='defaultcc'),
                            class_='field'))

                default_ccs = DefaultCC.select(self.env)

                stream |= Transformer('//table[@id="complist"]/thead'
                                      '/tr/th[3]') \
                          .after(tag.th('Default CC'))

                components = data.get('components')
                if components:
                    func = self._inject_default_cc_cols(
                        default_ccs, components)
                    stream |= Transformer('//table[@id="complist"]'
                                          '/tbody/tr').apply(func)
                return stream

        return stream