Ejemplo n.º 1
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
Ejemplo n.º 2
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
Ejemplo n.º 3
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)))
Ejemplo n.º 4
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)))
Ejemplo n.º 5
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
Ejemplo n.º 6
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(),
     )
Ejemplo n.º 7
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()
Ejemplo n.º 8
0
    def get_navigation_items(self, req):
        if req.authname and req.authname != 'anonymous':
            # Use the same names as LoginModule to avoid duplicates.
            yield ('metanav', 'login',
                   _('logged in as %(user)s', user=req.authname))
            logout_href = req.href('%s/logout' % self.auth_path_prefix)
            from pkg_resources import parse_version
            if parse_version(trac.__version__) < parse_version('1.0.2'):
                yield ('metanav', 'logout', tag.a(_('Logout'), logout_href))
            else:
                yield ('metanav', 'logout',
                       tag.form(tag.div(
                           tag.button(_('Logout'),
                                      name='logout',
                                      type='submit')),
                                action=logout_href,
                                method='post',
                                id='logout',
                                class_='trac-logout'))
        else:
            text = _('GitHub Login')
            if self.fontawesome_url:
                add_script(req, self.fontawesome_url)
                text = tag(tag.i(class_='fab fa-github-alt'), ' ', text)

            yield ('metanav', 'github_login',
                   tag.a(text,
                         href=req.href('%s/login' % self.auth_path_prefix)))
Ejemplo n.º 9
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)))
Ejemplo n.º 10
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())
Ejemplo n.º 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
Ejemplo n.º 12
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')
Ejemplo n.º 13
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')
Ejemplo n.º 14
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')
Ejemplo n.º 15
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
    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())
Ejemplo n.º 17
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'))
Ejemplo n.º 18
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != 'anonymous':
         yield ('metanav', 'login', _('logged in as %(user)s',
                                      user=req.authname))
         yield ('metanav', 'logout',
                tag.form(tag.div(tag.button(_('Logout'),
                                            name='logout', type='submit')),
                         action=req.href.logout(), method='post',
                         id='logout', class_='trac-logout'))
     else:
         yield ('metanav', 'login',
                tag.a(_('Login'), href=req.href.login()))
Ejemplo n.º 19
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != 'anonymous':
         yield ('metanav', 'login',
                tag_("logged in as %(user)s",
                     user=Chrome(self.env).authorinfo(req, req.authname)))
         yield ('metanav', 'logout',
                tag.form(tag.div(tag.button(_("Logout"),
                                            name='logout', type='submit')),
                         action=req.href.logout(), method='post',
                         id='logout', class_='trac-logout'))
     else:
         yield ('metanav', 'login',
                tag.a(_("Login"), href=req.href.login()))
Ejemplo n.º 20
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')
Ejemplo n.º 21
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",
            )
Ejemplo n.º 22
0
def _logout_form(href, **kwargs):
    '''Return "Logout" "link"

    This version returns a form — styled to look like a link — as used
    by trac >= 1.0.2 (for CSRF protection.)  Unfortunately, this does
    not render nicely in older tracs, since ``trac.css`` does not
    include the proper styling for ``form.trac-logout``.

    '''
    fields = [tag.button(_('Logout'), name='logout', type='submit')]
    for name, value in kwargs.items():
        fields.append(tag.input(type='hidden', name=name, value=value))
    return tag.form(tag.div(*fields),
                    action=href('logout'), id='logout', class_='trac-logout')
Ejemplo n.º 23
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",
            )
Ejemplo n.º 24
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="",
            )
Ejemplo n.º 25
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="",
            )
Ejemplo n.º 26
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')
Ejemplo n.º 27
0
def _logout_form(href, **kwargs):
    '''Return "Logout" "link"

    This version returns a form — styled to look like a link — as used
    by trac >= 1.0.2 (for CSRF protection.)  Unfortunately, this does
    not render nicely in older tracs, since ``trac.css`` does not
    include the proper styling for ``form.trac-logout``.

    '''
    fields = [tag.button(_('Logout'), name='logout', type='submit')]
    for name, value in kwargs.items():
        fields.append(tag.input(type='hidden', name=name, value=value))
    return tag.form(tag.div(*fields),
                    action=href('logout'),
                    id='logout',
                    class_='trac-logout')
Ejemplo n.º 28
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')
    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)
Ejemplo n.º 31
0
    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())
Ejemplo n.º 32
0
 def _clone_form(self, req, ticket, data):
     fields = {}
     for f in data.get('fields', []):
         name = f['name']
         if name == 'summary':
             fields['summary'] = ticket['summary'] + u" (複製)"
         elif name == 'description':
             fields['description'] = u"次のチケットの複製: #%s: \n----\n%s" % \
                 (ticket.id, ticket['description'])
         else:
             fields[name] = ticket[name]
     return tag.form(
         tag.div(
             tag.input(type="submit", name="clone", value=u"複製",
                 title=u"このチケットの複製を作成"),
             [tag.input(type="hidden", name='field_'+n, value=v) for n, v in
                 fields.items()],
             tag.input(type="hidden", name='preview', value=''),
             class_="inlinebuttons"),
         method="post", action=req.href.newticket())
Ejemplo n.º 33
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != 'anonymous':
         # Use the same names as LoginModule to avoid duplicates.
         yield ('metanav', 'login', _('logged in as %(user)s',
                                      user=req.authname))
         from pkg_resources import parse_version
         if parse_version(trac.__version__) < parse_version('1.0.2'):
             yield ('metanav', 'logout',
                    tag.a(_('Logout'), href=req.href.github('logout')))
         else:
             yield ('metanav', 'logout',
                    tag.form(tag.div(tag.button(_('Logout'),
                                                name='logout',
                                                type='submit')),
                             action=req.href.github('logout'),
                             method='post', id='logout',
                             class_='trac-logout'))
     else:
         # Use a different name from LoginModule to allow both in parallel.
         yield ('metanav', 'github_login',
                tag.a(_('GitHub Login'), href=req.href.github('login')))
Ejemplo n.º 34
0
 def get_navigation_items(self, req):
     if req.authname and req.authname != 'anonymous':
         # Use the same names as LoginModule to avoid duplicates.
         yield ('metanav', 'login', _('logged in as %(user)s',
                                      user=req.authname))
         from pkg_resources import parse_version
         if parse_version(trac.__version__) < parse_version('1.0.2'):
             yield ('metanav', 'logout',
                    tag.a(_('Logout'), href=req.href.github('logout')))
         else:
             yield ('metanav', 'logout',
                    tag.form(tag.div(tag.button(_('Logout'),
                                                name='logout',
                                                type='submit')),
                             action=req.href.github('logout'),
                             method='post', id='logout',
                             class_='trac-logout'))
     else:
         # Use a different name from LoginModule to allow both in parallel.
         yield ('metanav', 'github_login',
                tag.a(_('GitHub Login'), href=req.href.github('login')))
Ejemplo n.º 35
0
 def _generate_attachmentflags_fieldset(self,
                                        readonly=True,
                                        current_flags=None,
                                        form=False):
     fields = Fragment()
     for flag in self.known_flags:
         flagid = 'flag_' + flag
         if current_flags and flag in current_flags:
             date = datetime.datetime.fromtimestamp(
                 current_flags[flag]["updated_on"], utc)
             text = tag.span(
                 tag.strong(flag), " set by ",
                 tag.em(current_flags[flag]["updated_by"]), ", ",
                 tag.span(pretty_timedelta(date),
                          title=format_datetime(date)), " ago")
             if readonly == True:
                 fields += tag.input(text, \
                                     type='checkbox', id=flagid, \
                                     name=flagid, checked="checked",
                                     disabled="true") + tag.br()
             else:
                 fields += tag.input(text, \
                                     type='checkbox', id=flagid, \
                                     name=flagid, checked="checked") + tag.br()
         else:
             if readonly == True:
                 fields += tag.input(flag, \
                                     type='checkbox', id=flagid, \
                                     name=flagid, disabled="true") + tag.br()
             else:
                 fields += tag.input(flag, \
                                     type='checkbox', id=flagid, \
                                     name=flagid) + tag.br()
     if form and not readonly:
         return tag.form(tag.fieldset(
             tag.legend("Attachment Flags") + fields,
             tag.input(type="hidden", name="action", value="update_flags"),
             tag.input(type="submit", value="Update flags")),
                         method="POST")
     return tag.fieldset(tag.legend("Attachment Flags") + fields)
Ejemplo n.º 36
0
    def _contruct_buttons(self, req, ticket):
        # Always pass these fields
        default_child_fields = (
                tag.input(type="hidden", name="parent", value=str(ticket.id)),
                )

        #Pass extra fields defined in inherit parameter of parent
        inherited_child_fields = [
                tag.input(type="hidden",name="%s"%field,value=ticket[field]) for field in self.config.getlist('childtickets','parent.%s.inherit' % ticket['type'])
                ]

        # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type).
        restrict_child_types = self.config.getlist('childtickets','parent.%s.restrict_child_type' % ticket['type'],default=[])

        if not restrict_child_types:
            # trac.ini : Default 'type' of child tickets?
            default_child_type = self.config.get('childtickets', 'parent.%s.default_child_type' % ticket['type'], default=self.config.get('ticket','default_type'))

            # ... create a default submit button
            if ticket['status'] == 'closed':
                submit_button_fields = (
                        tag.input(type="submit",disabled="disabled",name="childticket",value="New Child Ticket",title="Create a child ticket"),
                        tag.input(type="hidden", name="type", value=default_child_type),
                        )
            else:
                submit_button_fields = (
                        tag.input(type="submit",name="childticket",value="New Child Ticket",title="Create a child ticket"),
                        tag.input(type="hidden",name="type",value=default_child_type),
                        )
        else:
            if ticket['status'] == 'closed':
                submit_button_fields = [ tag.input(type="submit",disabled="disabled",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ]
            else:
                submit_button_fields = [ tag.input(type="submit",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ]
        buttondiv = tag.form(
                        tag.div(default_child_fields, inherited_child_fields, submit_button_fields, class_="buttons"),
                        method="get", action=req.href.newticket(),
                    )
        return buttondiv
Ejemplo n.º 37
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=_("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())
Ejemplo n.º 38
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)))
Ejemplo n.º 39
0
    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)
Ejemplo n.º 40
0
 def _review_attrs(self, req, changeset):
     review = Review.get(self.env.get_db_cnx(),changeset.rev, self.author(changeset))
     if req.perm.has_permission('CODE_REVIEW'):
         comment = tag.textarea(review.comment, name="review_comment", rows=6, cols=100 )
         if review.status=="ACCEPTED":
             checkbox = tag.input(type="checkbox", name="review_passed", checked="true")
         else:
             checkbox = tag.input(type="checkbox", name="review_passed")
         submit = tag.input(type="hidden", name="review_rev", value=changeset.rev)+ \
             tag.input(type="hidden", name="review_author", value=self.author(changeset))+ \
             tag.input(type="submit", name="review", value="Review")
     else:
         comment = tag.span(review.comment)
         checkbox = tag.span(review.status)
         submit = "";
     return tag.form(
                     tag.dt("Reviewer:",class_="property author"),
                     tag.dd( req.authname,class_="author"),
                     tag.dt("Comment:",class_="property author"),
                     tag.dd( comment ),       
                     tag.dt("Passed:",class_="property author"),
                     tag.dd(checkbox+submit)
                     )       
Ejemplo n.º 41
0
    def filter_stream(self, req, method, filename, stream, data):
        """Return a filtered Genshi event stream, or the original unfiltered
        stream if no match.

        `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.

        See the Genshi documentation for more information.
        """
        if filename == 'ticket.html':
            ticket = data['ticket']
            if ticket.exists:
                sensitive = (ticket.values.get('sensitive') == '1')
                if req.perm.has_permission('SENSITIVE_VIEW'):
                    action = data['ticket'].exists and \
                        req.href.ticket(data['ticket'].id) or \
                        req.href.newticket()
                    form = tag.form(
                        tag.input(
                            id="field-sensitive",
                            name="field_sensitive",
                            value=sensitive and '0' or '1',
                            type='hidden'),
                        tag.input(
                            type="hidden",
                            name="ts",
                            value=data['timestamp']),
                        tag.input(
                            type="hidden",
                            name="action",
                            value=data['action']),
                        tag.input(
                            type="submit",
                            name="submit",
                            class_='btn',
                            # TODO: translations
                            value=sensitive and 'make public' or 'make private'),
                        method="post",
                        id="sensitiveform",
                        action="%s#trac-modify-sensitive" % action,
                    )
                    if sensitive:
                        div = tag.div(
                            # TODO: translations
                            tag.div(
                                form,
                                # XXX i18n TODO tag.span(_("trac_por_ticket_sensitive"),
                                tag.span(u'Il ticket è riservato ai developer e non visibile al cliente',
                                         class_="sensitive-message"),
                                class_="alert alert-success"),
                            id='sensitiveticket')
                    else:
                        div = tag.div(
                            # TODO: translations
                            tag.div(
                                form,
                                # XXX i18n TODO tag.span(_("trac_por_ticket_public"),
                                tag.span(u'Ticket condiviso con il cliente',
                                         class_="sensitive-message"),
                                class_="alert alert-error"),
                            id='sensitiveticket')
                    return stream | \
                        Transformer("//div[@id='ticket']").before(div)
        return stream
Ejemplo n.º 42
0
def AddComment(macro, environ, data, *args, **kwargs):
    """Display an add comment form allowing users to post comments.

    This macro allows you to display an add comment form on the current
    page allowing users to post comments. The comments are added to the
    page's content itself.
    
    **Arguments:** //No Arguments//

    **Example(s):**
    {{{
    <<AddComment>>
    }}}

    <<AddComment>>
    """

    # Setup info and defaults
    parser = environ.parser
    request = environ.request

    page = data["page"]
    page_name = page["name"]
    page_text = page["text"]

    # Get the data from the POST
    comment = request.kwargs.get("comment", "")
    action = request.kwargs.get("action", "")
    author = request.kwargs.get("author", environ._user())

    # Ensure <<AddComment>> is not present in comment, so that infinite
    # recursion does not occur.
    comment = re.sub("(^|[^!])(\<\<AddComment)", "\\1!\\2", comment)

    the_preview = None
    the_comment = None

    # If we are submitting or previewing, inject comment as it should look
    if action == "preview":
        the_preview = tag.div(tag.h1("Preview"), id="preview")
        the_preview += tag.div(parser.generate(comment,
                                               environ=(environ, data)),
                               class_="article")

    # When submitting, inject comment before macro
    if comment and action == "save":
        new_text = ""
        comment_text = "\n==== Comment by %s on %s ====\n\n%s\n\n" % (
            author, time.strftime('%c', time.localtime()), comment)
        for line in page_text.split("\n"):
            if line.find("<<AddComment") == 0:
                new_text += comment_text
            new_text += line + "\n"

        search = environ.search
        storage = environ.storage

        storage.reopen()
        search.update(environ)

        storage.save_text(page_name, new_text, author,
                          "Comment added by %s" % author)

        search.update_page(environ.get_page(page_name),
                           page_name,
                           text=new_text)

        the_comment = tag.div(parser.generate(comment_text,
                                              environ=(environ, data)),
                              class_="article")

    the_form = tag.form(
        tag.input(type="hidden", name="parent", value=page["node"]),
        tag.fieldset(
            tag.legend("Add Comment"),
            tag.p(tag.textarea(
                (not action in ("cancel", "save") and comment or ""),
                id="comment",
                name="comment",
                cols=80,
                rows=5),
                  class_="text"),
            tag.h4(tag.label("Your email or username:"******"author")),
            tag.p(tag.input(id="author",
                            name="author",
                            type="text",
                            value=(not action in ("cancel", "save")) and author
                            or ""),
                  class_="input"),
            tag.p(tag.button("Preview",
                             type="submit",
                             name="action",
                             value="preview"),
                  tag.button("Save",
                             type="submit",
                             name="action",
                             value="save"),
                  tag.button("Cancel",
                             type="submit",
                             name="action",
                             value="cancel"),
                  class_="button"),
        ),
        method="post",
        action="")

    return tag(the_preview, the_comment, the_form)
Ejemplo n.º 43
0
def AddComment(macro, environ, data, *args, **kwargs):
    """Display an add comment form allowing users to post comments.

    This macro allows you to display an add comment form on the current
    page allowing users to post comments. The comments are added to the
    page's content itself.
    
    **Arguments:** //No Arguments//

    **Example(s):**
    {{{
    <<AddComment>>
    }}}

    <<AddComment>>
    """

    # Setup info and defaults
    parser = environ.parser
    request = environ.request

    page = data["page"]
    page_name = page["name"]
    page_text = page["text"]
    
    # Get the data from the POST
    comment = request.kwargs.get("comment", "")
    action = request.kwargs.get("action", "")
    author = request.kwargs.get("author", environ._user())
    
    # Ensure <<AddComment>> is not present in comment, so that infinite
    # recursion does not occur.
    comment = re.sub("(^|[^!])(\<\<AddComment)", "\\1!\\2", comment)
    
    the_preview = None
    the_comment = None

    # If we are submitting or previewing, inject comment as it should look
    if action == "preview":
        the_preview = tag.div(tag.h1("Preview"), id="preview")
        the_preview += tag.div(parser.generate(comment,
            environ=(environ, data)), class_="article")

    # When submitting, inject comment before macro
    if comment and action == "save":
        new_text = ""
        comment_text = "\n==== Comment by %s on %s ====\n\n%s\n\n" % (
                author, time.strftime('%c', time.localtime()), comment)
        for line in page_text.split("\n"):
            if line.find("<<AddComment") == 0:
                new_text += comment_text
            new_text += line + "\n"

        search = environ.search
        storage = environ.storage

        storage.reopen()
        search.update(environ)

        storage.save_text(page_name, new_text, author,
                "Comment added by %s" % author)

        search.update_page(environ.get_page(page_name), page_name,
                text=new_text)

        the_comment = tag.div(parser.generate(comment_text,
            environ=(environ, data)), class_="article")

    the_form = tag.form(
            tag.input(type="hidden", name="parent", value=page["node"]),
            tag.fieldset(
                tag.legend("Add Comment"),
                tag.p(
                    tag.textarea(
                        (not action in ("cancel", "save") and comment or ""),
                        id="comment",
                        name="comment",
                        cols=80, rows=5
                    ),
                    class_="text"
                ),
                tag.h4(tag.label("Your email or username:"******"author")),
                tag.p(
                    tag.input(id="author", name="author", type="text",
                        value=(not action in ("cancel", "save"))
                        and author or ""
                    ),
                    class_="input"
                ),
                tag.p(
                    tag.button("Preview", type="submit",
                        name="action", value="preview"),
                    tag.button("Save", type="submit",
                        name="action", value="save"),
                    tag.button("Cancel", type="submit",
                        name="action", value="cancel"),
                    class_="button"
                ),
            ),
            method="post", action=""
    )

    return tag(the_preview, the_comment, the_form)
Ejemplo n.º 44
0
def enter_secret(macro, environ, *secrets):
    """Macro for entering a secret. Takes a several secrets as args.

    Requires the following keys in the environ:
    
    ``user``
       An instance of :class:`django.contrib.auth.models.User`. Will be used
       to generate a security token of a secret that is only valid for this
       user.

    ``enter_secret_target``
       An url for the action attribute of the form element. Submitting the
       form will generate a POST request with the following data:

       ``secret``
          The secret which was entered by the user

       ``secret_token``
          Occurs several times, one time for each secret that is valid for
          this form. It is a security token that is build by generating
          a HMAC with ``settings.SECRET_KEY`` as key. The message is the
          user id and the valid secret divided by a colon.

    ``all_secrets``
       A list of strings containing all available secrets for this scenario.
    
    ``submitted_secrets``
       A list of strings containing all secrets submitted by the user for
       this scenario.

    ``secret_token_function``
       A function that calculates the secret's security token. Takes an user
       and a secret.

    ``csrf_token``
       Django's CSRF token. Use :func:`django.middleware.csrf.get_token` to
       get it.
    """
    target = environ['enter_secret_target']
    user = environ['user']

    # If all secrets are already submitted, change css class
    solved = all(secret in environ['submitted_secrets'] for secret in secrets)
    css_class = 'enter_secret secret_solved' if solved else 'enter_secret'
    secret_div = tag.div(macro.parsed_body(), class_=css_class)

    if not solved:
        # If there are no secrets in the arguments, we will accept all secrets
        if not secrets:
            secrets = environ['all_secrets']

        form = tag.form(method='post', action=target)

        for secret in secrets:
            secret_token = environ['secret_token_function'](user, secret)
            form.append(
                tag.input(name='secret_token',
                          value=secret_token,
                          type='hidden'))

        form.append(
            tag.input(type='hidden',
                      name='csrfmiddlewaretoken',
                      value=environ['csrf_token']))

        p = tag.p(tag.strong(_('Enter secret:')), ' ')
        p.append(tag.input(name='secret', type='text'))
        p.append(
            tag.input(type='submit', name='enter_secret', value=_('Submit')))
        form.append(p)
        secret_div.append(form)

    form_submitted_secrets = [
        secret for secret in secrets if secret in environ['submitted_secrets']
    ]
    if form_submitted_secrets:
        submitted_div = tag.div(tag.p(_('Already submitted secrets:')),
                                _class='submitted_secrets')
        secret_list = tag.ul()
        for secret in form_submitted_secrets:
            secret_list.append(tag.li(secret))
        submitted_div.append(secret_list)
        secret_div.append(submitted_div)

    return secret_div
Ejemplo n.º 45
0
    def filter_stream(self, req, method, filename, stream, data):
        if not req.path_info.startswith('/ticket/'):
            return stream

        div = None
        link = None
        button = None

        if 'ticket' in data:
            # get parents data
            ticket = data['ticket']
            # title
            div = tag.div(class_='description')
            if 'TICKET_CREATE' in req.perm(ticket.resource) \
                    and ticket['status'] != 'closed':
                opt_inherit = self.env.config.getlist(
                    'subtickets', 'type.%(type)s.child_inherits' % ticket)
                if self.opt_add_style == 'link':
                    inh = {f: ticket[f] for f in opt_inherit}
                    link = tag.a(_('add'),
                                 href=req.href.newticket(parents=ticket.id,
                                                         **inh))
                    link = tag.span('(', link, ')', class_='addsubticket')
                else:
                    inh = [
                        tag.input(type='hidden', name=f, value=ticket[f])
                        for f in opt_inherit
                    ]

                    button = tag.form(tag.div(tag.input(
                        type="submit",
                        value=_("Create"),
                        title=_("Create a child ticket")),
                                              inh,
                                              tag.input(type="hidden",
                                                        name="parents",
                                                        value=str(ticket.id)),
                                              class_="inlinebuttons"),
                                      method="get",
                                      action=req.href.newticket())
            div.append(button)
            div.append(tag.h3(_('Subtickets '), link))

        if 'subtickets' in data:
            # table
            tbody = tag.tbody()
            div.append(tag.table(tbody, class_='subtickets'))
            # tickets
            self._create_subtickets_table(req, data['subtickets'], tbody)

        if div:
            add_stylesheet(req, 'subtickets/css/subtickets.css')
            '''
            If rendered in preview mode, DIV we're interested in isn't a child
            but the root and transformation won't succeed.
            According to HTML specification, id's must be unique within a
            document, so it's safe to omit the leading '.' in XPath expression
            to select all matching regardless of hierarchy their in. 
            '''
            stream |= Transformer('//div[@id="ticket"]').append(div)

        return stream
Ejemplo n.º 46
0
    def filter_stream(self, req, method, filename, stream, data):

        # Tickets will be modified to show the child tickets as a list under the 'Description' section.
        if filename == 'ticket.html':

            # Add our own styles for the ticket lists.
            add_stylesheet(req, 'ct/css/childtickets.css')

            # Get the ticket info.
            ticket = data.get('ticket')

            # Modify ticket.html with sub-ticket table, create button, etc...
            # As follows:
            # - If ticket has no child tickets and child tickets are NOT allowed then skip.
            # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned),
            #   print list of tickets but do not allow any tickets to be created.
            # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned.
            # 
            if ticket and ticket.exists:

                # The additional section on the ticket is built up of (potentially) three parts: header, ticket table, buttons. These
                # are all 'wrapped up' in a 'div' with the 'attachments' id (we'll just pinch this to make look and feel consistent with any
                # future changes!)
                filter = Transformer('//div[@id="ticket"]')
                snippet = tag.div()

                # Are there any child tickets to display?
                childtickets = [ Ticket(self.env,n) for n in self.childtickets.get(ticket.id,[]) ]

                # (tempish) fix for #8612 : force sorting by ticket id
                childtickets = sorted(childtickets, key=lambda t: t.id)

                # Are child tickets allowed?
                childtickets_allowed = self.config.getbool('childtickets', 'parent.%s.allow_child_tickets' % ticket['type'])

                # If there are no childtickets and the ticket should not have any child tickets, we can simply drop out here.
                if not childtickets_allowed and not childtickets:
                    return stream

                # Our 'main' display consists of two divs.
                buttondiv = tag.div()
                tablediv = tag.div()

                # Test if the ticket has children: If so, then list in pretty table.
                if childtickets:

                    # trac.ini : Which columns to display in child ticket listing?
                    columns = self.config.getlist('childtickets', 'parent.%s.table_headers' % ticket['type'], default=['summary','owner'])

                    tablediv = tag.div(
                                tag.table(
                                    tag.thead(
                                        tag.tr(
                                            tag.th("Ticket",class_="id"),
                                            [ tag.th(s.title(),class_=s) for s in columns ])
                                        ),
                                    tag.tbody([ self._table_row(req,tkt,columns) for tkt in childtickets ]),
                                    class_="listing tickets",
                                    ),
                                tag.br(),
                                )

                # trac.ini : child tickets are allowed - Set up 'create new ticket' buttons.
                if childtickets_allowed:

                    # Can user create a new ticket? If not, just display title (ie. no 'create' button).
                    if 'TICKET_CREATE' in req.perm(ticket.resource):

                        # Always pass these fields
                        default_child_fields = (
                                tag.input(type="hidden", name="parent", value='#'+str(ticket.id)),
                                )

                        #Pass extra fields defined in inherit parameter of parent
                        inherited_child_fields = [
                                tag.input(type="hidden",name="%s"%field,value=ticket[field]) for field in self.config.getlist('childtickets','parent.%s.inherit' % ticket['type'])
                                ]

                        # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type).
                        restrict_child_types = self.config.getlist('childtickets','parent.%s.restrict_child_type' % ticket['type'],default=[])

                        if not restrict_child_types:
                            # trac.ini : Default 'type' of child tickets?
                            default_child_type = self.config.get('childtickets', 'parent.%s.default_child_type' % ticket['type'], default=self.config.get('ticket','default_type'))

                            # ... create a default submit button
                            if ticket['status'] == 'closed':
                                submit_button_fields = (
                                        tag.input(type="submit",disabled="disabled",name="childticket",value="New Child Ticket",title="Create a child ticket"),
                                        tag.input(type="hidden", name="type", value=default_child_type),
                                        )
                            else:
                                submit_button_fields = (
                                        tag.input(type="submit",name="childticket",value="New Child Ticket",title="Create a child ticket"),
                                        tag.input(type="hidden",name="type",value=default_child_type),
                                        )
                        else:
                            if ticket['status'] == 'closed':
                                submit_button_fields = [ tag.input(type="submit",disabled="disabled",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ]
                            else:
                                submit_button_fields = [ tag.input(type="submit",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ]
                        buttondiv = tag.form(
                                    tag.div( default_child_fields, inherited_child_fields, submit_button_fields),
                                    method="get", action=req.href.newticket(),
                                    )

                snippet.append(tag.h2("Child Tickets",class_="foldable"))
                snippet.append(tag.div(tablediv, buttondiv, id="childtickets"))

                return stream | filter.after(snippet)

        return stream
Ejemplo n.º 47
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        tag_system = TagSystem(self.env)

        all_releases = natural_sort([r.id for r, _ in
                                     tag_system.query(req, 'realm:wiki release')])
        all_categories = sorted([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki type')])

        hide_release_picker = False
        hide_fieldset_legend = False
        hide_fieldset_description = False
        other = []
        if args:
            categories = []
            releases = []
            for arg in args.split():
                if arg in all_releases:
                    hide_release_picker = True
                    releases.append(arg)
                elif arg in all_categories:
                    categories.append(arg)
                else:
                    other.append(arg)

            if len(categories) or len(releases):
                hide_fieldset_description = True

            if not len(categories):
                categories = all_categories
            elif len(categories) == 1:
                hide_fieldset_legend = True

            if not len(releases):
                releases = all_releases
        else:
            categories = all_categories
            releases = all_releases

        if 'update_th_filter' in req.args:
            show_releases = req.args.get('release', ['0.11'])
            if isinstance(show_releases, basestring):
                show_releases = [show_releases]
            req.session['th_release_filter'] = ','.join(show_releases)
        else:
            show_releases = req.session.get('th_release_filter', '0.11').split(',')

        output = ""
        if not hide_release_picker:
            style = "text-align:right; padding-top:1em; margin-right:5em;"
            form = builder.form('\n', style=style, method="get")

            style = "font-size:xx-small;"
            span = builder.span("Show hacks for releases:", style=style)

            for version in releases:
                inp = builder.input(version, type_="checkbox", name="release",
                                    value=version)
                if version in show_releases:
                    inp(checked="checked")
                span(inp, '\n')

            style = "font-size:xx-small; padding:0; border:solid 1px black;"
            span(builder.input(name="update_th_filter", type_="submit",
                               style=style, value="Update"), '\n')
            form('\n', span, '\n')
            output = "%s%s\n" % (output, form)


        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        for category in categories:
            page = WikiPage(self.env, category)
            match = self.title_extract.search(page.text)
            if match:
                cat_title = '%s' % match.group(1).strip()
                cat_body = self.title_extract.sub('', page.text, 1)
            else:
                cat_title = '%s' % category
                cat_body = page.text
            cat_body = self.self_extract.sub('', cat_body).strip()

            style = "padding:1em; margin:0em 5em 2em 5em; border:1px solid #999;"
            fieldset = builder.fieldset('\n', style=style)
            if not hide_fieldset_legend:
                legend = builder.legend(style="color: #999;")
                legend(builder.a(cat_title, href=self.env.href.wiki(category)))
                fieldset(legend, '\n')
            if not hide_fieldset_description:
                fieldset(builder.p(wiki_to_html(cat_body, self.env, req)))

            ul = builder.ul('\n', class_="listtagged")
            query = 'realm:wiki (%s) %s %s' % \
                (' or '.join(show_releases), category, ' '.join(other))

            lines = 0
            for resource, tags in tag_system.query(req, query):
                # filter out the page used to make important tags
                # persistent
                if resource.id == "tags/persistent":
                    continue

                lines += 1
                li = builder.li(link(resource), ': ')

                page = WikiPage(self.env, resource)
                match = self.title_extract.search(page.text)
                description = "''no description available''"
                if match:
                    if match.group(1):
                        description = match.group(1).strip()

                li(wiki_to_oneliner(description, self.env, req=req))
                if tags:
                    if hide_fieldset_legend == False and category in tags:
                        tags.remove(category)
                        self.log.debug("hide %s: no legend" % category)
                    for o in other:
                        if o in tags: tags.remove(o)
                    rendered_tags = [ link(resource('tag', tag))
                                      for tag in natural_sort(tags) ]

                    span = builder.span(style="font-size:xx-small;")
                    span(' (tags: ', rendered_tags[0],
                       [(', ', tag) for tag in rendered_tags[1:]], ')')
                    li(span)
                ul(li, '\n')

            if lines:
                fieldset(ul, '\n')
            else:
                message = "No results for %s." % \
                    (hide_release_picker and "this version" or "your selection")
                fieldset(builder.p(builder.em(message)), '\n')
            output = "%s%s\n" % (output, fieldset)

        return output
Ejemplo n.º 48
0
    def get_workflow_markup(self, req, base_href, realm, resource):
        rws = ResourceWorkflowState(self.env, resource.id, realm)

        # action_controls is an ordered list of "renders" tuples, where
        # renders is a list of (action_key, label, widgets, hints) representing
        # the user interface for each action
        action_controls = []
        sorted_actions = self.get_available_actions(req,
                                                    realm,
                                                    resource=resource)

        if len(sorted_actions) > 0:
            for action in sorted_actions:
                first_label = None
                hints = []
                widgets = []

                label, widget, hint = self.get_action_markup(
                    req, realm, action[1], resource)

                if not first_label:
                    first_label = label

                widgets.append(widget)
                hints.append(hint)

                action_controls.append(
                    (action[1], first_label, tag(widgets), hints))

            form = tag.form(id='resource_workflow_form',
                            name='resource_workflow_form',
                            action=base_href + '/workflowtransition',
                            method='get')(tag.input(name='id',
                                                    type='hidden',
                                                    value=resource.id),
                                          tag.input(name='res_realm',
                                                    type='hidden',
                                                    value=realm))

            form.append(tag.div()(tag.span()(
                "Current state: %s" % rws['state']), tag.br(), tag.br()))

            for i, ac in enumerate(action_controls):
                # The default action is the first in the action_controls list.
                if i == 0:
                    is_checked = 'true'
                else:
                    is_checked = None

                form.append(
                    tag.input(name='selected_action',
                              type='radio',
                              value=ac[0],
                              checked=is_checked)(ac[1], tag.div()(ac[2],
                                                                   ac[3])))

            form.append(tag.span()(
                tag.br(),
                tag.input(id='resource_workflow_form_submit_button',
                          type='submit',
                          value='Perform Action')))
        else:
            form = tag('')

        return form
Ejemplo n.º 49
0
    def filter_stream(self, req, method, filename, stream, data):

        # Tickets will be modified to show the child tickets as a list under the 'Description' section.
        if filename == 'ticket.html':

            # Get the ticket info.
            ticket = data.get('ticket')

            # Modify ticket.html with sub-ticket table, create button, etc...
            # As follows:
            # - If ticket has no child tickets and child tickets are NOT allowed then skip.
            # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned),
            #   print list of tickets but do not allow any tickets to be created.
            # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned.
            #
            if ticket and ticket.exists:

                filter = Transformer('//div[@class="description"]')
                snippet = tag()

                # Are there any child tickets to display?
                childtickets = [
                    Ticket(self.env, n)
                    for n in self.env.childtickets.get(ticket.id, [])
                ]

                # (tempish) fix for #8612 : force sorting by ticket id
                childtickets = sorted(childtickets, key=lambda t: t.id)

                # trac.ini : Which columns to display in child ticket listing?
                columns = self.config.getlist('childtickets',
                                              'parent.%s.table_headers' %
                                              ticket['type'],
                                              default=['summary', 'owner'])

                # trac.ini : child tickets are allowed.
                if self.config.getbool(
                        'childtickets',
                        'parent.%s.allow_child_tickets' % ticket['type']):

                    # trac.ini : Default 'type' of child tickets?
                    default_child_type = self.config.get(
                        'childtickets',
                        'parent.%s.default_child_type' % ticket['type'],
                        default=self.config.get('ticket', 'default_type'))

                    self.env.log.debug(
                        "TracchildticketsModule : default_child_type: %s" %
                        default_child_type)

                    # Can user create a new ticket? If not, just display title (ie. no 'create' button).
                    if 'TICKET_CREATE' in req.perm(ticket.resource):

                        # Always pass these fields
                        default_child_fields = (tag.input(type="hidden",
                                                          name="parent",
                                                          value='#' +
                                                          str(ticket.id)), )

                        #Pass extra fields defined in inherit parameter of parent
                        inherited_child_fields = [
                            tag.input(type="hidden",
                                      name="%s" % field,
                                      value=ticket[field])
                            for field in self.config.getlist(
                                'childtickets', 'parent.%s.inherit' %
                                ticket['type'])
                        ]

                        # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type).
                        restrict_child_types = self.config.getlist(
                            'childtickets',
                            'parent.%s.restrict_child_type' % ticket['type'],
                            default=[])
                        if not restrict_child_types:
                            # ... create a default submit button
                            submit_button_fields = (
                                tag.input(type="submit",
                                          name="childticket",
                                          value="New Child Ticket",
                                          title="Create a child ticket"),
                                tag.input(type="hidden",
                                          name="type",
                                          value=default_child_type),
                            )
                        else:
                            submit_button_fields = [
                                tag.input(type="submit",
                                          name="type",
                                          value="%s" % ticket_type,
                                          title="Create a %s child ticket" %
                                          ticket_type)
                                for ticket_type in restrict_child_types
                            ]

                        snippet.append(
                            tag.div(
                                tag.form(
                                    tag.div(default_child_fields,
                                            inherited_child_fields,
                                            submit_button_fields,
                                            class_="inlinebuttons"),
                                    method="get",
                                    action=req.href.newticket(),
                                ),
                                tag.h3("Child Tickets",
                                       id="comment:child_tickets"),
                            ))
                    else:
                        snippet.append(
                            tag.div(
                                tag.h3("Child Tickets",
                                       id="comment:child_tickets")))

                # trac.ini : child tickets are NOT allowed but (somehow?!) this parent ticket has children assigned.
                elif childtickets:
                    snippet.append(
                        tag.div(
                            tag.h3("Child Tickets",
                                   id="comment:child_tickets")))

                # Test if the ticket has children: If so, then list in pretty table.
                if childtickets:
                    snippet.append(
                        tag.div(
                            tag.table(
                                tag.thead(
                                    tag.tr(tag.th("Ticket", class_="id"), [
                                        tag.th(s.title(), class_=s)
                                        for s in columns
                                    ])),
                                tag.tbody([
                                    self._table_row(req, tkt, columns)
                                    for tkt in childtickets
                                ]),
                                class_="listing tickets",
                            ), ))
                elif self.config.getbool(
                        'childtickets',
                        'parent.%s.allow_child_tickets' % ticket['type']):
                    snippet.append(tag.div(tag.p("NO SUB-TICKETS.")))

                return stream | filter.append(snippet)

        return stream
Ejemplo n.º 50
0
    def filter_stream(self, req, method, filename, stream, data):
        """
        Quick and dirty solution - modify page on the fly to inject special field. It would be
        nicer if we can do it by creating custom field as this depends on page structure.
        """
        #embed(header='Ticket Stream Filter')
        if filename == 'ticket.html':
            # Disable any direct bounty input
            filter = Transformer('.//input[@id="field-bounty"]')
            stream |= filter.attr("disabled", "disabled")
            
            ticket = data.get('ticket')
            if ticket and ticket.exists:
                identifier = ticket.id
                user = req.authname if req.authname != 'anonymous' else None
                request = self.call_api('GET', '/issue/%s' % identifier)
                fragment = tag()
                sponsorships = {}
                status = self.convert_status(ticket.values['status'])
                owner = ticket.values['owner']
                tooltip = None
                if request != None and (request.status_code == 200 or request.status_code == 404):
                    sponsorships = self.get_sponsorships(identifier)
                    
                    pledged_amount = sum_amounts(sponsorships.values())
                    user_sponsorship = sponsorships.get(user, Sponsorship())

                    # Bounty
                    tooltip = u"Pledged: %d\u20ac" % pledged_amount
                    
                    if status == 'STARTED' or status == 'COMPLETED':
                        confirmed_amount = sum_amounts(sponsorships.values(), ('CONFIRMED', 'VALIDATED', 'REJECTED', 'TRANSFERRED', 'REFUNDED'))
                        tooltip += u" \nConfirmed: %d\u20ac" % confirmed_amount
                    if status == 'COMPLETED':
                        validated_amount = sum_amounts(sponsorships.values(), 'VALIDATED')
                        tooltip += u" \nValidated: %d\u20ac" % validated_amount
                    
                    # Action
                    action = None
                    if (((status == 'STARTED' or status == 'COMPLETED') 
                            and user_sponsorship.status == 'PLEDGED') 
                        or (status == 'STARTED' and user != None and user != owner
                            and user_sponsorship.status == None)):
                        response = self.call_api('GET', '/config/payment_gateways')
                        gateways = response.json().get('gateways')
                        gateway_tags = []
                        if 'DUMMY' in gateways:
                            gateway_tags.append(tag.input(type="submit", value="Payment Card", name='DUMMY'))
                        if 'PAYPAL_STANDARD' in gateways:
                            gateway_tags.append(tag.input(type="submit", value="PayPal", name='PAYPAL_STANDARD'))
                        if 'PAYPAL_ADAPTIVE' in gateways:
                            gateway_tags.append(tag.input(type="submit", value="PayPal", name='PAYPAL_ADAPTIVE'))
                        if user_sponsorship.status == 'PLEDGED':
                            action = tag.form(
                                tag.input(type="button", name="confirm", value=u"Confirm %d\u20ac" % user_sponsorship.amount, id="confirm-button"), 
                                tag.span(gateway_tags, id="confirm-options"), 
                                tag.input(type="submit", name="delete", value="Delete"), 
                                method="post", action=req.href.ticket(identifier, "confirm"))
                        else:
                            #TODO: should be separate action
                            action = tag.form(
                                tag.input(name="amount", type="text", size="3", value="0", pattern="[0-9]*", title="money amount"), 
                                tag.input(type="button", value="Pledge & Confirm", id="confirm-button"), 
                                tag.span(gateway_tags, id="confirm-options"), 
                                method="post", action=req.href.ticket(identifier, "confirm"))

                    elif status == 'COMPLETED' and user_sponsorship.status in ('CONFIRMED', 'REJECTED', 'VALIDATED'):
                        action = tag.form(method="post", action=req.href.ticket(identifier, "validate"))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'REJECTED':
                            action.append(tag.input(type="submit", name='validate', value=u"Validate %d\u20ac" % user_sponsorship.amount))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'VALIDATED':
                            action.append(tag.input(type="submit", name='reject', value="Reject"))
                    elif (status == 'READY' and user != None):
                        if user_sponsorship.status == None:
                            action = tag.form(tag.input(name="amount", type="text", size="3", value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", value="Pledge"), method="post", action=req.href.ticket(identifier, "sponsor"))
                        elif user_sponsorship.status == 'PLEDGED':
                            action = tag.form(tag.input(name="amount", type="text", size=3, value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", name="update", value="Update"), tag.input(type="submit", name="delete", value="Delete"), method="post", action=req.href.ticket(identifier, "update_sponsorship"))
                    
                    elif (user == None):
                        action = tag.span(u"\u00A0", tag.a("Login", href=req.href.login()), " or ", tag.a("Register", href=req.href.register()), " to sponsor")
                    
                    if action != None:
                        fragment.append(" ")
                        fragment.append(action)
                        
                else:
                    error = "Connection error"
                    if request:
                        error = request.json().get("error", "Unknown error")
                    fragment.append(tag.span("[BountyFunding Error]", title=error))
    
                #chrome = Chrome(self.env)
                #chrome.add_jquery_ui(req)
                
                add_stylesheet(req, 'htdocs/styles/bountyfunding.css')
                add_script(req, 'htdocs/scripts/bountyfunding.js')

                if tooltip != None:
                    filter = Transformer('.//td[@headers="h_bounty"]/text()')
                    stream |= filter.wrap(tag.span(title=tooltip))

                filter = Transformer('.//td[@headers="h_bounty"]')
                stream |= filter.attr("class", "bountyfunding")
                stream |= filter.append(fragment)
                
        return stream
Ejemplo n.º 51
0
    def filter_stream(self, req, method, filename, stream, data):

        # Tickets will be modified to show the child tickets as a list under the 'Description' section.
        if filename == 'ticket.html':

            # Get the ticket info.
            ticket = data.get('ticket')

            # Modify ticket.html with sub-ticket table, create button, etc...
            # As follows:
            # - If ticket has no child tickets and child tickets are NOT allowed then skip.
            # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned),
            #   print list of tickets but do not allow any tickets to be created.
            # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned.
            # 
            if ticket and ticket.exists:

                filter = Transformer('//div[@class="description"]')
                snippet = tag()
                
                # Are there any child tickets to display?
                childtickets = [ Ticket(self.env,n) for n in self.env.childtickets.get(ticket.id,[]) ]

                # (tempish) fix for #8612 : force sorting by ticket id
                childtickets = sorted(childtickets, key=lambda t: t.id)


                # trac.ini : Which columns to display in child ticket listing?
                columns = self.config.getlist('childtickets', 'parent.%s.table_headers' % ticket['type'], default=['summary','owner'])

                # trac.ini : child tickets are allowed.
                if self.config.getbool('childtickets', 'parent.%s.allow_child_tickets' % ticket['type']):

                    # trac.ini : Default 'type' of child tickets?
                    default_child_type = self.config.get('childtickets', 'parent.%s.default_child_type' % ticket['type'], default=self.config.get('ticket','default_type'))

                    self.env.log.debug("TracchildticketsModule : default_child_type: %s" % default_child_type)

                    # Can user create a new ticket? If not, just display title (ie. no 'create' button).
                    if 'TICKET_CREATE' in req.perm(ticket.resource):

                        # Always pass these fields
                        default_child_fields = (
                                tag.input(type="hidden", name="parent", value='#'+str(ticket.id)),
                                )

                        #Pass extra fields defined in inherit parameter of parent
                        inherited_child_fields = [
                                tag.input(type="hidden",name="%s"%field,value=ticket[field]) for field in self.config.getlist('childtickets','parent.%s.inherit' % ticket['type'])
                                ]

                        # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type).
                        restrict_child_types = self.config.getlist('childtickets','parent.%s.restrict_child_type' % ticket['type'],default=[])
                        if not restrict_child_types:
                            # ... create a default submit button
                            submit_button_fields = (
                                    tag.input(type="submit",name="childticket",value="New Child Ticket",title="Create a child ticket"),
                                    tag.input(type="hidden", name="type", value=default_child_type),
                                    )
                        else:
                            submit_button_fields = [ tag.input(type="submit",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ]
        
                        snippet.append(tag.div(
                            tag.form(
                                tag.div( default_child_fields, inherited_child_fields, submit_button_fields, class_="inlinebuttons"),                            
                                method="get", action=req.href.newticket(),
                                ),
                            tag.h3("Child Tickets",id="comment:child_tickets"),
                            ))
                    else:
                        snippet.append(tag.div(tag.h3("Child Tickets",id="comment:child_tickets")))

                # trac.ini : child tickets are NOT allowed but (somehow?!) this parent ticket has children assigned.
                elif childtickets:
                    snippet.append(tag.div(tag.h3("Child Tickets",id="comment:child_tickets")))

                # Test if the ticket has children: If so, then list in pretty table.
                if childtickets:
                    snippet.append(
                            tag.div(
                                tag.table(
                                    tag.thead(
                                        tag.tr(
                                            tag.th("Ticket",class_="id"),
                                            [ tag.th(s.title(),class_=s) for s in columns ])
                                        ),
                                    tag.tbody([ self._table_row(req,tkt,columns) for tkt in childtickets ]),
                                    class_="listing tickets",
                                    ),
                                )
                            )
                elif self.config.getbool('childtickets', 'parent.%s.allow_child_tickets' % ticket['type']):
                    snippet.append(tag.div(tag.p("NO SUB-TICKETS.")))

                return stream | filter.append(snippet)

        return stream
Ejemplo n.º 52
0
def enter_secret(macro, environ, *secrets):
    """Macro for entering a secret. Takes a several secrets as args.

    Requires the following keys in the environ:
    
    ``user``
       An instance of :class:`django.contrib.auth.models.User`. Will be used
       to generate a security token of a secret that is only valid for this
       user.

    ``enter_secret_target``
       An url for the action attribute of the form element. Submitting the
       form will generate a POST request with the following data:

       ``secret``
          The secret which was entered by the user

       ``secret_token``
          Occurs several times, one time for each secret that is valid for
          this form. It is a security token that is build by generating
          a HMAC with ``settings.SECRET_KEY`` as key. The message is the
          user id and the valid secret divided by a colon.

    ``all_secrets``
       A list of strings containing all available secrets for this scenario.
    
    ``submitted_secrets``
       A list of strings containing all secrets submitted by the user for
       this scenario.

    ``secret_token_function``
       A function that calculates the secret's security token. Takes an user
       and a secret.

    ``csrf_token``
       Django's CSRF token. Use :func:`django.middleware.csrf.get_token` to
       get it.
    """
    target = environ['enter_secret_target']
    user = environ['user']
    
    # If all secrets are already submitted, change css class
    solved = all(secret in environ['submitted_secrets'] for secret in secrets)
    css_class = 'enter_secret secret_solved' if solved else 'enter_secret'
    secret_div = tag.div(macro.parsed_body(), class_=css_class)
    
    if not solved:
        # If there are no secrets in the arguments, we will accept all secrets
        if not secrets:
            secrets = environ['all_secrets']
        
        form = tag.form(method='post', action=target)
        
        for secret in secrets:
            secret_token = environ['secret_token_function'](user, secret)
            form.append(tag.input(name='secret_token', value=secret_token,
                                  type='hidden'))
    
        form.append(tag.input(type='hidden', name='csrfmiddlewaretoken',
                              value=environ['csrf_token']))

        p = tag.p(tag.strong(_('Enter secret:')), ' ')
        p.append(tag.input(name='secret', type='text'))
        p.append(tag.input(type='submit', name='enter_secret', value=_('Submit')))
        form.append(p)
        secret_div.append(form)

    form_submitted_secrets = [secret for secret in secrets
                         if secret in environ['submitted_secrets']]
    if form_submitted_secrets:
        submitted_div = tag.div(tag.p(_('Already submitted secrets:')),
                                _class='submitted_secrets')
        secret_list = tag.ul()
        for secret in form_submitted_secrets:
            secret_list.append(tag.li(secret))
        submitted_div.append(secret_list)
        secret_div.append(submitted_div)

    return secret_div
Ejemplo n.º 53
0
    def filter_stream(self, req, method, filename, stream, data):
        """
        Quick and dirty solution - modify page on the fly to inject special field. It would be
        nicer if we can do it by creating custom field as this depends on page structure.
        """
        #embed(header='Ticket Stream Filter')
        if filename == 'ticket.html':
            # Disable any direct bounty input
            filter = Transformer('.//input[@id="field-bounty"]')
            stream |= filter.attr("disabled", "disabled")

            ticket = data.get('ticket')
            if ticket and ticket.exists:
                identifier = ticket.id
                user = req.authname if req.authname != 'anonymous' else None
                request = self.call_api('GET', '/issue/%s' % identifier)
                fragment = tag()
                sponsorships = {}
                status = self.convert_status(ticket.values['status'])
                owner = ticket.values['owner']
                tooltip = None
                if request != None and (request.status_code == 200
                                        or request.status_code == 404):
                    sponsorships = self.get_sponsorships(identifier)

                    pledged_amount = sum_amounts(sponsorships.values())
                    user_sponsorship = sponsorships.get(user, Sponsorship())

                    # Bounty
                    tooltip = u"Pledged: %d\u20ac" % pledged_amount

                    if status == 'STARTED' or status == 'COMPLETED':
                        confirmed_amount = sum_amounts(
                            sponsorships.values(),
                            ('CONFIRMED', 'VALIDATED', 'REJECTED',
                             'TRANSFERRED', 'REFUNDED'))
                        tooltip += u" \nConfirmed: %d\u20ac" % confirmed_amount
                    if status == 'COMPLETED':
                        validated_amount = sum_amounts(sponsorships.values(),
                                                       'VALIDATED')
                        tooltip += u" \nValidated: %d\u20ac" % validated_amount

                    # Action
                    action = None
                    if (((status == 'STARTED' or status == 'COMPLETED')
                         and user_sponsorship.status == 'PLEDGED') or
                        (status == 'STARTED' and user != None and user != owner
                         and user_sponsorship.status == None)):
                        response = self.call_api('GET',
                                                 '/config/payment_gateways')
                        gateways = response.json().get('gateways')
                        gateway_tags = []
                        if 'DUMMY' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="Payment Card",
                                          name='DUMMY'))
                        if 'PAYPAL_STANDARD' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="PayPal",
                                          name='PAYPAL_STANDARD'))
                        if 'PAYPAL_ADAPTIVE' in gateways:
                            gateway_tags.append(
                                tag.input(type="submit",
                                          value="PayPal",
                                          name='PAYPAL_ADAPTIVE'))
                        if user_sponsorship.status == 'PLEDGED':
                            action = tag.form(
                                tag.input(type="button",
                                          name="confirm",
                                          value=u"Confirm %d\u20ac" %
                                          user_sponsorship.amount,
                                          id="confirm-button"),
                                tag.span(gateway_tags, id="confirm-options"),
                                tag.input(type="submit",
                                          name="delete",
                                          value="Delete"),
                                method="post",
                                action=req.href.ticket(identifier, "confirm"))
                        else:
                            #TODO: should be separate action
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size="3",
                                          value="0",
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="button",
                                          value="Pledge & Confirm",
                                          id="confirm-button"),
                                tag.span(gateway_tags, id="confirm-options"),
                                method="post",
                                action=req.href.ticket(identifier, "confirm"))

                    elif status == 'COMPLETED' and user_sponsorship.status in (
                            'CONFIRMED', 'REJECTED', 'VALIDATED'):
                        action = tag.form(method="post",
                                          action=req.href.ticket(
                                              identifier, "validate"))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'REJECTED':
                            action.append(
                                tag.input(type="submit",
                                          name='validate',
                                          value=u"Validate %d\u20ac" %
                                          user_sponsorship.amount))
                        if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'VALIDATED':
                            action.append(
                                tag.input(type="submit",
                                          name='reject',
                                          value="Reject"))
                    elif (status == 'READY' and user != None):
                        if user_sponsorship.status == None:
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size="3",
                                          value=user_sponsorship.amount,
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="submit", value="Pledge"),
                                method="post",
                                action=req.href.ticket(identifier, "sponsor"))
                        elif user_sponsorship.status == 'PLEDGED':
                            action = tag.form(
                                tag.input(name="amount",
                                          type="text",
                                          size=3,
                                          value=user_sponsorship.amount,
                                          pattern="[0-9]*",
                                          title="money amount"),
                                tag.input(type="submit",
                                          name="update",
                                          value="Update"),
                                tag.input(type="submit",
                                          name="delete",
                                          value="Delete"),
                                method="post",
                                action=req.href.ticket(identifier,
                                                       "update_sponsorship"))

                    elif (user == None):
                        action = tag.span(
                            u"\u00A0", tag.a("Login",
                                             href=req.href.login()), " or ",
                            tag.a("Register", href=req.href.register()),
                            " to sponsor")

                    if action != None:
                        fragment.append(" ")
                        fragment.append(action)

                else:
                    error = "Connection error"
                    if request:
                        error = request.json().get("error", "Unknown error")
                    fragment.append(
                        tag.span("[BountyFunding Error]", title=error))

                #chrome = Chrome(self.env)
                #chrome.add_jquery_ui(req)

                add_stylesheet(req, 'htdocs/styles/bountyfunding.css')
                add_script(req, 'htdocs/scripts/bountyfunding.js')

                if tooltip != None:
                    filter = Transformer('.//td[@headers="h_bounty"]/text()')
                    stream |= filter.wrap(tag.span(title=tooltip))

                filter = Transformer('.//td[@headers="h_bounty"]')
                stream |= filter.attr("class", "bountyfunding")
                stream |= filter.append(fragment)

        return stream
Ejemplo n.º 54
0
class AddCommentMacro(WikiMacroBase):
    """A macro to add comments to a page. Usage:
    {{{
    [[AddComment]]
    }}}
    The macro accepts one optional argument that allows appending
    to the wiki page even though user may not have modify permission:
    {{{
    [[AddComment(appendonly)]]
    }}}
    """
    implements(IWikiMacroProvider, IRequestFilter, IMacroPoster)

    def expand_macro(self, formatter, name, content):

        args, kw = parse_args(content)
        req = formatter.req
        context = formatter.context

        # Prevent multiple inclusions - store a temp in req
        if hasattr(req, 'addcommentmacro'):
            raise TracError('\'AddComment\' macro cannot be included twice.')
        req.addcommentmacro = True

        # Prevent it being used outside of wiki page context
        resource = context.resource
        if not resource.realm == 'wiki':
            raise TracError(
                '\'AddComment\' macro can only be used in Wiki pages.')

        # Setup info and defaults
        authname = req.authname
        page = WikiPage(self.env, resource)
        page_url = req.href.wiki(resource.id)
        wikipreview = req.args.get("preview", "")

        # Can this user add a comment to this page?
        appendonly = ('appendonly' in args)
        cancomment = False
        if page.readonly:
            if 'WIKI_ADMIN' in req.perm(resource):
                cancomment = True
        elif 'WIKI_MODIFY' in req.perm(resource):
            cancomment = True
        elif appendonly and 'WIKI_VIEW' in req.perm(resource):
            cancomment = True
        else:
            self.log.debug(
                'Insufficient privileges for %s to AddComment to %s',
                req.authname, resource.id)

        # Get the data from the POST
        comment = req.args.get("addcomment", "")
        preview = req.args.get("previewaddcomment", "")
        cancel = req.args.get("canceladdcomment", "")
        submit = req.args.get("submitaddcomment", "")
        if not cancel and req.authname == 'anonymous':
            authname = req.args.get("authoraddcomment", authname)

        # Ensure [[AddComment]] is not present in comment, so that infinite
        # recursion does not occur.
        comment = to_unicode(
            re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', comment))

        the_preview = the_message = the_form = tag()

        # If we are submitting or previewing, inject comment as it should look
        if cancomment and comment and (preview or submit):
            heading = tag.h4("Comment by ",
                             authname,
                             " on ",
                             to_unicode(time.strftime('%c', time.localtime())),
                             id="commentpreview")
            if preview:
                the_preview = tag.div(heading,
                                      format_to_html(self.env, context,
                                                     comment),
                                      class_="wikipage",
                                      id="preview")

        # Check the form_token
        form_ok = True
        if submit and req.args.get('__FORM_TOKEN', '') != req.form_token:
            form_ok = False
            the_message = tag.div(tag.strong("ERROR: "),
                                  "AddComment received incorrect form token. "
                                  "Do you have cookies enabled?",
                                  class_="system-message")

        # When submitting, inject comment before macro
        if comment and submit and cancomment and form_ok:
            submitted = False
            newtext = ""
            for line in page.text.splitlines():
                if line.find('[[AddComment') == 0:
                    newtext += "==== Comment by %s on %s ====\n%s\n\n" % (
                        authname,
                        to_unicode(time.strftime('%c',
                                                 time.localtime())), comment)
                    submitted = True
                newtext += line + "\n"
            if submitted:
                page.text = newtext

                # Let the wiki page manipulators have a look at the
                # submission.
                valid = True
                req.args.setdefault('comment', 'Comment added.')
                try:
                    for manipulator in WikiModule(self.env).page_manipulators:
                        for field, message in manipulator.validate_wiki_page(
                                req, page):
                            valid = False
                            if field:
                                the_message += tag.div(tag.strong(
                                    "invalid field '%s': " % field),
                                                       message,
                                                       class_="system-message")
                            else:
                                the_message += tag.div(tag.strong("invalid: "),
                                                       message,
                                                       class_="system-message")

                # The TracSpamfilterPlugin does not generate messages,
                # but throws RejectContent.
                except TracError, s:
                    valid = False
                    the_message += tag.div(tag.strong("ERROR: "),
                                           s,
                                           class_="system-message")

                if valid:
                    page.save(authname, req.args['comment'],
                              req.environ['REMOTE_ADDR'])
                    # We can't redirect from macro as it will raise RequestDone
                    # which like other macro errors gets swallowed in the Formatter.
                    # We need to re-raise it in a post_process_request instead.
                    try:
                        self.env.log.debug(
                            "AddComment saved - redirecting to: %s" % page_url)
                        req._outheaders = []
                        req.redirect(page_url)
                    except RequestDone:
                        req.addcomment_raise = True
            else:
                the_message = tag.div(
                    tag.strong("ERROR: "), "[[AddComment]] "
                    "macro call must be the only content on its line. "
                    "Could not add comment.",
                    class_="system-message")

        the_form = tag.form(
            tag.fieldset(
                tag.legend("Add comment"),
                tag.div((wikipreview and "Page preview..." or None),
                        tag.textarea((not cancel and comment or ""),
                                     class_="wikitext",
                                     id="addcomment",
                                     name="addcomment",
                                     cols=80,
                                     rows=5,
                                     disabled=(not cancomment and "disabled"
                                               or None)),
                        class_="field"),
                (req.authname == 'anonymous' and tag.div(
                    tag.label("Your email or username:"******"authoraddcomment"),
                    tag.input(id="authoraddcomment",
                              type="text",
                              size=30,
                              value=authname,
                              name="authoraddcomment",
                              disabled=(not cancomment and "disabled"
                                        or None))) or None),
                tag.input(type="hidden",
                          name="__FORM_TOKEN",
                          value=req.form_token),
                tag.div(tag.input(value="Add comment",
                                  type="submit",
                                  name="submitaddcomment",
                                  size=30,
                                  disabled=(not cancomment and "disabled"
                                            or None)),
                        tag.input(value="Preview comment",
                                  type="submit",
                                  name="previewaddcomment",
                                  disabled=(not cancomment and "disabled"
                                            or None)),
                        tag.input(value="Cancel",
                                  type="submit",
                                  name="canceladdcomment",
                                  disabled=(not cancomment and "disabled"
                                            or None)),
                        class_="buttons"),
            ),
            method="post",
            action=page_url + "#commenting",
        )

        if not wikipreview:
            # Wiki edit preview already adds this javascript file
            add_script(req, 'common/js/wikitoolbar.js')

        return tag.div(the_preview, the_message, the_form, id="commenting")